ActivityManagerService.java revision 1f4c02bb18ef8e8cc0fecd6786209089f84de147
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.os.BackgroundThread; 65import com.android.internal.os.BatteryStatsImpl; 66import com.android.internal.os.ProcessCpuTracker; 67import com.android.internal.os.TransferPipe; 68import com.android.internal.os.Zygote; 69import com.android.internal.util.FastPrintWriter; 70import com.android.internal.util.FastXmlSerializer; 71import com.android.internal.util.MemInfoReader; 72import com.android.internal.util.Preconditions; 73import com.android.server.AppOpsService; 74import com.android.server.AttributeCache; 75import com.android.server.IntentResolver; 76import com.android.server.LocalServices; 77import com.android.server.ServiceThread; 78import com.android.server.SystemService; 79import com.android.server.SystemServiceManager; 80import com.android.server.Watchdog; 81import com.android.server.am.ActivityStack.ActivityState; 82import com.android.server.firewall.IntentFirewall; 83import com.android.server.pm.Installer; 84import com.android.server.pm.UserManagerService; 85import com.android.server.statusbar.StatusBarManagerInternal; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.Process; 177import android.os.RemoteCallbackList; 178import android.os.RemoteException; 179import android.os.SELinux; 180import android.os.ServiceManager; 181import android.os.StrictMode; 182import android.os.SystemClock; 183import android.os.SystemProperties; 184import android.os.UpdateLock; 185import android.os.UserHandle; 186import android.os.UserManager; 187import android.provider.Settings; 188import android.text.format.DateUtils; 189import android.text.format.Time; 190import android.util.AtomicFile; 191import android.util.EventLog; 192import android.util.Log; 193import android.util.Pair; 194import android.util.PrintWriterPrinter; 195import android.util.Slog; 196import android.util.SparseArray; 197import android.util.TimeUtils; 198import android.util.Xml; 199import android.view.Gravity; 200import android.view.LayoutInflater; 201import android.view.View; 202import android.view.WindowManager; 203 204import dalvik.system.VMRuntime; 205 206import java.io.BufferedInputStream; 207import java.io.BufferedOutputStream; 208import java.io.DataInputStream; 209import java.io.DataOutputStream; 210import java.io.File; 211import java.io.FileDescriptor; 212import java.io.FileInputStream; 213import java.io.FileNotFoundException; 214import java.io.FileOutputStream; 215import java.io.IOException; 216import java.io.InputStreamReader; 217import java.io.PrintWriter; 218import java.io.StringWriter; 219import java.lang.ref.WeakReference; 220import java.util.ArrayList; 221import java.util.Arrays; 222import java.util.Collections; 223import java.util.Comparator; 224import java.util.HashMap; 225import java.util.HashSet; 226import java.util.Iterator; 227import java.util.List; 228import java.util.Locale; 229import java.util.Map; 230import java.util.Set; 231import java.util.concurrent.atomic.AtomicBoolean; 232import java.util.concurrent.atomic.AtomicLong; 233 234public final class ActivityManagerService extends ActivityManagerNative 235 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 236 237 private static final String USER_DATA_DIR = "/data/user/"; 238 // File that stores last updated system version and called preboot receivers 239 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 240 241 static final String TAG = "ActivityManager"; 242 static final String TAG_MU = "ActivityManagerServiceMU"; 243 static final boolean DEBUG = false; 244 static final boolean localLOGV = DEBUG; 245 static final boolean DEBUG_BACKUP = localLOGV || false; 246 static final boolean DEBUG_BROADCAST = localLOGV || false; 247 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 248 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 249 static final boolean DEBUG_CLEANUP = localLOGV || false; 250 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 251 static final boolean DEBUG_FOCUS = false; 252 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 253 static final boolean DEBUG_MU = localLOGV || false; 254 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 255 static final boolean DEBUG_LRU = localLOGV || false; 256 static final boolean DEBUG_PAUSE = localLOGV || false; 257 static final boolean DEBUG_POWER = localLOGV || false; 258 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 259 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 260 static final boolean DEBUG_PROCESSES = localLOGV || false; 261 static final boolean DEBUG_PROVIDER = localLOGV || false; 262 static final boolean DEBUG_RESULTS = localLOGV || false; 263 static final boolean DEBUG_SERVICE = localLOGV || false; 264 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 265 static final boolean DEBUG_STACK = localLOGV || false; 266 static final boolean DEBUG_SWITCH = localLOGV || false; 267 static final boolean DEBUG_TASKS = localLOGV || false; 268 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 269 static final boolean DEBUG_TRANSITION = localLOGV || false; 270 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 271 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 272 static final boolean DEBUG_VISBILITY = localLOGV || false; 273 static final boolean DEBUG_PSS = localLOGV || false; 274 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 275 static final boolean DEBUG_RECENTS = localLOGV || false; 276 static final boolean VALIDATE_TOKENS = false; 277 static final boolean SHOW_ACTIVITY_START_TIME = true; 278 279 // Control over CPU and battery monitoring. 280 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 281 static final boolean MONITOR_CPU_USAGE = true; 282 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 283 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 284 static final boolean MONITOR_THREAD_CPU_USAGE = false; 285 286 // The flags that are set for all calls we make to the package manager. 287 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 288 289 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 290 291 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 292 293 // Maximum number recent bitmaps to keep in memory. 294 static final int MAX_RECENT_BITMAPS = 5; 295 296 // Amount of time after a call to stopAppSwitches() during which we will 297 // prevent further untrusted switches from happening. 298 static final long APP_SWITCH_DELAY_TIME = 5*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real. 302 static final int PROC_START_TIMEOUT = 10*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real, when the process was 306 // started with a wrapper for instrumentation (such as Valgrind) because it 307 // could take much longer than usual. 308 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 309 310 // How long to wait after going idle before forcing apps to GC. 311 static final int GC_TIMEOUT = 5*1000; 312 313 // The minimum amount of time between successive GC requests for a process. 314 static final int GC_MIN_INTERVAL = 60*1000; 315 316 // The minimum amount of time between successive PSS requests for a process. 317 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process 320 // when the request is due to the memory state being lowered. 321 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 322 323 // The rate at which we check for apps using excessive power -- 15 mins. 324 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on wake locks to start killing things. 328 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on CPU usage to start killing things. 332 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // How long we allow a receiver to run before giving up on it. 335 static final int BROADCAST_FG_TIMEOUT = 10*1000; 336 static final int BROADCAST_BG_TIMEOUT = 60*1000; 337 338 // How long we wait until we timeout on key dispatching. 339 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 340 341 // How long we wait until we timeout on key dispatching during instrumentation. 342 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 343 344 // Amount of time we wait for observers to handle a user switch before 345 // giving up on them and unfreezing the screen. 346 static final int USER_SWITCH_TIMEOUT = 2*1000; 347 348 // Maximum number of users we allow to be running at a time. 349 static final int MAX_RUNNING_USERS = 3; 350 351 // How long to wait in getAssistContextExtras for the activity and foreground services 352 // to respond with the result. 353 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 354 355 // Maximum number of persisted Uri grants a package is allowed 356 static final int MAX_PERSISTED_URI_GRANTS = 128; 357 358 static final int MY_PID = Process.myPid(); 359 360 static final String[] EMPTY_STRING_ARRAY = new String[0]; 361 362 // How many bytes to write into the dropbox log before truncating 363 static final int DROPBOX_MAX_SIZE = 256 * 1024; 364 365 // Access modes for handleIncomingUser. 366 static final int ALLOW_NON_FULL = 0; 367 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 368 static final int ALLOW_FULL_ONLY = 2; 369 370 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 371 372 /** All system services */ 373 SystemServiceManager mSystemServiceManager; 374 375 private Installer mInstaller; 376 377 /** Run all ActivityStacks through this */ 378 ActivityStackSupervisor mStackSupervisor; 379 380 public IntentFirewall mIntentFirewall; 381 382 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 383 // default actuion automatically. Important for devices without direct input 384 // devices. 385 private boolean mShowDialogs = true; 386 387 BroadcastQueue mFgBroadcastQueue; 388 BroadcastQueue mBgBroadcastQueue; 389 // Convenient for easy iteration over the queues. Foreground is first 390 // so that dispatch of foreground broadcasts gets precedence. 391 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 392 393 BroadcastQueue broadcastQueueForIntent(Intent intent) { 394 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 395 if (DEBUG_BACKGROUND_BROADCAST) { 396 Slog.i(TAG, "Broadcast intent " + intent + " on " 397 + (isFg ? "foreground" : "background") 398 + " queue"); 399 } 400 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 401 } 402 403 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 404 for (BroadcastQueue queue : mBroadcastQueues) { 405 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 406 if (r != null) { 407 return r; 408 } 409 } 410 return null; 411 } 412 413 /** 414 * Activity we have told the window manager to have key focus. 415 */ 416 ActivityRecord mFocusedActivity = null; 417 418 /** 419 * List of intents that were used to start the most recent tasks. 420 */ 421 ArrayList<TaskRecord> mRecentTasks; 422 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 423 424 /** 425 * For addAppTask: cached of the last activity component that was added. 426 */ 427 ComponentName mLastAddedTaskComponent; 428 429 /** 430 * For addAppTask: cached of the last activity uid that was added. 431 */ 432 int mLastAddedTaskUid; 433 434 /** 435 * For addAppTask: cached of the last ActivityInfo that was added. 436 */ 437 ActivityInfo mLastAddedTaskActivity; 438 439 public class PendingAssistExtras extends Binder implements Runnable { 440 public final ActivityRecord activity; 441 public final Bundle extras; 442 public final Intent intent; 443 public final String hint; 444 public final int userHandle; 445 public boolean haveResult = false; 446 public Bundle result = null; 447 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 448 String _hint, int _userHandle) { 449 activity = _activity; 450 extras = _extras; 451 intent = _intent; 452 hint = _hint; 453 userHandle = _userHandle; 454 } 455 @Override 456 public void run() { 457 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 458 synchronized (this) { 459 haveResult = true; 460 notifyAll(); 461 } 462 } 463 } 464 465 final ArrayList<PendingAssistExtras> mPendingAssistExtras 466 = new ArrayList<PendingAssistExtras>(); 467 468 /** 469 * Process management. 470 */ 471 final ProcessList mProcessList = new ProcessList(); 472 473 /** 474 * All of the applications we currently have running organized by name. 475 * The keys are strings of the application package name (as 476 * returned by the package manager), and the keys are ApplicationRecord 477 * objects. 478 */ 479 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 480 481 /** 482 * Tracking long-term execution of processes to look for abuse and other 483 * bad app behavior. 484 */ 485 final ProcessStatsService mProcessStats; 486 487 /** 488 * The currently running isolated processes. 489 */ 490 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 491 492 /** 493 * Counter for assigning isolated process uids, to avoid frequently reusing the 494 * same ones. 495 */ 496 int mNextIsolatedProcessUid = 0; 497 498 /** 499 * The currently running heavy-weight process, if any. 500 */ 501 ProcessRecord mHeavyWeightProcess = null; 502 503 /** 504 * The last time that various processes have crashed. 505 */ 506 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 507 508 /** 509 * Information about a process that is currently marked as bad. 510 */ 511 static final class BadProcessInfo { 512 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 513 this.time = time; 514 this.shortMsg = shortMsg; 515 this.longMsg = longMsg; 516 this.stack = stack; 517 } 518 519 final long time; 520 final String shortMsg; 521 final String longMsg; 522 final String stack; 523 } 524 525 /** 526 * Set of applications that we consider to be bad, and will reject 527 * incoming broadcasts from (which the user has no control over). 528 * Processes are added to this set when they have crashed twice within 529 * a minimum amount of time; they are removed from it when they are 530 * later restarted (hopefully due to some user action). The value is the 531 * time it was added to the list. 532 */ 533 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 534 535 /** 536 * All of the processes we currently have running organized by pid. 537 * The keys are the pid running the application. 538 * 539 * <p>NOTE: This object is protected by its own lock, NOT the global 540 * activity manager lock! 541 */ 542 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 543 544 /** 545 * All of the processes that have been forced to be foreground. The key 546 * is the pid of the caller who requested it (we hold a death 547 * link on it). 548 */ 549 abstract class ForegroundToken implements IBinder.DeathRecipient { 550 int pid; 551 IBinder token; 552 } 553 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 554 555 /** 556 * List of records for processes that someone had tried to start before the 557 * system was ready. We don't start them at that point, but ensure they 558 * are started by the time booting is complete. 559 */ 560 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 561 562 /** 563 * List of persistent applications that are in the process 564 * of being started. 565 */ 566 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 567 568 /** 569 * Processes that are being forcibly torn down. 570 */ 571 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 572 573 /** 574 * List of running applications, sorted by recent usage. 575 * The first entry in the list is the least recently used. 576 */ 577 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Where in mLruProcesses that the processes hosting activities start. 581 */ 582 int mLruProcessActivityStart = 0; 583 584 /** 585 * Where in mLruProcesses that the processes hosting services start. 586 * This is after (lower index) than mLruProcessesActivityStart. 587 */ 588 int mLruProcessServiceStart = 0; 589 590 /** 591 * List of processes that should gc as soon as things are idle. 592 */ 593 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 594 595 /** 596 * Processes we want to collect PSS data from. 597 */ 598 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 599 600 /** 601 * Last time we requested PSS data of all processes. 602 */ 603 long mLastFullPssTime = SystemClock.uptimeMillis(); 604 605 /** 606 * If set, the next time we collect PSS data we should do a full collection 607 * with data from native processes and the kernel. 608 */ 609 boolean mFullPssPending = false; 610 611 /** 612 * This is the process holding what we currently consider to be 613 * the "home" activity. 614 */ 615 ProcessRecord mHomeProcess; 616 617 /** 618 * This is the process holding the activity the user last visited that 619 * is in a different process from the one they are currently in. 620 */ 621 ProcessRecord mPreviousProcess; 622 623 /** 624 * The time at which the previous process was last visible. 625 */ 626 long mPreviousProcessVisibleTime; 627 628 /** 629 * Which uses have been started, so are allowed to run code. 630 */ 631 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 632 633 /** 634 * LRU list of history of current users. Most recently current is at the end. 635 */ 636 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 637 638 /** 639 * Constant array of the users that are currently started. 640 */ 641 int[] mStartedUserArray = new int[] { 0 }; 642 643 /** 644 * Registered observers of the user switching mechanics. 645 */ 646 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 647 = new RemoteCallbackList<IUserSwitchObserver>(); 648 649 /** 650 * Currently active user switch. 651 */ 652 Object mCurUserSwitchCallback; 653 654 /** 655 * Packages that the user has asked to have run in screen size 656 * compatibility mode instead of filling the screen. 657 */ 658 final CompatModePackages mCompatModePackages; 659 660 /** 661 * Set of IntentSenderRecord objects that are currently active. 662 */ 663 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 664 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 665 666 /** 667 * Fingerprints (hashCode()) of stack traces that we've 668 * already logged DropBox entries for. Guarded by itself. If 669 * something (rogue user app) forces this over 670 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 671 */ 672 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 673 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 674 675 /** 676 * Strict Mode background batched logging state. 677 * 678 * The string buffer is guarded by itself, and its lock is also 679 * used to determine if another batched write is already 680 * in-flight. 681 */ 682 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 683 684 /** 685 * Keeps track of all IIntentReceivers that have been registered for 686 * broadcasts. Hash keys are the receiver IBinder, hash value is 687 * a ReceiverList. 688 */ 689 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 690 new HashMap<IBinder, ReceiverList>(); 691 692 /** 693 * Resolver for broadcast intents to registered receivers. 694 * Holds BroadcastFilter (subclass of IntentFilter). 695 */ 696 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 697 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 698 @Override 699 protected boolean allowFilterResult( 700 BroadcastFilter filter, List<BroadcastFilter> dest) { 701 IBinder target = filter.receiverList.receiver.asBinder(); 702 for (int i=dest.size()-1; i>=0; i--) { 703 if (dest.get(i).receiverList.receiver.asBinder() == target) { 704 return false; 705 } 706 } 707 return true; 708 } 709 710 @Override 711 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 712 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 713 || userId == filter.owningUserId) { 714 return super.newResult(filter, match, userId); 715 } 716 return null; 717 } 718 719 @Override 720 protected BroadcastFilter[] newArray(int size) { 721 return new BroadcastFilter[size]; 722 } 723 724 @Override 725 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 726 return packageName.equals(filter.packageName); 727 } 728 }; 729 730 /** 731 * State of all active sticky broadcasts per user. Keys are the action of the 732 * sticky Intent, values are an ArrayList of all broadcasted intents with 733 * that action (which should usually be one). The SparseArray is keyed 734 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 735 * for stickies that are sent to all users. 736 */ 737 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 738 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 739 740 final ActiveServices mServices; 741 742 /** 743 * Backup/restore process management 744 */ 745 String mBackupAppName = null; 746 BackupRecord mBackupTarget = null; 747 748 final ProviderMap mProviderMap; 749 750 /** 751 * List of content providers who have clients waiting for them. The 752 * application is currently being launched and the provider will be 753 * removed from this list once it is published. 754 */ 755 final ArrayList<ContentProviderRecord> mLaunchingProviders 756 = new ArrayList<ContentProviderRecord>(); 757 758 /** 759 * File storing persisted {@link #mGrantedUriPermissions}. 760 */ 761 private final AtomicFile mGrantFile; 762 763 /** XML constants used in {@link #mGrantFile} */ 764 private static final String TAG_URI_GRANTS = "uri-grants"; 765 private static final String TAG_URI_GRANT = "uri-grant"; 766 private static final String ATTR_USER_HANDLE = "userHandle"; 767 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 768 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 769 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 770 private static final String ATTR_TARGET_PKG = "targetPkg"; 771 private static final String ATTR_URI = "uri"; 772 private static final String ATTR_MODE_FLAGS = "modeFlags"; 773 private static final String ATTR_CREATED_TIME = "createdTime"; 774 private static final String ATTR_PREFIX = "prefix"; 775 776 /** 777 * Global set of specific {@link Uri} permissions that have been granted. 778 * This optimized lookup structure maps from {@link UriPermission#targetUid} 779 * to {@link UriPermission#uri} to {@link UriPermission}. 780 */ 781 @GuardedBy("this") 782 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 783 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 784 785 public static class GrantUri { 786 public final int sourceUserId; 787 public final Uri uri; 788 public boolean prefix; 789 790 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 791 this.sourceUserId = sourceUserId; 792 this.uri = uri; 793 this.prefix = prefix; 794 } 795 796 @Override 797 public int hashCode() { 798 int hashCode = 1; 799 hashCode = 31 * hashCode + sourceUserId; 800 hashCode = 31 * hashCode + uri.hashCode(); 801 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 802 return hashCode; 803 } 804 805 @Override 806 public boolean equals(Object o) { 807 if (o instanceof GrantUri) { 808 GrantUri other = (GrantUri) o; 809 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 810 && prefix == other.prefix; 811 } 812 return false; 813 } 814 815 @Override 816 public String toString() { 817 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 818 if (prefix) result += " [prefix]"; 819 return result; 820 } 821 822 public String toSafeString() { 823 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 824 if (prefix) result += " [prefix]"; 825 return result; 826 } 827 828 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 829 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 830 ContentProvider.getUriWithoutUserId(uri), false); 831 } 832 } 833 834 CoreSettingsObserver mCoreSettingsObserver; 835 836 /** 837 * Thread-local storage used to carry caller permissions over through 838 * indirect content-provider access. 839 */ 840 private class Identity { 841 public int pid; 842 public int uid; 843 844 Identity(int _pid, int _uid) { 845 pid = _pid; 846 uid = _uid; 847 } 848 } 849 850 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 851 852 /** 853 * All information we have collected about the runtime performance of 854 * any user id that can impact battery performance. 855 */ 856 final BatteryStatsService mBatteryStatsService; 857 858 /** 859 * Information about component usage 860 */ 861 UsageStatsManagerInternal mUsageStatsService; 862 863 /** 864 * Information about and control over application operations 865 */ 866 final AppOpsService mAppOpsService; 867 868 /** 869 * Save recent tasks information across reboots. 870 */ 871 final TaskPersister mTaskPersister; 872 873 /** 874 * Current configuration information. HistoryRecord objects are given 875 * a reference to this object to indicate which configuration they are 876 * currently running in, so this object must be kept immutable. 877 */ 878 Configuration mConfiguration = new Configuration(); 879 880 /** 881 * Current sequencing integer of the configuration, for skipping old 882 * configurations. 883 */ 884 int mConfigurationSeq = 0; 885 886 /** 887 * Hardware-reported OpenGLES version. 888 */ 889 final int GL_ES_VERSION; 890 891 /** 892 * List of initialization arguments to pass to all processes when binding applications to them. 893 * For example, references to the commonly used services. 894 */ 895 HashMap<String, IBinder> mAppBindArgs; 896 897 /** 898 * Temporary to avoid allocations. Protected by main lock. 899 */ 900 final StringBuilder mStringBuilder = new StringBuilder(256); 901 902 /** 903 * Used to control how we initialize the service. 904 */ 905 ComponentName mTopComponent; 906 String mTopAction = Intent.ACTION_MAIN; 907 String mTopData; 908 boolean mProcessesReady = false; 909 boolean mSystemReady = false; 910 boolean mBooting = false; 911 boolean mCallFinishBooting = false; 912 boolean mBootAnimationComplete = false; 913 boolean mWaitingUpdate = false; 914 boolean mDidUpdate = false; 915 boolean mOnBattery = false; 916 boolean mLaunchWarningShown = false; 917 918 Context mContext; 919 920 int mFactoryTest; 921 922 boolean mCheckedForSetup; 923 924 /** 925 * The time at which we will allow normal application switches again, 926 * after a call to {@link #stopAppSwitches()}. 927 */ 928 long mAppSwitchesAllowedTime; 929 930 /** 931 * This is set to true after the first switch after mAppSwitchesAllowedTime 932 * is set; any switches after that will clear the time. 933 */ 934 boolean mDidAppSwitch; 935 936 /** 937 * Last time (in realtime) at which we checked for power usage. 938 */ 939 long mLastPowerCheckRealtime; 940 941 /** 942 * Last time (in uptime) at which we checked for power usage. 943 */ 944 long mLastPowerCheckUptime; 945 946 /** 947 * Set while we are wanting to sleep, to prevent any 948 * activities from being started/resumed. 949 */ 950 private boolean mSleeping = false; 951 952 /** 953 * Set while we are running a voice interaction. This overrides 954 * sleeping while it is active. 955 */ 956 private boolean mRunningVoice = false; 957 958 /** 959 * State of external calls telling us if the device is asleep. 960 */ 961 private boolean mWentToSleep = false; 962 963 static final int LOCK_SCREEN_HIDDEN = 0; 964 static final int LOCK_SCREEN_LEAVING = 1; 965 static final int LOCK_SCREEN_SHOWN = 2; 966 /** 967 * State of external call telling us if the lock screen is shown. 968 */ 969 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 970 971 /** 972 * Set if we are shutting down the system, similar to sleeping. 973 */ 974 boolean mShuttingDown = false; 975 976 /** 977 * Current sequence id for oom_adj computation traversal. 978 */ 979 int mAdjSeq = 0; 980 981 /** 982 * Current sequence id for process LRU updating. 983 */ 984 int mLruSeq = 0; 985 986 /** 987 * Keep track of the non-cached/empty process we last found, to help 988 * determine how to distribute cached/empty processes next time. 989 */ 990 int mNumNonCachedProcs = 0; 991 992 /** 993 * Keep track of the number of cached hidden procs, to balance oom adj 994 * distribution between those and empty procs. 995 */ 996 int mNumCachedHiddenProcs = 0; 997 998 /** 999 * Keep track of the number of service processes we last found, to 1000 * determine on the next iteration which should be B services. 1001 */ 1002 int mNumServiceProcs = 0; 1003 int mNewNumAServiceProcs = 0; 1004 int mNewNumServiceProcs = 0; 1005 1006 /** 1007 * Allow the current computed overall memory level of the system to go down? 1008 * This is set to false when we are killing processes for reasons other than 1009 * memory management, so that the now smaller process list will not be taken as 1010 * an indication that memory is tighter. 1011 */ 1012 boolean mAllowLowerMemLevel = false; 1013 1014 /** 1015 * The last computed memory level, for holding when we are in a state that 1016 * processes are going away for other reasons. 1017 */ 1018 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1019 1020 /** 1021 * The last total number of process we have, to determine if changes actually look 1022 * like a shrinking number of process due to lower RAM. 1023 */ 1024 int mLastNumProcesses; 1025 1026 /** 1027 * The uptime of the last time we performed idle maintenance. 1028 */ 1029 long mLastIdleTime = SystemClock.uptimeMillis(); 1030 1031 /** 1032 * Total time spent with RAM that has been added in the past since the last idle time. 1033 */ 1034 long mLowRamTimeSinceLastIdle = 0; 1035 1036 /** 1037 * If RAM is currently low, when that horrible situation started. 1038 */ 1039 long mLowRamStartTime = 0; 1040 1041 /** 1042 * For reporting to battery stats the current top application. 1043 */ 1044 private String mCurResumedPackage = null; 1045 private int mCurResumedUid = -1; 1046 1047 /** 1048 * For reporting to battery stats the apps currently running foreground 1049 * service. The ProcessMap is package/uid tuples; each of these contain 1050 * an array of the currently foreground processes. 1051 */ 1052 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1053 = new ProcessMap<ArrayList<ProcessRecord>>(); 1054 1055 /** 1056 * This is set if we had to do a delayed dexopt of an app before launching 1057 * it, to increase the ANR timeouts in that case. 1058 */ 1059 boolean mDidDexOpt; 1060 1061 /** 1062 * Set if the systemServer made a call to enterSafeMode. 1063 */ 1064 boolean mSafeMode; 1065 1066 String mDebugApp = null; 1067 boolean mWaitForDebugger = false; 1068 boolean mDebugTransient = false; 1069 String mOrigDebugApp = null; 1070 boolean mOrigWaitForDebugger = false; 1071 boolean mAlwaysFinishActivities = false; 1072 IActivityController mController = null; 1073 String mProfileApp = null; 1074 ProcessRecord mProfileProc = null; 1075 String mProfileFile; 1076 ParcelFileDescriptor mProfileFd; 1077 int mSamplingInterval = 0; 1078 boolean mAutoStopProfiler = false; 1079 int mProfileType = 0; 1080 String mOpenGlTraceApp = null; 1081 1082 static class ProcessChangeItem { 1083 static final int CHANGE_ACTIVITIES = 1<<0; 1084 static final int CHANGE_PROCESS_STATE = 1<<1; 1085 int changes; 1086 int uid; 1087 int pid; 1088 int processState; 1089 boolean foregroundActivities; 1090 } 1091 1092 final RemoteCallbackList<IProcessObserver> mProcessObservers 1093 = new RemoteCallbackList<IProcessObserver>(); 1094 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1095 1096 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1097 = new ArrayList<ProcessChangeItem>(); 1098 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1099 = new ArrayList<ProcessChangeItem>(); 1100 1101 /** 1102 * Runtime CPU use collection thread. This object's lock is used to 1103 * perform synchronization with the thread (notifying it to run). 1104 */ 1105 final Thread mProcessCpuThread; 1106 1107 /** 1108 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1109 * Must acquire this object's lock when accessing it. 1110 * NOTE: this lock will be held while doing long operations (trawling 1111 * through all processes in /proc), so it should never be acquired by 1112 * any critical paths such as when holding the main activity manager lock. 1113 */ 1114 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1115 MONITOR_THREAD_CPU_USAGE); 1116 final AtomicLong mLastCpuTime = new AtomicLong(0); 1117 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1118 1119 long mLastWriteTime = 0; 1120 1121 /** 1122 * Used to retain an update lock when the foreground activity is in 1123 * immersive mode. 1124 */ 1125 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1126 1127 /** 1128 * Set to true after the system has finished booting. 1129 */ 1130 boolean mBooted = false; 1131 1132 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1133 int mProcessLimitOverride = -1; 1134 1135 WindowManagerService mWindowManager; 1136 1137 final ActivityThread mSystemThread; 1138 1139 // Holds the current foreground user's id 1140 int mCurrentUserId = 0; 1141 // Holds the target user's id during a user switch 1142 int mTargetUserId = UserHandle.USER_NULL; 1143 // If there are multiple profiles for the current user, their ids are here 1144 // Currently only the primary user can have managed profiles 1145 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1146 1147 /** 1148 * Mapping from each known user ID to the profile group ID it is associated with. 1149 */ 1150 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1151 1152 private UserManagerService mUserManager; 1153 1154 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1155 final ProcessRecord mApp; 1156 final int mPid; 1157 final IApplicationThread mAppThread; 1158 1159 AppDeathRecipient(ProcessRecord app, int pid, 1160 IApplicationThread thread) { 1161 if (localLOGV) Slog.v( 1162 TAG, "New death recipient " + this 1163 + " for thread " + thread.asBinder()); 1164 mApp = app; 1165 mPid = pid; 1166 mAppThread = thread; 1167 } 1168 1169 @Override 1170 public void binderDied() { 1171 if (localLOGV) Slog.v( 1172 TAG, "Death received in " + this 1173 + " for thread " + mAppThread.asBinder()); 1174 synchronized(ActivityManagerService.this) { 1175 appDiedLocked(mApp, mPid, mAppThread); 1176 } 1177 } 1178 } 1179 1180 static final int SHOW_ERROR_MSG = 1; 1181 static final int SHOW_NOT_RESPONDING_MSG = 2; 1182 static final int SHOW_FACTORY_ERROR_MSG = 3; 1183 static final int UPDATE_CONFIGURATION_MSG = 4; 1184 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1185 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1186 static final int SERVICE_TIMEOUT_MSG = 12; 1187 static final int UPDATE_TIME_ZONE = 13; 1188 static final int SHOW_UID_ERROR_MSG = 14; 1189 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1190 static final int PROC_START_TIMEOUT_MSG = 20; 1191 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1192 static final int KILL_APPLICATION_MSG = 22; 1193 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1194 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1195 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1196 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1197 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1198 static final int CLEAR_DNS_CACHE_MSG = 28; 1199 static final int UPDATE_HTTP_PROXY_MSG = 29; 1200 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1201 static final int DISPATCH_PROCESSES_CHANGED = 31; 1202 static final int DISPATCH_PROCESS_DIED = 32; 1203 static final int REPORT_MEM_USAGE_MSG = 33; 1204 static final int REPORT_USER_SWITCH_MSG = 34; 1205 static final int CONTINUE_USER_SWITCH_MSG = 35; 1206 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1207 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1208 static final int PERSIST_URI_GRANTS_MSG = 38; 1209 static final int REQUEST_ALL_PSS_MSG = 39; 1210 static final int START_PROFILES_MSG = 40; 1211 static final int UPDATE_TIME = 41; 1212 static final int SYSTEM_USER_START_MSG = 42; 1213 static final int SYSTEM_USER_CURRENT_MSG = 43; 1214 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1215 static final int FINISH_BOOTING_MSG = 45; 1216 static final int START_USER_SWITCH_MSG = 46; 1217 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1218 static final int DISMISS_DIALOG_MSG = 48; 1219 1220 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1221 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1222 static final int FIRST_COMPAT_MODE_MSG = 300; 1223 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1224 1225 CompatModeDialog mCompatModeDialog; 1226 long mLastMemUsageReportTime = 0; 1227 1228 /** 1229 * Flag whether the current user is a "monkey", i.e. whether 1230 * the UI is driven by a UI automation tool. 1231 */ 1232 private boolean mUserIsMonkey; 1233 1234 /** Flag whether the device has a Recents UI */ 1235 boolean mHasRecents; 1236 1237 /** The dimensions of the thumbnails in the Recents UI. */ 1238 int mThumbnailWidth; 1239 int mThumbnailHeight; 1240 1241 final ServiceThread mHandlerThread; 1242 final MainHandler mHandler; 1243 1244 final class MainHandler extends Handler { 1245 public MainHandler(Looper looper) { 1246 super(looper, null, true); 1247 } 1248 1249 @Override 1250 public void handleMessage(Message msg) { 1251 switch (msg.what) { 1252 case SHOW_ERROR_MSG: { 1253 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1254 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1255 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1256 synchronized (ActivityManagerService.this) { 1257 ProcessRecord proc = (ProcessRecord)data.get("app"); 1258 AppErrorResult res = (AppErrorResult) data.get("result"); 1259 if (proc != null && proc.crashDialog != null) { 1260 Slog.e(TAG, "App already has crash dialog: " + proc); 1261 if (res != null) { 1262 res.set(0); 1263 } 1264 return; 1265 } 1266 boolean isBackground = (UserHandle.getAppId(proc.uid) 1267 >= Process.FIRST_APPLICATION_UID 1268 && proc.pid != MY_PID); 1269 for (int userId : mCurrentProfileIds) { 1270 isBackground &= (proc.userId != userId); 1271 } 1272 if (isBackground && !showBackground) { 1273 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1274 if (res != null) { 1275 res.set(0); 1276 } 1277 return; 1278 } 1279 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1280 Dialog d = new AppErrorDialog(mContext, 1281 ActivityManagerService.this, res, proc); 1282 d.show(); 1283 proc.crashDialog = d; 1284 } else { 1285 // The device is asleep, so just pretend that the user 1286 // saw a crash dialog and hit "force quit". 1287 if (res != null) { 1288 res.set(0); 1289 } 1290 } 1291 } 1292 1293 ensureBootCompleted(); 1294 } break; 1295 case SHOW_NOT_RESPONDING_MSG: { 1296 synchronized (ActivityManagerService.this) { 1297 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1298 ProcessRecord proc = (ProcessRecord)data.get("app"); 1299 if (proc != null && proc.anrDialog != null) { 1300 Slog.e(TAG, "App already has anr dialog: " + proc); 1301 return; 1302 } 1303 1304 Intent intent = new Intent("android.intent.action.ANR"); 1305 if (!mProcessesReady) { 1306 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1307 | Intent.FLAG_RECEIVER_FOREGROUND); 1308 } 1309 broadcastIntentLocked(null, null, intent, 1310 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1311 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1312 1313 if (mShowDialogs) { 1314 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1315 mContext, proc, (ActivityRecord)data.get("activity"), 1316 msg.arg1 != 0); 1317 d.show(); 1318 proc.anrDialog = d; 1319 } else { 1320 // Just kill the app if there is no dialog to be shown. 1321 killAppAtUsersRequest(proc, null); 1322 } 1323 } 1324 1325 ensureBootCompleted(); 1326 } break; 1327 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1328 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1329 synchronized (ActivityManagerService.this) { 1330 ProcessRecord proc = (ProcessRecord) data.get("app"); 1331 if (proc == null) { 1332 Slog.e(TAG, "App not found when showing strict mode dialog."); 1333 break; 1334 } 1335 if (proc.crashDialog != null) { 1336 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1337 return; 1338 } 1339 AppErrorResult res = (AppErrorResult) data.get("result"); 1340 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1341 Dialog d = new StrictModeViolationDialog(mContext, 1342 ActivityManagerService.this, res, proc); 1343 d.show(); 1344 proc.crashDialog = d; 1345 } else { 1346 // The device is asleep, so just pretend that the user 1347 // saw a crash dialog and hit "force quit". 1348 res.set(0); 1349 } 1350 } 1351 ensureBootCompleted(); 1352 } break; 1353 case SHOW_FACTORY_ERROR_MSG: { 1354 Dialog d = new FactoryErrorDialog( 1355 mContext, msg.getData().getCharSequence("msg")); 1356 d.show(); 1357 ensureBootCompleted(); 1358 } break; 1359 case UPDATE_CONFIGURATION_MSG: { 1360 final ContentResolver resolver = mContext.getContentResolver(); 1361 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1362 } break; 1363 case GC_BACKGROUND_PROCESSES_MSG: { 1364 synchronized (ActivityManagerService.this) { 1365 performAppGcsIfAppropriateLocked(); 1366 } 1367 } break; 1368 case WAIT_FOR_DEBUGGER_MSG: { 1369 synchronized (ActivityManagerService.this) { 1370 ProcessRecord app = (ProcessRecord)msg.obj; 1371 if (msg.arg1 != 0) { 1372 if (!app.waitedForDebugger) { 1373 Dialog d = new AppWaitingForDebuggerDialog( 1374 ActivityManagerService.this, 1375 mContext, app); 1376 app.waitDialog = d; 1377 app.waitedForDebugger = true; 1378 d.show(); 1379 } 1380 } else { 1381 if (app.waitDialog != null) { 1382 app.waitDialog.dismiss(); 1383 app.waitDialog = null; 1384 } 1385 } 1386 } 1387 } break; 1388 case SERVICE_TIMEOUT_MSG: { 1389 if (mDidDexOpt) { 1390 mDidDexOpt = false; 1391 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1392 nmsg.obj = msg.obj; 1393 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1394 return; 1395 } 1396 mServices.serviceTimeout((ProcessRecord)msg.obj); 1397 } break; 1398 case UPDATE_TIME_ZONE: { 1399 synchronized (ActivityManagerService.this) { 1400 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1401 ProcessRecord r = mLruProcesses.get(i); 1402 if (r.thread != null) { 1403 try { 1404 r.thread.updateTimeZone(); 1405 } catch (RemoteException ex) { 1406 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1407 } 1408 } 1409 } 1410 } 1411 } break; 1412 case CLEAR_DNS_CACHE_MSG: { 1413 synchronized (ActivityManagerService.this) { 1414 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1415 ProcessRecord r = mLruProcesses.get(i); 1416 if (r.thread != null) { 1417 try { 1418 r.thread.clearDnsCache(); 1419 } catch (RemoteException ex) { 1420 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1421 } 1422 } 1423 } 1424 } 1425 } break; 1426 case UPDATE_HTTP_PROXY_MSG: { 1427 ProxyInfo proxy = (ProxyInfo)msg.obj; 1428 String host = ""; 1429 String port = ""; 1430 String exclList = ""; 1431 Uri pacFileUrl = Uri.EMPTY; 1432 if (proxy != null) { 1433 host = proxy.getHost(); 1434 port = Integer.toString(proxy.getPort()); 1435 exclList = proxy.getExclusionListAsString(); 1436 pacFileUrl = proxy.getPacFileUrl(); 1437 } 1438 synchronized (ActivityManagerService.this) { 1439 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1440 ProcessRecord r = mLruProcesses.get(i); 1441 if (r.thread != null) { 1442 try { 1443 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1444 } catch (RemoteException ex) { 1445 Slog.w(TAG, "Failed to update http proxy for: " + 1446 r.info.processName); 1447 } 1448 } 1449 } 1450 } 1451 } break; 1452 case SHOW_UID_ERROR_MSG: { 1453 if (mShowDialogs) { 1454 AlertDialog d = new BaseErrorDialog(mContext); 1455 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1456 d.setCancelable(false); 1457 d.setTitle(mContext.getText(R.string.android_system_label)); 1458 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1459 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1460 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1461 d.show(); 1462 } 1463 } break; 1464 case SHOW_FINGERPRINT_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_manufacturer)); 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 PROC_START_TIMEOUT_MSG: { 1477 if (mDidDexOpt) { 1478 mDidDexOpt = false; 1479 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1480 nmsg.obj = msg.obj; 1481 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1482 return; 1483 } 1484 ProcessRecord app = (ProcessRecord)msg.obj; 1485 synchronized (ActivityManagerService.this) { 1486 processStartTimedOutLocked(app); 1487 } 1488 } break; 1489 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1490 synchronized (ActivityManagerService.this) { 1491 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1492 } 1493 } break; 1494 case KILL_APPLICATION_MSG: { 1495 synchronized (ActivityManagerService.this) { 1496 int appid = msg.arg1; 1497 boolean restart = (msg.arg2 == 1); 1498 Bundle bundle = (Bundle)msg.obj; 1499 String pkg = bundle.getString("pkg"); 1500 String reason = bundle.getString("reason"); 1501 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1502 false, UserHandle.USER_ALL, reason); 1503 } 1504 } break; 1505 case FINALIZE_PENDING_INTENT_MSG: { 1506 ((PendingIntentRecord)msg.obj).completeFinalize(); 1507 } break; 1508 case POST_HEAVY_NOTIFICATION_MSG: { 1509 INotificationManager inm = NotificationManager.getService(); 1510 if (inm == null) { 1511 return; 1512 } 1513 1514 ActivityRecord root = (ActivityRecord)msg.obj; 1515 ProcessRecord process = root.app; 1516 if (process == null) { 1517 return; 1518 } 1519 1520 try { 1521 Context context = mContext.createPackageContext(process.info.packageName, 0); 1522 String text = mContext.getString(R.string.heavy_weight_notification, 1523 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1524 Notification notification = new Notification(); 1525 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1526 notification.when = 0; 1527 notification.flags = Notification.FLAG_ONGOING_EVENT; 1528 notification.tickerText = text; 1529 notification.defaults = 0; // please be quiet 1530 notification.sound = null; 1531 notification.vibrate = null; 1532 notification.color = mContext.getResources().getColor( 1533 com.android.internal.R.color.system_notification_accent_color); 1534 notification.setLatestEventInfo(context, text, 1535 mContext.getText(R.string.heavy_weight_notification_detail), 1536 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1537 PendingIntent.FLAG_CANCEL_CURRENT, null, 1538 new UserHandle(root.userId))); 1539 1540 try { 1541 int[] outId = new int[1]; 1542 inm.enqueueNotificationWithTag("android", "android", null, 1543 R.string.heavy_weight_notification, 1544 notification, outId, root.userId); 1545 } catch (RuntimeException e) { 1546 Slog.w(ActivityManagerService.TAG, 1547 "Error showing notification for heavy-weight app", e); 1548 } catch (RemoteException e) { 1549 } 1550 } catch (NameNotFoundException e) { 1551 Slog.w(TAG, "Unable to create context for heavy notification", e); 1552 } 1553 } break; 1554 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1555 INotificationManager inm = NotificationManager.getService(); 1556 if (inm == null) { 1557 return; 1558 } 1559 try { 1560 inm.cancelNotificationWithTag("android", null, 1561 R.string.heavy_weight_notification, msg.arg1); 1562 } catch (RuntimeException e) { 1563 Slog.w(ActivityManagerService.TAG, 1564 "Error canceling notification for service", e); 1565 } catch (RemoteException e) { 1566 } 1567 } break; 1568 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1569 synchronized (ActivityManagerService.this) { 1570 checkExcessivePowerUsageLocked(true); 1571 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1572 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1573 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1574 } 1575 } break; 1576 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1577 synchronized (ActivityManagerService.this) { 1578 ActivityRecord ar = (ActivityRecord)msg.obj; 1579 if (mCompatModeDialog != null) { 1580 if (mCompatModeDialog.mAppInfo.packageName.equals( 1581 ar.info.applicationInfo.packageName)) { 1582 return; 1583 } 1584 mCompatModeDialog.dismiss(); 1585 mCompatModeDialog = null; 1586 } 1587 if (ar != null && false) { 1588 if (mCompatModePackages.getPackageAskCompatModeLocked( 1589 ar.packageName)) { 1590 int mode = mCompatModePackages.computeCompatModeLocked( 1591 ar.info.applicationInfo); 1592 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1593 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1594 mCompatModeDialog = new CompatModeDialog( 1595 ActivityManagerService.this, mContext, 1596 ar.info.applicationInfo); 1597 mCompatModeDialog.show(); 1598 } 1599 } 1600 } 1601 } 1602 break; 1603 } 1604 case DISPATCH_PROCESSES_CHANGED: { 1605 dispatchProcessesChanged(); 1606 break; 1607 } 1608 case DISPATCH_PROCESS_DIED: { 1609 final int pid = msg.arg1; 1610 final int uid = msg.arg2; 1611 dispatchProcessDied(pid, uid); 1612 break; 1613 } 1614 case REPORT_MEM_USAGE_MSG: { 1615 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1616 Thread thread = new Thread() { 1617 @Override public void run() { 1618 reportMemUsage(memInfos); 1619 } 1620 }; 1621 thread.start(); 1622 break; 1623 } 1624 case START_USER_SWITCH_MSG: { 1625 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1626 break; 1627 } 1628 case REPORT_USER_SWITCH_MSG: { 1629 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1630 break; 1631 } 1632 case CONTINUE_USER_SWITCH_MSG: { 1633 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1634 break; 1635 } 1636 case USER_SWITCH_TIMEOUT_MSG: { 1637 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1638 break; 1639 } 1640 case IMMERSIVE_MODE_LOCK_MSG: { 1641 final boolean nextState = (msg.arg1 != 0); 1642 if (mUpdateLock.isHeld() != nextState) { 1643 if (DEBUG_IMMERSIVE) { 1644 final ActivityRecord r = (ActivityRecord) msg.obj; 1645 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1646 } 1647 if (nextState) { 1648 mUpdateLock.acquire(); 1649 } else { 1650 mUpdateLock.release(); 1651 } 1652 } 1653 break; 1654 } 1655 case PERSIST_URI_GRANTS_MSG: { 1656 writeGrantedUriPermissions(); 1657 break; 1658 } 1659 case REQUEST_ALL_PSS_MSG: { 1660 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1661 break; 1662 } 1663 case START_PROFILES_MSG: { 1664 synchronized (ActivityManagerService.this) { 1665 startProfilesLocked(); 1666 } 1667 break; 1668 } 1669 case UPDATE_TIME: { 1670 synchronized (ActivityManagerService.this) { 1671 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1672 ProcessRecord r = mLruProcesses.get(i); 1673 if (r.thread != null) { 1674 try { 1675 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1676 } catch (RemoteException ex) { 1677 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1678 } 1679 } 1680 } 1681 } 1682 break; 1683 } 1684 case SYSTEM_USER_START_MSG: { 1685 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1686 Integer.toString(msg.arg1), msg.arg1); 1687 mSystemServiceManager.startUser(msg.arg1); 1688 break; 1689 } 1690 case SYSTEM_USER_CURRENT_MSG: { 1691 mBatteryStatsService.noteEvent( 1692 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1693 Integer.toString(msg.arg2), msg.arg2); 1694 mBatteryStatsService.noteEvent( 1695 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1696 Integer.toString(msg.arg1), msg.arg1); 1697 mSystemServiceManager.switchUser(msg.arg1); 1698 break; 1699 } 1700 case ENTER_ANIMATION_COMPLETE_MSG: { 1701 synchronized (ActivityManagerService.this) { 1702 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1703 if (r != null && r.app != null && r.app.thread != null) { 1704 try { 1705 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1706 } catch (RemoteException e) { 1707 } 1708 } 1709 } 1710 break; 1711 } 1712 case FINISH_BOOTING_MSG: { 1713 if (msg.arg1 != 0) { 1714 finishBooting(); 1715 } 1716 if (msg.arg2 != 0) { 1717 enableScreenAfterBoot(); 1718 } 1719 break; 1720 } 1721 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1722 try { 1723 Locale l = (Locale) msg.obj; 1724 IBinder service = ServiceManager.getService("mount"); 1725 IMountService mountService = IMountService.Stub.asInterface(service); 1726 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1727 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1728 } catch (RemoteException e) { 1729 Log.e(TAG, "Error storing locale for decryption UI", e); 1730 } 1731 break; 1732 } 1733 case DISMISS_DIALOG_MSG: { 1734 final Dialog d = (Dialog) msg.obj; 1735 d.dismiss(); 1736 break; 1737 } 1738 } 1739 } 1740 }; 1741 1742 static final int COLLECT_PSS_BG_MSG = 1; 1743 1744 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1745 @Override 1746 public void handleMessage(Message msg) { 1747 switch (msg.what) { 1748 case COLLECT_PSS_BG_MSG: { 1749 long start = SystemClock.uptimeMillis(); 1750 MemInfoReader memInfo = null; 1751 synchronized (ActivityManagerService.this) { 1752 if (mFullPssPending) { 1753 mFullPssPending = false; 1754 memInfo = new MemInfoReader(); 1755 } 1756 } 1757 if (memInfo != null) { 1758 updateCpuStatsNow(); 1759 long nativeTotalPss = 0; 1760 synchronized (mProcessCpuTracker) { 1761 final int N = mProcessCpuTracker.countStats(); 1762 for (int j=0; j<N; j++) { 1763 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1764 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1765 // This is definitely an application process; skip it. 1766 continue; 1767 } 1768 synchronized (mPidsSelfLocked) { 1769 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1770 // This is one of our own processes; skip it. 1771 continue; 1772 } 1773 } 1774 nativeTotalPss += Debug.getPss(st.pid, null); 1775 } 1776 } 1777 memInfo.readMemInfo(); 1778 synchronized (ActivityManagerService.this) { 1779 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1780 + (SystemClock.uptimeMillis()-start) + "ms"); 1781 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1782 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1783 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1784 } 1785 } 1786 1787 int i = 0; 1788 int num = 0; 1789 long[] tmp = new long[1]; 1790 do { 1791 ProcessRecord proc; 1792 int procState; 1793 int pid; 1794 synchronized (ActivityManagerService.this) { 1795 if (i >= mPendingPssProcesses.size()) { 1796 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1797 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1798 mPendingPssProcesses.clear(); 1799 return; 1800 } 1801 proc = mPendingPssProcesses.get(i); 1802 procState = proc.pssProcState; 1803 if (proc.thread != null && procState == proc.setProcState) { 1804 pid = proc.pid; 1805 } else { 1806 proc = null; 1807 pid = 0; 1808 } 1809 i++; 1810 } 1811 if (proc != null) { 1812 long pss = Debug.getPss(pid, tmp); 1813 synchronized (ActivityManagerService.this) { 1814 if (proc.thread != null && proc.setProcState == procState 1815 && proc.pid == pid) { 1816 num++; 1817 proc.lastPssTime = SystemClock.uptimeMillis(); 1818 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1819 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1820 + ": " + pss + " lastPss=" + proc.lastPss 1821 + " state=" + ProcessList.makeProcStateString(procState)); 1822 if (proc.initialIdlePss == 0) { 1823 proc.initialIdlePss = pss; 1824 } 1825 proc.lastPss = pss; 1826 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1827 proc.lastCachedPss = pss; 1828 } 1829 } 1830 } 1831 } 1832 } while (true); 1833 } 1834 } 1835 } 1836 }; 1837 1838 public void setSystemProcess() { 1839 try { 1840 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1841 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1842 ServiceManager.addService("meminfo", new MemBinder(this)); 1843 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1844 ServiceManager.addService("dbinfo", new DbBinder(this)); 1845 if (MONITOR_CPU_USAGE) { 1846 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1847 } 1848 ServiceManager.addService("permission", new PermissionController(this)); 1849 1850 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1851 "android", STOCK_PM_FLAGS); 1852 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1853 1854 synchronized (this) { 1855 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1856 app.persistent = true; 1857 app.pid = MY_PID; 1858 app.maxAdj = ProcessList.SYSTEM_ADJ; 1859 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1860 mProcessNames.put(app.processName, app.uid, app); 1861 synchronized (mPidsSelfLocked) { 1862 mPidsSelfLocked.put(app.pid, app); 1863 } 1864 updateLruProcessLocked(app, false, null); 1865 updateOomAdjLocked(); 1866 } 1867 } catch (PackageManager.NameNotFoundException e) { 1868 throw new RuntimeException( 1869 "Unable to find android system package", e); 1870 } 1871 } 1872 1873 public void setWindowManager(WindowManagerService wm) { 1874 mWindowManager = wm; 1875 mStackSupervisor.setWindowManager(wm); 1876 } 1877 1878 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1879 mUsageStatsService = usageStatsManager; 1880 } 1881 1882 public void startObservingNativeCrashes() { 1883 final NativeCrashListener ncl = new NativeCrashListener(this); 1884 ncl.start(); 1885 } 1886 1887 public IAppOpsService getAppOpsService() { 1888 return mAppOpsService; 1889 } 1890 1891 static class MemBinder extends Binder { 1892 ActivityManagerService mActivityManagerService; 1893 MemBinder(ActivityManagerService activityManagerService) { 1894 mActivityManagerService = activityManagerService; 1895 } 1896 1897 @Override 1898 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1899 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1900 != PackageManager.PERMISSION_GRANTED) { 1901 pw.println("Permission Denial: can't dump meminfo from from pid=" 1902 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1903 + " without permission " + android.Manifest.permission.DUMP); 1904 return; 1905 } 1906 1907 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1908 } 1909 } 1910 1911 static class GraphicsBinder extends Binder { 1912 ActivityManagerService mActivityManagerService; 1913 GraphicsBinder(ActivityManagerService activityManagerService) { 1914 mActivityManagerService = activityManagerService; 1915 } 1916 1917 @Override 1918 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1919 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1920 != PackageManager.PERMISSION_GRANTED) { 1921 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1922 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1923 + " without permission " + android.Manifest.permission.DUMP); 1924 return; 1925 } 1926 1927 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1928 } 1929 } 1930 1931 static class DbBinder extends Binder { 1932 ActivityManagerService mActivityManagerService; 1933 DbBinder(ActivityManagerService activityManagerService) { 1934 mActivityManagerService = activityManagerService; 1935 } 1936 1937 @Override 1938 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1939 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1940 != PackageManager.PERMISSION_GRANTED) { 1941 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1942 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1943 + " without permission " + android.Manifest.permission.DUMP); 1944 return; 1945 } 1946 1947 mActivityManagerService.dumpDbInfo(fd, pw, args); 1948 } 1949 } 1950 1951 static class CpuBinder extends Binder { 1952 ActivityManagerService mActivityManagerService; 1953 CpuBinder(ActivityManagerService activityManagerService) { 1954 mActivityManagerService = activityManagerService; 1955 } 1956 1957 @Override 1958 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1959 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1960 != PackageManager.PERMISSION_GRANTED) { 1961 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1962 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1963 + " without permission " + android.Manifest.permission.DUMP); 1964 return; 1965 } 1966 1967 synchronized (mActivityManagerService.mProcessCpuTracker) { 1968 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1969 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1970 SystemClock.uptimeMillis())); 1971 } 1972 } 1973 } 1974 1975 public static final class Lifecycle extends SystemService { 1976 private final ActivityManagerService mService; 1977 1978 public Lifecycle(Context context) { 1979 super(context); 1980 mService = new ActivityManagerService(context); 1981 } 1982 1983 @Override 1984 public void onStart() { 1985 mService.start(); 1986 } 1987 1988 public ActivityManagerService getService() { 1989 return mService; 1990 } 1991 } 1992 1993 // Note: This method is invoked on the main thread but may need to attach various 1994 // handlers to other threads. So take care to be explicit about the looper. 1995 public ActivityManagerService(Context systemContext) { 1996 mContext = systemContext; 1997 mFactoryTest = FactoryTest.getMode(); 1998 mSystemThread = ActivityThread.currentActivityThread(); 1999 2000 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2001 2002 mHandlerThread = new ServiceThread(TAG, 2003 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2004 mHandlerThread.start(); 2005 mHandler = new MainHandler(mHandlerThread.getLooper()); 2006 2007 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2008 "foreground", BROADCAST_FG_TIMEOUT, false); 2009 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2010 "background", BROADCAST_BG_TIMEOUT, true); 2011 mBroadcastQueues[0] = mFgBroadcastQueue; 2012 mBroadcastQueues[1] = mBgBroadcastQueue; 2013 2014 mServices = new ActiveServices(this); 2015 mProviderMap = new ProviderMap(this); 2016 2017 // TODO: Move creation of battery stats service outside of activity manager service. 2018 File dataDir = Environment.getDataDirectory(); 2019 File systemDir = new File(dataDir, "system"); 2020 systemDir.mkdirs(); 2021 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2022 mBatteryStatsService.getActiveStatistics().readLocked(); 2023 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2024 mOnBattery = DEBUG_POWER ? true 2025 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2026 mBatteryStatsService.getActiveStatistics().setCallback(this); 2027 2028 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2029 2030 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2031 2032 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2033 2034 // User 0 is the first and only user that runs at boot. 2035 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2036 mUserLru.add(Integer.valueOf(0)); 2037 updateStartedUserArrayLocked(); 2038 2039 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2040 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2041 2042 mConfiguration.setToDefaults(); 2043 mConfiguration.setLocale(Locale.getDefault()); 2044 2045 mConfigurationSeq = mConfiguration.seq = 1; 2046 mProcessCpuTracker.init(); 2047 2048 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2049 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2050 mStackSupervisor = new ActivityStackSupervisor(this); 2051 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2052 2053 mProcessCpuThread = new Thread("CpuTracker") { 2054 @Override 2055 public void run() { 2056 while (true) { 2057 try { 2058 try { 2059 synchronized(this) { 2060 final long now = SystemClock.uptimeMillis(); 2061 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2062 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2063 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2064 // + ", write delay=" + nextWriteDelay); 2065 if (nextWriteDelay < nextCpuDelay) { 2066 nextCpuDelay = nextWriteDelay; 2067 } 2068 if (nextCpuDelay > 0) { 2069 mProcessCpuMutexFree.set(true); 2070 this.wait(nextCpuDelay); 2071 } 2072 } 2073 } catch (InterruptedException e) { 2074 } 2075 updateCpuStatsNow(); 2076 } catch (Exception e) { 2077 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2078 } 2079 } 2080 } 2081 }; 2082 2083 Watchdog.getInstance().addMonitor(this); 2084 Watchdog.getInstance().addThread(mHandler); 2085 } 2086 2087 public void setSystemServiceManager(SystemServiceManager mgr) { 2088 mSystemServiceManager = mgr; 2089 } 2090 2091 public void setInstaller(Installer installer) { 2092 mInstaller = installer; 2093 } 2094 2095 private void start() { 2096 Process.removeAllProcessGroups(); 2097 mProcessCpuThread.start(); 2098 2099 mBatteryStatsService.publish(mContext); 2100 mAppOpsService.publish(mContext); 2101 Slog.d("AppOps", "AppOpsService published"); 2102 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2103 } 2104 2105 public void initPowerManagement() { 2106 mStackSupervisor.initPowerManagement(); 2107 mBatteryStatsService.initPowerManagement(); 2108 } 2109 2110 @Override 2111 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2112 throws RemoteException { 2113 if (code == SYSPROPS_TRANSACTION) { 2114 // We need to tell all apps about the system property change. 2115 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2116 synchronized(this) { 2117 final int NP = mProcessNames.getMap().size(); 2118 for (int ip=0; ip<NP; ip++) { 2119 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2120 final int NA = apps.size(); 2121 for (int ia=0; ia<NA; ia++) { 2122 ProcessRecord app = apps.valueAt(ia); 2123 if (app.thread != null) { 2124 procs.add(app.thread.asBinder()); 2125 } 2126 } 2127 } 2128 } 2129 2130 int N = procs.size(); 2131 for (int i=0; i<N; i++) { 2132 Parcel data2 = Parcel.obtain(); 2133 try { 2134 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2135 } catch (RemoteException e) { 2136 } 2137 data2.recycle(); 2138 } 2139 } 2140 try { 2141 return super.onTransact(code, data, reply, flags); 2142 } catch (RuntimeException e) { 2143 // The activity manager only throws security exceptions, so let's 2144 // log all others. 2145 if (!(e instanceof SecurityException)) { 2146 Slog.wtf(TAG, "Activity Manager Crash", e); 2147 } 2148 throw e; 2149 } 2150 } 2151 2152 void updateCpuStats() { 2153 final long now = SystemClock.uptimeMillis(); 2154 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2155 return; 2156 } 2157 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2158 synchronized (mProcessCpuThread) { 2159 mProcessCpuThread.notify(); 2160 } 2161 } 2162 } 2163 2164 void updateCpuStatsNow() { 2165 synchronized (mProcessCpuTracker) { 2166 mProcessCpuMutexFree.set(false); 2167 final long now = SystemClock.uptimeMillis(); 2168 boolean haveNewCpuStats = false; 2169 2170 if (MONITOR_CPU_USAGE && 2171 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2172 mLastCpuTime.set(now); 2173 haveNewCpuStats = true; 2174 mProcessCpuTracker.update(); 2175 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2176 //Slog.i(TAG, "Total CPU usage: " 2177 // + mProcessCpu.getTotalCpuPercent() + "%"); 2178 2179 // Slog the cpu usage if the property is set. 2180 if ("true".equals(SystemProperties.get("events.cpu"))) { 2181 int user = mProcessCpuTracker.getLastUserTime(); 2182 int system = mProcessCpuTracker.getLastSystemTime(); 2183 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2184 int irq = mProcessCpuTracker.getLastIrqTime(); 2185 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2186 int idle = mProcessCpuTracker.getLastIdleTime(); 2187 2188 int total = user + system + iowait + irq + softIrq + idle; 2189 if (total == 0) total = 1; 2190 2191 EventLog.writeEvent(EventLogTags.CPU, 2192 ((user+system+iowait+irq+softIrq) * 100) / total, 2193 (user * 100) / total, 2194 (system * 100) / total, 2195 (iowait * 100) / total, 2196 (irq * 100) / total, 2197 (softIrq * 100) / total); 2198 } 2199 } 2200 2201 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2202 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2203 synchronized(bstats) { 2204 synchronized(mPidsSelfLocked) { 2205 if (haveNewCpuStats) { 2206 if (mOnBattery) { 2207 int perc = bstats.startAddingCpuLocked(); 2208 int totalUTime = 0; 2209 int totalSTime = 0; 2210 final int N = mProcessCpuTracker.countStats(); 2211 for (int i=0; i<N; i++) { 2212 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2213 if (!st.working) { 2214 continue; 2215 } 2216 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2217 int otherUTime = (st.rel_utime*perc)/100; 2218 int otherSTime = (st.rel_stime*perc)/100; 2219 totalUTime += otherUTime; 2220 totalSTime += otherSTime; 2221 if (pr != null) { 2222 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2223 if (ps == null || !ps.isActive()) { 2224 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2225 pr.info.uid, pr.processName); 2226 } 2227 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2228 st.rel_stime-otherSTime); 2229 ps.addSpeedStepTimes(cpuSpeedTimes); 2230 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2231 } else { 2232 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2233 if (ps == null || !ps.isActive()) { 2234 st.batteryStats = ps = bstats.getProcessStatsLocked( 2235 bstats.mapUid(st.uid), st.name); 2236 } 2237 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2238 st.rel_stime-otherSTime); 2239 ps.addSpeedStepTimes(cpuSpeedTimes); 2240 } 2241 } 2242 bstats.finishAddingCpuLocked(perc, totalUTime, 2243 totalSTime, cpuSpeedTimes); 2244 } 2245 } 2246 } 2247 2248 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2249 mLastWriteTime = now; 2250 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2251 } 2252 } 2253 } 2254 } 2255 2256 @Override 2257 public void batteryNeedsCpuUpdate() { 2258 updateCpuStatsNow(); 2259 } 2260 2261 @Override 2262 public void batteryPowerChanged(boolean onBattery) { 2263 // When plugging in, update the CPU stats first before changing 2264 // the plug state. 2265 updateCpuStatsNow(); 2266 synchronized (this) { 2267 synchronized(mPidsSelfLocked) { 2268 mOnBattery = DEBUG_POWER ? true : onBattery; 2269 } 2270 } 2271 } 2272 2273 /** 2274 * Initialize the application bind args. These are passed to each 2275 * process when the bindApplication() IPC is sent to the process. They're 2276 * lazily setup to make sure the services are running when they're asked for. 2277 */ 2278 private HashMap<String, IBinder> getCommonServicesLocked() { 2279 if (mAppBindArgs == null) { 2280 mAppBindArgs = new HashMap<String, IBinder>(); 2281 2282 // Setup the application init args 2283 mAppBindArgs.put("package", ServiceManager.getService("package")); 2284 mAppBindArgs.put("window", ServiceManager.getService("window")); 2285 mAppBindArgs.put(Context.ALARM_SERVICE, 2286 ServiceManager.getService(Context.ALARM_SERVICE)); 2287 } 2288 return mAppBindArgs; 2289 } 2290 2291 final void setFocusedActivityLocked(ActivityRecord r) { 2292 if (mFocusedActivity != r) { 2293 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2294 mFocusedActivity = r; 2295 if (r.task != null && r.task.voiceInteractor != null) { 2296 startRunningVoiceLocked(); 2297 } else { 2298 finishRunningVoiceLocked(); 2299 } 2300 mStackSupervisor.setFocusedStack(r); 2301 if (r != null) { 2302 mWindowManager.setFocusedApp(r.appToken, true); 2303 } 2304 applyUpdateLockStateLocked(r); 2305 } 2306 } 2307 2308 final void clearFocusedActivity(ActivityRecord r) { 2309 if (mFocusedActivity == r) { 2310 mFocusedActivity = null; 2311 } 2312 } 2313 2314 @Override 2315 public void setFocusedStack(int stackId) { 2316 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2317 synchronized (ActivityManagerService.this) { 2318 ActivityStack stack = mStackSupervisor.getStack(stackId); 2319 if (stack != null) { 2320 ActivityRecord r = stack.topRunningActivityLocked(null); 2321 if (r != null) { 2322 setFocusedActivityLocked(r); 2323 } 2324 } 2325 } 2326 } 2327 2328 @Override 2329 public void notifyActivityDrawn(IBinder token) { 2330 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2331 synchronized (this) { 2332 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2333 if (r != null) { 2334 r.task.stack.notifyActivityDrawnLocked(r); 2335 } 2336 } 2337 } 2338 2339 final void applyUpdateLockStateLocked(ActivityRecord r) { 2340 // Modifications to the UpdateLock state are done on our handler, outside 2341 // the activity manager's locks. The new state is determined based on the 2342 // state *now* of the relevant activity record. The object is passed to 2343 // the handler solely for logging detail, not to be consulted/modified. 2344 final boolean nextState = r != null && r.immersive; 2345 mHandler.sendMessage( 2346 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2347 } 2348 2349 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2350 Message msg = Message.obtain(); 2351 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2352 msg.obj = r.task.askedCompatMode ? null : r; 2353 mHandler.sendMessage(msg); 2354 } 2355 2356 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2357 String what, Object obj, ProcessRecord srcApp) { 2358 app.lastActivityTime = now; 2359 2360 if (app.activities.size() > 0) { 2361 // Don't want to touch dependent processes that are hosting activities. 2362 return index; 2363 } 2364 2365 int lrui = mLruProcesses.lastIndexOf(app); 2366 if (lrui < 0) { 2367 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2368 + what + " " + obj + " from " + srcApp); 2369 return index; 2370 } 2371 2372 if (lrui >= index) { 2373 // Don't want to cause this to move dependent processes *back* in the 2374 // list as if they were less frequently used. 2375 return index; 2376 } 2377 2378 if (lrui >= mLruProcessActivityStart) { 2379 // Don't want to touch dependent processes that are hosting activities. 2380 return index; 2381 } 2382 2383 mLruProcesses.remove(lrui); 2384 if (index > 0) { 2385 index--; 2386 } 2387 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2388 + " in LRU list: " + app); 2389 mLruProcesses.add(index, app); 2390 return index; 2391 } 2392 2393 final void removeLruProcessLocked(ProcessRecord app) { 2394 int lrui = mLruProcesses.lastIndexOf(app); 2395 if (lrui >= 0) { 2396 if (!app.killed) { 2397 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2398 Process.killProcessQuiet(app.pid); 2399 Process.killProcessGroup(app.info.uid, app.pid); 2400 } 2401 if (lrui <= mLruProcessActivityStart) { 2402 mLruProcessActivityStart--; 2403 } 2404 if (lrui <= mLruProcessServiceStart) { 2405 mLruProcessServiceStart--; 2406 } 2407 mLruProcesses.remove(lrui); 2408 } 2409 } 2410 2411 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2412 ProcessRecord client) { 2413 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2414 || app.treatLikeActivity; 2415 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2416 if (!activityChange && hasActivity) { 2417 // The process has activities, so we are only allowing activity-based adjustments 2418 // to move it. It should be kept in the front of the list with other 2419 // processes that have activities, and we don't want those to change their 2420 // order except due to activity operations. 2421 return; 2422 } 2423 2424 mLruSeq++; 2425 final long now = SystemClock.uptimeMillis(); 2426 app.lastActivityTime = now; 2427 2428 // First a quick reject: if the app is already at the position we will 2429 // put it, then there is nothing to do. 2430 if (hasActivity) { 2431 final int N = mLruProcesses.size(); 2432 if (N > 0 && mLruProcesses.get(N-1) == app) { 2433 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2434 return; 2435 } 2436 } else { 2437 if (mLruProcessServiceStart > 0 2438 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2439 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2440 return; 2441 } 2442 } 2443 2444 int lrui = mLruProcesses.lastIndexOf(app); 2445 2446 if (app.persistent && lrui >= 0) { 2447 // We don't care about the position of persistent processes, as long as 2448 // they are in the list. 2449 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2450 return; 2451 } 2452 2453 /* In progress: compute new position first, so we can avoid doing work 2454 if the process is not actually going to move. Not yet working. 2455 int addIndex; 2456 int nextIndex; 2457 boolean inActivity = false, inService = false; 2458 if (hasActivity) { 2459 // Process has activities, put it at the very tipsy-top. 2460 addIndex = mLruProcesses.size(); 2461 nextIndex = mLruProcessServiceStart; 2462 inActivity = true; 2463 } else if (hasService) { 2464 // Process has services, put it at the top of the service list. 2465 addIndex = mLruProcessActivityStart; 2466 nextIndex = mLruProcessServiceStart; 2467 inActivity = true; 2468 inService = true; 2469 } else { 2470 // Process not otherwise of interest, it goes to the top of the non-service area. 2471 addIndex = mLruProcessServiceStart; 2472 if (client != null) { 2473 int clientIndex = mLruProcesses.lastIndexOf(client); 2474 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2475 + app); 2476 if (clientIndex >= 0 && addIndex > clientIndex) { 2477 addIndex = clientIndex; 2478 } 2479 } 2480 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2481 } 2482 2483 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2484 + mLruProcessActivityStart + "): " + app); 2485 */ 2486 2487 if (lrui >= 0) { 2488 if (lrui < mLruProcessActivityStart) { 2489 mLruProcessActivityStart--; 2490 } 2491 if (lrui < mLruProcessServiceStart) { 2492 mLruProcessServiceStart--; 2493 } 2494 /* 2495 if (addIndex > lrui) { 2496 addIndex--; 2497 } 2498 if (nextIndex > lrui) { 2499 nextIndex--; 2500 } 2501 */ 2502 mLruProcesses.remove(lrui); 2503 } 2504 2505 /* 2506 mLruProcesses.add(addIndex, app); 2507 if (inActivity) { 2508 mLruProcessActivityStart++; 2509 } 2510 if (inService) { 2511 mLruProcessActivityStart++; 2512 } 2513 */ 2514 2515 int nextIndex; 2516 if (hasActivity) { 2517 final int N = mLruProcesses.size(); 2518 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2519 // Process doesn't have activities, but has clients with 2520 // activities... move it up, but one below the top (the top 2521 // should always have a real activity). 2522 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2523 mLruProcesses.add(N-1, app); 2524 // To keep it from spamming the LRU list (by making a bunch of clients), 2525 // we will push down any other entries owned by the app. 2526 final int uid = app.info.uid; 2527 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2528 ProcessRecord subProc = mLruProcesses.get(i); 2529 if (subProc.info.uid == uid) { 2530 // We want to push this one down the list. If the process after 2531 // it is for the same uid, however, don't do so, because we don't 2532 // want them internally to be re-ordered. 2533 if (mLruProcesses.get(i-1).info.uid != uid) { 2534 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2535 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2536 ProcessRecord tmp = mLruProcesses.get(i); 2537 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2538 mLruProcesses.set(i-1, tmp); 2539 i--; 2540 } 2541 } else { 2542 // A gap, we can stop here. 2543 break; 2544 } 2545 } 2546 } else { 2547 // Process has activities, put it at the very tipsy-top. 2548 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2549 mLruProcesses.add(app); 2550 } 2551 nextIndex = mLruProcessServiceStart; 2552 } else if (hasService) { 2553 // Process has services, put it at the top of the service list. 2554 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2555 mLruProcesses.add(mLruProcessActivityStart, app); 2556 nextIndex = mLruProcessServiceStart; 2557 mLruProcessActivityStart++; 2558 } else { 2559 // Process not otherwise of interest, it goes to the top of the non-service area. 2560 int index = mLruProcessServiceStart; 2561 if (client != null) { 2562 // If there is a client, don't allow the process to be moved up higher 2563 // in the list than that client. 2564 int clientIndex = mLruProcesses.lastIndexOf(client); 2565 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2566 + " when updating " + app); 2567 if (clientIndex <= lrui) { 2568 // Don't allow the client index restriction to push it down farther in the 2569 // list than it already is. 2570 clientIndex = lrui; 2571 } 2572 if (clientIndex >= 0 && index > clientIndex) { 2573 index = clientIndex; 2574 } 2575 } 2576 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2577 mLruProcesses.add(index, app); 2578 nextIndex = index-1; 2579 mLruProcessActivityStart++; 2580 mLruProcessServiceStart++; 2581 } 2582 2583 // If the app is currently using a content provider or service, 2584 // bump those processes as well. 2585 for (int j=app.connections.size()-1; j>=0; j--) { 2586 ConnectionRecord cr = app.connections.valueAt(j); 2587 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2588 && cr.binding.service.app != null 2589 && cr.binding.service.app.lruSeq != mLruSeq 2590 && !cr.binding.service.app.persistent) { 2591 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2592 "service connection", cr, app); 2593 } 2594 } 2595 for (int j=app.conProviders.size()-1; j>=0; j--) { 2596 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2597 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2598 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2599 "provider reference", cpr, app); 2600 } 2601 } 2602 } 2603 2604 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2605 if (uid == Process.SYSTEM_UID) { 2606 // The system gets to run in any process. If there are multiple 2607 // processes with the same uid, just pick the first (this 2608 // should never happen). 2609 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2610 if (procs == null) return null; 2611 final int N = procs.size(); 2612 for (int i = 0; i < N; i++) { 2613 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2614 } 2615 } 2616 ProcessRecord proc = mProcessNames.get(processName, uid); 2617 if (false && proc != null && !keepIfLarge 2618 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2619 && proc.lastCachedPss >= 4000) { 2620 // Turn this condition on to cause killing to happen regularly, for testing. 2621 if (proc.baseProcessTracker != null) { 2622 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2623 } 2624 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2625 } else if (proc != null && !keepIfLarge 2626 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2627 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2628 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2629 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2630 if (proc.baseProcessTracker != null) { 2631 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2632 } 2633 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2634 } 2635 } 2636 return proc; 2637 } 2638 2639 void ensurePackageDexOpt(String packageName) { 2640 IPackageManager pm = AppGlobals.getPackageManager(); 2641 try { 2642 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2643 mDidDexOpt = true; 2644 } 2645 } catch (RemoteException e) { 2646 } 2647 } 2648 2649 boolean isNextTransitionForward() { 2650 int transit = mWindowManager.getPendingAppTransition(); 2651 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2652 || transit == AppTransition.TRANSIT_TASK_OPEN 2653 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2654 } 2655 2656 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2657 String processName, String abiOverride, int uid, Runnable crashHandler) { 2658 synchronized(this) { 2659 ApplicationInfo info = new ApplicationInfo(); 2660 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2661 // For isolated processes, the former contains the parent's uid and the latter the 2662 // actual uid of the isolated process. 2663 // In the special case introduced by this method (which is, starting an isolated 2664 // process directly from the SystemServer without an actual parent app process) the 2665 // closest thing to a parent's uid is SYSTEM_UID. 2666 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2667 // the |isolated| logic in the ProcessRecord constructor. 2668 info.uid = Process.SYSTEM_UID; 2669 info.processName = processName; 2670 info.className = entryPoint; 2671 info.packageName = "android"; 2672 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2673 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2674 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2675 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2676 crashHandler); 2677 return proc != null ? proc.pid : 0; 2678 } 2679 } 2680 2681 final ProcessRecord startProcessLocked(String processName, 2682 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2683 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2684 boolean isolated, boolean keepIfLarge) { 2685 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2686 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2687 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2688 null /* crashHandler */); 2689 } 2690 2691 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2692 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2693 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2694 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2695 long startTime = SystemClock.elapsedRealtime(); 2696 ProcessRecord app; 2697 if (!isolated) { 2698 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2699 checkTime(startTime, "startProcess: after getProcessRecord"); 2700 } else { 2701 // If this is an isolated process, it can't re-use an existing process. 2702 app = null; 2703 } 2704 // We don't have to do anything more if: 2705 // (1) There is an existing application record; and 2706 // (2) The caller doesn't think it is dead, OR there is no thread 2707 // object attached to it so we know it couldn't have crashed; and 2708 // (3) There is a pid assigned to it, so it is either starting or 2709 // already running. 2710 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2711 + " app=" + app + " knownToBeDead=" + knownToBeDead 2712 + " thread=" + (app != null ? app.thread : null) 2713 + " pid=" + (app != null ? app.pid : -1)); 2714 if (app != null && app.pid > 0) { 2715 if (!knownToBeDead || app.thread == null) { 2716 // We already have the app running, or are waiting for it to 2717 // come up (we have a pid but not yet its thread), so keep it. 2718 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2719 // If this is a new package in the process, add the package to the list 2720 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2721 checkTime(startTime, "startProcess: done, added package to proc"); 2722 return app; 2723 } 2724 2725 // An application record is attached to a previous process, 2726 // clean it up now. 2727 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2728 checkTime(startTime, "startProcess: bad proc running, killing"); 2729 Process.killProcessGroup(app.info.uid, app.pid); 2730 handleAppDiedLocked(app, true, true); 2731 checkTime(startTime, "startProcess: done killing old proc"); 2732 } 2733 2734 String hostingNameStr = hostingName != null 2735 ? hostingName.flattenToShortString() : null; 2736 2737 if (!isolated) { 2738 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2739 // If we are in the background, then check to see if this process 2740 // is bad. If so, we will just silently fail. 2741 if (mBadProcesses.get(info.processName, info.uid) != null) { 2742 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2743 + "/" + info.processName); 2744 return null; 2745 } 2746 } else { 2747 // When the user is explicitly starting a process, then clear its 2748 // crash count so that we won't make it bad until they see at 2749 // least one crash dialog again, and make the process good again 2750 // if it had been bad. 2751 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2752 + "/" + info.processName); 2753 mProcessCrashTimes.remove(info.processName, info.uid); 2754 if (mBadProcesses.get(info.processName, info.uid) != null) { 2755 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2756 UserHandle.getUserId(info.uid), info.uid, 2757 info.processName); 2758 mBadProcesses.remove(info.processName, info.uid); 2759 if (app != null) { 2760 app.bad = false; 2761 } 2762 } 2763 } 2764 } 2765 2766 if (app == null) { 2767 checkTime(startTime, "startProcess: creating new process record"); 2768 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2769 app.crashHandler = crashHandler; 2770 if (app == null) { 2771 Slog.w(TAG, "Failed making new process record for " 2772 + processName + "/" + info.uid + " isolated=" + isolated); 2773 return null; 2774 } 2775 mProcessNames.put(processName, app.uid, app); 2776 if (isolated) { 2777 mIsolatedProcesses.put(app.uid, app); 2778 } 2779 checkTime(startTime, "startProcess: done creating new process record"); 2780 } else { 2781 // If this is a new package in the process, add the package to the list 2782 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2783 checkTime(startTime, "startProcess: added package to existing proc"); 2784 } 2785 2786 // If the system is not ready yet, then hold off on starting this 2787 // process until it is. 2788 if (!mProcessesReady 2789 && !isAllowedWhileBooting(info) 2790 && !allowWhileBooting) { 2791 if (!mProcessesOnHold.contains(app)) { 2792 mProcessesOnHold.add(app); 2793 } 2794 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2795 checkTime(startTime, "startProcess: returning with proc on hold"); 2796 return app; 2797 } 2798 2799 checkTime(startTime, "startProcess: stepping in to startProcess"); 2800 startProcessLocked( 2801 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2802 checkTime(startTime, "startProcess: done starting proc!"); 2803 return (app.pid != 0) ? app : null; 2804 } 2805 2806 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2807 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2808 } 2809 2810 private final void startProcessLocked(ProcessRecord app, 2811 String hostingType, String hostingNameStr) { 2812 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2813 null /* entryPoint */, null /* entryPointArgs */); 2814 } 2815 2816 private final void startProcessLocked(ProcessRecord app, String hostingType, 2817 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2818 long startTime = SystemClock.elapsedRealtime(); 2819 if (app.pid > 0 && app.pid != MY_PID) { 2820 checkTime(startTime, "startProcess: removing from pids map"); 2821 synchronized (mPidsSelfLocked) { 2822 mPidsSelfLocked.remove(app.pid); 2823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2824 } 2825 checkTime(startTime, "startProcess: done removing from pids map"); 2826 app.setPid(0); 2827 } 2828 2829 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2830 "startProcessLocked removing on hold: " + app); 2831 mProcessesOnHold.remove(app); 2832 2833 checkTime(startTime, "startProcess: starting to update cpu stats"); 2834 updateCpuStats(); 2835 checkTime(startTime, "startProcess: done updating cpu stats"); 2836 2837 try { 2838 int uid = app.uid; 2839 2840 int[] gids = null; 2841 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2842 if (!app.isolated) { 2843 int[] permGids = null; 2844 try { 2845 checkTime(startTime, "startProcess: getting gids from package manager"); 2846 final PackageManager pm = mContext.getPackageManager(); 2847 permGids = pm.getPackageGids(app.info.packageName); 2848 2849 if (Environment.isExternalStorageEmulated()) { 2850 checkTime(startTime, "startProcess: checking external storage perm"); 2851 if (pm.checkPermission( 2852 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2853 app.info.packageName) == PERMISSION_GRANTED) { 2854 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2855 } else { 2856 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2857 } 2858 } 2859 } catch (PackageManager.NameNotFoundException e) { 2860 Slog.w(TAG, "Unable to retrieve gids", e); 2861 } 2862 2863 /* 2864 * Add shared application and profile GIDs so applications can share some 2865 * resources like shared libraries and access user-wide resources 2866 */ 2867 if (permGids == null) { 2868 gids = new int[2]; 2869 } else { 2870 gids = new int[permGids.length + 2]; 2871 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2872 } 2873 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2874 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2875 } 2876 checkTime(startTime, "startProcess: building args"); 2877 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2878 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2879 && mTopComponent != null 2880 && app.processName.equals(mTopComponent.getPackageName())) { 2881 uid = 0; 2882 } 2883 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2884 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2885 uid = 0; 2886 } 2887 } 2888 int debugFlags = 0; 2889 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2890 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2891 // Also turn on CheckJNI for debuggable apps. It's quite 2892 // awkward to turn on otherwise. 2893 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2894 } 2895 // Run the app in safe mode if its manifest requests so or the 2896 // system is booted in safe mode. 2897 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2898 mSafeMode == true) { 2899 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2900 } 2901 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2902 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2903 } 2904 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2905 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2906 } 2907 if ("1".equals(SystemProperties.get("debug.assert"))) { 2908 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2909 } 2910 2911 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2912 if (requiredAbi == null) { 2913 requiredAbi = Build.SUPPORTED_ABIS[0]; 2914 } 2915 2916 String instructionSet = null; 2917 if (app.info.primaryCpuAbi != null) { 2918 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2919 } 2920 2921 // Start the process. It will either succeed and return a result containing 2922 // the PID of the new process, or else throw a RuntimeException. 2923 boolean isActivityProcess = (entryPoint == null); 2924 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2925 checkTime(startTime, "startProcess: asking zygote to start proc"); 2926 Process.ProcessStartResult startResult = Process.start(entryPoint, 2927 app.processName, uid, uid, gids, debugFlags, mountExternal, 2928 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2929 app.info.dataDir, entryPointArgs); 2930 checkTime(startTime, "startProcess: returned from zygote!"); 2931 2932 if (app.isolated) { 2933 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2934 } 2935 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2936 checkTime(startTime, "startProcess: done updating battery stats"); 2937 2938 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2939 UserHandle.getUserId(uid), startResult.pid, uid, 2940 app.processName, hostingType, 2941 hostingNameStr != null ? hostingNameStr : ""); 2942 2943 if (app.persistent) { 2944 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2945 } 2946 2947 checkTime(startTime, "startProcess: building log message"); 2948 StringBuilder buf = mStringBuilder; 2949 buf.setLength(0); 2950 buf.append("Start proc "); 2951 buf.append(app.processName); 2952 if (!isActivityProcess) { 2953 buf.append(" ["); 2954 buf.append(entryPoint); 2955 buf.append("]"); 2956 } 2957 buf.append(" for "); 2958 buf.append(hostingType); 2959 if (hostingNameStr != null) { 2960 buf.append(" "); 2961 buf.append(hostingNameStr); 2962 } 2963 buf.append(": pid="); 2964 buf.append(startResult.pid); 2965 buf.append(" uid="); 2966 buf.append(uid); 2967 buf.append(" gids={"); 2968 if (gids != null) { 2969 for (int gi=0; gi<gids.length; gi++) { 2970 if (gi != 0) buf.append(", "); 2971 buf.append(gids[gi]); 2972 2973 } 2974 } 2975 buf.append("}"); 2976 if (requiredAbi != null) { 2977 buf.append(" abi="); 2978 buf.append(requiredAbi); 2979 } 2980 Slog.i(TAG, buf.toString()); 2981 app.setPid(startResult.pid); 2982 app.usingWrapper = startResult.usingWrapper; 2983 app.removed = false; 2984 app.killed = false; 2985 app.killedByAm = false; 2986 checkTime(startTime, "startProcess: starting to update pids map"); 2987 synchronized (mPidsSelfLocked) { 2988 this.mPidsSelfLocked.put(startResult.pid, app); 2989 if (isActivityProcess) { 2990 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2991 msg.obj = app; 2992 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2993 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2994 } 2995 } 2996 checkTime(startTime, "startProcess: done updating pids map"); 2997 } catch (RuntimeException e) { 2998 // XXX do better error recovery. 2999 app.setPid(0); 3000 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3001 if (app.isolated) { 3002 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3003 } 3004 Slog.e(TAG, "Failure starting process " + app.processName, e); 3005 } 3006 } 3007 3008 void updateUsageStats(ActivityRecord component, boolean resumed) { 3009 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3010 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3011 if (resumed) { 3012 if (mUsageStatsService != null) { 3013 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3014 UsageEvents.Event.MOVE_TO_FOREGROUND); 3015 } 3016 synchronized (stats) { 3017 stats.noteActivityResumedLocked(component.app.uid); 3018 } 3019 } else { 3020 if (mUsageStatsService != null) { 3021 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3022 UsageEvents.Event.MOVE_TO_BACKGROUND); 3023 } 3024 synchronized (stats) { 3025 stats.noteActivityPausedLocked(component.app.uid); 3026 } 3027 } 3028 } 3029 3030 Intent getHomeIntent() { 3031 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3032 intent.setComponent(mTopComponent); 3033 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3034 intent.addCategory(Intent.CATEGORY_HOME); 3035 } 3036 return intent; 3037 } 3038 3039 boolean startHomeActivityLocked(int userId) { 3040 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3041 && mTopAction == null) { 3042 // We are running in factory test mode, but unable to find 3043 // the factory test app, so just sit around displaying the 3044 // error message and don't try to start anything. 3045 return false; 3046 } 3047 Intent intent = getHomeIntent(); 3048 ActivityInfo aInfo = 3049 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3050 if (aInfo != null) { 3051 intent.setComponent(new ComponentName( 3052 aInfo.applicationInfo.packageName, aInfo.name)); 3053 // Don't do this if the home app is currently being 3054 // instrumented. 3055 aInfo = new ActivityInfo(aInfo); 3056 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3057 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3058 aInfo.applicationInfo.uid, true); 3059 if (app == null || app.instrumentationClass == null) { 3060 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3061 mStackSupervisor.startHomeActivity(intent, aInfo); 3062 } 3063 } 3064 3065 return true; 3066 } 3067 3068 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3069 ActivityInfo ai = null; 3070 ComponentName comp = intent.getComponent(); 3071 try { 3072 if (comp != null) { 3073 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3074 } else { 3075 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3076 intent, 3077 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3078 flags, userId); 3079 3080 if (info != null) { 3081 ai = info.activityInfo; 3082 } 3083 } 3084 } catch (RemoteException e) { 3085 // ignore 3086 } 3087 3088 return ai; 3089 } 3090 3091 /** 3092 * Starts the "new version setup screen" if appropriate. 3093 */ 3094 void startSetupActivityLocked() { 3095 // Only do this once per boot. 3096 if (mCheckedForSetup) { 3097 return; 3098 } 3099 3100 // We will show this screen if the current one is a different 3101 // version than the last one shown, and we are not running in 3102 // low-level factory test mode. 3103 final ContentResolver resolver = mContext.getContentResolver(); 3104 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3105 Settings.Global.getInt(resolver, 3106 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3107 mCheckedForSetup = true; 3108 3109 // See if we should be showing the platform update setup UI. 3110 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3111 List<ResolveInfo> ris = mContext.getPackageManager() 3112 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3113 3114 // We don't allow third party apps to replace this. 3115 ResolveInfo ri = null; 3116 for (int i=0; ris != null && i<ris.size(); i++) { 3117 if ((ris.get(i).activityInfo.applicationInfo.flags 3118 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3119 ri = ris.get(i); 3120 break; 3121 } 3122 } 3123 3124 if (ri != null) { 3125 String vers = ri.activityInfo.metaData != null 3126 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3127 : null; 3128 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3129 vers = ri.activityInfo.applicationInfo.metaData.getString( 3130 Intent.METADATA_SETUP_VERSION); 3131 } 3132 String lastVers = Settings.Secure.getString( 3133 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3134 if (vers != null && !vers.equals(lastVers)) { 3135 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3136 intent.setComponent(new ComponentName( 3137 ri.activityInfo.packageName, ri.activityInfo.name)); 3138 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3139 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3140 null); 3141 } 3142 } 3143 } 3144 } 3145 3146 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3147 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3148 } 3149 3150 void enforceNotIsolatedCaller(String caller) { 3151 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3152 throw new SecurityException("Isolated process not allowed to call " + caller); 3153 } 3154 } 3155 3156 void enforceShellRestriction(String restriction, int userHandle) { 3157 if (Binder.getCallingUid() == Process.SHELL_UID) { 3158 if (userHandle < 0 3159 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3160 throw new SecurityException("Shell does not have permission to access user " 3161 + userHandle); 3162 } 3163 } 3164 } 3165 3166 @Override 3167 public int getFrontActivityScreenCompatMode() { 3168 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3169 synchronized (this) { 3170 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3171 } 3172 } 3173 3174 @Override 3175 public void setFrontActivityScreenCompatMode(int mode) { 3176 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3177 "setFrontActivityScreenCompatMode"); 3178 synchronized (this) { 3179 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3180 } 3181 } 3182 3183 @Override 3184 public int getPackageScreenCompatMode(String packageName) { 3185 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3186 synchronized (this) { 3187 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3188 } 3189 } 3190 3191 @Override 3192 public void setPackageScreenCompatMode(String packageName, int mode) { 3193 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3194 "setPackageScreenCompatMode"); 3195 synchronized (this) { 3196 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3197 } 3198 } 3199 3200 @Override 3201 public boolean getPackageAskScreenCompat(String packageName) { 3202 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3203 synchronized (this) { 3204 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3205 } 3206 } 3207 3208 @Override 3209 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3210 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3211 "setPackageAskScreenCompat"); 3212 synchronized (this) { 3213 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3214 } 3215 } 3216 3217 private void dispatchProcessesChanged() { 3218 int N; 3219 synchronized (this) { 3220 N = mPendingProcessChanges.size(); 3221 if (mActiveProcessChanges.length < N) { 3222 mActiveProcessChanges = new ProcessChangeItem[N]; 3223 } 3224 mPendingProcessChanges.toArray(mActiveProcessChanges); 3225 mAvailProcessChanges.addAll(mPendingProcessChanges); 3226 mPendingProcessChanges.clear(); 3227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3228 } 3229 3230 int i = mProcessObservers.beginBroadcast(); 3231 while (i > 0) { 3232 i--; 3233 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3234 if (observer != null) { 3235 try { 3236 for (int j=0; j<N; j++) { 3237 ProcessChangeItem item = mActiveProcessChanges[j]; 3238 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3239 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3240 + item.pid + " uid=" + item.uid + ": " 3241 + item.foregroundActivities); 3242 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3243 item.foregroundActivities); 3244 } 3245 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3246 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3247 + item.pid + " uid=" + item.uid + ": " + item.processState); 3248 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3249 } 3250 } 3251 } catch (RemoteException e) { 3252 } 3253 } 3254 } 3255 mProcessObservers.finishBroadcast(); 3256 } 3257 3258 private void dispatchProcessDied(int pid, int uid) { 3259 int i = mProcessObservers.beginBroadcast(); 3260 while (i > 0) { 3261 i--; 3262 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3263 if (observer != null) { 3264 try { 3265 observer.onProcessDied(pid, uid); 3266 } catch (RemoteException e) { 3267 } 3268 } 3269 } 3270 mProcessObservers.finishBroadcast(); 3271 } 3272 3273 @Override 3274 public final int startActivity(IApplicationThread caller, String callingPackage, 3275 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3276 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3277 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3278 resultWho, requestCode, startFlags, profilerInfo, options, 3279 UserHandle.getCallingUserId()); 3280 } 3281 3282 @Override 3283 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3284 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3285 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3286 enforceNotIsolatedCaller("startActivity"); 3287 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3288 false, ALLOW_FULL_ONLY, "startActivity", null); 3289 // TODO: Switch to user app stacks here. 3290 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3291 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3292 profilerInfo, null, null, options, userId, null, null); 3293 } 3294 3295 @Override 3296 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3297 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3298 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3299 3300 // This is very dangerous -- it allows you to perform a start activity (including 3301 // permission grants) as any app that may launch one of your own activities. So 3302 // we will only allow this to be done from activities that are part of the core framework, 3303 // and then only when they are running as the system. 3304 final ActivityRecord sourceRecord; 3305 final int targetUid; 3306 final String targetPackage; 3307 synchronized (this) { 3308 if (resultTo == null) { 3309 throw new SecurityException("Must be called from an activity"); 3310 } 3311 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3312 if (sourceRecord == null) { 3313 throw new SecurityException("Called with bad activity token: " + resultTo); 3314 } 3315 if (!sourceRecord.info.packageName.equals("android")) { 3316 throw new SecurityException( 3317 "Must be called from an activity that is declared in the android package"); 3318 } 3319 if (sourceRecord.app == null) { 3320 throw new SecurityException("Called without a process attached to activity"); 3321 } 3322 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3323 // This is still okay, as long as this activity is running under the 3324 // uid of the original calling activity. 3325 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3326 throw new SecurityException( 3327 "Calling activity in uid " + sourceRecord.app.uid 3328 + " must be system uid or original calling uid " 3329 + sourceRecord.launchedFromUid); 3330 } 3331 } 3332 targetUid = sourceRecord.launchedFromUid; 3333 targetPackage = sourceRecord.launchedFromPackage; 3334 } 3335 3336 if (userId == UserHandle.USER_NULL) { 3337 userId = UserHandle.getUserId(sourceRecord.app.uid); 3338 } 3339 3340 // TODO: Switch to user app stacks here. 3341 try { 3342 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3343 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3344 null, null, options, userId, null, null); 3345 return ret; 3346 } catch (SecurityException e) { 3347 // XXX need to figure out how to propagate to original app. 3348 // A SecurityException here is generally actually a fault of the original 3349 // calling activity (such as a fairly granting permissions), so propagate it 3350 // back to them. 3351 /* 3352 StringBuilder msg = new StringBuilder(); 3353 msg.append("While launching"); 3354 msg.append(intent.toString()); 3355 msg.append(": "); 3356 msg.append(e.getMessage()); 3357 */ 3358 throw e; 3359 } 3360 } 3361 3362 @Override 3363 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3364 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3365 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3366 enforceNotIsolatedCaller("startActivityAndWait"); 3367 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3368 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3369 WaitResult res = new WaitResult(); 3370 // TODO: Switch to user app stacks here. 3371 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3372 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3373 options, userId, null, null); 3374 return res; 3375 } 3376 3377 @Override 3378 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3379 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3380 int startFlags, Configuration config, Bundle options, int userId) { 3381 enforceNotIsolatedCaller("startActivityWithConfig"); 3382 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3383 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3384 // TODO: Switch to user app stacks here. 3385 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3386 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3387 null, null, config, options, userId, null, null); 3388 return ret; 3389 } 3390 3391 @Override 3392 public int startActivityIntentSender(IApplicationThread caller, 3393 IntentSender intent, Intent fillInIntent, String resolvedType, 3394 IBinder resultTo, String resultWho, int requestCode, 3395 int flagsMask, int flagsValues, Bundle options) { 3396 enforceNotIsolatedCaller("startActivityIntentSender"); 3397 // Refuse possible leaked file descriptors 3398 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3399 throw new IllegalArgumentException("File descriptors passed in Intent"); 3400 } 3401 3402 IIntentSender sender = intent.getTarget(); 3403 if (!(sender instanceof PendingIntentRecord)) { 3404 throw new IllegalArgumentException("Bad PendingIntent object"); 3405 } 3406 3407 PendingIntentRecord pir = (PendingIntentRecord)sender; 3408 3409 synchronized (this) { 3410 // If this is coming from the currently resumed activity, it is 3411 // effectively saying that app switches are allowed at this point. 3412 final ActivityStack stack = getFocusedStack(); 3413 if (stack.mResumedActivity != null && 3414 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3415 mAppSwitchesAllowedTime = 0; 3416 } 3417 } 3418 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3419 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3420 return ret; 3421 } 3422 3423 @Override 3424 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3425 Intent intent, String resolvedType, IVoiceInteractionSession session, 3426 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3427 Bundle options, int userId) { 3428 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3429 != PackageManager.PERMISSION_GRANTED) { 3430 String msg = "Permission Denial: startVoiceActivity() from pid=" 3431 + Binder.getCallingPid() 3432 + ", uid=" + Binder.getCallingUid() 3433 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3434 Slog.w(TAG, msg); 3435 throw new SecurityException(msg); 3436 } 3437 if (session == null || interactor == null) { 3438 throw new NullPointerException("null session or interactor"); 3439 } 3440 userId = handleIncomingUser(callingPid, callingUid, userId, 3441 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3442 // TODO: Switch to user app stacks here. 3443 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3444 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3445 null, options, userId, null, null); 3446 } 3447 3448 @Override 3449 public boolean startNextMatchingActivity(IBinder callingActivity, 3450 Intent intent, Bundle options) { 3451 // Refuse possible leaked file descriptors 3452 if (intent != null && intent.hasFileDescriptors() == true) { 3453 throw new IllegalArgumentException("File descriptors passed in Intent"); 3454 } 3455 3456 synchronized (this) { 3457 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3458 if (r == null) { 3459 ActivityOptions.abort(options); 3460 return false; 3461 } 3462 if (r.app == null || r.app.thread == null) { 3463 // The caller is not running... d'oh! 3464 ActivityOptions.abort(options); 3465 return false; 3466 } 3467 intent = new Intent(intent); 3468 // The caller is not allowed to change the data. 3469 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3470 // And we are resetting to find the next component... 3471 intent.setComponent(null); 3472 3473 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3474 3475 ActivityInfo aInfo = null; 3476 try { 3477 List<ResolveInfo> resolves = 3478 AppGlobals.getPackageManager().queryIntentActivities( 3479 intent, r.resolvedType, 3480 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3481 UserHandle.getCallingUserId()); 3482 3483 // Look for the original activity in the list... 3484 final int N = resolves != null ? resolves.size() : 0; 3485 for (int i=0; i<N; i++) { 3486 ResolveInfo rInfo = resolves.get(i); 3487 if (rInfo.activityInfo.packageName.equals(r.packageName) 3488 && rInfo.activityInfo.name.equals(r.info.name)) { 3489 // We found the current one... the next matching is 3490 // after it. 3491 i++; 3492 if (i<N) { 3493 aInfo = resolves.get(i).activityInfo; 3494 } 3495 if (debug) { 3496 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3497 + "/" + r.info.name); 3498 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3499 + "/" + aInfo.name); 3500 } 3501 break; 3502 } 3503 } 3504 } catch (RemoteException e) { 3505 } 3506 3507 if (aInfo == null) { 3508 // Nobody who is next! 3509 ActivityOptions.abort(options); 3510 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3511 return false; 3512 } 3513 3514 intent.setComponent(new ComponentName( 3515 aInfo.applicationInfo.packageName, aInfo.name)); 3516 intent.setFlags(intent.getFlags()&~( 3517 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3518 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3519 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3520 Intent.FLAG_ACTIVITY_NEW_TASK)); 3521 3522 // Okay now we need to start the new activity, replacing the 3523 // currently running activity. This is a little tricky because 3524 // we want to start the new one as if the current one is finished, 3525 // but not finish the current one first so that there is no flicker. 3526 // And thus... 3527 final boolean wasFinishing = r.finishing; 3528 r.finishing = true; 3529 3530 // Propagate reply information over to the new activity. 3531 final ActivityRecord resultTo = r.resultTo; 3532 final String resultWho = r.resultWho; 3533 final int requestCode = r.requestCode; 3534 r.resultTo = null; 3535 if (resultTo != null) { 3536 resultTo.removeResultsLocked(r, resultWho, requestCode); 3537 } 3538 3539 final long origId = Binder.clearCallingIdentity(); 3540 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3541 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3542 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3543 -1, r.launchedFromUid, 0, options, false, null, null, null); 3544 Binder.restoreCallingIdentity(origId); 3545 3546 r.finishing = wasFinishing; 3547 if (res != ActivityManager.START_SUCCESS) { 3548 return false; 3549 } 3550 return true; 3551 } 3552 } 3553 3554 @Override 3555 public final int startActivityFromRecents(int taskId, Bundle options) { 3556 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3557 String msg = "Permission Denial: startActivityFromRecents called without " + 3558 START_TASKS_FROM_RECENTS; 3559 Slog.w(TAG, msg); 3560 throw new SecurityException(msg); 3561 } 3562 return startActivityFromRecentsInner(taskId, options); 3563 } 3564 3565 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3566 final TaskRecord task; 3567 final int callingUid; 3568 final String callingPackage; 3569 final Intent intent; 3570 final int userId; 3571 synchronized (this) { 3572 task = recentTaskForIdLocked(taskId); 3573 if (task == null) { 3574 throw new IllegalArgumentException("Task " + taskId + " not found."); 3575 } 3576 callingUid = task.mCallingUid; 3577 callingPackage = task.mCallingPackage; 3578 intent = task.intent; 3579 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3580 userId = task.userId; 3581 } 3582 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3583 options, userId, null, task); 3584 } 3585 3586 final int startActivityInPackage(int uid, String callingPackage, 3587 Intent intent, String resolvedType, IBinder resultTo, 3588 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3589 IActivityContainer container, TaskRecord inTask) { 3590 3591 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3592 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3593 3594 // TODO: Switch to user app stacks here. 3595 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3596 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3597 null, null, null, options, userId, container, inTask); 3598 return ret; 3599 } 3600 3601 @Override 3602 public final int startActivities(IApplicationThread caller, String callingPackage, 3603 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3604 int userId) { 3605 enforceNotIsolatedCaller("startActivities"); 3606 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3607 false, ALLOW_FULL_ONLY, "startActivity", null); 3608 // TODO: Switch to user app stacks here. 3609 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3610 resolvedTypes, resultTo, options, userId); 3611 return ret; 3612 } 3613 3614 final int startActivitiesInPackage(int uid, String callingPackage, 3615 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3616 Bundle options, int userId) { 3617 3618 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3619 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3620 // TODO: Switch to user app stacks here. 3621 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3622 resultTo, options, userId); 3623 return ret; 3624 } 3625 3626 //explicitly remove thd old information in mRecentTasks when removing existing user. 3627 private void removeRecentTasksForUserLocked(int userId) { 3628 if(userId <= 0) { 3629 Slog.i(TAG, "Can't remove recent task on user " + userId); 3630 return; 3631 } 3632 3633 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3634 TaskRecord tr = mRecentTasks.get(i); 3635 if (tr.userId == userId) { 3636 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3637 + " when finishing user" + userId); 3638 mRecentTasks.remove(i); 3639 tr.removedFromRecents(mTaskPersister); 3640 } 3641 } 3642 3643 // Remove tasks from persistent storage. 3644 mTaskPersister.wakeup(null, true); 3645 } 3646 3647 // Sort by taskId 3648 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3649 @Override 3650 public int compare(TaskRecord lhs, TaskRecord rhs) { 3651 return rhs.taskId - lhs.taskId; 3652 } 3653 }; 3654 3655 // Extract the affiliates of the chain containing mRecentTasks[start]. 3656 private int processNextAffiliateChain(int start) { 3657 final TaskRecord startTask = mRecentTasks.get(start); 3658 final int affiliateId = startTask.mAffiliatedTaskId; 3659 3660 // Quick identification of isolated tasks. I.e. those not launched behind. 3661 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3662 startTask.mNextAffiliate == null) { 3663 // There is still a slim chance that there are other tasks that point to this task 3664 // and that the chain is so messed up that this task no longer points to them but 3665 // the gain of this optimization outweighs the risk. 3666 startTask.inRecents = true; 3667 return start + 1; 3668 } 3669 3670 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3671 mTmpRecents.clear(); 3672 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3673 final TaskRecord task = mRecentTasks.get(i); 3674 if (task.mAffiliatedTaskId == affiliateId) { 3675 mRecentTasks.remove(i); 3676 mTmpRecents.add(task); 3677 } 3678 } 3679 3680 // Sort them all by taskId. That is the order they were create in and that order will 3681 // always be correct. 3682 Collections.sort(mTmpRecents, mTaskRecordComparator); 3683 3684 // Go through and fix up the linked list. 3685 // The first one is the end of the chain and has no next. 3686 final TaskRecord first = mTmpRecents.get(0); 3687 first.inRecents = true; 3688 if (first.mNextAffiliate != null) { 3689 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3690 first.setNextAffiliate(null); 3691 mTaskPersister.wakeup(first, false); 3692 } 3693 // Everything in the middle is doubly linked from next to prev. 3694 final int tmpSize = mTmpRecents.size(); 3695 for (int i = 0; i < tmpSize - 1; ++i) { 3696 final TaskRecord next = mTmpRecents.get(i); 3697 final TaskRecord prev = mTmpRecents.get(i + 1); 3698 if (next.mPrevAffiliate != prev) { 3699 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3700 " setting prev=" + prev); 3701 next.setPrevAffiliate(prev); 3702 mTaskPersister.wakeup(next, false); 3703 } 3704 if (prev.mNextAffiliate != next) { 3705 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3706 " setting next=" + next); 3707 prev.setNextAffiliate(next); 3708 mTaskPersister.wakeup(prev, false); 3709 } 3710 prev.inRecents = true; 3711 } 3712 // The last one is the beginning of the list and has no prev. 3713 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3714 if (last.mPrevAffiliate != null) { 3715 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3716 last.setPrevAffiliate(null); 3717 mTaskPersister.wakeup(last, false); 3718 } 3719 3720 // Insert the group back into mRecentTasks at start. 3721 mRecentTasks.addAll(start, mTmpRecents); 3722 3723 // Let the caller know where we left off. 3724 return start + tmpSize; 3725 } 3726 3727 /** 3728 * Update the recent tasks lists: make sure tasks should still be here (their 3729 * applications / activities still exist), update their availability, fixup ordering 3730 * of affiliations. 3731 */ 3732 void cleanupRecentTasksLocked(int userId) { 3733 if (mRecentTasks == null) { 3734 // Happens when called from the packagemanager broadcast before boot. 3735 return; 3736 } 3737 3738 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3739 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3740 final IPackageManager pm = AppGlobals.getPackageManager(); 3741 final ActivityInfo dummyAct = new ActivityInfo(); 3742 final ApplicationInfo dummyApp = new ApplicationInfo(); 3743 3744 int N = mRecentTasks.size(); 3745 3746 int[] users = userId == UserHandle.USER_ALL 3747 ? getUsersLocked() : new int[] { userId }; 3748 for (int user : users) { 3749 for (int i = 0; i < N; i++) { 3750 TaskRecord task = mRecentTasks.get(i); 3751 if (task.userId != user) { 3752 // Only look at tasks for the user ID of interest. 3753 continue; 3754 } 3755 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3756 // This situation is broken, and we should just get rid of it now. 3757 mRecentTasks.remove(i); 3758 task.removedFromRecents(mTaskPersister); 3759 i--; 3760 N--; 3761 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3762 continue; 3763 } 3764 // Check whether this activity is currently available. 3765 if (task.realActivity != null) { 3766 ActivityInfo ai = availActCache.get(task.realActivity); 3767 if (ai == null) { 3768 try { 3769 ai = pm.getActivityInfo(task.realActivity, 3770 PackageManager.GET_UNINSTALLED_PACKAGES 3771 | PackageManager.GET_DISABLED_COMPONENTS, user); 3772 } catch (RemoteException e) { 3773 // Will never happen. 3774 continue; 3775 } 3776 if (ai == null) { 3777 ai = dummyAct; 3778 } 3779 availActCache.put(task.realActivity, ai); 3780 } 3781 if (ai == dummyAct) { 3782 // This could be either because the activity no longer exists, or the 3783 // app is temporarily gone. For the former we want to remove the recents 3784 // entry; for the latter we want to mark it as unavailable. 3785 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3786 if (app == null) { 3787 try { 3788 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3789 PackageManager.GET_UNINSTALLED_PACKAGES 3790 | PackageManager.GET_DISABLED_COMPONENTS, user); 3791 } catch (RemoteException e) { 3792 // Will never happen. 3793 continue; 3794 } 3795 if (app == null) { 3796 app = dummyApp; 3797 } 3798 availAppCache.put(task.realActivity.getPackageName(), app); 3799 } 3800 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3801 // Doesn't exist any more! Good-bye. 3802 mRecentTasks.remove(i); 3803 task.removedFromRecents(mTaskPersister); 3804 i--; 3805 N--; 3806 Slog.w(TAG, "Removing no longer valid recent: " + task); 3807 continue; 3808 } else { 3809 // Otherwise just not available for now. 3810 if (task.isAvailable) { 3811 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3812 + task); 3813 } 3814 task.isAvailable = false; 3815 } 3816 } else { 3817 if (!ai.enabled || !ai.applicationInfo.enabled 3818 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3819 if (task.isAvailable) { 3820 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3821 + task + " (enabled=" + ai.enabled + "/" 3822 + ai.applicationInfo.enabled + " flags=" 3823 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3824 } 3825 task.isAvailable = false; 3826 } else { 3827 if (!task.isAvailable) { 3828 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3829 + task); 3830 } 3831 task.isAvailable = true; 3832 } 3833 } 3834 } 3835 } 3836 } 3837 3838 // Verify the affiliate chain for each task. 3839 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3840 } 3841 3842 mTmpRecents.clear(); 3843 // mRecentTasks is now in sorted, affiliated order. 3844 } 3845 3846 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3847 int N = mRecentTasks.size(); 3848 TaskRecord top = task; 3849 int topIndex = taskIndex; 3850 while (top.mNextAffiliate != null && topIndex > 0) { 3851 top = top.mNextAffiliate; 3852 topIndex--; 3853 } 3854 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3855 + topIndex + " from intial " + taskIndex); 3856 // Find the end of the chain, doing a sanity check along the way. 3857 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3858 int endIndex = topIndex; 3859 TaskRecord prev = top; 3860 while (endIndex < N) { 3861 TaskRecord cur = mRecentTasks.get(endIndex); 3862 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3863 + endIndex + " " + cur); 3864 if (cur == top) { 3865 // Verify start of the chain. 3866 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3867 Slog.wtf(TAG, "Bad chain @" + endIndex 3868 + ": first task has next affiliate: " + prev); 3869 sane = false; 3870 break; 3871 } 3872 } else { 3873 // Verify middle of the chain's next points back to the one before. 3874 if (cur.mNextAffiliate != prev 3875 || cur.mNextAffiliateTaskId != prev.taskId) { 3876 Slog.wtf(TAG, "Bad chain @" + endIndex 3877 + ": middle task " + cur + " @" + endIndex 3878 + " has bad next affiliate " 3879 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3880 + ", expected " + prev); 3881 sane = false; 3882 break; 3883 } 3884 } 3885 if (cur.mPrevAffiliateTaskId == -1) { 3886 // Chain ends here. 3887 if (cur.mPrevAffiliate != null) { 3888 Slog.wtf(TAG, "Bad chain @" + endIndex 3889 + ": last task " + cur + " has previous affiliate " 3890 + cur.mPrevAffiliate); 3891 sane = false; 3892 } 3893 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3894 break; 3895 } else { 3896 // Verify middle of the chain's prev points to a valid item. 3897 if (cur.mPrevAffiliate == null) { 3898 Slog.wtf(TAG, "Bad chain @" + endIndex 3899 + ": task " + cur + " has previous affiliate " 3900 + cur.mPrevAffiliate + " but should be id " 3901 + cur.mPrevAffiliate); 3902 sane = false; 3903 break; 3904 } 3905 } 3906 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3907 Slog.wtf(TAG, "Bad chain @" + endIndex 3908 + ": task " + cur + " has affiliated id " 3909 + cur.mAffiliatedTaskId + " but should be " 3910 + task.mAffiliatedTaskId); 3911 sane = false; 3912 break; 3913 } 3914 prev = cur; 3915 endIndex++; 3916 if (endIndex >= N) { 3917 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3918 + ": last task " + prev); 3919 sane = false; 3920 break; 3921 } 3922 } 3923 if (sane) { 3924 if (endIndex < taskIndex) { 3925 Slog.wtf(TAG, "Bad chain @" + endIndex 3926 + ": did not extend to task " + task + " @" + taskIndex); 3927 sane = false; 3928 } 3929 } 3930 if (sane) { 3931 // All looks good, we can just move all of the affiliated tasks 3932 // to the top. 3933 for (int i=topIndex; i<=endIndex; i++) { 3934 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3935 + " from " + i + " to " + (i-topIndex)); 3936 TaskRecord cur = mRecentTasks.remove(i); 3937 mRecentTasks.add(i-topIndex, cur); 3938 } 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3940 + " to " + endIndex); 3941 return true; 3942 } 3943 3944 // Whoops, couldn't do it. 3945 return false; 3946 } 3947 3948 final void addRecentTaskLocked(TaskRecord task) { 3949 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3950 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3951 3952 int N = mRecentTasks.size(); 3953 // Quick case: check if the top-most recent task is the same. 3954 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3955 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3956 return; 3957 } 3958 // Another quick case: check if this is part of a set of affiliated 3959 // tasks that are at the top. 3960 if (isAffiliated && N > 0 && task.inRecents 3961 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3962 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3963 + " at top when adding " + task); 3964 return; 3965 } 3966 // Another quick case: never add voice sessions. 3967 if (task.voiceSession != null) { 3968 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3969 return; 3970 } 3971 3972 boolean needAffiliationFix = false; 3973 3974 // Slightly less quick case: the task is already in recents, so all we need 3975 // to do is move it. 3976 if (task.inRecents) { 3977 int taskIndex = mRecentTasks.indexOf(task); 3978 if (taskIndex >= 0) { 3979 if (!isAffiliated) { 3980 // Simple case: this is not an affiliated task, so we just move it to the front. 3981 mRecentTasks.remove(taskIndex); 3982 mRecentTasks.add(0, task); 3983 notifyTaskPersisterLocked(task, false); 3984 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3985 + " from " + taskIndex); 3986 return; 3987 } else { 3988 // More complicated: need to keep all affiliated tasks together. 3989 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3990 // All went well. 3991 return; 3992 } 3993 3994 // Uh oh... something bad in the affiliation chain, try to rebuild 3995 // everything and then go through our general path of adding a new task. 3996 needAffiliationFix = true; 3997 } 3998 } else { 3999 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4000 needAffiliationFix = true; 4001 } 4002 } 4003 4004 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4005 trimRecentsForTask(task, true); 4006 4007 N = mRecentTasks.size(); 4008 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4009 final TaskRecord tr = mRecentTasks.remove(N - 1); 4010 tr.removedFromRecents(mTaskPersister); 4011 N--; 4012 } 4013 task.inRecents = true; 4014 if (!isAffiliated || needAffiliationFix) { 4015 // If this is a simple non-affiliated task, or we had some failure trying to 4016 // handle it as part of an affilated task, then just place it at the top. 4017 mRecentTasks.add(0, task); 4018 } else if (isAffiliated) { 4019 // If this is a new affiliated task, then move all of the affiliated tasks 4020 // to the front and insert this new one. 4021 TaskRecord other = task.mNextAffiliate; 4022 if (other == null) { 4023 other = task.mPrevAffiliate; 4024 } 4025 if (other != null) { 4026 int otherIndex = mRecentTasks.indexOf(other); 4027 if (otherIndex >= 0) { 4028 // Insert new task at appropriate location. 4029 int taskIndex; 4030 if (other == task.mNextAffiliate) { 4031 // We found the index of our next affiliation, which is who is 4032 // before us in the list, so add after that point. 4033 taskIndex = otherIndex+1; 4034 } else { 4035 // We found the index of our previous affiliation, which is who is 4036 // after us in the list, so add at their position. 4037 taskIndex = otherIndex; 4038 } 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4040 + taskIndex + ": " + task); 4041 mRecentTasks.add(taskIndex, task); 4042 4043 // Now move everything to the front. 4044 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4045 // All went well. 4046 return; 4047 } 4048 4049 // Uh oh... something bad in the affiliation chain, try to rebuild 4050 // everything and then go through our general path of adding a new task. 4051 needAffiliationFix = true; 4052 } else { 4053 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4054 + other); 4055 needAffiliationFix = true; 4056 } 4057 } else { 4058 if (DEBUG_RECENTS) Slog.d(TAG, 4059 "addRecent: adding affiliated task without next/prev:" + task); 4060 needAffiliationFix = true; 4061 } 4062 } 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4064 4065 if (needAffiliationFix) { 4066 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4067 cleanupRecentTasksLocked(task.userId); 4068 } 4069 } 4070 4071 /** 4072 * If needed, remove oldest existing entries in recents that are for the same kind 4073 * of task as the given one. 4074 */ 4075 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4076 int N = mRecentTasks.size(); 4077 final Intent intent = task.intent; 4078 final boolean document = intent != null && intent.isDocument(); 4079 4080 int maxRecents = task.maxRecents - 1; 4081 for (int i=0; i<N; i++) { 4082 final TaskRecord tr = mRecentTasks.get(i); 4083 if (task != tr) { 4084 if (task.userId != tr.userId) { 4085 continue; 4086 } 4087 if (i > MAX_RECENT_BITMAPS) { 4088 tr.freeLastThumbnail(); 4089 } 4090 final Intent trIntent = tr.intent; 4091 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4092 (intent == null || !intent.filterEquals(trIntent))) { 4093 continue; 4094 } 4095 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4096 if (document && trIsDocument) { 4097 // These are the same document activity (not necessarily the same doc). 4098 if (maxRecents > 0) { 4099 --maxRecents; 4100 continue; 4101 } 4102 // Hit the maximum number of documents for this task. Fall through 4103 // and remove this document from recents. 4104 } else if (document || trIsDocument) { 4105 // Only one of these is a document. Not the droid we're looking for. 4106 continue; 4107 } 4108 } 4109 4110 if (!doTrim) { 4111 // If the caller is not actually asking for a trim, just tell them we reached 4112 // a point where the trim would happen. 4113 return i; 4114 } 4115 4116 // Either task and tr are the same or, their affinities match or their intents match 4117 // and neither of them is a document, or they are documents using the same activity 4118 // and their maxRecents has been reached. 4119 tr.disposeThumbnail(); 4120 mRecentTasks.remove(i); 4121 if (task != tr) { 4122 tr.removedFromRecents(mTaskPersister); 4123 } 4124 i--; 4125 N--; 4126 if (task.intent == null) { 4127 // If the new recent task we are adding is not fully 4128 // specified, then replace it with the existing recent task. 4129 task = tr; 4130 } 4131 notifyTaskPersisterLocked(tr, false); 4132 } 4133 4134 return -1; 4135 } 4136 4137 @Override 4138 public void reportActivityFullyDrawn(IBinder token) { 4139 synchronized (this) { 4140 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4141 if (r == null) { 4142 return; 4143 } 4144 r.reportFullyDrawnLocked(); 4145 } 4146 } 4147 4148 @Override 4149 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4150 synchronized (this) { 4151 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4152 if (r == null) { 4153 return; 4154 } 4155 final long origId = Binder.clearCallingIdentity(); 4156 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4157 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4158 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4159 if (config != null) { 4160 r.frozenBeforeDestroy = true; 4161 if (!updateConfigurationLocked(config, r, false, false)) { 4162 mStackSupervisor.resumeTopActivitiesLocked(); 4163 } 4164 } 4165 Binder.restoreCallingIdentity(origId); 4166 } 4167 } 4168 4169 @Override 4170 public int getRequestedOrientation(IBinder token) { 4171 synchronized (this) { 4172 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4173 if (r == null) { 4174 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4175 } 4176 return mWindowManager.getAppOrientation(r.appToken); 4177 } 4178 } 4179 4180 /** 4181 * This is the internal entry point for handling Activity.finish(). 4182 * 4183 * @param token The Binder token referencing the Activity we want to finish. 4184 * @param resultCode Result code, if any, from this Activity. 4185 * @param resultData Result data (Intent), if any, from this Activity. 4186 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4187 * the root Activity in the task. 4188 * 4189 * @return Returns true if the activity successfully finished, or false if it is still running. 4190 */ 4191 @Override 4192 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4193 boolean finishTask) { 4194 // Refuse possible leaked file descriptors 4195 if (resultData != null && resultData.hasFileDescriptors() == true) { 4196 throw new IllegalArgumentException("File descriptors passed in Intent"); 4197 } 4198 4199 synchronized(this) { 4200 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4201 if (r == null) { 4202 return true; 4203 } 4204 // Keep track of the root activity of the task before we finish it 4205 TaskRecord tr = r.task; 4206 ActivityRecord rootR = tr.getRootActivity(); 4207 if (rootR == null) { 4208 Slog.w(TAG, "Finishing task with all activities already finished"); 4209 } 4210 // Do not allow task to finish in Lock Task mode. 4211 if (tr == mStackSupervisor.mLockTaskModeTask) { 4212 if (rootR == r) { 4213 Slog.i(TAG, "Not finishing task in lock task mode"); 4214 mStackSupervisor.showLockTaskToast(); 4215 return false; 4216 } 4217 } 4218 if (mController != null) { 4219 // Find the first activity that is not finishing. 4220 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4221 if (next != null) { 4222 // ask watcher if this is allowed 4223 boolean resumeOK = true; 4224 try { 4225 resumeOK = mController.activityResuming(next.packageName); 4226 } catch (RemoteException e) { 4227 mController = null; 4228 Watchdog.getInstance().setActivityController(null); 4229 } 4230 4231 if (!resumeOK) { 4232 Slog.i(TAG, "Not finishing activity because controller resumed"); 4233 return false; 4234 } 4235 } 4236 } 4237 final long origId = Binder.clearCallingIdentity(); 4238 try { 4239 boolean res; 4240 if (finishTask && r == rootR) { 4241 // If requested, remove the task that is associated to this activity only if it 4242 // was the root activity in the task. The result code and data is ignored 4243 // because we don't support returning them across task boundaries. 4244 res = removeTaskByIdLocked(tr.taskId, false); 4245 if (!res) { 4246 Slog.i(TAG, "Removing task failed to finish activity"); 4247 } 4248 } else { 4249 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4250 resultData, "app-request", true); 4251 if (!res) { 4252 Slog.i(TAG, "Failed to finish by app-request"); 4253 } 4254 } 4255 return res; 4256 } finally { 4257 Binder.restoreCallingIdentity(origId); 4258 } 4259 } 4260 } 4261 4262 @Override 4263 public final void finishHeavyWeightApp() { 4264 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4265 != PackageManager.PERMISSION_GRANTED) { 4266 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4267 + Binder.getCallingPid() 4268 + ", uid=" + Binder.getCallingUid() 4269 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4270 Slog.w(TAG, msg); 4271 throw new SecurityException(msg); 4272 } 4273 4274 synchronized(this) { 4275 if (mHeavyWeightProcess == null) { 4276 return; 4277 } 4278 4279 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4280 mHeavyWeightProcess.activities); 4281 for (int i=0; i<activities.size(); i++) { 4282 ActivityRecord r = activities.get(i); 4283 if (!r.finishing) { 4284 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4285 null, "finish-heavy", true); 4286 } 4287 } 4288 4289 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4290 mHeavyWeightProcess.userId, 0)); 4291 mHeavyWeightProcess = null; 4292 } 4293 } 4294 4295 @Override 4296 public void crashApplication(int uid, int initialPid, String packageName, 4297 String message) { 4298 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4299 != PackageManager.PERMISSION_GRANTED) { 4300 String msg = "Permission Denial: crashApplication() from pid=" 4301 + Binder.getCallingPid() 4302 + ", uid=" + Binder.getCallingUid() 4303 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4304 Slog.w(TAG, msg); 4305 throw new SecurityException(msg); 4306 } 4307 4308 synchronized(this) { 4309 ProcessRecord proc = null; 4310 4311 // Figure out which process to kill. We don't trust that initialPid 4312 // still has any relation to current pids, so must scan through the 4313 // list. 4314 synchronized (mPidsSelfLocked) { 4315 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4316 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4317 if (p.uid != uid) { 4318 continue; 4319 } 4320 if (p.pid == initialPid) { 4321 proc = p; 4322 break; 4323 } 4324 if (p.pkgList.containsKey(packageName)) { 4325 proc = p; 4326 } 4327 } 4328 } 4329 4330 if (proc == null) { 4331 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4332 + " initialPid=" + initialPid 4333 + " packageName=" + packageName); 4334 return; 4335 } 4336 4337 if (proc.thread != null) { 4338 if (proc.pid == Process.myPid()) { 4339 Log.w(TAG, "crashApplication: trying to crash self!"); 4340 return; 4341 } 4342 long ident = Binder.clearCallingIdentity(); 4343 try { 4344 proc.thread.scheduleCrash(message); 4345 } catch (RemoteException e) { 4346 } 4347 Binder.restoreCallingIdentity(ident); 4348 } 4349 } 4350 } 4351 4352 @Override 4353 public final void finishSubActivity(IBinder token, String resultWho, 4354 int requestCode) { 4355 synchronized(this) { 4356 final long origId = Binder.clearCallingIdentity(); 4357 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4358 if (r != null) { 4359 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4360 } 4361 Binder.restoreCallingIdentity(origId); 4362 } 4363 } 4364 4365 @Override 4366 public boolean finishActivityAffinity(IBinder token) { 4367 synchronized(this) { 4368 final long origId = Binder.clearCallingIdentity(); 4369 try { 4370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4371 4372 ActivityRecord rootR = r.task.getRootActivity(); 4373 // Do not allow task to finish in Lock Task mode. 4374 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4375 if (rootR == r) { 4376 mStackSupervisor.showLockTaskToast(); 4377 return false; 4378 } 4379 } 4380 boolean res = false; 4381 if (r != null) { 4382 res = r.task.stack.finishActivityAffinityLocked(r); 4383 } 4384 return res; 4385 } finally { 4386 Binder.restoreCallingIdentity(origId); 4387 } 4388 } 4389 } 4390 4391 @Override 4392 public void finishVoiceTask(IVoiceInteractionSession session) { 4393 synchronized(this) { 4394 final long origId = Binder.clearCallingIdentity(); 4395 try { 4396 mStackSupervisor.finishVoiceTask(session); 4397 } finally { 4398 Binder.restoreCallingIdentity(origId); 4399 } 4400 } 4401 4402 } 4403 4404 @Override 4405 public boolean releaseActivityInstance(IBinder token) { 4406 synchronized(this) { 4407 final long origId = Binder.clearCallingIdentity(); 4408 try { 4409 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4410 if (r.task == null || r.task.stack == null) { 4411 return false; 4412 } 4413 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4414 } finally { 4415 Binder.restoreCallingIdentity(origId); 4416 } 4417 } 4418 } 4419 4420 @Override 4421 public void releaseSomeActivities(IApplicationThread appInt) { 4422 synchronized(this) { 4423 final long origId = Binder.clearCallingIdentity(); 4424 try { 4425 ProcessRecord app = getRecordForAppLocked(appInt); 4426 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4427 } finally { 4428 Binder.restoreCallingIdentity(origId); 4429 } 4430 } 4431 } 4432 4433 @Override 4434 public boolean willActivityBeVisible(IBinder token) { 4435 synchronized(this) { 4436 ActivityStack stack = ActivityRecord.getStackLocked(token); 4437 if (stack != null) { 4438 return stack.willActivityBeVisibleLocked(token); 4439 } 4440 return false; 4441 } 4442 } 4443 4444 @Override 4445 public void overridePendingTransition(IBinder token, String packageName, 4446 int enterAnim, int exitAnim) { 4447 synchronized(this) { 4448 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4449 if (self == null) { 4450 return; 4451 } 4452 4453 final long origId = Binder.clearCallingIdentity(); 4454 4455 if (self.state == ActivityState.RESUMED 4456 || self.state == ActivityState.PAUSING) { 4457 mWindowManager.overridePendingAppTransition(packageName, 4458 enterAnim, exitAnim, null); 4459 } 4460 4461 Binder.restoreCallingIdentity(origId); 4462 } 4463 } 4464 4465 /** 4466 * Main function for removing an existing process from the activity manager 4467 * as a result of that process going away. Clears out all connections 4468 * to the process. 4469 */ 4470 private final void handleAppDiedLocked(ProcessRecord app, 4471 boolean restarting, boolean allowRestart) { 4472 int pid = app.pid; 4473 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4474 if (!kept && !restarting) { 4475 removeLruProcessLocked(app); 4476 if (pid > 0) { 4477 ProcessList.remove(pid); 4478 } 4479 } 4480 4481 if (mProfileProc == app) { 4482 clearProfilerLocked(); 4483 } 4484 4485 // Remove this application's activities from active lists. 4486 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4487 4488 app.activities.clear(); 4489 4490 if (app.instrumentationClass != null) { 4491 Slog.w(TAG, "Crash of app " + app.processName 4492 + " running instrumentation " + app.instrumentationClass); 4493 Bundle info = new Bundle(); 4494 info.putString("shortMsg", "Process crashed."); 4495 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4496 } 4497 4498 if (!restarting) { 4499 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4500 // If there was nothing to resume, and we are not already 4501 // restarting this process, but there is a visible activity that 4502 // is hosted by the process... then make sure all visible 4503 // activities are running, taking care of restarting this 4504 // process. 4505 if (hasVisibleActivities) { 4506 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4507 } 4508 } 4509 } 4510 } 4511 4512 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4513 IBinder threadBinder = thread.asBinder(); 4514 // Find the application record. 4515 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4516 ProcessRecord rec = mLruProcesses.get(i); 4517 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4518 return i; 4519 } 4520 } 4521 return -1; 4522 } 4523 4524 final ProcessRecord getRecordForAppLocked( 4525 IApplicationThread thread) { 4526 if (thread == null) { 4527 return null; 4528 } 4529 4530 int appIndex = getLRURecordIndexForAppLocked(thread); 4531 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4532 } 4533 4534 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4535 // If there are no longer any background processes running, 4536 // and the app that died was not running instrumentation, 4537 // then tell everyone we are now low on memory. 4538 boolean haveBg = false; 4539 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4540 ProcessRecord rec = mLruProcesses.get(i); 4541 if (rec.thread != null 4542 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4543 haveBg = true; 4544 break; 4545 } 4546 } 4547 4548 if (!haveBg) { 4549 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4550 if (doReport) { 4551 long now = SystemClock.uptimeMillis(); 4552 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4553 doReport = false; 4554 } else { 4555 mLastMemUsageReportTime = now; 4556 } 4557 } 4558 final ArrayList<ProcessMemInfo> memInfos 4559 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4560 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4561 long now = SystemClock.uptimeMillis(); 4562 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4563 ProcessRecord rec = mLruProcesses.get(i); 4564 if (rec == dyingProc || rec.thread == null) { 4565 continue; 4566 } 4567 if (doReport) { 4568 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4569 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4570 } 4571 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4572 // The low memory report is overriding any current 4573 // state for a GC request. Make sure to do 4574 // heavy/important/visible/foreground processes first. 4575 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4576 rec.lastRequestedGc = 0; 4577 } else { 4578 rec.lastRequestedGc = rec.lastLowMemory; 4579 } 4580 rec.reportLowMemory = true; 4581 rec.lastLowMemory = now; 4582 mProcessesToGc.remove(rec); 4583 addProcessToGcListLocked(rec); 4584 } 4585 } 4586 if (doReport) { 4587 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4588 mHandler.sendMessage(msg); 4589 } 4590 scheduleAppGcsLocked(); 4591 } 4592 } 4593 4594 final void appDiedLocked(ProcessRecord app) { 4595 appDiedLocked(app, app.pid, app.thread); 4596 } 4597 4598 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4599 // First check if this ProcessRecord is actually active for the pid. 4600 synchronized (mPidsSelfLocked) { 4601 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4602 if (curProc != app) { 4603 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4604 return; 4605 } 4606 } 4607 4608 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4609 synchronized (stats) { 4610 stats.noteProcessDiedLocked(app.info.uid, pid); 4611 } 4612 4613 Process.killProcessQuiet(pid); 4614 Process.killProcessGroup(app.info.uid, pid); 4615 app.killed = true; 4616 4617 // Clean up already done if the process has been re-started. 4618 if (app.pid == pid && app.thread != null && 4619 app.thread.asBinder() == thread.asBinder()) { 4620 boolean doLowMem = app.instrumentationClass == null; 4621 boolean doOomAdj = doLowMem; 4622 if (!app.killedByAm) { 4623 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4624 + ") has died"); 4625 mAllowLowerMemLevel = true; 4626 } else { 4627 // Note that we always want to do oom adj to update our state with the 4628 // new number of procs. 4629 mAllowLowerMemLevel = false; 4630 doLowMem = false; 4631 } 4632 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4633 if (DEBUG_CLEANUP) Slog.v( 4634 TAG, "Dying app: " + app + ", pid: " + pid 4635 + ", thread: " + thread.asBinder()); 4636 handleAppDiedLocked(app, false, true); 4637 4638 if (doOomAdj) { 4639 updateOomAdjLocked(); 4640 } 4641 if (doLowMem) { 4642 doLowMemReportIfNeededLocked(app); 4643 } 4644 } else if (app.pid != pid) { 4645 // A new process has already been started. 4646 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4647 + ") has died and restarted (pid " + app.pid + ")."); 4648 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4649 } else if (DEBUG_PROCESSES) { 4650 Slog.d(TAG, "Received spurious death notification for thread " 4651 + thread.asBinder()); 4652 } 4653 } 4654 4655 /** 4656 * If a stack trace dump file is configured, dump process stack traces. 4657 * @param clearTraces causes the dump file to be erased prior to the new 4658 * traces being written, if true; when false, the new traces will be 4659 * appended to any existing file content. 4660 * @param firstPids of dalvik VM processes to dump stack traces for first 4661 * @param lastPids of dalvik VM processes to dump stack traces for last 4662 * @param nativeProcs optional list of native process names to dump stack crawls 4663 * @return file containing stack traces, or null if no dump file is configured 4664 */ 4665 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4666 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4667 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4668 if (tracesPath == null || tracesPath.length() == 0) { 4669 return null; 4670 } 4671 4672 File tracesFile = new File(tracesPath); 4673 try { 4674 File tracesDir = tracesFile.getParentFile(); 4675 if (!tracesDir.exists()) { 4676 tracesDir.mkdirs(); 4677 if (!SELinux.restorecon(tracesDir)) { 4678 return null; 4679 } 4680 } 4681 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4682 4683 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4684 tracesFile.createNewFile(); 4685 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4686 } catch (IOException e) { 4687 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4688 return null; 4689 } 4690 4691 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4692 return tracesFile; 4693 } 4694 4695 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4696 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4697 // Use a FileObserver to detect when traces finish writing. 4698 // The order of traces is considered important to maintain for legibility. 4699 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4700 @Override 4701 public synchronized void onEvent(int event, String path) { notify(); } 4702 }; 4703 4704 try { 4705 observer.startWatching(); 4706 4707 // First collect all of the stacks of the most important pids. 4708 if (firstPids != null) { 4709 try { 4710 int num = firstPids.size(); 4711 for (int i = 0; i < num; i++) { 4712 synchronized (observer) { 4713 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4714 observer.wait(200); // Wait for write-close, give up after 200msec 4715 } 4716 } 4717 } catch (InterruptedException e) { 4718 Slog.wtf(TAG, e); 4719 } 4720 } 4721 4722 // Next collect the stacks of the native pids 4723 if (nativeProcs != null) { 4724 int[] pids = Process.getPidsForCommands(nativeProcs); 4725 if (pids != null) { 4726 for (int pid : pids) { 4727 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4728 } 4729 } 4730 } 4731 4732 // Lastly, measure CPU usage. 4733 if (processCpuTracker != null) { 4734 processCpuTracker.init(); 4735 System.gc(); 4736 processCpuTracker.update(); 4737 try { 4738 synchronized (processCpuTracker) { 4739 processCpuTracker.wait(500); // measure over 1/2 second. 4740 } 4741 } catch (InterruptedException e) { 4742 } 4743 processCpuTracker.update(); 4744 4745 // We'll take the stack crawls of just the top apps using CPU. 4746 final int N = processCpuTracker.countWorkingStats(); 4747 int numProcs = 0; 4748 for (int i=0; i<N && numProcs<5; i++) { 4749 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4750 if (lastPids.indexOfKey(stats.pid) >= 0) { 4751 numProcs++; 4752 try { 4753 synchronized (observer) { 4754 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4755 observer.wait(200); // Wait for write-close, give up after 200msec 4756 } 4757 } catch (InterruptedException e) { 4758 Slog.wtf(TAG, e); 4759 } 4760 4761 } 4762 } 4763 } 4764 } finally { 4765 observer.stopWatching(); 4766 } 4767 } 4768 4769 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4770 if (true || IS_USER_BUILD) { 4771 return; 4772 } 4773 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4774 if (tracesPath == null || tracesPath.length() == 0) { 4775 return; 4776 } 4777 4778 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4779 StrictMode.allowThreadDiskWrites(); 4780 try { 4781 final File tracesFile = new File(tracesPath); 4782 final File tracesDir = tracesFile.getParentFile(); 4783 final File tracesTmp = new File(tracesDir, "__tmp__"); 4784 try { 4785 if (!tracesDir.exists()) { 4786 tracesDir.mkdirs(); 4787 if (!SELinux.restorecon(tracesDir.getPath())) { 4788 return; 4789 } 4790 } 4791 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4792 4793 if (tracesFile.exists()) { 4794 tracesTmp.delete(); 4795 tracesFile.renameTo(tracesTmp); 4796 } 4797 StringBuilder sb = new StringBuilder(); 4798 Time tobj = new Time(); 4799 tobj.set(System.currentTimeMillis()); 4800 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4801 sb.append(": "); 4802 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4803 sb.append(" since "); 4804 sb.append(msg); 4805 FileOutputStream fos = new FileOutputStream(tracesFile); 4806 fos.write(sb.toString().getBytes()); 4807 if (app == null) { 4808 fos.write("\n*** No application process!".getBytes()); 4809 } 4810 fos.close(); 4811 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4812 } catch (IOException e) { 4813 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4814 return; 4815 } 4816 4817 if (app != null) { 4818 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4819 firstPids.add(app.pid); 4820 dumpStackTraces(tracesPath, firstPids, null, null, null); 4821 } 4822 4823 File lastTracesFile = null; 4824 File curTracesFile = null; 4825 for (int i=9; i>=0; i--) { 4826 String name = String.format(Locale.US, "slow%02d.txt", i); 4827 curTracesFile = new File(tracesDir, name); 4828 if (curTracesFile.exists()) { 4829 if (lastTracesFile != null) { 4830 curTracesFile.renameTo(lastTracesFile); 4831 } else { 4832 curTracesFile.delete(); 4833 } 4834 } 4835 lastTracesFile = curTracesFile; 4836 } 4837 tracesFile.renameTo(curTracesFile); 4838 if (tracesTmp.exists()) { 4839 tracesTmp.renameTo(tracesFile); 4840 } 4841 } finally { 4842 StrictMode.setThreadPolicy(oldPolicy); 4843 } 4844 } 4845 4846 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4847 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4848 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4849 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4850 4851 if (mController != null) { 4852 try { 4853 // 0 == continue, -1 = kill process immediately 4854 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4855 if (res < 0 && app.pid != MY_PID) { 4856 app.kill("anr", true); 4857 } 4858 } catch (RemoteException e) { 4859 mController = null; 4860 Watchdog.getInstance().setActivityController(null); 4861 } 4862 } 4863 4864 long anrTime = SystemClock.uptimeMillis(); 4865 if (MONITOR_CPU_USAGE) { 4866 updateCpuStatsNow(); 4867 } 4868 4869 synchronized (this) { 4870 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4871 if (mShuttingDown) { 4872 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4873 return; 4874 } else if (app.notResponding) { 4875 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4876 return; 4877 } else if (app.crashing) { 4878 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4879 return; 4880 } 4881 4882 // In case we come through here for the same app before completing 4883 // this one, mark as anring now so we will bail out. 4884 app.notResponding = true; 4885 4886 // Log the ANR to the event log. 4887 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4888 app.processName, app.info.flags, annotation); 4889 4890 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4891 firstPids.add(app.pid); 4892 4893 int parentPid = app.pid; 4894 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4895 if (parentPid != app.pid) firstPids.add(parentPid); 4896 4897 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4898 4899 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4900 ProcessRecord r = mLruProcesses.get(i); 4901 if (r != null && r.thread != null) { 4902 int pid = r.pid; 4903 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4904 if (r.persistent) { 4905 firstPids.add(pid); 4906 } else { 4907 lastPids.put(pid, Boolean.TRUE); 4908 } 4909 } 4910 } 4911 } 4912 } 4913 4914 // Log the ANR to the main log. 4915 StringBuilder info = new StringBuilder(); 4916 info.setLength(0); 4917 info.append("ANR in ").append(app.processName); 4918 if (activity != null && activity.shortComponentName != null) { 4919 info.append(" (").append(activity.shortComponentName).append(")"); 4920 } 4921 info.append("\n"); 4922 info.append("PID: ").append(app.pid).append("\n"); 4923 if (annotation != null) { 4924 info.append("Reason: ").append(annotation).append("\n"); 4925 } 4926 if (parent != null && parent != activity) { 4927 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4928 } 4929 4930 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4931 4932 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4933 NATIVE_STACKS_OF_INTEREST); 4934 4935 String cpuInfo = null; 4936 if (MONITOR_CPU_USAGE) { 4937 updateCpuStatsNow(); 4938 synchronized (mProcessCpuTracker) { 4939 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4940 } 4941 info.append(processCpuTracker.printCurrentLoad()); 4942 info.append(cpuInfo); 4943 } 4944 4945 info.append(processCpuTracker.printCurrentState(anrTime)); 4946 4947 Slog.e(TAG, info.toString()); 4948 if (tracesFile == null) { 4949 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4950 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4951 } 4952 4953 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4954 cpuInfo, tracesFile, null); 4955 4956 if (mController != null) { 4957 try { 4958 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4959 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4960 if (res != 0) { 4961 if (res < 0 && app.pid != MY_PID) { 4962 app.kill("anr", true); 4963 } else { 4964 synchronized (this) { 4965 mServices.scheduleServiceTimeoutLocked(app); 4966 } 4967 } 4968 return; 4969 } 4970 } catch (RemoteException e) { 4971 mController = null; 4972 Watchdog.getInstance().setActivityController(null); 4973 } 4974 } 4975 4976 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4977 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4978 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4979 4980 synchronized (this) { 4981 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4982 app.kill("bg anr", true); 4983 return; 4984 } 4985 4986 // Set the app's notResponding state, and look up the errorReportReceiver 4987 makeAppNotRespondingLocked(app, 4988 activity != null ? activity.shortComponentName : null, 4989 annotation != null ? "ANR " + annotation : "ANR", 4990 info.toString()); 4991 4992 // Bring up the infamous App Not Responding dialog 4993 Message msg = Message.obtain(); 4994 HashMap<String, Object> map = new HashMap<String, Object>(); 4995 msg.what = SHOW_NOT_RESPONDING_MSG; 4996 msg.obj = map; 4997 msg.arg1 = aboveSystem ? 1 : 0; 4998 map.put("app", app); 4999 if (activity != null) { 5000 map.put("activity", activity); 5001 } 5002 5003 mHandler.sendMessage(msg); 5004 } 5005 } 5006 5007 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5008 if (!mLaunchWarningShown) { 5009 mLaunchWarningShown = true; 5010 mHandler.post(new Runnable() { 5011 @Override 5012 public void run() { 5013 synchronized (ActivityManagerService.this) { 5014 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5015 d.show(); 5016 mHandler.postDelayed(new Runnable() { 5017 @Override 5018 public void run() { 5019 synchronized (ActivityManagerService.this) { 5020 d.dismiss(); 5021 mLaunchWarningShown = false; 5022 } 5023 } 5024 }, 4000); 5025 } 5026 } 5027 }); 5028 } 5029 } 5030 5031 @Override 5032 public boolean clearApplicationUserData(final String packageName, 5033 final IPackageDataObserver observer, int userId) { 5034 enforceNotIsolatedCaller("clearApplicationUserData"); 5035 int uid = Binder.getCallingUid(); 5036 int pid = Binder.getCallingPid(); 5037 userId = handleIncomingUser(pid, uid, 5038 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5039 long callingId = Binder.clearCallingIdentity(); 5040 try { 5041 IPackageManager pm = AppGlobals.getPackageManager(); 5042 int pkgUid = -1; 5043 synchronized(this) { 5044 try { 5045 pkgUid = pm.getPackageUid(packageName, userId); 5046 } catch (RemoteException e) { 5047 } 5048 if (pkgUid == -1) { 5049 Slog.w(TAG, "Invalid packageName: " + packageName); 5050 if (observer != null) { 5051 try { 5052 observer.onRemoveCompleted(packageName, false); 5053 } catch (RemoteException e) { 5054 Slog.i(TAG, "Observer no longer exists."); 5055 } 5056 } 5057 return false; 5058 } 5059 if (uid == pkgUid || checkComponentPermission( 5060 android.Manifest.permission.CLEAR_APP_USER_DATA, 5061 pid, uid, -1, true) 5062 == PackageManager.PERMISSION_GRANTED) { 5063 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5064 } else { 5065 throw new SecurityException("PID " + pid + " does not have permission " 5066 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5067 + " of package " + packageName); 5068 } 5069 5070 // Remove all tasks match the cleared application package and user 5071 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5072 final TaskRecord tr = mRecentTasks.get(i); 5073 final String taskPackageName = 5074 tr.getBaseIntent().getComponent().getPackageName(); 5075 if (tr.userId != userId) continue; 5076 if (!taskPackageName.equals(packageName)) continue; 5077 removeTaskByIdLocked(tr.taskId, false); 5078 } 5079 } 5080 5081 try { 5082 // Clear application user data 5083 pm.clearApplicationUserData(packageName, observer, userId); 5084 5085 synchronized(this) { 5086 // Remove all permissions granted from/to this package 5087 removeUriPermissionsForPackageLocked(packageName, userId, true); 5088 } 5089 5090 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5091 Uri.fromParts("package", packageName, null)); 5092 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5093 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5094 null, null, 0, null, null, null, false, false, userId); 5095 } catch (RemoteException e) { 5096 } 5097 } finally { 5098 Binder.restoreCallingIdentity(callingId); 5099 } 5100 return true; 5101 } 5102 5103 @Override 5104 public void killBackgroundProcesses(final String packageName, int userId) { 5105 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5106 != PackageManager.PERMISSION_GRANTED && 5107 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5108 != PackageManager.PERMISSION_GRANTED) { 5109 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5110 + Binder.getCallingPid() 5111 + ", uid=" + Binder.getCallingUid() 5112 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5113 Slog.w(TAG, msg); 5114 throw new SecurityException(msg); 5115 } 5116 5117 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5118 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5119 long callingId = Binder.clearCallingIdentity(); 5120 try { 5121 IPackageManager pm = AppGlobals.getPackageManager(); 5122 synchronized(this) { 5123 int appId = -1; 5124 try { 5125 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5126 } catch (RemoteException e) { 5127 } 5128 if (appId == -1) { 5129 Slog.w(TAG, "Invalid packageName: " + packageName); 5130 return; 5131 } 5132 killPackageProcessesLocked(packageName, appId, userId, 5133 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5134 } 5135 } finally { 5136 Binder.restoreCallingIdentity(callingId); 5137 } 5138 } 5139 5140 @Override 5141 public void killAllBackgroundProcesses() { 5142 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5143 != PackageManager.PERMISSION_GRANTED) { 5144 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5145 + Binder.getCallingPid() 5146 + ", uid=" + Binder.getCallingUid() 5147 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5148 Slog.w(TAG, msg); 5149 throw new SecurityException(msg); 5150 } 5151 5152 long callingId = Binder.clearCallingIdentity(); 5153 try { 5154 synchronized(this) { 5155 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5156 final int NP = mProcessNames.getMap().size(); 5157 for (int ip=0; ip<NP; ip++) { 5158 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5159 final int NA = apps.size(); 5160 for (int ia=0; ia<NA; ia++) { 5161 ProcessRecord app = apps.valueAt(ia); 5162 if (app.persistent) { 5163 // we don't kill persistent processes 5164 continue; 5165 } 5166 if (app.removed) { 5167 procs.add(app); 5168 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5169 app.removed = true; 5170 procs.add(app); 5171 } 5172 } 5173 } 5174 5175 int N = procs.size(); 5176 for (int i=0; i<N; i++) { 5177 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5178 } 5179 mAllowLowerMemLevel = true; 5180 updateOomAdjLocked(); 5181 doLowMemReportIfNeededLocked(null); 5182 } 5183 } finally { 5184 Binder.restoreCallingIdentity(callingId); 5185 } 5186 } 5187 5188 @Override 5189 public void forceStopPackage(final String packageName, int userId) { 5190 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5191 != PackageManager.PERMISSION_GRANTED) { 5192 String msg = "Permission Denial: forceStopPackage() from pid=" 5193 + Binder.getCallingPid() 5194 + ", uid=" + Binder.getCallingUid() 5195 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5196 Slog.w(TAG, msg); 5197 throw new SecurityException(msg); 5198 } 5199 final int callingPid = Binder.getCallingPid(); 5200 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5201 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5202 long callingId = Binder.clearCallingIdentity(); 5203 try { 5204 IPackageManager pm = AppGlobals.getPackageManager(); 5205 synchronized(this) { 5206 int[] users = userId == UserHandle.USER_ALL 5207 ? getUsersLocked() : new int[] { userId }; 5208 for (int user : users) { 5209 int pkgUid = -1; 5210 try { 5211 pkgUid = pm.getPackageUid(packageName, user); 5212 } catch (RemoteException e) { 5213 } 5214 if (pkgUid == -1) { 5215 Slog.w(TAG, "Invalid packageName: " + packageName); 5216 continue; 5217 } 5218 try { 5219 pm.setPackageStoppedState(packageName, true, user); 5220 } catch (RemoteException e) { 5221 } catch (IllegalArgumentException e) { 5222 Slog.w(TAG, "Failed trying to unstop package " 5223 + packageName + ": " + e); 5224 } 5225 if (isUserRunningLocked(user, false)) { 5226 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5227 } 5228 } 5229 } 5230 } finally { 5231 Binder.restoreCallingIdentity(callingId); 5232 } 5233 } 5234 5235 @Override 5236 public void addPackageDependency(String packageName) { 5237 synchronized (this) { 5238 int callingPid = Binder.getCallingPid(); 5239 if (callingPid == Process.myPid()) { 5240 // Yeah, um, no. 5241 Slog.w(TAG, "Can't addPackageDependency on system process"); 5242 return; 5243 } 5244 ProcessRecord proc; 5245 synchronized (mPidsSelfLocked) { 5246 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5247 } 5248 if (proc != null) { 5249 if (proc.pkgDeps == null) { 5250 proc.pkgDeps = new ArraySet<String>(1); 5251 } 5252 proc.pkgDeps.add(packageName); 5253 } 5254 } 5255 } 5256 5257 /* 5258 * The pkg name and app id have to be specified. 5259 */ 5260 @Override 5261 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5262 if (pkg == null) { 5263 return; 5264 } 5265 // Make sure the uid is valid. 5266 if (appid < 0) { 5267 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5268 return; 5269 } 5270 int callerUid = Binder.getCallingUid(); 5271 // Only the system server can kill an application 5272 if (callerUid == Process.SYSTEM_UID) { 5273 // Post an aysnc message to kill the application 5274 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5275 msg.arg1 = appid; 5276 msg.arg2 = 0; 5277 Bundle bundle = new Bundle(); 5278 bundle.putString("pkg", pkg); 5279 bundle.putString("reason", reason); 5280 msg.obj = bundle; 5281 mHandler.sendMessage(msg); 5282 } else { 5283 throw new SecurityException(callerUid + " cannot kill pkg: " + 5284 pkg); 5285 } 5286 } 5287 5288 @Override 5289 public void closeSystemDialogs(String reason) { 5290 enforceNotIsolatedCaller("closeSystemDialogs"); 5291 5292 final int pid = Binder.getCallingPid(); 5293 final int uid = Binder.getCallingUid(); 5294 final long origId = Binder.clearCallingIdentity(); 5295 try { 5296 synchronized (this) { 5297 // Only allow this from foreground processes, so that background 5298 // applications can't abuse it to prevent system UI from being shown. 5299 if (uid >= Process.FIRST_APPLICATION_UID) { 5300 ProcessRecord proc; 5301 synchronized (mPidsSelfLocked) { 5302 proc = mPidsSelfLocked.get(pid); 5303 } 5304 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5305 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5306 + " from background process " + proc); 5307 return; 5308 } 5309 } 5310 closeSystemDialogsLocked(reason); 5311 } 5312 } finally { 5313 Binder.restoreCallingIdentity(origId); 5314 } 5315 } 5316 5317 void closeSystemDialogsLocked(String reason) { 5318 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5320 | Intent.FLAG_RECEIVER_FOREGROUND); 5321 if (reason != null) { 5322 intent.putExtra("reason", reason); 5323 } 5324 mWindowManager.closeSystemDialogs(reason); 5325 5326 mStackSupervisor.closeSystemDialogsLocked(); 5327 5328 broadcastIntentLocked(null, null, intent, null, 5329 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5330 Process.SYSTEM_UID, UserHandle.USER_ALL); 5331 } 5332 5333 @Override 5334 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5335 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5336 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5337 for (int i=pids.length-1; i>=0; i--) { 5338 ProcessRecord proc; 5339 int oomAdj; 5340 synchronized (this) { 5341 synchronized (mPidsSelfLocked) { 5342 proc = mPidsSelfLocked.get(pids[i]); 5343 oomAdj = proc != null ? proc.setAdj : 0; 5344 } 5345 } 5346 infos[i] = new Debug.MemoryInfo(); 5347 Debug.getMemoryInfo(pids[i], infos[i]); 5348 if (proc != null) { 5349 synchronized (this) { 5350 if (proc.thread != null && proc.setAdj == oomAdj) { 5351 // Record this for posterity if the process has been stable. 5352 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5353 infos[i].getTotalUss(), false, proc.pkgList); 5354 } 5355 } 5356 } 5357 } 5358 return infos; 5359 } 5360 5361 @Override 5362 public long[] getProcessPss(int[] pids) { 5363 enforceNotIsolatedCaller("getProcessPss"); 5364 long[] pss = new long[pids.length]; 5365 for (int i=pids.length-1; i>=0; i--) { 5366 ProcessRecord proc; 5367 int oomAdj; 5368 synchronized (this) { 5369 synchronized (mPidsSelfLocked) { 5370 proc = mPidsSelfLocked.get(pids[i]); 5371 oomAdj = proc != null ? proc.setAdj : 0; 5372 } 5373 } 5374 long[] tmpUss = new long[1]; 5375 pss[i] = Debug.getPss(pids[i], tmpUss); 5376 if (proc != null) { 5377 synchronized (this) { 5378 if (proc.thread != null && proc.setAdj == oomAdj) { 5379 // Record this for posterity if the process has been stable. 5380 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5381 } 5382 } 5383 } 5384 } 5385 return pss; 5386 } 5387 5388 @Override 5389 public void killApplicationProcess(String processName, int uid) { 5390 if (processName == null) { 5391 return; 5392 } 5393 5394 int callerUid = Binder.getCallingUid(); 5395 // Only the system server can kill an application 5396 if (callerUid == Process.SYSTEM_UID) { 5397 synchronized (this) { 5398 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5399 if (app != null && app.thread != null) { 5400 try { 5401 app.thread.scheduleSuicide(); 5402 } catch (RemoteException e) { 5403 // If the other end already died, then our work here is done. 5404 } 5405 } else { 5406 Slog.w(TAG, "Process/uid not found attempting kill of " 5407 + processName + " / " + uid); 5408 } 5409 } 5410 } else { 5411 throw new SecurityException(callerUid + " cannot kill app process: " + 5412 processName); 5413 } 5414 } 5415 5416 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5417 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5418 false, true, false, false, UserHandle.getUserId(uid), reason); 5419 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5420 Uri.fromParts("package", packageName, null)); 5421 if (!mProcessesReady) { 5422 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5423 | Intent.FLAG_RECEIVER_FOREGROUND); 5424 } 5425 intent.putExtra(Intent.EXTRA_UID, uid); 5426 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5427 broadcastIntentLocked(null, null, intent, 5428 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5429 false, false, 5430 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5431 } 5432 5433 private void forceStopUserLocked(int userId, String reason) { 5434 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5435 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5437 | Intent.FLAG_RECEIVER_FOREGROUND); 5438 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5439 broadcastIntentLocked(null, null, intent, 5440 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5441 false, false, 5442 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5443 } 5444 5445 private final boolean killPackageProcessesLocked(String packageName, int appId, 5446 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5447 boolean doit, boolean evenPersistent, String reason) { 5448 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5449 5450 // Remove all processes this package may have touched: all with the 5451 // same UID (except for the system or root user), and all whose name 5452 // matches the package name. 5453 final int NP = mProcessNames.getMap().size(); 5454 for (int ip=0; ip<NP; ip++) { 5455 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5456 final int NA = apps.size(); 5457 for (int ia=0; ia<NA; ia++) { 5458 ProcessRecord app = apps.valueAt(ia); 5459 if (app.persistent && !evenPersistent) { 5460 // we don't kill persistent processes 5461 continue; 5462 } 5463 if (app.removed) { 5464 if (doit) { 5465 procs.add(app); 5466 } 5467 continue; 5468 } 5469 5470 // Skip process if it doesn't meet our oom adj requirement. 5471 if (app.setAdj < minOomAdj) { 5472 continue; 5473 } 5474 5475 // If no package is specified, we call all processes under the 5476 // give user id. 5477 if (packageName == null) { 5478 if (app.userId != userId) { 5479 continue; 5480 } 5481 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5482 continue; 5483 } 5484 // Package has been specified, we want to hit all processes 5485 // that match it. We need to qualify this by the processes 5486 // that are running under the specified app and user ID. 5487 } else { 5488 final boolean isDep = app.pkgDeps != null 5489 && app.pkgDeps.contains(packageName); 5490 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5491 continue; 5492 } 5493 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5494 continue; 5495 } 5496 if (!app.pkgList.containsKey(packageName) && !isDep) { 5497 continue; 5498 } 5499 } 5500 5501 // Process has passed all conditions, kill it! 5502 if (!doit) { 5503 return true; 5504 } 5505 app.removed = true; 5506 procs.add(app); 5507 } 5508 } 5509 5510 int N = procs.size(); 5511 for (int i=0; i<N; i++) { 5512 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5513 } 5514 updateOomAdjLocked(); 5515 return N > 0; 5516 } 5517 5518 private final boolean forceStopPackageLocked(String name, int appId, 5519 boolean callerWillRestart, boolean purgeCache, boolean doit, 5520 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5521 int i; 5522 int N; 5523 5524 if (userId == UserHandle.USER_ALL && name == null) { 5525 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5526 } 5527 5528 if (appId < 0 && name != null) { 5529 try { 5530 appId = UserHandle.getAppId( 5531 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5532 } catch (RemoteException e) { 5533 } 5534 } 5535 5536 if (doit) { 5537 if (name != null) { 5538 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5539 + " user=" + userId + ": " + reason); 5540 } else { 5541 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5542 } 5543 5544 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5545 for (int ip=pmap.size()-1; ip>=0; ip--) { 5546 SparseArray<Long> ba = pmap.valueAt(ip); 5547 for (i=ba.size()-1; i>=0; i--) { 5548 boolean remove = false; 5549 final int entUid = ba.keyAt(i); 5550 if (name != null) { 5551 if (userId == UserHandle.USER_ALL) { 5552 if (UserHandle.getAppId(entUid) == appId) { 5553 remove = true; 5554 } 5555 } else { 5556 if (entUid == UserHandle.getUid(userId, appId)) { 5557 remove = true; 5558 } 5559 } 5560 } else if (UserHandle.getUserId(entUid) == userId) { 5561 remove = true; 5562 } 5563 if (remove) { 5564 ba.removeAt(i); 5565 } 5566 } 5567 if (ba.size() == 0) { 5568 pmap.removeAt(ip); 5569 } 5570 } 5571 } 5572 5573 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5574 -100, callerWillRestart, true, doit, evenPersistent, 5575 name == null ? ("stop user " + userId) : ("stop " + name)); 5576 5577 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5578 if (!doit) { 5579 return true; 5580 } 5581 didSomething = true; 5582 } 5583 5584 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5585 if (!doit) { 5586 return true; 5587 } 5588 didSomething = true; 5589 } 5590 5591 if (name == null) { 5592 // Remove all sticky broadcasts from this user. 5593 mStickyBroadcasts.remove(userId); 5594 } 5595 5596 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5597 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5598 userId, providers)) { 5599 if (!doit) { 5600 return true; 5601 } 5602 didSomething = true; 5603 } 5604 N = providers.size(); 5605 for (i=0; i<N; i++) { 5606 removeDyingProviderLocked(null, providers.get(i), true); 5607 } 5608 5609 // Remove transient permissions granted from/to this package/user 5610 removeUriPermissionsForPackageLocked(name, userId, false); 5611 5612 if (name == null || uninstalling) { 5613 // Remove pending intents. For now we only do this when force 5614 // stopping users, because we have some problems when doing this 5615 // for packages -- app widgets are not currently cleaned up for 5616 // such packages, so they can be left with bad pending intents. 5617 if (mIntentSenderRecords.size() > 0) { 5618 Iterator<WeakReference<PendingIntentRecord>> it 5619 = mIntentSenderRecords.values().iterator(); 5620 while (it.hasNext()) { 5621 WeakReference<PendingIntentRecord> wpir = it.next(); 5622 if (wpir == null) { 5623 it.remove(); 5624 continue; 5625 } 5626 PendingIntentRecord pir = wpir.get(); 5627 if (pir == null) { 5628 it.remove(); 5629 continue; 5630 } 5631 if (name == null) { 5632 // Stopping user, remove all objects for the user. 5633 if (pir.key.userId != userId) { 5634 // Not the same user, skip it. 5635 continue; 5636 } 5637 } else { 5638 if (UserHandle.getAppId(pir.uid) != appId) { 5639 // Different app id, skip it. 5640 continue; 5641 } 5642 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5643 // Different user, skip it. 5644 continue; 5645 } 5646 if (!pir.key.packageName.equals(name)) { 5647 // Different package, skip it. 5648 continue; 5649 } 5650 } 5651 if (!doit) { 5652 return true; 5653 } 5654 didSomething = true; 5655 it.remove(); 5656 pir.canceled = true; 5657 if (pir.key.activity != null) { 5658 pir.key.activity.pendingResults.remove(pir.ref); 5659 } 5660 } 5661 } 5662 } 5663 5664 if (doit) { 5665 if (purgeCache && name != null) { 5666 AttributeCache ac = AttributeCache.instance(); 5667 if (ac != null) { 5668 ac.removePackage(name); 5669 } 5670 } 5671 if (mBooted) { 5672 mStackSupervisor.resumeTopActivitiesLocked(); 5673 mStackSupervisor.scheduleIdleLocked(); 5674 } 5675 } 5676 5677 return didSomething; 5678 } 5679 5680 private final boolean removeProcessLocked(ProcessRecord app, 5681 boolean callerWillRestart, boolean allowRestart, String reason) { 5682 final String name = app.processName; 5683 final int uid = app.uid; 5684 if (DEBUG_PROCESSES) Slog.d( 5685 TAG, "Force removing proc " + app.toShortString() + " (" + name 5686 + "/" + uid + ")"); 5687 5688 mProcessNames.remove(name, uid); 5689 mIsolatedProcesses.remove(app.uid); 5690 if (mHeavyWeightProcess == app) { 5691 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5692 mHeavyWeightProcess.userId, 0)); 5693 mHeavyWeightProcess = null; 5694 } 5695 boolean needRestart = false; 5696 if (app.pid > 0 && app.pid != MY_PID) { 5697 int pid = app.pid; 5698 synchronized (mPidsSelfLocked) { 5699 mPidsSelfLocked.remove(pid); 5700 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5701 } 5702 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5703 if (app.isolated) { 5704 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5705 } 5706 app.kill(reason, true); 5707 handleAppDiedLocked(app, true, allowRestart); 5708 removeLruProcessLocked(app); 5709 5710 if (app.persistent && !app.isolated) { 5711 if (!callerWillRestart) { 5712 addAppLocked(app.info, false, null /* ABI override */); 5713 } else { 5714 needRestart = true; 5715 } 5716 } 5717 } else { 5718 mRemovedProcesses.add(app); 5719 } 5720 5721 return needRestart; 5722 } 5723 5724 private final void processStartTimedOutLocked(ProcessRecord app) { 5725 final int pid = app.pid; 5726 boolean gone = false; 5727 synchronized (mPidsSelfLocked) { 5728 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5729 if (knownApp != null && knownApp.thread == null) { 5730 mPidsSelfLocked.remove(pid); 5731 gone = true; 5732 } 5733 } 5734 5735 if (gone) { 5736 Slog.w(TAG, "Process " + app + " failed to attach"); 5737 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5738 pid, app.uid, app.processName); 5739 mProcessNames.remove(app.processName, app.uid); 5740 mIsolatedProcesses.remove(app.uid); 5741 if (mHeavyWeightProcess == app) { 5742 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5743 mHeavyWeightProcess.userId, 0)); 5744 mHeavyWeightProcess = null; 5745 } 5746 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5747 if (app.isolated) { 5748 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5749 } 5750 // Take care of any launching providers waiting for this process. 5751 checkAppInLaunchingProvidersLocked(app, true); 5752 // Take care of any services that are waiting for the process. 5753 mServices.processStartTimedOutLocked(app); 5754 app.kill("start timeout", true); 5755 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5756 Slog.w(TAG, "Unattached app died before backup, skipping"); 5757 try { 5758 IBackupManager bm = IBackupManager.Stub.asInterface( 5759 ServiceManager.getService(Context.BACKUP_SERVICE)); 5760 bm.agentDisconnected(app.info.packageName); 5761 } catch (RemoteException e) { 5762 // Can't happen; the backup manager is local 5763 } 5764 } 5765 if (isPendingBroadcastProcessLocked(pid)) { 5766 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5767 skipPendingBroadcastLocked(pid); 5768 } 5769 } else { 5770 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5771 } 5772 } 5773 5774 private final boolean attachApplicationLocked(IApplicationThread thread, 5775 int pid) { 5776 5777 // Find the application record that is being attached... either via 5778 // the pid if we are running in multiple processes, or just pull the 5779 // next app record if we are emulating process with anonymous threads. 5780 ProcessRecord app; 5781 if (pid != MY_PID && pid >= 0) { 5782 synchronized (mPidsSelfLocked) { 5783 app = mPidsSelfLocked.get(pid); 5784 } 5785 } else { 5786 app = null; 5787 } 5788 5789 if (app == null) { 5790 Slog.w(TAG, "No pending application record for pid " + pid 5791 + " (IApplicationThread " + thread + "); dropping process"); 5792 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5793 if (pid > 0 && pid != MY_PID) { 5794 Process.killProcessQuiet(pid); 5795 //TODO: Process.killProcessGroup(app.info.uid, pid); 5796 } else { 5797 try { 5798 thread.scheduleExit(); 5799 } catch (Exception e) { 5800 // Ignore exceptions. 5801 } 5802 } 5803 return false; 5804 } 5805 5806 // If this application record is still attached to a previous 5807 // process, clean it up now. 5808 if (app.thread != null) { 5809 handleAppDiedLocked(app, true, true); 5810 } 5811 5812 // Tell the process all about itself. 5813 5814 if (localLOGV) Slog.v( 5815 TAG, "Binding process pid " + pid + " to record " + app); 5816 5817 final String processName = app.processName; 5818 try { 5819 AppDeathRecipient adr = new AppDeathRecipient( 5820 app, pid, thread); 5821 thread.asBinder().linkToDeath(adr, 0); 5822 app.deathRecipient = adr; 5823 } catch (RemoteException e) { 5824 app.resetPackageList(mProcessStats); 5825 startProcessLocked(app, "link fail", processName); 5826 return false; 5827 } 5828 5829 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5830 5831 app.makeActive(thread, mProcessStats); 5832 app.curAdj = app.setAdj = -100; 5833 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5834 app.forcingToForeground = null; 5835 updateProcessForegroundLocked(app, false, false); 5836 app.hasShownUi = false; 5837 app.debugging = false; 5838 app.cached = false; 5839 5840 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5841 5842 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5843 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5844 5845 if (!normalMode) { 5846 Slog.i(TAG, "Launching preboot mode app: " + app); 5847 } 5848 5849 if (localLOGV) Slog.v( 5850 TAG, "New app record " + app 5851 + " thread=" + thread.asBinder() + " pid=" + pid); 5852 try { 5853 int testMode = IApplicationThread.DEBUG_OFF; 5854 if (mDebugApp != null && mDebugApp.equals(processName)) { 5855 testMode = mWaitForDebugger 5856 ? IApplicationThread.DEBUG_WAIT 5857 : IApplicationThread.DEBUG_ON; 5858 app.debugging = true; 5859 if (mDebugTransient) { 5860 mDebugApp = mOrigDebugApp; 5861 mWaitForDebugger = mOrigWaitForDebugger; 5862 } 5863 } 5864 String profileFile = app.instrumentationProfileFile; 5865 ParcelFileDescriptor profileFd = null; 5866 int samplingInterval = 0; 5867 boolean profileAutoStop = false; 5868 if (mProfileApp != null && mProfileApp.equals(processName)) { 5869 mProfileProc = app; 5870 profileFile = mProfileFile; 5871 profileFd = mProfileFd; 5872 samplingInterval = mSamplingInterval; 5873 profileAutoStop = mAutoStopProfiler; 5874 } 5875 boolean enableOpenGlTrace = false; 5876 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5877 enableOpenGlTrace = true; 5878 mOpenGlTraceApp = null; 5879 } 5880 5881 // If the app is being launched for restore or full backup, set it up specially 5882 boolean isRestrictedBackupMode = false; 5883 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5884 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5885 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5886 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5887 } 5888 5889 ensurePackageDexOpt(app.instrumentationInfo != null 5890 ? app.instrumentationInfo.packageName 5891 : app.info.packageName); 5892 if (app.instrumentationClass != null) { 5893 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5894 } 5895 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5896 + processName + " with config " + mConfiguration); 5897 ApplicationInfo appInfo = app.instrumentationInfo != null 5898 ? app.instrumentationInfo : app.info; 5899 app.compat = compatibilityInfoForPackageLocked(appInfo); 5900 if (profileFd != null) { 5901 profileFd = profileFd.dup(); 5902 } 5903 ProfilerInfo profilerInfo = profileFile == null ? null 5904 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5905 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5906 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5907 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5908 isRestrictedBackupMode || !normalMode, app.persistent, 5909 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5910 mCoreSettingsObserver.getCoreSettingsLocked()); 5911 updateLruProcessLocked(app, false, null); 5912 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5913 } catch (Exception e) { 5914 // todo: Yikes! What should we do? For now we will try to 5915 // start another process, but that could easily get us in 5916 // an infinite loop of restarting processes... 5917 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5918 5919 app.resetPackageList(mProcessStats); 5920 app.unlinkDeathRecipient(); 5921 startProcessLocked(app, "bind fail", processName); 5922 return false; 5923 } 5924 5925 // Remove this record from the list of starting applications. 5926 mPersistentStartingProcesses.remove(app); 5927 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5928 "Attach application locked removing on hold: " + app); 5929 mProcessesOnHold.remove(app); 5930 5931 boolean badApp = false; 5932 boolean didSomething = false; 5933 5934 // See if the top visible activity is waiting to run in this process... 5935 if (normalMode) { 5936 try { 5937 if (mStackSupervisor.attachApplicationLocked(app)) { 5938 didSomething = true; 5939 } 5940 } catch (Exception e) { 5941 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5942 badApp = true; 5943 } 5944 } 5945 5946 // Find any services that should be running in this process... 5947 if (!badApp) { 5948 try { 5949 didSomething |= mServices.attachApplicationLocked(app, processName); 5950 } catch (Exception e) { 5951 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5952 badApp = true; 5953 } 5954 } 5955 5956 // Check if a next-broadcast receiver is in this process... 5957 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5958 try { 5959 didSomething |= sendPendingBroadcastsLocked(app); 5960 } catch (Exception e) { 5961 // If the app died trying to launch the receiver we declare it 'bad' 5962 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5963 badApp = true; 5964 } 5965 } 5966 5967 // Check whether the next backup agent is in this process... 5968 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5969 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5970 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5971 try { 5972 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5973 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5974 mBackupTarget.backupMode); 5975 } catch (Exception e) { 5976 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5977 badApp = true; 5978 } 5979 } 5980 5981 if (badApp) { 5982 app.kill("error during init", true); 5983 handleAppDiedLocked(app, false, true); 5984 return false; 5985 } 5986 5987 if (!didSomething) { 5988 updateOomAdjLocked(); 5989 } 5990 5991 return true; 5992 } 5993 5994 @Override 5995 public final void attachApplication(IApplicationThread thread) { 5996 synchronized (this) { 5997 int callingPid = Binder.getCallingPid(); 5998 final long origId = Binder.clearCallingIdentity(); 5999 attachApplicationLocked(thread, callingPid); 6000 Binder.restoreCallingIdentity(origId); 6001 } 6002 } 6003 6004 @Override 6005 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6006 final long origId = Binder.clearCallingIdentity(); 6007 synchronized (this) { 6008 ActivityStack stack = ActivityRecord.getStackLocked(token); 6009 if (stack != null) { 6010 ActivityRecord r = 6011 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6012 if (stopProfiling) { 6013 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6014 try { 6015 mProfileFd.close(); 6016 } catch (IOException e) { 6017 } 6018 clearProfilerLocked(); 6019 } 6020 } 6021 } 6022 } 6023 Binder.restoreCallingIdentity(origId); 6024 } 6025 6026 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6027 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6028 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6029 } 6030 6031 void enableScreenAfterBoot() { 6032 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6033 SystemClock.uptimeMillis()); 6034 mWindowManager.enableScreenAfterBoot(); 6035 6036 synchronized (this) { 6037 updateEventDispatchingLocked(); 6038 } 6039 } 6040 6041 @Override 6042 public void showBootMessage(final CharSequence msg, final boolean always) { 6043 enforceNotIsolatedCaller("showBootMessage"); 6044 mWindowManager.showBootMessage(msg, always); 6045 } 6046 6047 @Override 6048 public void keyguardWaitingForActivityDrawn() { 6049 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6050 final long token = Binder.clearCallingIdentity(); 6051 try { 6052 synchronized (this) { 6053 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6054 mWindowManager.keyguardWaitingForActivityDrawn(); 6055 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6056 mLockScreenShown = LOCK_SCREEN_LEAVING; 6057 } 6058 } 6059 } finally { 6060 Binder.restoreCallingIdentity(token); 6061 } 6062 } 6063 6064 final void finishBooting() { 6065 synchronized (this) { 6066 if (!mBootAnimationComplete) { 6067 mCallFinishBooting = true; 6068 return; 6069 } 6070 mCallFinishBooting = false; 6071 } 6072 6073 ArraySet<String> completedIsas = new ArraySet<String>(); 6074 for (String abi : Build.SUPPORTED_ABIS) { 6075 Process.establishZygoteConnectionForAbi(abi); 6076 final String instructionSet = VMRuntime.getInstructionSet(abi); 6077 if (!completedIsas.contains(instructionSet)) { 6078 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6079 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6080 } 6081 completedIsas.add(instructionSet); 6082 } 6083 } 6084 6085 IntentFilter pkgFilter = new IntentFilter(); 6086 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6087 pkgFilter.addDataScheme("package"); 6088 mContext.registerReceiver(new BroadcastReceiver() { 6089 @Override 6090 public void onReceive(Context context, Intent intent) { 6091 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6092 if (pkgs != null) { 6093 for (String pkg : pkgs) { 6094 synchronized (ActivityManagerService.this) { 6095 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6096 0, "finished booting")) { 6097 setResultCode(Activity.RESULT_OK); 6098 return; 6099 } 6100 } 6101 } 6102 } 6103 } 6104 }, pkgFilter); 6105 6106 // Let system services know. 6107 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6108 6109 synchronized (this) { 6110 // Ensure that any processes we had put on hold are now started 6111 // up. 6112 final int NP = mProcessesOnHold.size(); 6113 if (NP > 0) { 6114 ArrayList<ProcessRecord> procs = 6115 new ArrayList<ProcessRecord>(mProcessesOnHold); 6116 for (int ip=0; ip<NP; ip++) { 6117 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6118 + procs.get(ip)); 6119 startProcessLocked(procs.get(ip), "on-hold", null); 6120 } 6121 } 6122 6123 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6124 // Start looking for apps that are abusing wake locks. 6125 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6126 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6127 // Tell anyone interested that we are done booting! 6128 SystemProperties.set("sys.boot_completed", "1"); 6129 6130 // And trigger dev.bootcomplete if we are not showing encryption progress 6131 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6132 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6133 SystemProperties.set("dev.bootcomplete", "1"); 6134 } 6135 for (int i=0; i<mStartedUsers.size(); i++) { 6136 UserStartedState uss = mStartedUsers.valueAt(i); 6137 if (uss.mState == UserStartedState.STATE_BOOTING) { 6138 uss.mState = UserStartedState.STATE_RUNNING; 6139 final int userId = mStartedUsers.keyAt(i); 6140 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6141 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6142 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6143 broadcastIntentLocked(null, null, intent, null, 6144 new IIntentReceiver.Stub() { 6145 @Override 6146 public void performReceive(Intent intent, int resultCode, 6147 String data, Bundle extras, boolean ordered, 6148 boolean sticky, int sendingUser) { 6149 synchronized (ActivityManagerService.this) { 6150 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6151 true, false); 6152 } 6153 } 6154 }, 6155 0, null, null, 6156 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6157 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6158 userId); 6159 } 6160 } 6161 scheduleStartProfilesLocked(); 6162 } 6163 } 6164 } 6165 6166 @Override 6167 public void bootAnimationComplete() { 6168 final boolean callFinishBooting; 6169 synchronized (this) { 6170 callFinishBooting = mCallFinishBooting; 6171 mBootAnimationComplete = true; 6172 } 6173 if (callFinishBooting) { 6174 finishBooting(); 6175 } 6176 } 6177 6178 final void ensureBootCompleted() { 6179 boolean booting; 6180 boolean enableScreen; 6181 synchronized (this) { 6182 booting = mBooting; 6183 mBooting = false; 6184 enableScreen = !mBooted; 6185 mBooted = true; 6186 } 6187 6188 if (booting) { 6189 finishBooting(); 6190 } 6191 6192 if (enableScreen) { 6193 enableScreenAfterBoot(); 6194 } 6195 } 6196 6197 @Override 6198 public final void activityResumed(IBinder token) { 6199 final long origId = Binder.clearCallingIdentity(); 6200 synchronized(this) { 6201 ActivityStack stack = ActivityRecord.getStackLocked(token); 6202 if (stack != null) { 6203 ActivityRecord.activityResumedLocked(token); 6204 } 6205 } 6206 Binder.restoreCallingIdentity(origId); 6207 } 6208 6209 @Override 6210 public final void activityPaused(IBinder token) { 6211 final long origId = Binder.clearCallingIdentity(); 6212 synchronized(this) { 6213 ActivityStack stack = ActivityRecord.getStackLocked(token); 6214 if (stack != null) { 6215 stack.activityPausedLocked(token, false); 6216 } 6217 } 6218 Binder.restoreCallingIdentity(origId); 6219 } 6220 6221 @Override 6222 public final void activityStopped(IBinder token, Bundle icicle, 6223 PersistableBundle persistentState, CharSequence description) { 6224 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6225 6226 // Refuse possible leaked file descriptors 6227 if (icicle != null && icicle.hasFileDescriptors()) { 6228 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6229 } 6230 6231 final long origId = Binder.clearCallingIdentity(); 6232 6233 synchronized (this) { 6234 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6235 if (r != null) { 6236 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6237 } 6238 } 6239 6240 trimApplications(); 6241 6242 Binder.restoreCallingIdentity(origId); 6243 } 6244 6245 @Override 6246 public final void activityDestroyed(IBinder token) { 6247 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6248 synchronized (this) { 6249 ActivityStack stack = ActivityRecord.getStackLocked(token); 6250 if (stack != null) { 6251 stack.activityDestroyedLocked(token); 6252 } 6253 } 6254 } 6255 6256 @Override 6257 public final void backgroundResourcesReleased(IBinder token) { 6258 final long origId = Binder.clearCallingIdentity(); 6259 try { 6260 synchronized (this) { 6261 ActivityStack stack = ActivityRecord.getStackLocked(token); 6262 if (stack != null) { 6263 stack.backgroundResourcesReleased(); 6264 } 6265 } 6266 } finally { 6267 Binder.restoreCallingIdentity(origId); 6268 } 6269 } 6270 6271 @Override 6272 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6273 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6274 } 6275 6276 @Override 6277 public final void notifyEnterAnimationComplete(IBinder token) { 6278 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6279 } 6280 6281 @Override 6282 public String getCallingPackage(IBinder token) { 6283 synchronized (this) { 6284 ActivityRecord r = getCallingRecordLocked(token); 6285 return r != null ? r.info.packageName : null; 6286 } 6287 } 6288 6289 @Override 6290 public ComponentName getCallingActivity(IBinder token) { 6291 synchronized (this) { 6292 ActivityRecord r = getCallingRecordLocked(token); 6293 return r != null ? r.intent.getComponent() : null; 6294 } 6295 } 6296 6297 private ActivityRecord getCallingRecordLocked(IBinder token) { 6298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6299 if (r == null) { 6300 return null; 6301 } 6302 return r.resultTo; 6303 } 6304 6305 @Override 6306 public ComponentName getActivityClassForToken(IBinder token) { 6307 synchronized(this) { 6308 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6309 if (r == null) { 6310 return null; 6311 } 6312 return r.intent.getComponent(); 6313 } 6314 } 6315 6316 @Override 6317 public String getPackageForToken(IBinder token) { 6318 synchronized(this) { 6319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6320 if (r == null) { 6321 return null; 6322 } 6323 return r.packageName; 6324 } 6325 } 6326 6327 @Override 6328 public IIntentSender getIntentSender(int type, 6329 String packageName, IBinder token, String resultWho, 6330 int requestCode, Intent[] intents, String[] resolvedTypes, 6331 int flags, Bundle options, int userId) { 6332 enforceNotIsolatedCaller("getIntentSender"); 6333 // Refuse possible leaked file descriptors 6334 if (intents != null) { 6335 if (intents.length < 1) { 6336 throw new IllegalArgumentException("Intents array length must be >= 1"); 6337 } 6338 for (int i=0; i<intents.length; i++) { 6339 Intent intent = intents[i]; 6340 if (intent != null) { 6341 if (intent.hasFileDescriptors()) { 6342 throw new IllegalArgumentException("File descriptors passed in Intent"); 6343 } 6344 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6345 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6346 throw new IllegalArgumentException( 6347 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6348 } 6349 intents[i] = new Intent(intent); 6350 } 6351 } 6352 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6353 throw new IllegalArgumentException( 6354 "Intent array length does not match resolvedTypes length"); 6355 } 6356 } 6357 if (options != null) { 6358 if (options.hasFileDescriptors()) { 6359 throw new IllegalArgumentException("File descriptors passed in options"); 6360 } 6361 } 6362 6363 synchronized(this) { 6364 int callingUid = Binder.getCallingUid(); 6365 int origUserId = userId; 6366 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6367 type == ActivityManager.INTENT_SENDER_BROADCAST, 6368 ALLOW_NON_FULL, "getIntentSender", null); 6369 if (origUserId == UserHandle.USER_CURRENT) { 6370 // We don't want to evaluate this until the pending intent is 6371 // actually executed. However, we do want to always do the 6372 // security checking for it above. 6373 userId = UserHandle.USER_CURRENT; 6374 } 6375 try { 6376 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6377 int uid = AppGlobals.getPackageManager() 6378 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6379 if (!UserHandle.isSameApp(callingUid, uid)) { 6380 String msg = "Permission Denial: getIntentSender() from pid=" 6381 + Binder.getCallingPid() 6382 + ", uid=" + Binder.getCallingUid() 6383 + ", (need uid=" + uid + ")" 6384 + " is not allowed to send as package " + packageName; 6385 Slog.w(TAG, msg); 6386 throw new SecurityException(msg); 6387 } 6388 } 6389 6390 return getIntentSenderLocked(type, packageName, callingUid, userId, 6391 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6392 6393 } catch (RemoteException e) { 6394 throw new SecurityException(e); 6395 } 6396 } 6397 } 6398 6399 IIntentSender getIntentSenderLocked(int type, String packageName, 6400 int callingUid, int userId, IBinder token, String resultWho, 6401 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6402 Bundle options) { 6403 if (DEBUG_MU) 6404 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6405 ActivityRecord activity = null; 6406 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6407 activity = ActivityRecord.isInStackLocked(token); 6408 if (activity == null) { 6409 return null; 6410 } 6411 if (activity.finishing) { 6412 return null; 6413 } 6414 } 6415 6416 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6417 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6418 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6419 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6420 |PendingIntent.FLAG_UPDATE_CURRENT); 6421 6422 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6423 type, packageName, activity, resultWho, 6424 requestCode, intents, resolvedTypes, flags, options, userId); 6425 WeakReference<PendingIntentRecord> ref; 6426 ref = mIntentSenderRecords.get(key); 6427 PendingIntentRecord rec = ref != null ? ref.get() : null; 6428 if (rec != null) { 6429 if (!cancelCurrent) { 6430 if (updateCurrent) { 6431 if (rec.key.requestIntent != null) { 6432 rec.key.requestIntent.replaceExtras(intents != null ? 6433 intents[intents.length - 1] : null); 6434 } 6435 if (intents != null) { 6436 intents[intents.length-1] = rec.key.requestIntent; 6437 rec.key.allIntents = intents; 6438 rec.key.allResolvedTypes = resolvedTypes; 6439 } else { 6440 rec.key.allIntents = null; 6441 rec.key.allResolvedTypes = null; 6442 } 6443 } 6444 return rec; 6445 } 6446 rec.canceled = true; 6447 mIntentSenderRecords.remove(key); 6448 } 6449 if (noCreate) { 6450 return rec; 6451 } 6452 rec = new PendingIntentRecord(this, key, callingUid); 6453 mIntentSenderRecords.put(key, rec.ref); 6454 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6455 if (activity.pendingResults == null) { 6456 activity.pendingResults 6457 = new HashSet<WeakReference<PendingIntentRecord>>(); 6458 } 6459 activity.pendingResults.add(rec.ref); 6460 } 6461 return rec; 6462 } 6463 6464 @Override 6465 public void cancelIntentSender(IIntentSender sender) { 6466 if (!(sender instanceof PendingIntentRecord)) { 6467 return; 6468 } 6469 synchronized(this) { 6470 PendingIntentRecord rec = (PendingIntentRecord)sender; 6471 try { 6472 int uid = AppGlobals.getPackageManager() 6473 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6474 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6475 String msg = "Permission Denial: cancelIntentSender() from pid=" 6476 + Binder.getCallingPid() 6477 + ", uid=" + Binder.getCallingUid() 6478 + " is not allowed to cancel packges " 6479 + rec.key.packageName; 6480 Slog.w(TAG, msg); 6481 throw new SecurityException(msg); 6482 } 6483 } catch (RemoteException e) { 6484 throw new SecurityException(e); 6485 } 6486 cancelIntentSenderLocked(rec, true); 6487 } 6488 } 6489 6490 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6491 rec.canceled = true; 6492 mIntentSenderRecords.remove(rec.key); 6493 if (cleanActivity && rec.key.activity != null) { 6494 rec.key.activity.pendingResults.remove(rec.ref); 6495 } 6496 } 6497 6498 @Override 6499 public String getPackageForIntentSender(IIntentSender pendingResult) { 6500 if (!(pendingResult instanceof PendingIntentRecord)) { 6501 return null; 6502 } 6503 try { 6504 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6505 return res.key.packageName; 6506 } catch (ClassCastException e) { 6507 } 6508 return null; 6509 } 6510 6511 @Override 6512 public int getUidForIntentSender(IIntentSender sender) { 6513 if (sender instanceof PendingIntentRecord) { 6514 try { 6515 PendingIntentRecord res = (PendingIntentRecord)sender; 6516 return res.uid; 6517 } catch (ClassCastException e) { 6518 } 6519 } 6520 return -1; 6521 } 6522 6523 @Override 6524 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6525 if (!(pendingResult instanceof PendingIntentRecord)) { 6526 return false; 6527 } 6528 try { 6529 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6530 if (res.key.allIntents == null) { 6531 return false; 6532 } 6533 for (int i=0; i<res.key.allIntents.length; i++) { 6534 Intent intent = res.key.allIntents[i]; 6535 if (intent.getPackage() != null && intent.getComponent() != null) { 6536 return false; 6537 } 6538 } 6539 return true; 6540 } catch (ClassCastException e) { 6541 } 6542 return false; 6543 } 6544 6545 @Override 6546 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6547 if (!(pendingResult instanceof PendingIntentRecord)) { 6548 return false; 6549 } 6550 try { 6551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6552 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6553 return true; 6554 } 6555 return false; 6556 } catch (ClassCastException e) { 6557 } 6558 return false; 6559 } 6560 6561 @Override 6562 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6563 if (!(pendingResult instanceof PendingIntentRecord)) { 6564 return null; 6565 } 6566 try { 6567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6568 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6569 } catch (ClassCastException e) { 6570 } 6571 return null; 6572 } 6573 6574 @Override 6575 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6576 if (!(pendingResult instanceof PendingIntentRecord)) { 6577 return null; 6578 } 6579 try { 6580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6581 Intent intent = res.key.requestIntent; 6582 if (intent != null) { 6583 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6584 || res.lastTagPrefix.equals(prefix))) { 6585 return res.lastTag; 6586 } 6587 res.lastTagPrefix = prefix; 6588 StringBuilder sb = new StringBuilder(128); 6589 if (prefix != null) { 6590 sb.append(prefix); 6591 } 6592 if (intent.getAction() != null) { 6593 sb.append(intent.getAction()); 6594 } else if (intent.getComponent() != null) { 6595 intent.getComponent().appendShortString(sb); 6596 } else { 6597 sb.append("?"); 6598 } 6599 return res.lastTag = sb.toString(); 6600 } 6601 } catch (ClassCastException e) { 6602 } 6603 return null; 6604 } 6605 6606 @Override 6607 public void setProcessLimit(int max) { 6608 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6609 "setProcessLimit()"); 6610 synchronized (this) { 6611 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6612 mProcessLimitOverride = max; 6613 } 6614 trimApplications(); 6615 } 6616 6617 @Override 6618 public int getProcessLimit() { 6619 synchronized (this) { 6620 return mProcessLimitOverride; 6621 } 6622 } 6623 6624 void foregroundTokenDied(ForegroundToken token) { 6625 synchronized (ActivityManagerService.this) { 6626 synchronized (mPidsSelfLocked) { 6627 ForegroundToken cur 6628 = mForegroundProcesses.get(token.pid); 6629 if (cur != token) { 6630 return; 6631 } 6632 mForegroundProcesses.remove(token.pid); 6633 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6634 if (pr == null) { 6635 return; 6636 } 6637 pr.forcingToForeground = null; 6638 updateProcessForegroundLocked(pr, false, false); 6639 } 6640 updateOomAdjLocked(); 6641 } 6642 } 6643 6644 @Override 6645 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6646 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6647 "setProcessForeground()"); 6648 synchronized(this) { 6649 boolean changed = false; 6650 6651 synchronized (mPidsSelfLocked) { 6652 ProcessRecord pr = mPidsSelfLocked.get(pid); 6653 if (pr == null && isForeground) { 6654 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6655 return; 6656 } 6657 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6658 if (oldToken != null) { 6659 oldToken.token.unlinkToDeath(oldToken, 0); 6660 mForegroundProcesses.remove(pid); 6661 if (pr != null) { 6662 pr.forcingToForeground = null; 6663 } 6664 changed = true; 6665 } 6666 if (isForeground && token != null) { 6667 ForegroundToken newToken = new ForegroundToken() { 6668 @Override 6669 public void binderDied() { 6670 foregroundTokenDied(this); 6671 } 6672 }; 6673 newToken.pid = pid; 6674 newToken.token = token; 6675 try { 6676 token.linkToDeath(newToken, 0); 6677 mForegroundProcesses.put(pid, newToken); 6678 pr.forcingToForeground = token; 6679 changed = true; 6680 } catch (RemoteException e) { 6681 // If the process died while doing this, we will later 6682 // do the cleanup with the process death link. 6683 } 6684 } 6685 } 6686 6687 if (changed) { 6688 updateOomAdjLocked(); 6689 } 6690 } 6691 } 6692 6693 // ========================================================= 6694 // PERMISSIONS 6695 // ========================================================= 6696 6697 static class PermissionController extends IPermissionController.Stub { 6698 ActivityManagerService mActivityManagerService; 6699 PermissionController(ActivityManagerService activityManagerService) { 6700 mActivityManagerService = activityManagerService; 6701 } 6702 6703 @Override 6704 public boolean checkPermission(String permission, int pid, int uid) { 6705 return mActivityManagerService.checkPermission(permission, pid, 6706 uid) == PackageManager.PERMISSION_GRANTED; 6707 } 6708 } 6709 6710 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6711 @Override 6712 public int checkComponentPermission(String permission, int pid, int uid, 6713 int owningUid, boolean exported) { 6714 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6715 owningUid, exported); 6716 } 6717 6718 @Override 6719 public Object getAMSLock() { 6720 return ActivityManagerService.this; 6721 } 6722 } 6723 6724 /** 6725 * This can be called with or without the global lock held. 6726 */ 6727 int checkComponentPermission(String permission, int pid, int uid, 6728 int owningUid, boolean exported) { 6729 // We might be performing an operation on behalf of an indirect binder 6730 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6731 // client identity accordingly before proceeding. 6732 Identity tlsIdentity = sCallerIdentity.get(); 6733 if (tlsIdentity != null) { 6734 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6735 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6736 uid = tlsIdentity.uid; 6737 pid = tlsIdentity.pid; 6738 } 6739 6740 if (pid == MY_PID) { 6741 return PackageManager.PERMISSION_GRANTED; 6742 } 6743 6744 return ActivityManager.checkComponentPermission(permission, uid, 6745 owningUid, exported); 6746 } 6747 6748 /** 6749 * As the only public entry point for permissions checking, this method 6750 * can enforce the semantic that requesting a check on a null global 6751 * permission is automatically denied. (Internally a null permission 6752 * string is used when calling {@link #checkComponentPermission} in cases 6753 * when only uid-based security is needed.) 6754 * 6755 * This can be called with or without the global lock held. 6756 */ 6757 @Override 6758 public int checkPermission(String permission, int pid, int uid) { 6759 if (permission == null) { 6760 return PackageManager.PERMISSION_DENIED; 6761 } 6762 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6763 } 6764 6765 /** 6766 * Binder IPC calls go through the public entry point. 6767 * This can be called with or without the global lock held. 6768 */ 6769 int checkCallingPermission(String permission) { 6770 return checkPermission(permission, 6771 Binder.getCallingPid(), 6772 UserHandle.getAppId(Binder.getCallingUid())); 6773 } 6774 6775 /** 6776 * This can be called with or without the global lock held. 6777 */ 6778 void enforceCallingPermission(String permission, String func) { 6779 if (checkCallingPermission(permission) 6780 == PackageManager.PERMISSION_GRANTED) { 6781 return; 6782 } 6783 6784 String msg = "Permission Denial: " + func + " from pid=" 6785 + Binder.getCallingPid() 6786 + ", uid=" + Binder.getCallingUid() 6787 + " requires " + permission; 6788 Slog.w(TAG, msg); 6789 throw new SecurityException(msg); 6790 } 6791 6792 /** 6793 * Determine if UID is holding permissions required to access {@link Uri} in 6794 * the given {@link ProviderInfo}. Final permission checking is always done 6795 * in {@link ContentProvider}. 6796 */ 6797 private final boolean checkHoldingPermissionsLocked( 6798 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6799 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6800 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6801 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6802 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6803 != PERMISSION_GRANTED) { 6804 return false; 6805 } 6806 } 6807 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6808 } 6809 6810 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6811 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6812 if (pi.applicationInfo.uid == uid) { 6813 return true; 6814 } else if (!pi.exported) { 6815 return false; 6816 } 6817 6818 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6819 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6820 try { 6821 // check if target holds top-level <provider> permissions 6822 if (!readMet && pi.readPermission != null && considerUidPermissions 6823 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6824 readMet = true; 6825 } 6826 if (!writeMet && pi.writePermission != null && considerUidPermissions 6827 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6828 writeMet = true; 6829 } 6830 6831 // track if unprotected read/write is allowed; any denied 6832 // <path-permission> below removes this ability 6833 boolean allowDefaultRead = pi.readPermission == null; 6834 boolean allowDefaultWrite = pi.writePermission == null; 6835 6836 // check if target holds any <path-permission> that match uri 6837 final PathPermission[] pps = pi.pathPermissions; 6838 if (pps != null) { 6839 final String path = grantUri.uri.getPath(); 6840 int i = pps.length; 6841 while (i > 0 && (!readMet || !writeMet)) { 6842 i--; 6843 PathPermission pp = pps[i]; 6844 if (pp.match(path)) { 6845 if (!readMet) { 6846 final String pprperm = pp.getReadPermission(); 6847 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6848 + pprperm + " for " + pp.getPath() 6849 + ": match=" + pp.match(path) 6850 + " check=" + pm.checkUidPermission(pprperm, uid)); 6851 if (pprperm != null) { 6852 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6853 == PERMISSION_GRANTED) { 6854 readMet = true; 6855 } else { 6856 allowDefaultRead = false; 6857 } 6858 } 6859 } 6860 if (!writeMet) { 6861 final String ppwperm = pp.getWritePermission(); 6862 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6863 + ppwperm + " for " + pp.getPath() 6864 + ": match=" + pp.match(path) 6865 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6866 if (ppwperm != null) { 6867 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6868 == PERMISSION_GRANTED) { 6869 writeMet = true; 6870 } else { 6871 allowDefaultWrite = false; 6872 } 6873 } 6874 } 6875 } 6876 } 6877 } 6878 6879 // grant unprotected <provider> read/write, if not blocked by 6880 // <path-permission> above 6881 if (allowDefaultRead) readMet = true; 6882 if (allowDefaultWrite) writeMet = true; 6883 6884 } catch (RemoteException e) { 6885 return false; 6886 } 6887 6888 return readMet && writeMet; 6889 } 6890 6891 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6892 ProviderInfo pi = null; 6893 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6894 if (cpr != null) { 6895 pi = cpr.info; 6896 } else { 6897 try { 6898 pi = AppGlobals.getPackageManager().resolveContentProvider( 6899 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6900 } catch (RemoteException ex) { 6901 } 6902 } 6903 return pi; 6904 } 6905 6906 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6907 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6908 if (targetUris != null) { 6909 return targetUris.get(grantUri); 6910 } 6911 return null; 6912 } 6913 6914 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6915 String targetPkg, int targetUid, GrantUri grantUri) { 6916 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6917 if (targetUris == null) { 6918 targetUris = Maps.newArrayMap(); 6919 mGrantedUriPermissions.put(targetUid, targetUris); 6920 } 6921 6922 UriPermission perm = targetUris.get(grantUri); 6923 if (perm == null) { 6924 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6925 targetUris.put(grantUri, perm); 6926 } 6927 6928 return perm; 6929 } 6930 6931 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6932 final int modeFlags) { 6933 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6934 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6935 : UriPermission.STRENGTH_OWNED; 6936 6937 // Root gets to do everything. 6938 if (uid == 0) { 6939 return true; 6940 } 6941 6942 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6943 if (perms == null) return false; 6944 6945 // First look for exact match 6946 final UriPermission exactPerm = perms.get(grantUri); 6947 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6948 return true; 6949 } 6950 6951 // No exact match, look for prefixes 6952 final int N = perms.size(); 6953 for (int i = 0; i < N; i++) { 6954 final UriPermission perm = perms.valueAt(i); 6955 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6956 && perm.getStrength(modeFlags) >= minStrength) { 6957 return true; 6958 } 6959 } 6960 6961 return false; 6962 } 6963 6964 /** 6965 * @param uri This uri must NOT contain an embedded userId. 6966 * @param userId The userId in which the uri is to be resolved. 6967 */ 6968 @Override 6969 public int checkUriPermission(Uri uri, int pid, int uid, 6970 final int modeFlags, int userId) { 6971 enforceNotIsolatedCaller("checkUriPermission"); 6972 6973 // Another redirected-binder-call permissions check as in 6974 // {@link checkComponentPermission}. 6975 Identity tlsIdentity = sCallerIdentity.get(); 6976 if (tlsIdentity != null) { 6977 uid = tlsIdentity.uid; 6978 pid = tlsIdentity.pid; 6979 } 6980 6981 // Our own process gets to do everything. 6982 if (pid == MY_PID) { 6983 return PackageManager.PERMISSION_GRANTED; 6984 } 6985 synchronized (this) { 6986 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6987 ? PackageManager.PERMISSION_GRANTED 6988 : PackageManager.PERMISSION_DENIED; 6989 } 6990 } 6991 6992 /** 6993 * Check if the targetPkg can be granted permission to access uri by 6994 * the callingUid using the given modeFlags. Throws a security exception 6995 * if callingUid is not allowed to do this. Returns the uid of the target 6996 * if the URI permission grant should be performed; returns -1 if it is not 6997 * needed (for example targetPkg already has permission to access the URI). 6998 * If you already know the uid of the target, you can supply it in 6999 * lastTargetUid else set that to -1. 7000 */ 7001 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7002 final int modeFlags, int lastTargetUid) { 7003 if (!Intent.isAccessUriMode(modeFlags)) { 7004 return -1; 7005 } 7006 7007 if (targetPkg != null) { 7008 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7009 "Checking grant " + targetPkg + " permission to " + grantUri); 7010 } 7011 7012 final IPackageManager pm = AppGlobals.getPackageManager(); 7013 7014 // If this is not a content: uri, we can't do anything with it. 7015 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7017 "Can't grant URI permission for non-content URI: " + grantUri); 7018 return -1; 7019 } 7020 7021 final String authority = grantUri.uri.getAuthority(); 7022 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7023 if (pi == null) { 7024 Slog.w(TAG, "No content provider found for permission check: " + 7025 grantUri.uri.toSafeString()); 7026 return -1; 7027 } 7028 7029 int targetUid = lastTargetUid; 7030 if (targetUid < 0 && targetPkg != null) { 7031 try { 7032 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7033 if (targetUid < 0) { 7034 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7035 "Can't grant URI permission no uid for: " + targetPkg); 7036 return -1; 7037 } 7038 } catch (RemoteException ex) { 7039 return -1; 7040 } 7041 } 7042 7043 if (targetUid >= 0) { 7044 // First... does the target actually need this permission? 7045 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7046 // No need to grant the target this permission. 7047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7048 "Target " + targetPkg + " already has full permission to " + grantUri); 7049 return -1; 7050 } 7051 } else { 7052 // First... there is no target package, so can anyone access it? 7053 boolean allowed = pi.exported; 7054 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7055 if (pi.readPermission != null) { 7056 allowed = false; 7057 } 7058 } 7059 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7060 if (pi.writePermission != null) { 7061 allowed = false; 7062 } 7063 } 7064 if (allowed) { 7065 return -1; 7066 } 7067 } 7068 7069 /* There is a special cross user grant if: 7070 * - The target is on another user. 7071 * - Apps on the current user can access the uri without any uid permissions. 7072 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7073 * grant uri permissions. 7074 */ 7075 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7076 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7077 modeFlags, false /*without considering the uid permissions*/); 7078 7079 // Second... is the provider allowing granting of URI permissions? 7080 if (!specialCrossUserGrant) { 7081 if (!pi.grantUriPermissions) { 7082 throw new SecurityException("Provider " + pi.packageName 7083 + "/" + pi.name 7084 + " does not allow granting of Uri permissions (uri " 7085 + grantUri + ")"); 7086 } 7087 if (pi.uriPermissionPatterns != null) { 7088 final int N = pi.uriPermissionPatterns.length; 7089 boolean allowed = false; 7090 for (int i=0; i<N; i++) { 7091 if (pi.uriPermissionPatterns[i] != null 7092 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7093 allowed = true; 7094 break; 7095 } 7096 } 7097 if (!allowed) { 7098 throw new SecurityException("Provider " + pi.packageName 7099 + "/" + pi.name 7100 + " does not allow granting of permission to path of Uri " 7101 + grantUri); 7102 } 7103 } 7104 } 7105 7106 // Third... does the caller itself have permission to access 7107 // this uri? 7108 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7109 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7110 // Require they hold a strong enough Uri permission 7111 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7112 throw new SecurityException("Uid " + callingUid 7113 + " does not have permission to uri " + grantUri); 7114 } 7115 } 7116 } 7117 return targetUid; 7118 } 7119 7120 /** 7121 * @param uri This uri must NOT contain an embedded userId. 7122 * @param userId The userId in which the uri is to be resolved. 7123 */ 7124 @Override 7125 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7126 final int modeFlags, int userId) { 7127 enforceNotIsolatedCaller("checkGrantUriPermission"); 7128 synchronized(this) { 7129 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7130 new GrantUri(userId, uri, false), modeFlags, -1); 7131 } 7132 } 7133 7134 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7135 final int modeFlags, UriPermissionOwner owner) { 7136 if (!Intent.isAccessUriMode(modeFlags)) { 7137 return; 7138 } 7139 7140 // So here we are: the caller has the assumed permission 7141 // to the uri, and the target doesn't. Let's now give this to 7142 // the target. 7143 7144 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7145 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7146 7147 final String authority = grantUri.uri.getAuthority(); 7148 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7149 if (pi == null) { 7150 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7151 return; 7152 } 7153 7154 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7155 grantUri.prefix = true; 7156 } 7157 final UriPermission perm = findOrCreateUriPermissionLocked( 7158 pi.packageName, targetPkg, targetUid, grantUri); 7159 perm.grantModes(modeFlags, owner); 7160 } 7161 7162 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7163 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7164 if (targetPkg == null) { 7165 throw new NullPointerException("targetPkg"); 7166 } 7167 int targetUid; 7168 final IPackageManager pm = AppGlobals.getPackageManager(); 7169 try { 7170 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7171 } catch (RemoteException ex) { 7172 return; 7173 } 7174 7175 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7176 targetUid); 7177 if (targetUid < 0) { 7178 return; 7179 } 7180 7181 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7182 owner); 7183 } 7184 7185 static class NeededUriGrants extends ArrayList<GrantUri> { 7186 final String targetPkg; 7187 final int targetUid; 7188 final int flags; 7189 7190 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7191 this.targetPkg = targetPkg; 7192 this.targetUid = targetUid; 7193 this.flags = flags; 7194 } 7195 } 7196 7197 /** 7198 * Like checkGrantUriPermissionLocked, but takes an Intent. 7199 */ 7200 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7201 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7202 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7203 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7204 + " clip=" + (intent != null ? intent.getClipData() : null) 7205 + " from " + intent + "; flags=0x" 7206 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7207 7208 if (targetPkg == null) { 7209 throw new NullPointerException("targetPkg"); 7210 } 7211 7212 if (intent == null) { 7213 return null; 7214 } 7215 Uri data = intent.getData(); 7216 ClipData clip = intent.getClipData(); 7217 if (data == null && clip == null) { 7218 return null; 7219 } 7220 // Default userId for uris in the intent (if they don't specify it themselves) 7221 int contentUserHint = intent.getContentUserHint(); 7222 if (contentUserHint == UserHandle.USER_CURRENT) { 7223 contentUserHint = UserHandle.getUserId(callingUid); 7224 } 7225 final IPackageManager pm = AppGlobals.getPackageManager(); 7226 int targetUid; 7227 if (needed != null) { 7228 targetUid = needed.targetUid; 7229 } else { 7230 try { 7231 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7232 } catch (RemoteException ex) { 7233 return null; 7234 } 7235 if (targetUid < 0) { 7236 if (DEBUG_URI_PERMISSION) { 7237 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7238 + " on user " + targetUserId); 7239 } 7240 return null; 7241 } 7242 } 7243 if (data != null) { 7244 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7245 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7246 targetUid); 7247 if (targetUid > 0) { 7248 if (needed == null) { 7249 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7250 } 7251 needed.add(grantUri); 7252 } 7253 } 7254 if (clip != null) { 7255 for (int i=0; i<clip.getItemCount(); i++) { 7256 Uri uri = clip.getItemAt(i).getUri(); 7257 if (uri != null) { 7258 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7259 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7260 targetUid); 7261 if (targetUid > 0) { 7262 if (needed == null) { 7263 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7264 } 7265 needed.add(grantUri); 7266 } 7267 } else { 7268 Intent clipIntent = clip.getItemAt(i).getIntent(); 7269 if (clipIntent != null) { 7270 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7271 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7272 if (newNeeded != null) { 7273 needed = newNeeded; 7274 } 7275 } 7276 } 7277 } 7278 } 7279 7280 return needed; 7281 } 7282 7283 /** 7284 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7285 */ 7286 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7287 UriPermissionOwner owner) { 7288 if (needed != null) { 7289 for (int i=0; i<needed.size(); i++) { 7290 GrantUri grantUri = needed.get(i); 7291 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7292 grantUri, needed.flags, owner); 7293 } 7294 } 7295 } 7296 7297 void grantUriPermissionFromIntentLocked(int callingUid, 7298 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7299 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7300 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7301 if (needed == null) { 7302 return; 7303 } 7304 7305 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7306 } 7307 7308 /** 7309 * @param uri This uri must NOT contain an embedded userId. 7310 * @param userId The userId in which the uri is to be resolved. 7311 */ 7312 @Override 7313 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7314 final int modeFlags, int userId) { 7315 enforceNotIsolatedCaller("grantUriPermission"); 7316 GrantUri grantUri = new GrantUri(userId, uri, false); 7317 synchronized(this) { 7318 final ProcessRecord r = getRecordForAppLocked(caller); 7319 if (r == null) { 7320 throw new SecurityException("Unable to find app for caller " 7321 + caller 7322 + " when granting permission to uri " + grantUri); 7323 } 7324 if (targetPkg == null) { 7325 throw new IllegalArgumentException("null target"); 7326 } 7327 if (grantUri == null) { 7328 throw new IllegalArgumentException("null uri"); 7329 } 7330 7331 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7332 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7333 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7334 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7335 7336 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7337 UserHandle.getUserId(r.uid)); 7338 } 7339 } 7340 7341 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7342 if (perm.modeFlags == 0) { 7343 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7344 perm.targetUid); 7345 if (perms != null) { 7346 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7347 "Removing " + perm.targetUid + " permission to " + perm.uri); 7348 7349 perms.remove(perm.uri); 7350 if (perms.isEmpty()) { 7351 mGrantedUriPermissions.remove(perm.targetUid); 7352 } 7353 } 7354 } 7355 } 7356 7357 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7359 7360 final IPackageManager pm = AppGlobals.getPackageManager(); 7361 final String authority = grantUri.uri.getAuthority(); 7362 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7363 if (pi == null) { 7364 Slog.w(TAG, "No content provider found for permission revoke: " 7365 + grantUri.toSafeString()); 7366 return; 7367 } 7368 7369 // Does the caller have this permission on the URI? 7370 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7371 // If they don't have direct access to the URI, then revoke any 7372 // ownerless URI permissions that have been granted to them. 7373 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7374 if (perms != null) { 7375 boolean persistChanged = false; 7376 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7377 final UriPermission perm = it.next(); 7378 if (perm.uri.sourceUserId == grantUri.sourceUserId 7379 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7380 if (DEBUG_URI_PERMISSION) 7381 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7382 " permission to " + perm.uri); 7383 persistChanged |= perm.revokeModes( 7384 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7385 if (perm.modeFlags == 0) { 7386 it.remove(); 7387 } 7388 } 7389 } 7390 if (perms.isEmpty()) { 7391 mGrantedUriPermissions.remove(callingUid); 7392 } 7393 if (persistChanged) { 7394 schedulePersistUriGrants(); 7395 } 7396 } 7397 return; 7398 } 7399 7400 boolean persistChanged = false; 7401 7402 // Go through all of the permissions and remove any that match. 7403 int N = mGrantedUriPermissions.size(); 7404 for (int i = 0; i < N; i++) { 7405 final int targetUid = mGrantedUriPermissions.keyAt(i); 7406 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7407 7408 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7409 final UriPermission perm = it.next(); 7410 if (perm.uri.sourceUserId == grantUri.sourceUserId 7411 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7412 if (DEBUG_URI_PERMISSION) 7413 Slog.v(TAG, 7414 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7415 persistChanged |= perm.revokeModes( 7416 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7417 if (perm.modeFlags == 0) { 7418 it.remove(); 7419 } 7420 } 7421 } 7422 7423 if (perms.isEmpty()) { 7424 mGrantedUriPermissions.remove(targetUid); 7425 N--; 7426 i--; 7427 } 7428 } 7429 7430 if (persistChanged) { 7431 schedulePersistUriGrants(); 7432 } 7433 } 7434 7435 /** 7436 * @param uri This uri must NOT contain an embedded userId. 7437 * @param userId The userId in which the uri is to be resolved. 7438 */ 7439 @Override 7440 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7441 int userId) { 7442 enforceNotIsolatedCaller("revokeUriPermission"); 7443 synchronized(this) { 7444 final ProcessRecord r = getRecordForAppLocked(caller); 7445 if (r == null) { 7446 throw new SecurityException("Unable to find app for caller " 7447 + caller 7448 + " when revoking permission to uri " + uri); 7449 } 7450 if (uri == null) { 7451 Slog.w(TAG, "revokeUriPermission: null uri"); 7452 return; 7453 } 7454 7455 if (!Intent.isAccessUriMode(modeFlags)) { 7456 return; 7457 } 7458 7459 final IPackageManager pm = AppGlobals.getPackageManager(); 7460 final String authority = uri.getAuthority(); 7461 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7462 if (pi == null) { 7463 Slog.w(TAG, "No content provider found for permission revoke: " 7464 + uri.toSafeString()); 7465 return; 7466 } 7467 7468 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7469 } 7470 } 7471 7472 /** 7473 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7474 * given package. 7475 * 7476 * @param packageName Package name to match, or {@code null} to apply to all 7477 * packages. 7478 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7479 * to all users. 7480 * @param persistable If persistable grants should be removed. 7481 */ 7482 private void removeUriPermissionsForPackageLocked( 7483 String packageName, int userHandle, boolean persistable) { 7484 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7485 throw new IllegalArgumentException("Must narrow by either package or user"); 7486 } 7487 7488 boolean persistChanged = false; 7489 7490 int N = mGrantedUriPermissions.size(); 7491 for (int i = 0; i < N; i++) { 7492 final int targetUid = mGrantedUriPermissions.keyAt(i); 7493 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7494 7495 // Only inspect grants matching user 7496 if (userHandle == UserHandle.USER_ALL 7497 || userHandle == UserHandle.getUserId(targetUid)) { 7498 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7499 final UriPermission perm = it.next(); 7500 7501 // Only inspect grants matching package 7502 if (packageName == null || perm.sourcePkg.equals(packageName) 7503 || perm.targetPkg.equals(packageName)) { 7504 persistChanged |= perm.revokeModes(persistable 7505 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7506 7507 // Only remove when no modes remain; any persisted grants 7508 // will keep this alive. 7509 if (perm.modeFlags == 0) { 7510 it.remove(); 7511 } 7512 } 7513 } 7514 7515 if (perms.isEmpty()) { 7516 mGrantedUriPermissions.remove(targetUid); 7517 N--; 7518 i--; 7519 } 7520 } 7521 } 7522 7523 if (persistChanged) { 7524 schedulePersistUriGrants(); 7525 } 7526 } 7527 7528 @Override 7529 public IBinder newUriPermissionOwner(String name) { 7530 enforceNotIsolatedCaller("newUriPermissionOwner"); 7531 synchronized(this) { 7532 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7533 return owner.getExternalTokenLocked(); 7534 } 7535 } 7536 7537 /** 7538 * @param uri This uri must NOT contain an embedded userId. 7539 * @param sourceUserId The userId in which the uri is to be resolved. 7540 * @param targetUserId The userId of the app that receives the grant. 7541 */ 7542 @Override 7543 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7544 final int modeFlags, int sourceUserId, int targetUserId) { 7545 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7546 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7547 synchronized(this) { 7548 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7549 if (owner == null) { 7550 throw new IllegalArgumentException("Unknown owner: " + token); 7551 } 7552 if (fromUid != Binder.getCallingUid()) { 7553 if (Binder.getCallingUid() != Process.myUid()) { 7554 // Only system code can grant URI permissions on behalf 7555 // of other users. 7556 throw new SecurityException("nice try"); 7557 } 7558 } 7559 if (targetPkg == null) { 7560 throw new IllegalArgumentException("null target"); 7561 } 7562 if (uri == null) { 7563 throw new IllegalArgumentException("null uri"); 7564 } 7565 7566 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7567 modeFlags, owner, targetUserId); 7568 } 7569 } 7570 7571 /** 7572 * @param uri This uri must NOT contain an embedded userId. 7573 * @param userId The userId in which the uri is to be resolved. 7574 */ 7575 @Override 7576 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7577 synchronized(this) { 7578 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7579 if (owner == null) { 7580 throw new IllegalArgumentException("Unknown owner: " + token); 7581 } 7582 7583 if (uri == null) { 7584 owner.removeUriPermissionsLocked(mode); 7585 } else { 7586 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7587 } 7588 } 7589 } 7590 7591 private void schedulePersistUriGrants() { 7592 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7593 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7594 10 * DateUtils.SECOND_IN_MILLIS); 7595 } 7596 } 7597 7598 private void writeGrantedUriPermissions() { 7599 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7600 7601 // Snapshot permissions so we can persist without lock 7602 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7603 synchronized (this) { 7604 final int size = mGrantedUriPermissions.size(); 7605 for (int i = 0; i < size; i++) { 7606 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7607 for (UriPermission perm : perms.values()) { 7608 if (perm.persistedModeFlags != 0) { 7609 persist.add(perm.snapshot()); 7610 } 7611 } 7612 } 7613 } 7614 7615 FileOutputStream fos = null; 7616 try { 7617 fos = mGrantFile.startWrite(); 7618 7619 XmlSerializer out = new FastXmlSerializer(); 7620 out.setOutput(fos, "utf-8"); 7621 out.startDocument(null, true); 7622 out.startTag(null, TAG_URI_GRANTS); 7623 for (UriPermission.Snapshot perm : persist) { 7624 out.startTag(null, TAG_URI_GRANT); 7625 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7626 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7627 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7628 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7629 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7630 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7631 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7632 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7633 out.endTag(null, TAG_URI_GRANT); 7634 } 7635 out.endTag(null, TAG_URI_GRANTS); 7636 out.endDocument(); 7637 7638 mGrantFile.finishWrite(fos); 7639 } catch (IOException e) { 7640 if (fos != null) { 7641 mGrantFile.failWrite(fos); 7642 } 7643 } 7644 } 7645 7646 private void readGrantedUriPermissionsLocked() { 7647 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7648 7649 final long now = System.currentTimeMillis(); 7650 7651 FileInputStream fis = null; 7652 try { 7653 fis = mGrantFile.openRead(); 7654 final XmlPullParser in = Xml.newPullParser(); 7655 in.setInput(fis, null); 7656 7657 int type; 7658 while ((type = in.next()) != END_DOCUMENT) { 7659 final String tag = in.getName(); 7660 if (type == START_TAG) { 7661 if (TAG_URI_GRANT.equals(tag)) { 7662 final int sourceUserId; 7663 final int targetUserId; 7664 final int userHandle = readIntAttribute(in, 7665 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7666 if (userHandle != UserHandle.USER_NULL) { 7667 // For backwards compatibility. 7668 sourceUserId = userHandle; 7669 targetUserId = userHandle; 7670 } else { 7671 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7672 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7673 } 7674 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7675 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7676 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7677 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7678 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7679 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7680 7681 // Sanity check that provider still belongs to source package 7682 final ProviderInfo pi = getProviderInfoLocked( 7683 uri.getAuthority(), sourceUserId); 7684 if (pi != null && sourcePkg.equals(pi.packageName)) { 7685 int targetUid = -1; 7686 try { 7687 targetUid = AppGlobals.getPackageManager() 7688 .getPackageUid(targetPkg, targetUserId); 7689 } catch (RemoteException e) { 7690 } 7691 if (targetUid != -1) { 7692 final UriPermission perm = findOrCreateUriPermissionLocked( 7693 sourcePkg, targetPkg, targetUid, 7694 new GrantUri(sourceUserId, uri, prefix)); 7695 perm.initPersistedModes(modeFlags, createdTime); 7696 } 7697 } else { 7698 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7699 + " but instead found " + pi); 7700 } 7701 } 7702 } 7703 } 7704 } catch (FileNotFoundException e) { 7705 // Missing grants is okay 7706 } catch (IOException e) { 7707 Slog.wtf(TAG, "Failed reading Uri grants", e); 7708 } catch (XmlPullParserException e) { 7709 Slog.wtf(TAG, "Failed reading Uri grants", e); 7710 } finally { 7711 IoUtils.closeQuietly(fis); 7712 } 7713 } 7714 7715 /** 7716 * @param uri This uri must NOT contain an embedded userId. 7717 * @param userId The userId in which the uri is to be resolved. 7718 */ 7719 @Override 7720 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7721 enforceNotIsolatedCaller("takePersistableUriPermission"); 7722 7723 Preconditions.checkFlagsArgument(modeFlags, 7724 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7725 7726 synchronized (this) { 7727 final int callingUid = Binder.getCallingUid(); 7728 boolean persistChanged = false; 7729 GrantUri grantUri = new GrantUri(userId, uri, false); 7730 7731 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7732 new GrantUri(userId, uri, false)); 7733 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7734 new GrantUri(userId, uri, true)); 7735 7736 final boolean exactValid = (exactPerm != null) 7737 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7738 final boolean prefixValid = (prefixPerm != null) 7739 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7740 7741 if (!(exactValid || prefixValid)) { 7742 throw new SecurityException("No persistable permission grants found for UID " 7743 + callingUid + " and Uri " + grantUri.toSafeString()); 7744 } 7745 7746 if (exactValid) { 7747 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7748 } 7749 if (prefixValid) { 7750 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7751 } 7752 7753 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7754 7755 if (persistChanged) { 7756 schedulePersistUriGrants(); 7757 } 7758 } 7759 } 7760 7761 /** 7762 * @param uri This uri must NOT contain an embedded userId. 7763 * @param userId The userId in which the uri is to be resolved. 7764 */ 7765 @Override 7766 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7767 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7768 7769 Preconditions.checkFlagsArgument(modeFlags, 7770 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7771 7772 synchronized (this) { 7773 final int callingUid = Binder.getCallingUid(); 7774 boolean persistChanged = false; 7775 7776 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7777 new GrantUri(userId, uri, false)); 7778 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7779 new GrantUri(userId, uri, true)); 7780 if (exactPerm == null && prefixPerm == null) { 7781 throw new SecurityException("No permission grants found for UID " + callingUid 7782 + " and Uri " + uri.toSafeString()); 7783 } 7784 7785 if (exactPerm != null) { 7786 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7787 removeUriPermissionIfNeededLocked(exactPerm); 7788 } 7789 if (prefixPerm != null) { 7790 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7791 removeUriPermissionIfNeededLocked(prefixPerm); 7792 } 7793 7794 if (persistChanged) { 7795 schedulePersistUriGrants(); 7796 } 7797 } 7798 } 7799 7800 /** 7801 * Prune any older {@link UriPermission} for the given UID until outstanding 7802 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7803 * 7804 * @return if any mutations occured that require persisting. 7805 */ 7806 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7807 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7808 if (perms == null) return false; 7809 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7810 7811 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7812 for (UriPermission perm : perms.values()) { 7813 if (perm.persistedModeFlags != 0) { 7814 persisted.add(perm); 7815 } 7816 } 7817 7818 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7819 if (trimCount <= 0) return false; 7820 7821 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7822 for (int i = 0; i < trimCount; i++) { 7823 final UriPermission perm = persisted.get(i); 7824 7825 if (DEBUG_URI_PERMISSION) { 7826 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7827 } 7828 7829 perm.releasePersistableModes(~0); 7830 removeUriPermissionIfNeededLocked(perm); 7831 } 7832 7833 return true; 7834 } 7835 7836 @Override 7837 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7838 String packageName, boolean incoming) { 7839 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7840 Preconditions.checkNotNull(packageName, "packageName"); 7841 7842 final int callingUid = Binder.getCallingUid(); 7843 final IPackageManager pm = AppGlobals.getPackageManager(); 7844 try { 7845 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7846 if (packageUid != callingUid) { 7847 throw new SecurityException( 7848 "Package " + packageName + " does not belong to calling UID " + callingUid); 7849 } 7850 } catch (RemoteException e) { 7851 throw new SecurityException("Failed to verify package name ownership"); 7852 } 7853 7854 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7855 synchronized (this) { 7856 if (incoming) { 7857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7858 callingUid); 7859 if (perms == null) { 7860 Slog.w(TAG, "No permission grants found for " + packageName); 7861 } else { 7862 for (UriPermission perm : perms.values()) { 7863 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7864 result.add(perm.buildPersistedPublicApiObject()); 7865 } 7866 } 7867 } 7868 } else { 7869 final int size = mGrantedUriPermissions.size(); 7870 for (int i = 0; i < size; i++) { 7871 final ArrayMap<GrantUri, UriPermission> perms = 7872 mGrantedUriPermissions.valueAt(i); 7873 for (UriPermission perm : perms.values()) { 7874 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7875 result.add(perm.buildPersistedPublicApiObject()); 7876 } 7877 } 7878 } 7879 } 7880 } 7881 return new ParceledListSlice<android.content.UriPermission>(result); 7882 } 7883 7884 @Override 7885 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7886 synchronized (this) { 7887 ProcessRecord app = 7888 who != null ? getRecordForAppLocked(who) : null; 7889 if (app == null) return; 7890 7891 Message msg = Message.obtain(); 7892 msg.what = WAIT_FOR_DEBUGGER_MSG; 7893 msg.obj = app; 7894 msg.arg1 = waiting ? 1 : 0; 7895 mHandler.sendMessage(msg); 7896 } 7897 } 7898 7899 @Override 7900 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7901 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7902 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7903 outInfo.availMem = Process.getFreeMemory(); 7904 outInfo.totalMem = Process.getTotalMemory(); 7905 outInfo.threshold = homeAppMem; 7906 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7907 outInfo.hiddenAppThreshold = cachedAppMem; 7908 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7909 ProcessList.SERVICE_ADJ); 7910 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7911 ProcessList.VISIBLE_APP_ADJ); 7912 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7913 ProcessList.FOREGROUND_APP_ADJ); 7914 } 7915 7916 // ========================================================= 7917 // TASK MANAGEMENT 7918 // ========================================================= 7919 7920 @Override 7921 public List<IAppTask> getAppTasks(String callingPackage) { 7922 int callingUid = Binder.getCallingUid(); 7923 long ident = Binder.clearCallingIdentity(); 7924 7925 synchronized(this) { 7926 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7927 try { 7928 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7929 7930 final int N = mRecentTasks.size(); 7931 for (int i = 0; i < N; i++) { 7932 TaskRecord tr = mRecentTasks.get(i); 7933 // Skip tasks that do not match the caller. We don't need to verify 7934 // callingPackage, because we are also limiting to callingUid and know 7935 // that will limit to the correct security sandbox. 7936 if (tr.effectiveUid != callingUid) { 7937 continue; 7938 } 7939 Intent intent = tr.getBaseIntent(); 7940 if (intent == null || 7941 !callingPackage.equals(intent.getComponent().getPackageName())) { 7942 continue; 7943 } 7944 ActivityManager.RecentTaskInfo taskInfo = 7945 createRecentTaskInfoFromTaskRecord(tr); 7946 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7947 list.add(taskImpl); 7948 } 7949 } finally { 7950 Binder.restoreCallingIdentity(ident); 7951 } 7952 return list; 7953 } 7954 } 7955 7956 @Override 7957 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7958 final int callingUid = Binder.getCallingUid(); 7959 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7960 7961 synchronized(this) { 7962 if (localLOGV) Slog.v( 7963 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7964 7965 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7966 callingUid); 7967 7968 // TODO: Improve with MRU list from all ActivityStacks. 7969 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7970 } 7971 7972 return list; 7973 } 7974 7975 TaskRecord getMostRecentTask() { 7976 return mRecentTasks.get(0); 7977 } 7978 7979 /** 7980 * Creates a new RecentTaskInfo from a TaskRecord. 7981 */ 7982 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7983 // Update the task description to reflect any changes in the task stack 7984 tr.updateTaskDescription(); 7985 7986 // Compose the recent task info 7987 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7988 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7989 rti.persistentId = tr.taskId; 7990 rti.baseIntent = new Intent(tr.getBaseIntent()); 7991 rti.origActivity = tr.origActivity; 7992 rti.description = tr.lastDescription; 7993 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7994 rti.userId = tr.userId; 7995 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7996 rti.firstActiveTime = tr.firstActiveTime; 7997 rti.lastActiveTime = tr.lastActiveTime; 7998 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7999 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8000 return rti; 8001 } 8002 8003 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8004 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8005 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8006 if (!allowed) { 8007 if (checkPermission(android.Manifest.permission.GET_TASKS, 8008 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8009 // Temporary compatibility: some existing apps on the system image may 8010 // still be requesting the old permission and not switched to the new 8011 // one; if so, we'll still allow them full access. This means we need 8012 // to see if they are holding the old permission and are a system app. 8013 try { 8014 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8015 allowed = true; 8016 Slog.w(TAG, caller + ": caller " + callingUid 8017 + " is using old GET_TASKS but privileged; allowing"); 8018 } 8019 } catch (RemoteException e) { 8020 } 8021 } 8022 } 8023 if (!allowed) { 8024 Slog.w(TAG, caller + ": caller " + callingUid 8025 + " does not hold GET_TASKS; limiting output"); 8026 } 8027 return allowed; 8028 } 8029 8030 @Override 8031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8032 final int callingUid = Binder.getCallingUid(); 8033 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8034 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8035 8036 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8037 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8038 synchronized (this) { 8039 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8040 callingUid); 8041 final boolean detailed = checkCallingPermission( 8042 android.Manifest.permission.GET_DETAILED_TASKS) 8043 == PackageManager.PERMISSION_GRANTED; 8044 8045 final int N = mRecentTasks.size(); 8046 ArrayList<ActivityManager.RecentTaskInfo> res 8047 = new ArrayList<ActivityManager.RecentTaskInfo>( 8048 maxNum < N ? maxNum : N); 8049 8050 final Set<Integer> includedUsers; 8051 if (includeProfiles) { 8052 includedUsers = getProfileIdsLocked(userId); 8053 } else { 8054 includedUsers = new HashSet<Integer>(); 8055 } 8056 includedUsers.add(Integer.valueOf(userId)); 8057 8058 for (int i=0; i<N && maxNum > 0; i++) { 8059 TaskRecord tr = mRecentTasks.get(i); 8060 // Only add calling user or related users recent tasks 8061 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8062 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8063 continue; 8064 } 8065 8066 // Return the entry if desired by the caller. We always return 8067 // the first entry, because callers always expect this to be the 8068 // foreground app. We may filter others if the caller has 8069 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8070 // we should exclude the entry. 8071 8072 if (i == 0 8073 || withExcluded 8074 || (tr.intent == null) 8075 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8076 == 0)) { 8077 if (!allowed) { 8078 // If the caller doesn't have the GET_TASKS permission, then only 8079 // allow them to see a small subset of tasks -- their own and home. 8080 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8081 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8082 continue; 8083 } 8084 } 8085 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8086 if (tr.stack != null && tr.stack.isHomeStack()) { 8087 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8088 continue; 8089 } 8090 } 8091 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8092 // Don't include auto remove tasks that are finished or finishing. 8093 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8094 + tr); 8095 continue; 8096 } 8097 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8098 && !tr.isAvailable) { 8099 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8100 continue; 8101 } 8102 8103 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8104 if (!detailed) { 8105 rti.baseIntent.replaceExtras((Bundle)null); 8106 } 8107 8108 res.add(rti); 8109 maxNum--; 8110 } 8111 } 8112 return res; 8113 } 8114 } 8115 8116 private TaskRecord taskForIdLocked(int id) { 8117 final TaskRecord task = recentTaskForIdLocked(id); 8118 if (task != null) { 8119 return task; 8120 } 8121 8122 // Don't give up. Sometimes it just hasn't made it to recents yet. 8123 return mStackSupervisor.anyTaskForIdLocked(id); 8124 } 8125 8126 private TaskRecord recentTaskForIdLocked(int id) { 8127 final int N = mRecentTasks.size(); 8128 for (int i=0; i<N; i++) { 8129 TaskRecord tr = mRecentTasks.get(i); 8130 if (tr.taskId == id) { 8131 return tr; 8132 } 8133 } 8134 return null; 8135 } 8136 8137 @Override 8138 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8139 synchronized (this) { 8140 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8141 "getTaskThumbnail()"); 8142 TaskRecord tr = recentTaskForIdLocked(id); 8143 if (tr != null) { 8144 return tr.getTaskThumbnailLocked(); 8145 } 8146 } 8147 return null; 8148 } 8149 8150 @Override 8151 public int addAppTask(IBinder activityToken, Intent intent, 8152 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8153 final int callingUid = Binder.getCallingUid(); 8154 final long callingIdent = Binder.clearCallingIdentity(); 8155 8156 try { 8157 synchronized (this) { 8158 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8159 if (r == null) { 8160 throw new IllegalArgumentException("Activity does not exist; token=" 8161 + activityToken); 8162 } 8163 ComponentName comp = intent.getComponent(); 8164 if (comp == null) { 8165 throw new IllegalArgumentException("Intent " + intent 8166 + " must specify explicit component"); 8167 } 8168 if (thumbnail.getWidth() != mThumbnailWidth 8169 || thumbnail.getHeight() != mThumbnailHeight) { 8170 throw new IllegalArgumentException("Bad thumbnail size: got " 8171 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8172 + mThumbnailWidth + "x" + mThumbnailHeight); 8173 } 8174 if (intent.getSelector() != null) { 8175 intent.setSelector(null); 8176 } 8177 if (intent.getSourceBounds() != null) { 8178 intent.setSourceBounds(null); 8179 } 8180 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8181 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8182 // The caller has added this as an auto-remove task... that makes no 8183 // sense, so turn off auto-remove. 8184 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8185 } 8186 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8187 // Must be a new task. 8188 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8189 } 8190 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8191 mLastAddedTaskActivity = null; 8192 } 8193 ActivityInfo ainfo = mLastAddedTaskActivity; 8194 if (ainfo == null) { 8195 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8196 comp, 0, UserHandle.getUserId(callingUid)); 8197 if (ainfo.applicationInfo.uid != callingUid) { 8198 throw new SecurityException( 8199 "Can't add task for another application: target uid=" 8200 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8201 } 8202 } 8203 8204 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8205 intent, description); 8206 8207 int trimIdx = trimRecentsForTask(task, false); 8208 if (trimIdx >= 0) { 8209 // If this would have caused a trim, then we'll abort because that 8210 // means it would be added at the end of the list but then just removed. 8211 return -1; 8212 } 8213 8214 final int N = mRecentTasks.size(); 8215 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8216 final TaskRecord tr = mRecentTasks.remove(N - 1); 8217 tr.removedFromRecents(mTaskPersister); 8218 } 8219 8220 task.inRecents = true; 8221 mRecentTasks.add(task); 8222 r.task.stack.addTask(task, false, false); 8223 8224 task.setLastThumbnail(thumbnail); 8225 task.freeLastThumbnail(); 8226 8227 return task.taskId; 8228 } 8229 } finally { 8230 Binder.restoreCallingIdentity(callingIdent); 8231 } 8232 } 8233 8234 @Override 8235 public Point getAppTaskThumbnailSize() { 8236 synchronized (this) { 8237 return new Point(mThumbnailWidth, mThumbnailHeight); 8238 } 8239 } 8240 8241 @Override 8242 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8243 synchronized (this) { 8244 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8245 if (r != null) { 8246 r.setTaskDescription(td); 8247 r.task.updateTaskDescription(); 8248 } 8249 } 8250 } 8251 8252 @Override 8253 public Bitmap getTaskDescriptionIcon(String filename) { 8254 if (!FileUtils.isValidExtFilename(filename) 8255 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8256 throw new IllegalArgumentException("Bad filename: " + filename); 8257 } 8258 return mTaskPersister.getTaskDescriptionIcon(filename); 8259 } 8260 8261 @Override 8262 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8263 throws RemoteException { 8264 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8265 opts.getCustomInPlaceResId() == 0) { 8266 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8267 "with valid animation"); 8268 } 8269 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8270 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8271 opts.getCustomInPlaceResId()); 8272 mWindowManager.executeAppTransition(); 8273 } 8274 8275 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8276 mRecentTasks.remove(tr); 8277 tr.removedFromRecents(mTaskPersister); 8278 ComponentName component = tr.getBaseIntent().getComponent(); 8279 if (component == null) { 8280 Slog.w(TAG, "No component for base intent of task: " + tr); 8281 return; 8282 } 8283 8284 if (!killProcess) { 8285 return; 8286 } 8287 8288 // Determine if the process(es) for this task should be killed. 8289 final String pkg = component.getPackageName(); 8290 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8291 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8292 for (int i = 0; i < pmap.size(); i++) { 8293 8294 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8295 for (int j = 0; j < uids.size(); j++) { 8296 ProcessRecord proc = uids.valueAt(j); 8297 if (proc.userId != tr.userId) { 8298 // Don't kill process for a different user. 8299 continue; 8300 } 8301 if (proc == mHomeProcess) { 8302 // Don't kill the home process along with tasks from the same package. 8303 continue; 8304 } 8305 if (!proc.pkgList.containsKey(pkg)) { 8306 // Don't kill process that is not associated with this task. 8307 continue; 8308 } 8309 8310 for (int k = 0; k < proc.activities.size(); k++) { 8311 TaskRecord otherTask = proc.activities.get(k).task; 8312 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8313 // Don't kill process(es) that has an activity in a different task that is 8314 // also in recents. 8315 return; 8316 } 8317 } 8318 8319 // Add process to kill list. 8320 procsToKill.add(proc); 8321 } 8322 } 8323 8324 // Find any running services associated with this app and stop if needed. 8325 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8326 8327 // Kill the running processes. 8328 for (int i = 0; i < procsToKill.size(); i++) { 8329 ProcessRecord pr = procsToKill.get(i); 8330 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8331 pr.kill("remove task", true); 8332 } else { 8333 pr.waitingToKill = "remove task"; 8334 } 8335 } 8336 } 8337 8338 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8339 // Remove all tasks with activities in the specified package from the list of recent tasks 8340 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8341 TaskRecord tr = mRecentTasks.get(i); 8342 if (tr.userId != userId) continue; 8343 8344 ComponentName cn = tr.intent.getComponent(); 8345 if (cn != null && cn.getPackageName().equals(packageName)) { 8346 // If the package name matches, remove the task. 8347 removeTaskByIdLocked(tr.taskId, true); 8348 } 8349 } 8350 } 8351 8352 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8353 final IPackageManager pm = AppGlobals.getPackageManager(); 8354 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8355 8356 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8357 TaskRecord tr = mRecentTasks.get(i); 8358 if (tr.userId != userId) continue; 8359 8360 ComponentName cn = tr.intent.getComponent(); 8361 if (cn != null && cn.getPackageName().equals(packageName)) { 8362 // Skip if component still exists in the package. 8363 if (componentsKnownToExist.contains(cn)) continue; 8364 8365 try { 8366 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8367 if (info != null) { 8368 componentsKnownToExist.add(cn); 8369 } else { 8370 removeTaskByIdLocked(tr.taskId, false); 8371 } 8372 } catch (RemoteException e) { 8373 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8374 } 8375 } 8376 } 8377 } 8378 8379 /** 8380 * Removes the task with the specified task id. 8381 * 8382 * @param taskId Identifier of the task to be removed. 8383 * @param killProcess Kill any process associated with the task if possible. 8384 * @return Returns true if the given task was found and removed. 8385 */ 8386 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8387 TaskRecord tr = taskForIdLocked(taskId); 8388 if (tr != null) { 8389 tr.removeTaskActivitiesLocked(); 8390 cleanUpRemovedTaskLocked(tr, killProcess); 8391 if (tr.isPersistable) { 8392 notifyTaskPersisterLocked(null, true); 8393 } 8394 return true; 8395 } 8396 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8397 return false; 8398 } 8399 8400 @Override 8401 public boolean removeTask(int taskId) { 8402 synchronized (this) { 8403 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8404 "removeTask()"); 8405 long ident = Binder.clearCallingIdentity(); 8406 try { 8407 return removeTaskByIdLocked(taskId, true); 8408 } finally { 8409 Binder.restoreCallingIdentity(ident); 8410 } 8411 } 8412 } 8413 8414 /** 8415 * TODO: Add mController hook 8416 */ 8417 @Override 8418 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8419 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8420 "moveTaskToFront()"); 8421 8422 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8423 synchronized(this) { 8424 moveTaskToFrontLocked(taskId, flags, options); 8425 } 8426 } 8427 8428 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8429 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8430 Binder.getCallingUid(), -1, -1, "Task to front")) { 8431 ActivityOptions.abort(options); 8432 return; 8433 } 8434 final long origId = Binder.clearCallingIdentity(); 8435 try { 8436 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8437 if (task == null) { 8438 Slog.d(TAG, "Could not find task for id: "+ taskId); 8439 return; 8440 } 8441 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8442 mStackSupervisor.showLockTaskToast(); 8443 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8444 return; 8445 } 8446 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8447 if (prev != null && prev.isRecentsActivity()) { 8448 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8449 } 8450 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8451 } finally { 8452 Binder.restoreCallingIdentity(origId); 8453 } 8454 ActivityOptions.abort(options); 8455 } 8456 8457 @Override 8458 public void moveTaskToBack(int taskId) { 8459 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8460 "moveTaskToBack()"); 8461 8462 synchronized(this) { 8463 TaskRecord tr = taskForIdLocked(taskId); 8464 if (tr != null) { 8465 if (tr == mStackSupervisor.mLockTaskModeTask) { 8466 mStackSupervisor.showLockTaskToast(); 8467 return; 8468 } 8469 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8470 ActivityStack stack = tr.stack; 8471 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8472 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8473 Binder.getCallingUid(), -1, -1, "Task to back")) { 8474 return; 8475 } 8476 } 8477 final long origId = Binder.clearCallingIdentity(); 8478 try { 8479 stack.moveTaskToBackLocked(taskId, null); 8480 } finally { 8481 Binder.restoreCallingIdentity(origId); 8482 } 8483 } 8484 } 8485 } 8486 8487 /** 8488 * Moves an activity, and all of the other activities within the same task, to the bottom 8489 * of the history stack. The activity's order within the task is unchanged. 8490 * 8491 * @param token A reference to the activity we wish to move 8492 * @param nonRoot If false then this only works if the activity is the root 8493 * of a task; if true it will work for any activity in a task. 8494 * @return Returns true if the move completed, false if not. 8495 */ 8496 @Override 8497 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8498 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8499 synchronized(this) { 8500 final long origId = Binder.clearCallingIdentity(); 8501 try { 8502 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8503 if (taskId >= 0) { 8504 if ((mStackSupervisor.mLockTaskModeTask != null) 8505 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8506 mStackSupervisor.showLockTaskToast(); 8507 return false; 8508 } 8509 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8510 } 8511 } finally { 8512 Binder.restoreCallingIdentity(origId); 8513 } 8514 } 8515 return false; 8516 } 8517 8518 @Override 8519 public void moveTaskBackwards(int task) { 8520 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8521 "moveTaskBackwards()"); 8522 8523 synchronized(this) { 8524 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8525 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8526 return; 8527 } 8528 final long origId = Binder.clearCallingIdentity(); 8529 moveTaskBackwardsLocked(task); 8530 Binder.restoreCallingIdentity(origId); 8531 } 8532 } 8533 8534 private final void moveTaskBackwardsLocked(int task) { 8535 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8536 } 8537 8538 @Override 8539 public IBinder getHomeActivityToken() throws RemoteException { 8540 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8541 "getHomeActivityToken()"); 8542 synchronized (this) { 8543 return mStackSupervisor.getHomeActivityToken(); 8544 } 8545 } 8546 8547 @Override 8548 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8549 IActivityContainerCallback callback) throws RemoteException { 8550 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8551 "createActivityContainer()"); 8552 synchronized (this) { 8553 if (parentActivityToken == null) { 8554 throw new IllegalArgumentException("parent token must not be null"); 8555 } 8556 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8557 if (r == null) { 8558 return null; 8559 } 8560 if (callback == null) { 8561 throw new IllegalArgumentException("callback must not be null"); 8562 } 8563 return mStackSupervisor.createActivityContainer(r, callback); 8564 } 8565 } 8566 8567 @Override 8568 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8569 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8570 "deleteActivityContainer()"); 8571 synchronized (this) { 8572 mStackSupervisor.deleteActivityContainer(container); 8573 } 8574 } 8575 8576 @Override 8577 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8578 throws RemoteException { 8579 synchronized (this) { 8580 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8581 if (stack != null) { 8582 return stack.mActivityContainer; 8583 } 8584 return null; 8585 } 8586 } 8587 8588 @Override 8589 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8590 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8591 "moveTaskToStack()"); 8592 if (stackId == HOME_STACK_ID) { 8593 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8594 new RuntimeException("here").fillInStackTrace()); 8595 } 8596 synchronized (this) { 8597 long ident = Binder.clearCallingIdentity(); 8598 try { 8599 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8600 + stackId + " toTop=" + toTop); 8601 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8602 } finally { 8603 Binder.restoreCallingIdentity(ident); 8604 } 8605 } 8606 } 8607 8608 @Override 8609 public void resizeStack(int stackBoxId, Rect bounds) { 8610 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8611 "resizeStackBox()"); 8612 long ident = Binder.clearCallingIdentity(); 8613 try { 8614 mWindowManager.resizeStack(stackBoxId, bounds); 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public List<StackInfo> getAllStackInfos() { 8622 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8623 "getAllStackInfos()"); 8624 long ident = Binder.clearCallingIdentity(); 8625 try { 8626 synchronized (this) { 8627 return mStackSupervisor.getAllStackInfosLocked(); 8628 } 8629 } finally { 8630 Binder.restoreCallingIdentity(ident); 8631 } 8632 } 8633 8634 @Override 8635 public StackInfo getStackInfo(int stackId) { 8636 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8637 "getStackInfo()"); 8638 long ident = Binder.clearCallingIdentity(); 8639 try { 8640 synchronized (this) { 8641 return mStackSupervisor.getStackInfoLocked(stackId); 8642 } 8643 } finally { 8644 Binder.restoreCallingIdentity(ident); 8645 } 8646 } 8647 8648 @Override 8649 public boolean isInHomeStack(int taskId) { 8650 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8651 "getStackInfo()"); 8652 long ident = Binder.clearCallingIdentity(); 8653 try { 8654 synchronized (this) { 8655 TaskRecord tr = taskForIdLocked(taskId); 8656 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8657 } 8658 } finally { 8659 Binder.restoreCallingIdentity(ident); 8660 } 8661 } 8662 8663 @Override 8664 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8665 synchronized(this) { 8666 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8667 } 8668 } 8669 8670 private boolean isLockTaskAuthorized(String pkg) { 8671 final DevicePolicyManager dpm = (DevicePolicyManager) 8672 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8673 try { 8674 int uid = mContext.getPackageManager().getPackageUid(pkg, 8675 Binder.getCallingUserHandle().getIdentifier()); 8676 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8677 } catch (NameNotFoundException e) { 8678 return false; 8679 } 8680 } 8681 8682 void startLockTaskMode(TaskRecord task) { 8683 final String pkg; 8684 synchronized (this) { 8685 pkg = task.intent.getComponent().getPackageName(); 8686 } 8687 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8688 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8689 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8690 StatusBarManagerInternal.class); 8691 if (statusBarManager != null) { 8692 statusBarManager.showScreenPinningRequest(); 8693 } 8694 return; 8695 } 8696 long ident = Binder.clearCallingIdentity(); 8697 try { 8698 synchronized (this) { 8699 // Since we lost lock on task, make sure it is still there. 8700 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8701 if (task != null) { 8702 if (!isSystemInitiated 8703 && ((mStackSupervisor.getFocusedStack() == null) 8704 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8705 throw new IllegalArgumentException("Invalid task, not in foreground"); 8706 } 8707 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8708 } 8709 } 8710 } finally { 8711 Binder.restoreCallingIdentity(ident); 8712 } 8713 } 8714 8715 @Override 8716 public void startLockTaskMode(int taskId) { 8717 final TaskRecord task; 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 if (task != null) { 8727 startLockTaskMode(task); 8728 } 8729 } 8730 8731 @Override 8732 public void startLockTaskMode(IBinder token) { 8733 final TaskRecord task; 8734 long ident = Binder.clearCallingIdentity(); 8735 try { 8736 synchronized (this) { 8737 final ActivityRecord r = ActivityRecord.forToken(token); 8738 if (r == null) { 8739 return; 8740 } 8741 task = r.task; 8742 } 8743 } finally { 8744 Binder.restoreCallingIdentity(ident); 8745 } 8746 if (task != null) { 8747 startLockTaskMode(task); 8748 } 8749 } 8750 8751 @Override 8752 public void startLockTaskModeOnCurrent() throws RemoteException { 8753 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8754 "startLockTaskModeOnCurrent"); 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 ActivityRecord r = null; 8758 synchronized (this) { 8759 r = mStackSupervisor.topRunningActivityLocked(); 8760 } 8761 startLockTaskMode(r.task); 8762 } finally { 8763 Binder.restoreCallingIdentity(ident); 8764 } 8765 } 8766 8767 @Override 8768 public void stopLockTaskMode() { 8769 // Verify that the user matches the package of the intent for the TaskRecord 8770 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8771 // and stopLockTaskMode. 8772 final int callingUid = Binder.getCallingUid(); 8773 if (callingUid != Process.SYSTEM_UID) { 8774 try { 8775 String pkg = 8776 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8777 int uid = mContext.getPackageManager().getPackageUid(pkg, 8778 Binder.getCallingUserHandle().getIdentifier()); 8779 if (uid != callingUid) { 8780 throw new SecurityException("Invalid uid, expected " + uid); 8781 } 8782 } catch (NameNotFoundException e) { 8783 Log.d(TAG, "stopLockTaskMode " + e); 8784 return; 8785 } 8786 } 8787 long ident = Binder.clearCallingIdentity(); 8788 try { 8789 Log.d(TAG, "stopLockTaskMode"); 8790 // Stop lock task 8791 synchronized (this) { 8792 mStackSupervisor.setLockTaskModeLocked(null, false); 8793 } 8794 } finally { 8795 Binder.restoreCallingIdentity(ident); 8796 } 8797 } 8798 8799 @Override 8800 public void stopLockTaskModeOnCurrent() throws RemoteException { 8801 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8802 "stopLockTaskModeOnCurrent"); 8803 long ident = Binder.clearCallingIdentity(); 8804 try { 8805 stopLockTaskMode(); 8806 } finally { 8807 Binder.restoreCallingIdentity(ident); 8808 } 8809 } 8810 8811 @Override 8812 public boolean isInLockTaskMode() { 8813 synchronized (this) { 8814 return mStackSupervisor.isInLockTaskMode(); 8815 } 8816 } 8817 8818 // ========================================================= 8819 // CONTENT PROVIDERS 8820 // ========================================================= 8821 8822 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8823 List<ProviderInfo> providers = null; 8824 try { 8825 providers = AppGlobals.getPackageManager(). 8826 queryContentProviders(app.processName, app.uid, 8827 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8828 } catch (RemoteException ex) { 8829 } 8830 if (DEBUG_MU) 8831 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8832 int userId = app.userId; 8833 if (providers != null) { 8834 int N = providers.size(); 8835 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8836 for (int i=0; i<N; i++) { 8837 ProviderInfo cpi = 8838 (ProviderInfo)providers.get(i); 8839 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8840 cpi.name, cpi.flags); 8841 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8842 // This is a singleton provider, but a user besides the 8843 // default user is asking to initialize a process it runs 8844 // in... well, no, it doesn't actually run in this process, 8845 // it runs in the process of the default user. Get rid of it. 8846 providers.remove(i); 8847 N--; 8848 i--; 8849 continue; 8850 } 8851 8852 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8853 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8854 if (cpr == null) { 8855 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8856 mProviderMap.putProviderByClass(comp, cpr); 8857 } 8858 if (DEBUG_MU) 8859 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8860 app.pubProviders.put(cpi.name, cpr); 8861 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8862 // Don't add this if it is a platform component that is marked 8863 // to run in multiple processes, because this is actually 8864 // part of the framework so doesn't make sense to track as a 8865 // separate apk in the process. 8866 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8867 mProcessStats); 8868 } 8869 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8870 } 8871 } 8872 return providers; 8873 } 8874 8875 /** 8876 * Check if {@link ProcessRecord} has a possible chance at accessing the 8877 * given {@link ProviderInfo}. Final permission checking is always done 8878 * in {@link ContentProvider}. 8879 */ 8880 private final String checkContentProviderPermissionLocked( 8881 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8882 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8883 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8884 boolean checkedGrants = false; 8885 if (checkUser) { 8886 // Looking for cross-user grants before enforcing the typical cross-users permissions 8887 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8888 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8889 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8890 return null; 8891 } 8892 checkedGrants = true; 8893 } 8894 userId = handleIncomingUser(callingPid, callingUid, userId, 8895 false, ALLOW_NON_FULL, 8896 "checkContentProviderPermissionLocked " + cpi.authority, null); 8897 if (userId != tmpTargetUserId) { 8898 // When we actually went to determine the final targer user ID, this ended 8899 // up different than our initial check for the authority. This is because 8900 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8901 // SELF. So we need to re-check the grants again. 8902 checkedGrants = false; 8903 } 8904 } 8905 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8906 cpi.applicationInfo.uid, cpi.exported) 8907 == PackageManager.PERMISSION_GRANTED) { 8908 return null; 8909 } 8910 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8911 cpi.applicationInfo.uid, cpi.exported) 8912 == PackageManager.PERMISSION_GRANTED) { 8913 return null; 8914 } 8915 8916 PathPermission[] pps = cpi.pathPermissions; 8917 if (pps != null) { 8918 int i = pps.length; 8919 while (i > 0) { 8920 i--; 8921 PathPermission pp = pps[i]; 8922 String pprperm = pp.getReadPermission(); 8923 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8924 cpi.applicationInfo.uid, cpi.exported) 8925 == PackageManager.PERMISSION_GRANTED) { 8926 return null; 8927 } 8928 String ppwperm = pp.getWritePermission(); 8929 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8930 cpi.applicationInfo.uid, cpi.exported) 8931 == PackageManager.PERMISSION_GRANTED) { 8932 return null; 8933 } 8934 } 8935 } 8936 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8937 return null; 8938 } 8939 8940 String msg; 8941 if (!cpi.exported) { 8942 msg = "Permission Denial: opening provider " + cpi.name 8943 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8944 + ", uid=" + callingUid + ") that is not exported from uid " 8945 + cpi.applicationInfo.uid; 8946 } else { 8947 msg = "Permission Denial: opening provider " + cpi.name 8948 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8949 + ", uid=" + callingUid + ") requires " 8950 + cpi.readPermission + " or " + cpi.writePermission; 8951 } 8952 Slog.w(TAG, msg); 8953 return msg; 8954 } 8955 8956 /** 8957 * Returns if the ContentProvider has granted a uri to callingUid 8958 */ 8959 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8961 if (perms != null) { 8962 for (int i=perms.size()-1; i>=0; i--) { 8963 GrantUri grantUri = perms.keyAt(i); 8964 if (grantUri.sourceUserId == userId || !checkUser) { 8965 if (matchesProvider(grantUri.uri, cpi)) { 8966 return true; 8967 } 8968 } 8969 } 8970 } 8971 return false; 8972 } 8973 8974 /** 8975 * Returns true if the uri authority is one of the authorities specified in the provider. 8976 */ 8977 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8978 String uriAuth = uri.getAuthority(); 8979 String cpiAuth = cpi.authority; 8980 if (cpiAuth.indexOf(';') == -1) { 8981 return cpiAuth.equals(uriAuth); 8982 } 8983 String[] cpiAuths = cpiAuth.split(";"); 8984 int length = cpiAuths.length; 8985 for (int i = 0; i < length; i++) { 8986 if (cpiAuths[i].equals(uriAuth)) return true; 8987 } 8988 return false; 8989 } 8990 8991 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8992 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8993 if (r != null) { 8994 for (int i=0; i<r.conProviders.size(); i++) { 8995 ContentProviderConnection conn = r.conProviders.get(i); 8996 if (conn.provider == cpr) { 8997 if (DEBUG_PROVIDER) Slog.v(TAG, 8998 "Adding provider requested by " 8999 + r.processName + " from process " 9000 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9001 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9002 if (stable) { 9003 conn.stableCount++; 9004 conn.numStableIncs++; 9005 } else { 9006 conn.unstableCount++; 9007 conn.numUnstableIncs++; 9008 } 9009 return conn; 9010 } 9011 } 9012 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9013 if (stable) { 9014 conn.stableCount = 1; 9015 conn.numStableIncs = 1; 9016 } else { 9017 conn.unstableCount = 1; 9018 conn.numUnstableIncs = 1; 9019 } 9020 cpr.connections.add(conn); 9021 r.conProviders.add(conn); 9022 return conn; 9023 } 9024 cpr.addExternalProcessHandleLocked(externalProcessToken); 9025 return null; 9026 } 9027 9028 boolean decProviderCountLocked(ContentProviderConnection conn, 9029 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9030 if (conn != null) { 9031 cpr = conn.provider; 9032 if (DEBUG_PROVIDER) Slog.v(TAG, 9033 "Removing provider requested by " 9034 + conn.client.processName + " from process " 9035 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9036 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9037 if (stable) { 9038 conn.stableCount--; 9039 } else { 9040 conn.unstableCount--; 9041 } 9042 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9043 cpr.connections.remove(conn); 9044 conn.client.conProviders.remove(conn); 9045 return true; 9046 } 9047 return false; 9048 } 9049 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9050 return false; 9051 } 9052 9053 private void checkTime(long startTime, String where) { 9054 long now = SystemClock.elapsedRealtime(); 9055 if ((now-startTime) > 1000) { 9056 // If we are taking more than a second, log about it. 9057 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9058 } 9059 } 9060 9061 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9062 String name, IBinder token, boolean stable, int userId) { 9063 ContentProviderRecord cpr; 9064 ContentProviderConnection conn = null; 9065 ProviderInfo cpi = null; 9066 9067 synchronized(this) { 9068 long startTime = SystemClock.elapsedRealtime(); 9069 9070 ProcessRecord r = null; 9071 if (caller != null) { 9072 r = getRecordForAppLocked(caller); 9073 if (r == null) { 9074 throw new SecurityException( 9075 "Unable to find app for caller " + caller 9076 + " (pid=" + Binder.getCallingPid() 9077 + ") when getting content provider " + name); 9078 } 9079 } 9080 9081 boolean checkCrossUser = true; 9082 9083 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9084 9085 // First check if this content provider has been published... 9086 cpr = mProviderMap.getProviderByName(name, userId); 9087 // If that didn't work, check if it exists for user 0 and then 9088 // verify that it's a singleton provider before using it. 9089 if (cpr == null && userId != UserHandle.USER_OWNER) { 9090 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9091 if (cpr != null) { 9092 cpi = cpr.info; 9093 if (isSingleton(cpi.processName, cpi.applicationInfo, 9094 cpi.name, cpi.flags) 9095 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9096 userId = UserHandle.USER_OWNER; 9097 checkCrossUser = false; 9098 } else { 9099 cpr = null; 9100 cpi = null; 9101 } 9102 } 9103 } 9104 9105 boolean providerRunning = cpr != null; 9106 if (providerRunning) { 9107 cpi = cpr.info; 9108 String msg; 9109 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9110 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9111 != null) { 9112 throw new SecurityException(msg); 9113 } 9114 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9115 9116 if (r != null && cpr.canRunHere(r)) { 9117 // This provider has been published or is in the process 9118 // of being published... but it is also allowed to run 9119 // in the caller's process, so don't make a connection 9120 // and just let the caller instantiate its own instance. 9121 ContentProviderHolder holder = cpr.newHolder(null); 9122 // don't give caller the provider object, it needs 9123 // to make its own. 9124 holder.provider = null; 9125 return holder; 9126 } 9127 9128 final long origId = Binder.clearCallingIdentity(); 9129 9130 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9131 9132 // In this case the provider instance already exists, so we can 9133 // return it right away. 9134 conn = incProviderCountLocked(r, cpr, token, stable); 9135 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9136 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9137 // If this is a perceptible app accessing the provider, 9138 // make sure to count it as being accessed and thus 9139 // back up on the LRU list. This is good because 9140 // content providers are often expensive to start. 9141 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9142 updateLruProcessLocked(cpr.proc, false, null); 9143 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9144 } 9145 } 9146 9147 if (cpr.proc != null) { 9148 if (false) { 9149 if (cpr.name.flattenToShortString().equals( 9150 "com.android.providers.calendar/.CalendarProvider2")) { 9151 Slog.v(TAG, "****************** KILLING " 9152 + cpr.name.flattenToShortString()); 9153 Process.killProcess(cpr.proc.pid); 9154 } 9155 } 9156 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9157 boolean success = updateOomAdjLocked(cpr.proc); 9158 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9159 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9160 // NOTE: there is still a race here where a signal could be 9161 // pending on the process even though we managed to update its 9162 // adj level. Not sure what to do about this, but at least 9163 // the race is now smaller. 9164 if (!success) { 9165 // Uh oh... it looks like the provider's process 9166 // has been killed on us. We need to wait for a new 9167 // process to be started, and make sure its death 9168 // doesn't kill our process. 9169 Slog.i(TAG, 9170 "Existing provider " + cpr.name.flattenToShortString() 9171 + " is crashing; detaching " + r); 9172 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9173 checkTime(startTime, "getContentProviderImpl: before appDied"); 9174 appDiedLocked(cpr.proc); 9175 checkTime(startTime, "getContentProviderImpl: after appDied"); 9176 if (!lastRef) { 9177 // This wasn't the last ref our process had on 9178 // the provider... we have now been killed, bail. 9179 return null; 9180 } 9181 providerRunning = false; 9182 conn = null; 9183 } 9184 } 9185 9186 Binder.restoreCallingIdentity(origId); 9187 } 9188 9189 boolean singleton; 9190 if (!providerRunning) { 9191 try { 9192 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9193 cpi = AppGlobals.getPackageManager(). 9194 resolveContentProvider(name, 9195 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9196 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9197 } catch (RemoteException ex) { 9198 } 9199 if (cpi == null) { 9200 return null; 9201 } 9202 // If the provider is a singleton AND 9203 // (it's a call within the same user || the provider is a 9204 // privileged app) 9205 // Then allow connecting to the singleton provider 9206 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9207 cpi.name, cpi.flags) 9208 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9209 if (singleton) { 9210 userId = UserHandle.USER_OWNER; 9211 } 9212 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9213 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9214 9215 String msg; 9216 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9217 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9218 != null) { 9219 throw new SecurityException(msg); 9220 } 9221 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9222 9223 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9224 && !cpi.processName.equals("system")) { 9225 // If this content provider does not run in the system 9226 // process, and the system is not yet ready to run other 9227 // processes, then fail fast instead of hanging. 9228 throw new IllegalArgumentException( 9229 "Attempt to launch content provider before system ready"); 9230 } 9231 9232 // Make sure that the user who owns this provider is started. If not, 9233 // we don't want to allow it to run. 9234 if (mStartedUsers.get(userId) == null) { 9235 Slog.w(TAG, "Unable to launch app " 9236 + cpi.applicationInfo.packageName + "/" 9237 + cpi.applicationInfo.uid + " for provider " 9238 + name + ": user " + userId + " is stopped"); 9239 return null; 9240 } 9241 9242 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9243 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9244 cpr = mProviderMap.getProviderByClass(comp, userId); 9245 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9246 final boolean firstClass = cpr == null; 9247 if (firstClass) { 9248 final long ident = Binder.clearCallingIdentity(); 9249 try { 9250 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9251 ApplicationInfo ai = 9252 AppGlobals.getPackageManager(). 9253 getApplicationInfo( 9254 cpi.applicationInfo.packageName, 9255 STOCK_PM_FLAGS, userId); 9256 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9257 if (ai == null) { 9258 Slog.w(TAG, "No package info for content provider " 9259 + cpi.name); 9260 return null; 9261 } 9262 ai = getAppInfoForUser(ai, userId); 9263 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9264 } catch (RemoteException ex) { 9265 // pm is in same process, this will never happen. 9266 } finally { 9267 Binder.restoreCallingIdentity(ident); 9268 } 9269 } 9270 9271 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9272 9273 if (r != null && cpr.canRunHere(r)) { 9274 // If this is a multiprocess provider, then just return its 9275 // info and allow the caller to instantiate it. Only do 9276 // this if the provider is the same user as the caller's 9277 // process, or can run as root (so can be in any process). 9278 return cpr.newHolder(null); 9279 } 9280 9281 if (DEBUG_PROVIDER) { 9282 RuntimeException e = new RuntimeException("here"); 9283 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9284 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9285 } 9286 9287 // This is single process, and our app is now connecting to it. 9288 // See if we are already in the process of launching this 9289 // provider. 9290 final int N = mLaunchingProviders.size(); 9291 int i; 9292 for (i=0; i<N; i++) { 9293 if (mLaunchingProviders.get(i) == cpr) { 9294 break; 9295 } 9296 } 9297 9298 // If the provider is not already being launched, then get it 9299 // started. 9300 if (i >= N) { 9301 final long origId = Binder.clearCallingIdentity(); 9302 9303 try { 9304 // Content provider is now in use, its package can't be stopped. 9305 try { 9306 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9307 AppGlobals.getPackageManager().setPackageStoppedState( 9308 cpr.appInfo.packageName, false, userId); 9309 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9310 } catch (RemoteException e) { 9311 } catch (IllegalArgumentException e) { 9312 Slog.w(TAG, "Failed trying to unstop package " 9313 + cpr.appInfo.packageName + ": " + e); 9314 } 9315 9316 // Use existing process if already started 9317 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9318 ProcessRecord proc = getProcessRecordLocked( 9319 cpi.processName, cpr.appInfo.uid, false); 9320 if (proc != null && proc.thread != null) { 9321 if (DEBUG_PROVIDER) { 9322 Slog.d(TAG, "Installing in existing process " + proc); 9323 } 9324 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9325 proc.pubProviders.put(cpi.name, cpr); 9326 try { 9327 proc.thread.scheduleInstallProvider(cpi); 9328 } catch (RemoteException e) { 9329 } 9330 } else { 9331 checkTime(startTime, "getContentProviderImpl: before start process"); 9332 proc = startProcessLocked(cpi.processName, 9333 cpr.appInfo, false, 0, "content provider", 9334 new ComponentName(cpi.applicationInfo.packageName, 9335 cpi.name), false, false, false); 9336 checkTime(startTime, "getContentProviderImpl: after start process"); 9337 if (proc == null) { 9338 Slog.w(TAG, "Unable to launch app " 9339 + cpi.applicationInfo.packageName + "/" 9340 + cpi.applicationInfo.uid + " for provider " 9341 + name + ": process is bad"); 9342 return null; 9343 } 9344 } 9345 cpr.launchingApp = proc; 9346 mLaunchingProviders.add(cpr); 9347 } finally { 9348 Binder.restoreCallingIdentity(origId); 9349 } 9350 } 9351 9352 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9353 9354 // Make sure the provider is published (the same provider class 9355 // may be published under multiple names). 9356 if (firstClass) { 9357 mProviderMap.putProviderByClass(comp, cpr); 9358 } 9359 9360 mProviderMap.putProviderByName(name, cpr); 9361 conn = incProviderCountLocked(r, cpr, token, stable); 9362 if (conn != null) { 9363 conn.waiting = true; 9364 } 9365 } 9366 checkTime(startTime, "getContentProviderImpl: done!"); 9367 } 9368 9369 // Wait for the provider to be published... 9370 synchronized (cpr) { 9371 while (cpr.provider == null) { 9372 if (cpr.launchingApp == null) { 9373 Slog.w(TAG, "Unable to launch app " 9374 + cpi.applicationInfo.packageName + "/" 9375 + cpi.applicationInfo.uid + " for provider " 9376 + name + ": launching app became null"); 9377 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9378 UserHandle.getUserId(cpi.applicationInfo.uid), 9379 cpi.applicationInfo.packageName, 9380 cpi.applicationInfo.uid, name); 9381 return null; 9382 } 9383 try { 9384 if (DEBUG_MU) { 9385 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9386 + cpr.launchingApp); 9387 } 9388 if (conn != null) { 9389 conn.waiting = true; 9390 } 9391 cpr.wait(); 9392 } catch (InterruptedException ex) { 9393 } finally { 9394 if (conn != null) { 9395 conn.waiting = false; 9396 } 9397 } 9398 } 9399 } 9400 return cpr != null ? cpr.newHolder(conn) : null; 9401 } 9402 9403 @Override 9404 public final ContentProviderHolder getContentProvider( 9405 IApplicationThread caller, String name, int userId, boolean stable) { 9406 enforceNotIsolatedCaller("getContentProvider"); 9407 if (caller == null) { 9408 String msg = "null IApplicationThread when getting content provider " 9409 + name; 9410 Slog.w(TAG, msg); 9411 throw new SecurityException(msg); 9412 } 9413 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9414 // with cross-user grant. 9415 return getContentProviderImpl(caller, name, null, stable, userId); 9416 } 9417 9418 public ContentProviderHolder getContentProviderExternal( 9419 String name, int userId, IBinder token) { 9420 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9421 "Do not have permission in call getContentProviderExternal()"); 9422 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9423 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9424 return getContentProviderExternalUnchecked(name, token, userId); 9425 } 9426 9427 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9428 IBinder token, int userId) { 9429 return getContentProviderImpl(null, name, token, true, userId); 9430 } 9431 9432 /** 9433 * Drop a content provider from a ProcessRecord's bookkeeping 9434 */ 9435 public void removeContentProvider(IBinder connection, boolean stable) { 9436 enforceNotIsolatedCaller("removeContentProvider"); 9437 long ident = Binder.clearCallingIdentity(); 9438 try { 9439 synchronized (this) { 9440 ContentProviderConnection conn; 9441 try { 9442 conn = (ContentProviderConnection)connection; 9443 } catch (ClassCastException e) { 9444 String msg ="removeContentProvider: " + connection 9445 + " not a ContentProviderConnection"; 9446 Slog.w(TAG, msg); 9447 throw new IllegalArgumentException(msg); 9448 } 9449 if (conn == null) { 9450 throw new NullPointerException("connection is null"); 9451 } 9452 if (decProviderCountLocked(conn, null, null, stable)) { 9453 updateOomAdjLocked(); 9454 } 9455 } 9456 } finally { 9457 Binder.restoreCallingIdentity(ident); 9458 } 9459 } 9460 9461 public void removeContentProviderExternal(String name, IBinder token) { 9462 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9463 "Do not have permission in call removeContentProviderExternal()"); 9464 int userId = UserHandle.getCallingUserId(); 9465 long ident = Binder.clearCallingIdentity(); 9466 try { 9467 removeContentProviderExternalUnchecked(name, token, userId); 9468 } finally { 9469 Binder.restoreCallingIdentity(ident); 9470 } 9471 } 9472 9473 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9474 synchronized (this) { 9475 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9476 if(cpr == null) { 9477 //remove from mProvidersByClass 9478 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9479 return; 9480 } 9481 9482 //update content provider record entry info 9483 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9484 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9485 if (localCpr.hasExternalProcessHandles()) { 9486 if (localCpr.removeExternalProcessHandleLocked(token)) { 9487 updateOomAdjLocked(); 9488 } else { 9489 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9490 + " with no external reference for token: " 9491 + token + "."); 9492 } 9493 } else { 9494 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9495 + " with no external references."); 9496 } 9497 } 9498 } 9499 9500 public final void publishContentProviders(IApplicationThread caller, 9501 List<ContentProviderHolder> providers) { 9502 if (providers == null) { 9503 return; 9504 } 9505 9506 enforceNotIsolatedCaller("publishContentProviders"); 9507 synchronized (this) { 9508 final ProcessRecord r = getRecordForAppLocked(caller); 9509 if (DEBUG_MU) 9510 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9511 if (r == null) { 9512 throw new SecurityException( 9513 "Unable to find app for caller " + caller 9514 + " (pid=" + Binder.getCallingPid() 9515 + ") when publishing content providers"); 9516 } 9517 9518 final long origId = Binder.clearCallingIdentity(); 9519 9520 final int N = providers.size(); 9521 for (int i=0; i<N; i++) { 9522 ContentProviderHolder src = providers.get(i); 9523 if (src == null || src.info == null || src.provider == null) { 9524 continue; 9525 } 9526 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9527 if (DEBUG_MU) 9528 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9529 if (dst != null) { 9530 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9531 mProviderMap.putProviderByClass(comp, dst); 9532 String names[] = dst.info.authority.split(";"); 9533 for (int j = 0; j < names.length; j++) { 9534 mProviderMap.putProviderByName(names[j], dst); 9535 } 9536 9537 int NL = mLaunchingProviders.size(); 9538 int j; 9539 for (j=0; j<NL; j++) { 9540 if (mLaunchingProviders.get(j) == dst) { 9541 mLaunchingProviders.remove(j); 9542 j--; 9543 NL--; 9544 } 9545 } 9546 synchronized (dst) { 9547 dst.provider = src.provider; 9548 dst.proc = r; 9549 dst.notifyAll(); 9550 } 9551 updateOomAdjLocked(r); 9552 } 9553 } 9554 9555 Binder.restoreCallingIdentity(origId); 9556 } 9557 } 9558 9559 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9560 ContentProviderConnection conn; 9561 try { 9562 conn = (ContentProviderConnection)connection; 9563 } catch (ClassCastException e) { 9564 String msg ="refContentProvider: " + connection 9565 + " not a ContentProviderConnection"; 9566 Slog.w(TAG, msg); 9567 throw new IllegalArgumentException(msg); 9568 } 9569 if (conn == null) { 9570 throw new NullPointerException("connection is null"); 9571 } 9572 9573 synchronized (this) { 9574 if (stable > 0) { 9575 conn.numStableIncs += stable; 9576 } 9577 stable = conn.stableCount + stable; 9578 if (stable < 0) { 9579 throw new IllegalStateException("stableCount < 0: " + stable); 9580 } 9581 9582 if (unstable > 0) { 9583 conn.numUnstableIncs += unstable; 9584 } 9585 unstable = conn.unstableCount + unstable; 9586 if (unstable < 0) { 9587 throw new IllegalStateException("unstableCount < 0: " + unstable); 9588 } 9589 9590 if ((stable+unstable) <= 0) { 9591 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9592 + stable + " unstable=" + unstable); 9593 } 9594 conn.stableCount = stable; 9595 conn.unstableCount = unstable; 9596 return !conn.dead; 9597 } 9598 } 9599 9600 public void unstableProviderDied(IBinder connection) { 9601 ContentProviderConnection conn; 9602 try { 9603 conn = (ContentProviderConnection)connection; 9604 } catch (ClassCastException e) { 9605 String msg ="refContentProvider: " + connection 9606 + " not a ContentProviderConnection"; 9607 Slog.w(TAG, msg); 9608 throw new IllegalArgumentException(msg); 9609 } 9610 if (conn == null) { 9611 throw new NullPointerException("connection is null"); 9612 } 9613 9614 // Safely retrieve the content provider associated with the connection. 9615 IContentProvider provider; 9616 synchronized (this) { 9617 provider = conn.provider.provider; 9618 } 9619 9620 if (provider == null) { 9621 // Um, yeah, we're way ahead of you. 9622 return; 9623 } 9624 9625 // Make sure the caller is being honest with us. 9626 if (provider.asBinder().pingBinder()) { 9627 // Er, no, still looks good to us. 9628 synchronized (this) { 9629 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9630 + " says " + conn + " died, but we don't agree"); 9631 return; 9632 } 9633 } 9634 9635 // Well look at that! It's dead! 9636 synchronized (this) { 9637 if (conn.provider.provider != provider) { 9638 // But something changed... good enough. 9639 return; 9640 } 9641 9642 ProcessRecord proc = conn.provider.proc; 9643 if (proc == null || proc.thread == null) { 9644 // Seems like the process is already cleaned up. 9645 return; 9646 } 9647 9648 // As far as we're concerned, this is just like receiving a 9649 // death notification... just a bit prematurely. 9650 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9651 + ") early provider death"); 9652 final long ident = Binder.clearCallingIdentity(); 9653 try { 9654 appDiedLocked(proc); 9655 } finally { 9656 Binder.restoreCallingIdentity(ident); 9657 } 9658 } 9659 } 9660 9661 @Override 9662 public void appNotRespondingViaProvider(IBinder connection) { 9663 enforceCallingPermission( 9664 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9665 9666 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9667 if (conn == null) { 9668 Slog.w(TAG, "ContentProviderConnection is null"); 9669 return; 9670 } 9671 9672 final ProcessRecord host = conn.provider.proc; 9673 if (host == null) { 9674 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9675 return; 9676 } 9677 9678 final long token = Binder.clearCallingIdentity(); 9679 try { 9680 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9681 } finally { 9682 Binder.restoreCallingIdentity(token); 9683 } 9684 } 9685 9686 public final void installSystemProviders() { 9687 List<ProviderInfo> providers; 9688 synchronized (this) { 9689 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9690 providers = generateApplicationProvidersLocked(app); 9691 if (providers != null) { 9692 for (int i=providers.size()-1; i>=0; i--) { 9693 ProviderInfo pi = (ProviderInfo)providers.get(i); 9694 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9695 Slog.w(TAG, "Not installing system proc provider " + pi.name 9696 + ": not system .apk"); 9697 providers.remove(i); 9698 } 9699 } 9700 } 9701 } 9702 if (providers != null) { 9703 mSystemThread.installSystemProviders(providers); 9704 } 9705 9706 mCoreSettingsObserver = new CoreSettingsObserver(this); 9707 9708 //mUsageStatsService.monitorPackages(); 9709 } 9710 9711 /** 9712 * Allows apps to retrieve the MIME type of a URI. 9713 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9714 * users, then it does not need permission to access the ContentProvider. 9715 * Either, it needs cross-user uri grants. 9716 * 9717 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9718 * 9719 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9720 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9721 */ 9722 public String getProviderMimeType(Uri uri, int userId) { 9723 enforceNotIsolatedCaller("getProviderMimeType"); 9724 final String name = uri.getAuthority(); 9725 int callingUid = Binder.getCallingUid(); 9726 int callingPid = Binder.getCallingPid(); 9727 long ident = 0; 9728 boolean clearedIdentity = false; 9729 userId = unsafeConvertIncomingUser(userId); 9730 if (canClearIdentity(callingPid, callingUid, userId)) { 9731 clearedIdentity = true; 9732 ident = Binder.clearCallingIdentity(); 9733 } 9734 ContentProviderHolder holder = null; 9735 try { 9736 holder = getContentProviderExternalUnchecked(name, null, userId); 9737 if (holder != null) { 9738 return holder.provider.getType(uri); 9739 } 9740 } catch (RemoteException e) { 9741 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9742 return null; 9743 } finally { 9744 // We need to clear the identity to call removeContentProviderExternalUnchecked 9745 if (!clearedIdentity) { 9746 ident = Binder.clearCallingIdentity(); 9747 } 9748 try { 9749 if (holder != null) { 9750 removeContentProviderExternalUnchecked(name, null, userId); 9751 } 9752 } finally { 9753 Binder.restoreCallingIdentity(ident); 9754 } 9755 } 9756 9757 return null; 9758 } 9759 9760 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9761 if (UserHandle.getUserId(callingUid) == userId) { 9762 return true; 9763 } 9764 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9765 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9766 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9767 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9768 return true; 9769 } 9770 return false; 9771 } 9772 9773 // ========================================================= 9774 // GLOBAL MANAGEMENT 9775 // ========================================================= 9776 9777 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9778 boolean isolated, int isolatedUid) { 9779 String proc = customProcess != null ? customProcess : info.processName; 9780 BatteryStatsImpl.Uid.Proc ps = null; 9781 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9782 int uid = info.uid; 9783 if (isolated) { 9784 if (isolatedUid == 0) { 9785 int userId = UserHandle.getUserId(uid); 9786 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9787 while (true) { 9788 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9789 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9790 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9791 } 9792 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9793 mNextIsolatedProcessUid++; 9794 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9795 // No process for this uid, use it. 9796 break; 9797 } 9798 stepsLeft--; 9799 if (stepsLeft <= 0) { 9800 return null; 9801 } 9802 } 9803 } else { 9804 // Special case for startIsolatedProcess (internal only), where 9805 // the uid of the isolated process is specified by the caller. 9806 uid = isolatedUid; 9807 } 9808 } 9809 return new ProcessRecord(stats, info, proc, uid); 9810 } 9811 9812 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9813 String abiOverride) { 9814 ProcessRecord app; 9815 if (!isolated) { 9816 app = getProcessRecordLocked(info.processName, info.uid, true); 9817 } else { 9818 app = null; 9819 } 9820 9821 if (app == null) { 9822 app = newProcessRecordLocked(info, null, isolated, 0); 9823 mProcessNames.put(info.processName, app.uid, app); 9824 if (isolated) { 9825 mIsolatedProcesses.put(app.uid, app); 9826 } 9827 updateLruProcessLocked(app, false, null); 9828 updateOomAdjLocked(); 9829 } 9830 9831 // This package really, really can not be stopped. 9832 try { 9833 AppGlobals.getPackageManager().setPackageStoppedState( 9834 info.packageName, false, UserHandle.getUserId(app.uid)); 9835 } catch (RemoteException e) { 9836 } catch (IllegalArgumentException e) { 9837 Slog.w(TAG, "Failed trying to unstop package " 9838 + info.packageName + ": " + e); 9839 } 9840 9841 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9842 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9843 app.persistent = true; 9844 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9845 } 9846 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9847 mPersistentStartingProcesses.add(app); 9848 startProcessLocked(app, "added application", app.processName, abiOverride, 9849 null /* entryPoint */, null /* entryPointArgs */); 9850 } 9851 9852 return app; 9853 } 9854 9855 public void unhandledBack() { 9856 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9857 "unhandledBack()"); 9858 9859 synchronized(this) { 9860 final long origId = Binder.clearCallingIdentity(); 9861 try { 9862 getFocusedStack().unhandledBackLocked(); 9863 } finally { 9864 Binder.restoreCallingIdentity(origId); 9865 } 9866 } 9867 } 9868 9869 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9870 enforceNotIsolatedCaller("openContentUri"); 9871 final int userId = UserHandle.getCallingUserId(); 9872 String name = uri.getAuthority(); 9873 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9874 ParcelFileDescriptor pfd = null; 9875 if (cph != null) { 9876 // We record the binder invoker's uid in thread-local storage before 9877 // going to the content provider to open the file. Later, in the code 9878 // that handles all permissions checks, we look for this uid and use 9879 // that rather than the Activity Manager's own uid. The effect is that 9880 // we do the check against the caller's permissions even though it looks 9881 // to the content provider like the Activity Manager itself is making 9882 // the request. 9883 sCallerIdentity.set(new Identity( 9884 Binder.getCallingPid(), Binder.getCallingUid())); 9885 try { 9886 pfd = cph.provider.openFile(null, uri, "r", null); 9887 } catch (FileNotFoundException e) { 9888 // do nothing; pfd will be returned null 9889 } finally { 9890 // Ensure that whatever happens, we clean up the identity state 9891 sCallerIdentity.remove(); 9892 } 9893 9894 // We've got the fd now, so we're done with the provider. 9895 removeContentProviderExternalUnchecked(name, null, userId); 9896 } else { 9897 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9898 } 9899 return pfd; 9900 } 9901 9902 // Actually is sleeping or shutting down or whatever else in the future 9903 // is an inactive state. 9904 public boolean isSleepingOrShuttingDown() { 9905 return isSleeping() || mShuttingDown; 9906 } 9907 9908 public boolean isSleeping() { 9909 return mSleeping; 9910 } 9911 9912 void goingToSleep() { 9913 synchronized(this) { 9914 mWentToSleep = true; 9915 goToSleepIfNeededLocked(); 9916 } 9917 } 9918 9919 void finishRunningVoiceLocked() { 9920 if (mRunningVoice) { 9921 mRunningVoice = false; 9922 goToSleepIfNeededLocked(); 9923 } 9924 } 9925 9926 void goToSleepIfNeededLocked() { 9927 if (mWentToSleep && !mRunningVoice) { 9928 if (!mSleeping) { 9929 mSleeping = true; 9930 mStackSupervisor.goingToSleepLocked(); 9931 9932 // Initialize the wake times of all processes. 9933 checkExcessivePowerUsageLocked(false); 9934 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9935 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9936 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9937 } 9938 } 9939 } 9940 9941 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9942 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9943 // Never persist the home stack. 9944 return; 9945 } 9946 mTaskPersister.wakeup(task, flush); 9947 } 9948 9949 @Override 9950 public boolean shutdown(int timeout) { 9951 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9952 != PackageManager.PERMISSION_GRANTED) { 9953 throw new SecurityException("Requires permission " 9954 + android.Manifest.permission.SHUTDOWN); 9955 } 9956 9957 boolean timedout = false; 9958 9959 synchronized(this) { 9960 mShuttingDown = true; 9961 updateEventDispatchingLocked(); 9962 timedout = mStackSupervisor.shutdownLocked(timeout); 9963 } 9964 9965 mAppOpsService.shutdown(); 9966 if (mUsageStatsService != null) { 9967 mUsageStatsService.prepareShutdown(); 9968 } 9969 mBatteryStatsService.shutdown(); 9970 synchronized (this) { 9971 mProcessStats.shutdownLocked(); 9972 } 9973 notifyTaskPersisterLocked(null, true); 9974 9975 return timedout; 9976 } 9977 9978 public final void activitySlept(IBinder token) { 9979 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9980 9981 final long origId = Binder.clearCallingIdentity(); 9982 9983 synchronized (this) { 9984 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9985 if (r != null) { 9986 mStackSupervisor.activitySleptLocked(r); 9987 } 9988 } 9989 9990 Binder.restoreCallingIdentity(origId); 9991 } 9992 9993 private String lockScreenShownToString() { 9994 switch (mLockScreenShown) { 9995 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9996 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9997 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9998 default: return "Unknown=" + mLockScreenShown; 9999 } 10000 } 10001 10002 void logLockScreen(String msg) { 10003 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10004 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10005 mWentToSleep + " mSleeping=" + mSleeping); 10006 } 10007 10008 void comeOutOfSleepIfNeededLocked() { 10009 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10010 if (mSleeping) { 10011 mSleeping = false; 10012 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10013 } 10014 } 10015 } 10016 10017 void wakingUp() { 10018 synchronized(this) { 10019 mWentToSleep = false; 10020 comeOutOfSleepIfNeededLocked(); 10021 } 10022 } 10023 10024 void startRunningVoiceLocked() { 10025 if (!mRunningVoice) { 10026 mRunningVoice = true; 10027 comeOutOfSleepIfNeededLocked(); 10028 } 10029 } 10030 10031 private void updateEventDispatchingLocked() { 10032 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10033 } 10034 10035 public void setLockScreenShown(boolean shown) { 10036 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10037 != PackageManager.PERMISSION_GRANTED) { 10038 throw new SecurityException("Requires permission " 10039 + android.Manifest.permission.DEVICE_POWER); 10040 } 10041 10042 synchronized(this) { 10043 long ident = Binder.clearCallingIdentity(); 10044 try { 10045 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10046 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10047 comeOutOfSleepIfNeededLocked(); 10048 } finally { 10049 Binder.restoreCallingIdentity(ident); 10050 } 10051 } 10052 } 10053 10054 @Override 10055 public void stopAppSwitches() { 10056 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10057 != PackageManager.PERMISSION_GRANTED) { 10058 throw new SecurityException("Requires permission " 10059 + android.Manifest.permission.STOP_APP_SWITCHES); 10060 } 10061 10062 synchronized(this) { 10063 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10064 + APP_SWITCH_DELAY_TIME; 10065 mDidAppSwitch = false; 10066 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10067 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10068 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10069 } 10070 } 10071 10072 public void resumeAppSwitches() { 10073 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10074 != PackageManager.PERMISSION_GRANTED) { 10075 throw new SecurityException("Requires permission " 10076 + android.Manifest.permission.STOP_APP_SWITCHES); 10077 } 10078 10079 synchronized(this) { 10080 // Note that we don't execute any pending app switches... we will 10081 // let those wait until either the timeout, or the next start 10082 // activity request. 10083 mAppSwitchesAllowedTime = 0; 10084 } 10085 } 10086 10087 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10088 int callingPid, int callingUid, String name) { 10089 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10090 return true; 10091 } 10092 10093 int perm = checkComponentPermission( 10094 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10095 sourceUid, -1, true); 10096 if (perm == PackageManager.PERMISSION_GRANTED) { 10097 return true; 10098 } 10099 10100 // If the actual IPC caller is different from the logical source, then 10101 // also see if they are allowed to control app switches. 10102 if (callingUid != -1 && callingUid != sourceUid) { 10103 perm = checkComponentPermission( 10104 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10105 callingUid, -1, true); 10106 if (perm == PackageManager.PERMISSION_GRANTED) { 10107 return true; 10108 } 10109 } 10110 10111 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10112 return false; 10113 } 10114 10115 public void setDebugApp(String packageName, boolean waitForDebugger, 10116 boolean persistent) { 10117 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10118 "setDebugApp()"); 10119 10120 long ident = Binder.clearCallingIdentity(); 10121 try { 10122 // Note that this is not really thread safe if there are multiple 10123 // callers into it at the same time, but that's not a situation we 10124 // care about. 10125 if (persistent) { 10126 final ContentResolver resolver = mContext.getContentResolver(); 10127 Settings.Global.putString( 10128 resolver, Settings.Global.DEBUG_APP, 10129 packageName); 10130 Settings.Global.putInt( 10131 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10132 waitForDebugger ? 1 : 0); 10133 } 10134 10135 synchronized (this) { 10136 if (!persistent) { 10137 mOrigDebugApp = mDebugApp; 10138 mOrigWaitForDebugger = mWaitForDebugger; 10139 } 10140 mDebugApp = packageName; 10141 mWaitForDebugger = waitForDebugger; 10142 mDebugTransient = !persistent; 10143 if (packageName != null) { 10144 forceStopPackageLocked(packageName, -1, false, false, true, true, 10145 false, UserHandle.USER_ALL, "set debug app"); 10146 } 10147 } 10148 } finally { 10149 Binder.restoreCallingIdentity(ident); 10150 } 10151 } 10152 10153 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10154 synchronized (this) { 10155 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10156 if (!isDebuggable) { 10157 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10158 throw new SecurityException("Process not debuggable: " + app.packageName); 10159 } 10160 } 10161 10162 mOpenGlTraceApp = processName; 10163 } 10164 } 10165 10166 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10167 synchronized (this) { 10168 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10169 if (!isDebuggable) { 10170 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10171 throw new SecurityException("Process not debuggable: " + app.packageName); 10172 } 10173 } 10174 mProfileApp = processName; 10175 mProfileFile = profilerInfo.profileFile; 10176 if (mProfileFd != null) { 10177 try { 10178 mProfileFd.close(); 10179 } catch (IOException e) { 10180 } 10181 mProfileFd = null; 10182 } 10183 mProfileFd = profilerInfo.profileFd; 10184 mSamplingInterval = profilerInfo.samplingInterval; 10185 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10186 mProfileType = 0; 10187 } 10188 } 10189 10190 @Override 10191 public void setAlwaysFinish(boolean enabled) { 10192 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10193 "setAlwaysFinish()"); 10194 10195 Settings.Global.putInt( 10196 mContext.getContentResolver(), 10197 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10198 10199 synchronized (this) { 10200 mAlwaysFinishActivities = enabled; 10201 } 10202 } 10203 10204 @Override 10205 public void setActivityController(IActivityController controller) { 10206 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10207 "setActivityController()"); 10208 synchronized (this) { 10209 mController = controller; 10210 Watchdog.getInstance().setActivityController(controller); 10211 } 10212 } 10213 10214 @Override 10215 public void setUserIsMonkey(boolean userIsMonkey) { 10216 synchronized (this) { 10217 synchronized (mPidsSelfLocked) { 10218 final int callingPid = Binder.getCallingPid(); 10219 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10220 if (precessRecord == null) { 10221 throw new SecurityException("Unknown process: " + callingPid); 10222 } 10223 if (precessRecord.instrumentationUiAutomationConnection == null) { 10224 throw new SecurityException("Only an instrumentation process " 10225 + "with a UiAutomation can call setUserIsMonkey"); 10226 } 10227 } 10228 mUserIsMonkey = userIsMonkey; 10229 } 10230 } 10231 10232 @Override 10233 public boolean isUserAMonkey() { 10234 synchronized (this) { 10235 // If there is a controller also implies the user is a monkey. 10236 return (mUserIsMonkey || mController != null); 10237 } 10238 } 10239 10240 public void requestBugReport() { 10241 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10242 SystemProperties.set("ctl.start", "bugreport"); 10243 } 10244 10245 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10246 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10247 } 10248 10249 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10250 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10251 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10252 } 10253 return KEY_DISPATCHING_TIMEOUT; 10254 } 10255 10256 @Override 10257 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10258 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10259 != PackageManager.PERMISSION_GRANTED) { 10260 throw new SecurityException("Requires permission " 10261 + android.Manifest.permission.FILTER_EVENTS); 10262 } 10263 ProcessRecord proc; 10264 long timeout; 10265 synchronized (this) { 10266 synchronized (mPidsSelfLocked) { 10267 proc = mPidsSelfLocked.get(pid); 10268 } 10269 timeout = getInputDispatchingTimeoutLocked(proc); 10270 } 10271 10272 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10273 return -1; 10274 } 10275 10276 return timeout; 10277 } 10278 10279 /** 10280 * Handle input dispatching timeouts. 10281 * Returns whether input dispatching should be aborted or not. 10282 */ 10283 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10284 final ActivityRecord activity, final ActivityRecord parent, 10285 final boolean aboveSystem, String reason) { 10286 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10287 != PackageManager.PERMISSION_GRANTED) { 10288 throw new SecurityException("Requires permission " 10289 + android.Manifest.permission.FILTER_EVENTS); 10290 } 10291 10292 final String annotation; 10293 if (reason == null) { 10294 annotation = "Input dispatching timed out"; 10295 } else { 10296 annotation = "Input dispatching timed out (" + reason + ")"; 10297 } 10298 10299 if (proc != null) { 10300 synchronized (this) { 10301 if (proc.debugging) { 10302 return false; 10303 } 10304 10305 if (mDidDexOpt) { 10306 // Give more time since we were dexopting. 10307 mDidDexOpt = false; 10308 return false; 10309 } 10310 10311 if (proc.instrumentationClass != null) { 10312 Bundle info = new Bundle(); 10313 info.putString("shortMsg", "keyDispatchingTimedOut"); 10314 info.putString("longMsg", annotation); 10315 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10316 return true; 10317 } 10318 } 10319 mHandler.post(new Runnable() { 10320 @Override 10321 public void run() { 10322 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10323 } 10324 }); 10325 } 10326 10327 return true; 10328 } 10329 10330 public Bundle getAssistContextExtras(int requestType) { 10331 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10332 UserHandle.getCallingUserId()); 10333 if (pae == null) { 10334 return null; 10335 } 10336 synchronized (pae) { 10337 while (!pae.haveResult) { 10338 try { 10339 pae.wait(); 10340 } catch (InterruptedException e) { 10341 } 10342 } 10343 if (pae.result != null) { 10344 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10345 } 10346 } 10347 synchronized (this) { 10348 mPendingAssistExtras.remove(pae); 10349 mHandler.removeCallbacks(pae); 10350 } 10351 return pae.extras; 10352 } 10353 10354 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10355 int userHandle) { 10356 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10357 "getAssistContextExtras()"); 10358 PendingAssistExtras pae; 10359 Bundle extras = new Bundle(); 10360 synchronized (this) { 10361 ActivityRecord activity = getFocusedStack().mResumedActivity; 10362 if (activity == null) { 10363 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10364 return null; 10365 } 10366 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10367 if (activity.app == null || activity.app.thread == null) { 10368 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10369 return null; 10370 } 10371 if (activity.app.pid == Binder.getCallingPid()) { 10372 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10373 return null; 10374 } 10375 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10376 try { 10377 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10378 requestType); 10379 mPendingAssistExtras.add(pae); 10380 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10381 } catch (RemoteException e) { 10382 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10383 return null; 10384 } 10385 return pae; 10386 } 10387 } 10388 10389 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10390 PendingAssistExtras pae = (PendingAssistExtras)token; 10391 synchronized (pae) { 10392 pae.result = extras; 10393 pae.haveResult = true; 10394 pae.notifyAll(); 10395 if (pae.intent == null) { 10396 // Caller is just waiting for the result. 10397 return; 10398 } 10399 } 10400 10401 // We are now ready to launch the assist activity. 10402 synchronized (this) { 10403 boolean exists = mPendingAssistExtras.remove(pae); 10404 mHandler.removeCallbacks(pae); 10405 if (!exists) { 10406 // Timed out. 10407 return; 10408 } 10409 } 10410 pae.intent.replaceExtras(extras); 10411 if (pae.hint != null) { 10412 pae.intent.putExtra(pae.hint, true); 10413 } 10414 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10415 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10416 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10417 closeSystemDialogs("assist"); 10418 try { 10419 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10420 } catch (ActivityNotFoundException e) { 10421 Slog.w(TAG, "No activity to handle assist action.", e); 10422 } 10423 } 10424 10425 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10426 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10427 } 10428 10429 public void registerProcessObserver(IProcessObserver observer) { 10430 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10431 "registerProcessObserver()"); 10432 synchronized (this) { 10433 mProcessObservers.register(observer); 10434 } 10435 } 10436 10437 @Override 10438 public void unregisterProcessObserver(IProcessObserver observer) { 10439 synchronized (this) { 10440 mProcessObservers.unregister(observer); 10441 } 10442 } 10443 10444 @Override 10445 public boolean convertFromTranslucent(IBinder token) { 10446 final long origId = Binder.clearCallingIdentity(); 10447 try { 10448 synchronized (this) { 10449 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10450 if (r == null) { 10451 return false; 10452 } 10453 final boolean translucentChanged = r.changeWindowTranslucency(true); 10454 if (translucentChanged) { 10455 r.task.stack.releaseBackgroundResources(); 10456 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10457 } 10458 mWindowManager.setAppFullscreen(token, true); 10459 return translucentChanged; 10460 } 10461 } finally { 10462 Binder.restoreCallingIdentity(origId); 10463 } 10464 } 10465 10466 @Override 10467 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10468 final long origId = Binder.clearCallingIdentity(); 10469 try { 10470 synchronized (this) { 10471 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10472 if (r == null) { 10473 return false; 10474 } 10475 int index = r.task.mActivities.lastIndexOf(r); 10476 if (index > 0) { 10477 ActivityRecord under = r.task.mActivities.get(index - 1); 10478 under.returningOptions = options; 10479 } 10480 final boolean translucentChanged = r.changeWindowTranslucency(false); 10481 if (translucentChanged) { 10482 r.task.stack.convertToTranslucent(r); 10483 } 10484 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10485 mWindowManager.setAppFullscreen(token, false); 10486 return translucentChanged; 10487 } 10488 } finally { 10489 Binder.restoreCallingIdentity(origId); 10490 } 10491 } 10492 10493 @Override 10494 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10495 final long origId = Binder.clearCallingIdentity(); 10496 try { 10497 synchronized (this) { 10498 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10499 if (r != null) { 10500 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10501 } 10502 } 10503 return false; 10504 } finally { 10505 Binder.restoreCallingIdentity(origId); 10506 } 10507 } 10508 10509 @Override 10510 public boolean isBackgroundVisibleBehind(IBinder token) { 10511 final long origId = Binder.clearCallingIdentity(); 10512 try { 10513 synchronized (this) { 10514 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10515 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10516 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10517 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10518 return visible; 10519 } 10520 } finally { 10521 Binder.restoreCallingIdentity(origId); 10522 } 10523 } 10524 10525 @Override 10526 public ActivityOptions getActivityOptions(IBinder token) { 10527 final long origId = Binder.clearCallingIdentity(); 10528 try { 10529 synchronized (this) { 10530 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10531 if (r != null) { 10532 final ActivityOptions activityOptions = r.pendingOptions; 10533 r.pendingOptions = null; 10534 return activityOptions; 10535 } 10536 return null; 10537 } 10538 } finally { 10539 Binder.restoreCallingIdentity(origId); 10540 } 10541 } 10542 10543 @Override 10544 public void setImmersive(IBinder token, boolean immersive) { 10545 synchronized(this) { 10546 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10547 if (r == null) { 10548 throw new IllegalArgumentException(); 10549 } 10550 r.immersive = immersive; 10551 10552 // update associated state if we're frontmost 10553 if (r == mFocusedActivity) { 10554 if (DEBUG_IMMERSIVE) { 10555 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10556 } 10557 applyUpdateLockStateLocked(r); 10558 } 10559 } 10560 } 10561 10562 @Override 10563 public boolean isImmersive(IBinder token) { 10564 synchronized (this) { 10565 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10566 if (r == null) { 10567 throw new IllegalArgumentException(); 10568 } 10569 return r.immersive; 10570 } 10571 } 10572 10573 public boolean isTopActivityImmersive() { 10574 enforceNotIsolatedCaller("startActivity"); 10575 synchronized (this) { 10576 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10577 return (r != null) ? r.immersive : false; 10578 } 10579 } 10580 10581 @Override 10582 public boolean isTopOfTask(IBinder token) { 10583 synchronized (this) { 10584 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10585 if (r == null) { 10586 throw new IllegalArgumentException(); 10587 } 10588 return r.task.getTopActivity() == r; 10589 } 10590 } 10591 10592 public final void enterSafeMode() { 10593 synchronized(this) { 10594 // It only makes sense to do this before the system is ready 10595 // and started launching other packages. 10596 if (!mSystemReady) { 10597 try { 10598 AppGlobals.getPackageManager().enterSafeMode(); 10599 } catch (RemoteException e) { 10600 } 10601 } 10602 10603 mSafeMode = true; 10604 } 10605 } 10606 10607 public final void showSafeModeOverlay() { 10608 View v = LayoutInflater.from(mContext).inflate( 10609 com.android.internal.R.layout.safe_mode, null); 10610 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10611 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10612 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10613 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10614 lp.gravity = Gravity.BOTTOM | Gravity.START; 10615 lp.format = v.getBackground().getOpacity(); 10616 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10617 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10618 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10619 ((WindowManager)mContext.getSystemService( 10620 Context.WINDOW_SERVICE)).addView(v, lp); 10621 } 10622 10623 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10624 if (!(sender instanceof PendingIntentRecord)) { 10625 return; 10626 } 10627 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10628 synchronized (stats) { 10629 if (mBatteryStatsService.isOnBattery()) { 10630 mBatteryStatsService.enforceCallingPermission(); 10631 PendingIntentRecord rec = (PendingIntentRecord)sender; 10632 int MY_UID = Binder.getCallingUid(); 10633 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10634 BatteryStatsImpl.Uid.Pkg pkg = 10635 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10636 sourcePkg != null ? sourcePkg : rec.key.packageName); 10637 pkg.incWakeupsLocked(); 10638 } 10639 } 10640 } 10641 10642 public boolean killPids(int[] pids, String pReason, boolean secure) { 10643 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10644 throw new SecurityException("killPids only available to the system"); 10645 } 10646 String reason = (pReason == null) ? "Unknown" : pReason; 10647 // XXX Note: don't acquire main activity lock here, because the window 10648 // manager calls in with its locks held. 10649 10650 boolean killed = false; 10651 synchronized (mPidsSelfLocked) { 10652 int[] types = new int[pids.length]; 10653 int worstType = 0; 10654 for (int i=0; i<pids.length; i++) { 10655 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10656 if (proc != null) { 10657 int type = proc.setAdj; 10658 types[i] = type; 10659 if (type > worstType) { 10660 worstType = type; 10661 } 10662 } 10663 } 10664 10665 // If the worst oom_adj is somewhere in the cached proc LRU range, 10666 // then constrain it so we will kill all cached procs. 10667 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10668 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10669 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10670 } 10671 10672 // If this is not a secure call, don't let it kill processes that 10673 // are important. 10674 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10675 worstType = ProcessList.SERVICE_ADJ; 10676 } 10677 10678 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10679 for (int i=0; i<pids.length; i++) { 10680 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10681 if (proc == null) { 10682 continue; 10683 } 10684 int adj = proc.setAdj; 10685 if (adj >= worstType && !proc.killedByAm) { 10686 proc.kill(reason, true); 10687 killed = true; 10688 } 10689 } 10690 } 10691 return killed; 10692 } 10693 10694 @Override 10695 public void killUid(int uid, String reason) { 10696 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10697 throw new SecurityException("killUid only available to the system"); 10698 } 10699 synchronized (this) { 10700 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10701 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10702 reason != null ? reason : "kill uid"); 10703 } 10704 } 10705 10706 @Override 10707 public boolean killProcessesBelowForeground(String reason) { 10708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10709 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10710 } 10711 10712 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10713 } 10714 10715 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10716 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10717 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10718 } 10719 10720 boolean killed = false; 10721 synchronized (mPidsSelfLocked) { 10722 final int size = mPidsSelfLocked.size(); 10723 for (int i = 0; i < size; i++) { 10724 final int pid = mPidsSelfLocked.keyAt(i); 10725 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10726 if (proc == null) continue; 10727 10728 final int adj = proc.setAdj; 10729 if (adj > belowAdj && !proc.killedByAm) { 10730 proc.kill(reason, true); 10731 killed = true; 10732 } 10733 } 10734 } 10735 return killed; 10736 } 10737 10738 @Override 10739 public void hang(final IBinder who, boolean allowRestart) { 10740 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10741 != PackageManager.PERMISSION_GRANTED) { 10742 throw new SecurityException("Requires permission " 10743 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10744 } 10745 10746 final IBinder.DeathRecipient death = new DeathRecipient() { 10747 @Override 10748 public void binderDied() { 10749 synchronized (this) { 10750 notifyAll(); 10751 } 10752 } 10753 }; 10754 10755 try { 10756 who.linkToDeath(death, 0); 10757 } catch (RemoteException e) { 10758 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10759 return; 10760 } 10761 10762 synchronized (this) { 10763 Watchdog.getInstance().setAllowRestart(allowRestart); 10764 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10765 synchronized (death) { 10766 while (who.isBinderAlive()) { 10767 try { 10768 death.wait(); 10769 } catch (InterruptedException e) { 10770 } 10771 } 10772 } 10773 Watchdog.getInstance().setAllowRestart(true); 10774 } 10775 } 10776 10777 @Override 10778 public void restart() { 10779 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10780 != PackageManager.PERMISSION_GRANTED) { 10781 throw new SecurityException("Requires permission " 10782 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10783 } 10784 10785 Log.i(TAG, "Sending shutdown broadcast..."); 10786 10787 BroadcastReceiver br = new BroadcastReceiver() { 10788 @Override public void onReceive(Context context, Intent intent) { 10789 // Now the broadcast is done, finish up the low-level shutdown. 10790 Log.i(TAG, "Shutting down activity manager..."); 10791 shutdown(10000); 10792 Log.i(TAG, "Shutdown complete, restarting!"); 10793 Process.killProcess(Process.myPid()); 10794 System.exit(10); 10795 } 10796 }; 10797 10798 // First send the high-level shut down broadcast. 10799 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10800 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10801 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10802 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10803 mContext.sendOrderedBroadcastAsUser(intent, 10804 UserHandle.ALL, null, br, mHandler, 0, null, null); 10805 */ 10806 br.onReceive(mContext, intent); 10807 } 10808 10809 private long getLowRamTimeSinceIdle(long now) { 10810 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10811 } 10812 10813 @Override 10814 public void performIdleMaintenance() { 10815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10816 != PackageManager.PERMISSION_GRANTED) { 10817 throw new SecurityException("Requires permission " 10818 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10819 } 10820 10821 synchronized (this) { 10822 final long now = SystemClock.uptimeMillis(); 10823 final long timeSinceLastIdle = now - mLastIdleTime; 10824 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10825 mLastIdleTime = now; 10826 mLowRamTimeSinceLastIdle = 0; 10827 if (mLowRamStartTime != 0) { 10828 mLowRamStartTime = now; 10829 } 10830 10831 StringBuilder sb = new StringBuilder(128); 10832 sb.append("Idle maintenance over "); 10833 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10834 sb.append(" low RAM for "); 10835 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10836 Slog.i(TAG, sb.toString()); 10837 10838 // If at least 1/3 of our time since the last idle period has been spent 10839 // with RAM low, then we want to kill processes. 10840 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10841 10842 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10843 ProcessRecord proc = mLruProcesses.get(i); 10844 if (proc.notCachedSinceIdle) { 10845 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10846 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10847 if (doKilling && proc.initialIdlePss != 0 10848 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10849 proc.kill("idle maint (pss " + proc.lastPss 10850 + " from " + proc.initialIdlePss + ")", true); 10851 } 10852 } 10853 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10854 proc.notCachedSinceIdle = true; 10855 proc.initialIdlePss = 0; 10856 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10857 isSleeping(), now); 10858 } 10859 } 10860 10861 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10862 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10863 } 10864 } 10865 10866 private void retrieveSettings() { 10867 final ContentResolver resolver = mContext.getContentResolver(); 10868 String debugApp = Settings.Global.getString( 10869 resolver, Settings.Global.DEBUG_APP); 10870 boolean waitForDebugger = Settings.Global.getInt( 10871 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10872 boolean alwaysFinishActivities = Settings.Global.getInt( 10873 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10874 boolean forceRtl = Settings.Global.getInt( 10875 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10876 // Transfer any global setting for forcing RTL layout, into a System Property 10877 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10878 10879 Configuration configuration = new Configuration(); 10880 Settings.System.getConfiguration(resolver, configuration); 10881 if (forceRtl) { 10882 // This will take care of setting the correct layout direction flags 10883 configuration.setLayoutDirection(configuration.locale); 10884 } 10885 10886 synchronized (this) { 10887 mDebugApp = mOrigDebugApp = debugApp; 10888 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10889 mAlwaysFinishActivities = alwaysFinishActivities; 10890 // This happens before any activities are started, so we can 10891 // change mConfiguration in-place. 10892 updateConfigurationLocked(configuration, null, false, true); 10893 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10894 } 10895 } 10896 10897 /** Loads resources after the current configuration has been set. */ 10898 private void loadResourcesOnSystemReady() { 10899 final Resources res = mContext.getResources(); 10900 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10901 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10902 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10903 } 10904 10905 public boolean testIsSystemReady() { 10906 // no need to synchronize(this) just to read & return the value 10907 return mSystemReady; 10908 } 10909 10910 private static File getCalledPreBootReceiversFile() { 10911 File dataDir = Environment.getDataDirectory(); 10912 File systemDir = new File(dataDir, "system"); 10913 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10914 return fname; 10915 } 10916 10917 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10918 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10919 File file = getCalledPreBootReceiversFile(); 10920 FileInputStream fis = null; 10921 try { 10922 fis = new FileInputStream(file); 10923 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10924 int fvers = dis.readInt(); 10925 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10926 String vers = dis.readUTF(); 10927 String codename = dis.readUTF(); 10928 String build = dis.readUTF(); 10929 if (android.os.Build.VERSION.RELEASE.equals(vers) 10930 && android.os.Build.VERSION.CODENAME.equals(codename) 10931 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10932 int num = dis.readInt(); 10933 while (num > 0) { 10934 num--; 10935 String pkg = dis.readUTF(); 10936 String cls = dis.readUTF(); 10937 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10938 } 10939 } 10940 } 10941 } catch (FileNotFoundException e) { 10942 } catch (IOException e) { 10943 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10944 } finally { 10945 if (fis != null) { 10946 try { 10947 fis.close(); 10948 } catch (IOException e) { 10949 } 10950 } 10951 } 10952 return lastDoneReceivers; 10953 } 10954 10955 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10956 File file = getCalledPreBootReceiversFile(); 10957 FileOutputStream fos = null; 10958 DataOutputStream dos = null; 10959 try { 10960 fos = new FileOutputStream(file); 10961 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10962 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10963 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10964 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10965 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10966 dos.writeInt(list.size()); 10967 for (int i=0; i<list.size(); i++) { 10968 dos.writeUTF(list.get(i).getPackageName()); 10969 dos.writeUTF(list.get(i).getClassName()); 10970 } 10971 } catch (IOException e) { 10972 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10973 file.delete(); 10974 } finally { 10975 FileUtils.sync(fos); 10976 if (dos != null) { 10977 try { 10978 dos.close(); 10979 } catch (IOException e) { 10980 // TODO Auto-generated catch block 10981 e.printStackTrace(); 10982 } 10983 } 10984 } 10985 } 10986 10987 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10988 ArrayList<ComponentName> doneReceivers, int userId) { 10989 boolean waitingUpdate = false; 10990 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10991 List<ResolveInfo> ris = null; 10992 try { 10993 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10994 intent, null, 0, userId); 10995 } catch (RemoteException e) { 10996 } 10997 if (ris != null) { 10998 for (int i=ris.size()-1; i>=0; i--) { 10999 if ((ris.get(i).activityInfo.applicationInfo.flags 11000 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11001 ris.remove(i); 11002 } 11003 } 11004 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11005 11006 // For User 0, load the version number. When delivering to a new user, deliver 11007 // to all receivers. 11008 if (userId == UserHandle.USER_OWNER) { 11009 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11010 for (int i=0; i<ris.size(); i++) { 11011 ActivityInfo ai = ris.get(i).activityInfo; 11012 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11013 if (lastDoneReceivers.contains(comp)) { 11014 // We already did the pre boot receiver for this app with the current 11015 // platform version, so don't do it again... 11016 ris.remove(i); 11017 i--; 11018 // ...however, do keep it as one that has been done, so we don't 11019 // forget about it when rewriting the file of last done receivers. 11020 doneReceivers.add(comp); 11021 } 11022 } 11023 } 11024 11025 // If primary user, send broadcast to all available users, else just to userId 11026 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11027 : new int[] { userId }; 11028 for (int i = 0; i < ris.size(); i++) { 11029 ActivityInfo ai = ris.get(i).activityInfo; 11030 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11031 doneReceivers.add(comp); 11032 intent.setComponent(comp); 11033 for (int j=0; j<users.length; j++) { 11034 IIntentReceiver finisher = null; 11035 // On last receiver and user, set up a completion callback 11036 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11037 finisher = new IIntentReceiver.Stub() { 11038 public void performReceive(Intent intent, int resultCode, 11039 String data, Bundle extras, boolean ordered, 11040 boolean sticky, int sendingUser) { 11041 // The raw IIntentReceiver interface is called 11042 // with the AM lock held, so redispatch to 11043 // execute our code without the lock. 11044 mHandler.post(onFinishCallback); 11045 } 11046 }; 11047 } 11048 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11049 + " for user " + users[j]); 11050 broadcastIntentLocked(null, null, intent, null, finisher, 11051 0, null, null, null, AppOpsManager.OP_NONE, 11052 true, false, MY_PID, Process.SYSTEM_UID, 11053 users[j]); 11054 if (finisher != null) { 11055 waitingUpdate = true; 11056 } 11057 } 11058 } 11059 } 11060 11061 return waitingUpdate; 11062 } 11063 11064 public void systemReady(final Runnable goingCallback) { 11065 synchronized(this) { 11066 if (mSystemReady) { 11067 // If we're done calling all the receivers, run the next "boot phase" passed in 11068 // by the SystemServer 11069 if (goingCallback != null) { 11070 goingCallback.run(); 11071 } 11072 return; 11073 } 11074 11075 // Make sure we have the current profile info, since it is needed for 11076 // security checks. 11077 updateCurrentProfileIdsLocked(); 11078 11079 if (mRecentTasks == null) { 11080 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11081 if (!mRecentTasks.isEmpty()) { 11082 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11083 } 11084 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11085 mTaskPersister.startPersisting(); 11086 } 11087 11088 // Check to see if there are any update receivers to run. 11089 if (!mDidUpdate) { 11090 if (mWaitingUpdate) { 11091 return; 11092 } 11093 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11094 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11095 public void run() { 11096 synchronized (ActivityManagerService.this) { 11097 mDidUpdate = true; 11098 } 11099 writeLastDonePreBootReceivers(doneReceivers); 11100 showBootMessage(mContext.getText( 11101 R.string.android_upgrading_complete), 11102 false); 11103 systemReady(goingCallback); 11104 } 11105 }, doneReceivers, UserHandle.USER_OWNER); 11106 11107 if (mWaitingUpdate) { 11108 return; 11109 } 11110 mDidUpdate = true; 11111 } 11112 11113 mAppOpsService.systemReady(); 11114 mSystemReady = true; 11115 } 11116 11117 ArrayList<ProcessRecord> procsToKill = null; 11118 synchronized(mPidsSelfLocked) { 11119 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11120 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11121 if (!isAllowedWhileBooting(proc.info)){ 11122 if (procsToKill == null) { 11123 procsToKill = new ArrayList<ProcessRecord>(); 11124 } 11125 procsToKill.add(proc); 11126 } 11127 } 11128 } 11129 11130 synchronized(this) { 11131 if (procsToKill != null) { 11132 for (int i=procsToKill.size()-1; i>=0; i--) { 11133 ProcessRecord proc = procsToKill.get(i); 11134 Slog.i(TAG, "Removing system update proc: " + proc); 11135 removeProcessLocked(proc, true, false, "system update done"); 11136 } 11137 } 11138 11139 // Now that we have cleaned up any update processes, we 11140 // are ready to start launching real processes and know that 11141 // we won't trample on them any more. 11142 mProcessesReady = true; 11143 } 11144 11145 Slog.i(TAG, "System now ready"); 11146 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11147 SystemClock.uptimeMillis()); 11148 11149 synchronized(this) { 11150 // Make sure we have no pre-ready processes sitting around. 11151 11152 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11153 ResolveInfo ri = mContext.getPackageManager() 11154 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11155 STOCK_PM_FLAGS); 11156 CharSequence errorMsg = null; 11157 if (ri != null) { 11158 ActivityInfo ai = ri.activityInfo; 11159 ApplicationInfo app = ai.applicationInfo; 11160 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11161 mTopAction = Intent.ACTION_FACTORY_TEST; 11162 mTopData = null; 11163 mTopComponent = new ComponentName(app.packageName, 11164 ai.name); 11165 } else { 11166 errorMsg = mContext.getResources().getText( 11167 com.android.internal.R.string.factorytest_not_system); 11168 } 11169 } else { 11170 errorMsg = mContext.getResources().getText( 11171 com.android.internal.R.string.factorytest_no_action); 11172 } 11173 if (errorMsg != null) { 11174 mTopAction = null; 11175 mTopData = null; 11176 mTopComponent = null; 11177 Message msg = Message.obtain(); 11178 msg.what = SHOW_FACTORY_ERROR_MSG; 11179 msg.getData().putCharSequence("msg", errorMsg); 11180 mHandler.sendMessage(msg); 11181 } 11182 } 11183 } 11184 11185 retrieveSettings(); 11186 loadResourcesOnSystemReady(); 11187 11188 synchronized (this) { 11189 readGrantedUriPermissionsLocked(); 11190 } 11191 11192 if (goingCallback != null) goingCallback.run(); 11193 11194 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11195 Integer.toString(mCurrentUserId), mCurrentUserId); 11196 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11197 Integer.toString(mCurrentUserId), mCurrentUserId); 11198 mSystemServiceManager.startUser(mCurrentUserId); 11199 11200 synchronized (this) { 11201 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11202 try { 11203 List apps = AppGlobals.getPackageManager(). 11204 getPersistentApplications(STOCK_PM_FLAGS); 11205 if (apps != null) { 11206 int N = apps.size(); 11207 int i; 11208 for (i=0; i<N; i++) { 11209 ApplicationInfo info 11210 = (ApplicationInfo)apps.get(i); 11211 if (info != null && 11212 !info.packageName.equals("android")) { 11213 addAppLocked(info, false, null /* ABI override */); 11214 } 11215 } 11216 } 11217 } catch (RemoteException ex) { 11218 // pm is in same process, this will never happen. 11219 } 11220 } 11221 11222 // Start up initial activity. 11223 mBooting = true; 11224 startHomeActivityLocked(mCurrentUserId); 11225 11226 try { 11227 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11228 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11229 + " data partition or your device will be unstable."); 11230 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11231 } 11232 } catch (RemoteException e) { 11233 } 11234 11235 if (!Build.isFingerprintConsistent()) { 11236 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11237 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11238 } 11239 11240 long ident = Binder.clearCallingIdentity(); 11241 try { 11242 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11243 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11244 | Intent.FLAG_RECEIVER_FOREGROUND); 11245 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11246 broadcastIntentLocked(null, null, intent, 11247 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11248 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11249 intent = new Intent(Intent.ACTION_USER_STARTING); 11250 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11251 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11252 broadcastIntentLocked(null, null, intent, 11253 null, new IIntentReceiver.Stub() { 11254 @Override 11255 public void performReceive(Intent intent, int resultCode, String data, 11256 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11257 throws RemoteException { 11258 } 11259 }, 0, null, null, 11260 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11261 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11262 } catch (Throwable t) { 11263 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11264 } finally { 11265 Binder.restoreCallingIdentity(ident); 11266 } 11267 mStackSupervisor.resumeTopActivitiesLocked(); 11268 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11269 } 11270 } 11271 11272 private boolean makeAppCrashingLocked(ProcessRecord app, 11273 String shortMsg, String longMsg, String stackTrace) { 11274 app.crashing = true; 11275 app.crashingReport = generateProcessError(app, 11276 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11277 startAppProblemLocked(app); 11278 app.stopFreezingAllLocked(); 11279 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11280 } 11281 11282 private void makeAppNotRespondingLocked(ProcessRecord app, 11283 String activity, String shortMsg, String longMsg) { 11284 app.notResponding = true; 11285 app.notRespondingReport = generateProcessError(app, 11286 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11287 activity, shortMsg, longMsg, null); 11288 startAppProblemLocked(app); 11289 app.stopFreezingAllLocked(); 11290 } 11291 11292 /** 11293 * Generate a process error record, suitable for attachment to a ProcessRecord. 11294 * 11295 * @param app The ProcessRecord in which the error occurred. 11296 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11297 * ActivityManager.AppErrorStateInfo 11298 * @param activity The activity associated with the crash, if known. 11299 * @param shortMsg Short message describing the crash. 11300 * @param longMsg Long message describing the crash. 11301 * @param stackTrace Full crash stack trace, may be null. 11302 * 11303 * @return Returns a fully-formed AppErrorStateInfo record. 11304 */ 11305 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11306 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11307 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11308 11309 report.condition = condition; 11310 report.processName = app.processName; 11311 report.pid = app.pid; 11312 report.uid = app.info.uid; 11313 report.tag = activity; 11314 report.shortMsg = shortMsg; 11315 report.longMsg = longMsg; 11316 report.stackTrace = stackTrace; 11317 11318 return report; 11319 } 11320 11321 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11322 synchronized (this) { 11323 app.crashing = false; 11324 app.crashingReport = null; 11325 app.notResponding = false; 11326 app.notRespondingReport = null; 11327 if (app.anrDialog == fromDialog) { 11328 app.anrDialog = null; 11329 } 11330 if (app.waitDialog == fromDialog) { 11331 app.waitDialog = null; 11332 } 11333 if (app.pid > 0 && app.pid != MY_PID) { 11334 handleAppCrashLocked(app, null, null, null); 11335 app.kill("user request after error", true); 11336 } 11337 } 11338 } 11339 11340 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11341 String stackTrace) { 11342 long now = SystemClock.uptimeMillis(); 11343 11344 Long crashTime; 11345 if (!app.isolated) { 11346 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11347 } else { 11348 crashTime = null; 11349 } 11350 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11351 // This process loses! 11352 Slog.w(TAG, "Process " + app.info.processName 11353 + " has crashed too many times: killing!"); 11354 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11355 app.userId, app.info.processName, app.uid); 11356 mStackSupervisor.handleAppCrashLocked(app); 11357 if (!app.persistent) { 11358 // We don't want to start this process again until the user 11359 // explicitly does so... but for persistent process, we really 11360 // need to keep it running. If a persistent process is actually 11361 // repeatedly crashing, then badness for everyone. 11362 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11363 app.info.processName); 11364 if (!app.isolated) { 11365 // XXX We don't have a way to mark isolated processes 11366 // as bad, since they don't have a peristent identity. 11367 mBadProcesses.put(app.info.processName, app.uid, 11368 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11369 mProcessCrashTimes.remove(app.info.processName, app.uid); 11370 } 11371 app.bad = true; 11372 app.removed = true; 11373 // Don't let services in this process be restarted and potentially 11374 // annoy the user repeatedly. Unless it is persistent, since those 11375 // processes run critical code. 11376 removeProcessLocked(app, false, false, "crash"); 11377 mStackSupervisor.resumeTopActivitiesLocked(); 11378 return false; 11379 } 11380 mStackSupervisor.resumeTopActivitiesLocked(); 11381 } else { 11382 mStackSupervisor.finishTopRunningActivityLocked(app); 11383 } 11384 11385 // Bump up the crash count of any services currently running in the proc. 11386 for (int i=app.services.size()-1; i>=0; i--) { 11387 // Any services running in the application need to be placed 11388 // back in the pending list. 11389 ServiceRecord sr = app.services.valueAt(i); 11390 sr.crashCount++; 11391 } 11392 11393 // If the crashing process is what we consider to be the "home process" and it has been 11394 // replaced by a third-party app, clear the package preferred activities from packages 11395 // with a home activity running in the process to prevent a repeatedly crashing app 11396 // from blocking the user to manually clear the list. 11397 final ArrayList<ActivityRecord> activities = app.activities; 11398 if (app == mHomeProcess && activities.size() > 0 11399 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11400 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11401 final ActivityRecord r = activities.get(activityNdx); 11402 if (r.isHomeActivity()) { 11403 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11404 try { 11405 ActivityThread.getPackageManager() 11406 .clearPackagePreferredActivities(r.packageName); 11407 } catch (RemoteException c) { 11408 // pm is in same process, this will never happen. 11409 } 11410 } 11411 } 11412 } 11413 11414 if (!app.isolated) { 11415 // XXX Can't keep track of crash times for isolated processes, 11416 // because they don't have a perisistent identity. 11417 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11418 } 11419 11420 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11421 return true; 11422 } 11423 11424 void startAppProblemLocked(ProcessRecord app) { 11425 // If this app is not running under the current user, then we 11426 // can't give it a report button because that would require 11427 // launching the report UI under a different user. 11428 app.errorReportReceiver = null; 11429 11430 for (int userId : mCurrentProfileIds) { 11431 if (app.userId == userId) { 11432 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11433 mContext, app.info.packageName, app.info.flags); 11434 } 11435 } 11436 skipCurrentReceiverLocked(app); 11437 } 11438 11439 void skipCurrentReceiverLocked(ProcessRecord app) { 11440 for (BroadcastQueue queue : mBroadcastQueues) { 11441 queue.skipCurrentReceiverLocked(app); 11442 } 11443 } 11444 11445 /** 11446 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11447 * The application process will exit immediately after this call returns. 11448 * @param app object of the crashing app, null for the system server 11449 * @param crashInfo describing the exception 11450 */ 11451 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11452 ProcessRecord r = findAppProcess(app, "Crash"); 11453 final String processName = app == null ? "system_server" 11454 : (r == null ? "unknown" : r.processName); 11455 11456 handleApplicationCrashInner("crash", r, processName, crashInfo); 11457 } 11458 11459 /* Native crash reporting uses this inner version because it needs to be somewhat 11460 * decoupled from the AM-managed cleanup lifecycle 11461 */ 11462 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11463 ApplicationErrorReport.CrashInfo crashInfo) { 11464 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11465 UserHandle.getUserId(Binder.getCallingUid()), processName, 11466 r == null ? -1 : r.info.flags, 11467 crashInfo.exceptionClassName, 11468 crashInfo.exceptionMessage, 11469 crashInfo.throwFileName, 11470 crashInfo.throwLineNumber); 11471 11472 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11473 11474 crashApplication(r, crashInfo); 11475 } 11476 11477 public void handleApplicationStrictModeViolation( 11478 IBinder app, 11479 int violationMask, 11480 StrictMode.ViolationInfo info) { 11481 ProcessRecord r = findAppProcess(app, "StrictMode"); 11482 if (r == null) { 11483 return; 11484 } 11485 11486 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11487 Integer stackFingerprint = info.hashCode(); 11488 boolean logIt = true; 11489 synchronized (mAlreadyLoggedViolatedStacks) { 11490 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11491 logIt = false; 11492 // TODO: sub-sample into EventLog for these, with 11493 // the info.durationMillis? Then we'd get 11494 // the relative pain numbers, without logging all 11495 // the stack traces repeatedly. We'd want to do 11496 // likewise in the client code, which also does 11497 // dup suppression, before the Binder call. 11498 } else { 11499 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11500 mAlreadyLoggedViolatedStacks.clear(); 11501 } 11502 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11503 } 11504 } 11505 if (logIt) { 11506 logStrictModeViolationToDropBox(r, info); 11507 } 11508 } 11509 11510 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11511 AppErrorResult result = new AppErrorResult(); 11512 synchronized (this) { 11513 final long origId = Binder.clearCallingIdentity(); 11514 11515 Message msg = Message.obtain(); 11516 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11517 HashMap<String, Object> data = new HashMap<String, Object>(); 11518 data.put("result", result); 11519 data.put("app", r); 11520 data.put("violationMask", violationMask); 11521 data.put("info", info); 11522 msg.obj = data; 11523 mHandler.sendMessage(msg); 11524 11525 Binder.restoreCallingIdentity(origId); 11526 } 11527 int res = result.get(); 11528 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11529 } 11530 } 11531 11532 // Depending on the policy in effect, there could be a bunch of 11533 // these in quick succession so we try to batch these together to 11534 // minimize disk writes, number of dropbox entries, and maximize 11535 // compression, by having more fewer, larger records. 11536 private void logStrictModeViolationToDropBox( 11537 ProcessRecord process, 11538 StrictMode.ViolationInfo info) { 11539 if (info == null) { 11540 return; 11541 } 11542 final boolean isSystemApp = process == null || 11543 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11544 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11545 final String processName = process == null ? "unknown" : process.processName; 11546 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11547 final DropBoxManager dbox = (DropBoxManager) 11548 mContext.getSystemService(Context.DROPBOX_SERVICE); 11549 11550 // Exit early if the dropbox isn't configured to accept this report type. 11551 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11552 11553 boolean bufferWasEmpty; 11554 boolean needsFlush; 11555 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11556 synchronized (sb) { 11557 bufferWasEmpty = sb.length() == 0; 11558 appendDropBoxProcessHeaders(process, processName, sb); 11559 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11560 sb.append("System-App: ").append(isSystemApp).append("\n"); 11561 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11562 if (info.violationNumThisLoop != 0) { 11563 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11564 } 11565 if (info.numAnimationsRunning != 0) { 11566 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11567 } 11568 if (info.broadcastIntentAction != null) { 11569 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11570 } 11571 if (info.durationMillis != -1) { 11572 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11573 } 11574 if (info.numInstances != -1) { 11575 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11576 } 11577 if (info.tags != null) { 11578 for (String tag : info.tags) { 11579 sb.append("Span-Tag: ").append(tag).append("\n"); 11580 } 11581 } 11582 sb.append("\n"); 11583 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11584 sb.append(info.crashInfo.stackTrace); 11585 } 11586 sb.append("\n"); 11587 11588 // Only buffer up to ~64k. Various logging bits truncate 11589 // things at 128k. 11590 needsFlush = (sb.length() > 64 * 1024); 11591 } 11592 11593 // Flush immediately if the buffer's grown too large, or this 11594 // is a non-system app. Non-system apps are isolated with a 11595 // different tag & policy and not batched. 11596 // 11597 // Batching is useful during internal testing with 11598 // StrictMode settings turned up high. Without batching, 11599 // thousands of separate files could be created on boot. 11600 if (!isSystemApp || needsFlush) { 11601 new Thread("Error dump: " + dropboxTag) { 11602 @Override 11603 public void run() { 11604 String report; 11605 synchronized (sb) { 11606 report = sb.toString(); 11607 sb.delete(0, sb.length()); 11608 sb.trimToSize(); 11609 } 11610 if (report.length() != 0) { 11611 dbox.addText(dropboxTag, report); 11612 } 11613 } 11614 }.start(); 11615 return; 11616 } 11617 11618 // System app batching: 11619 if (!bufferWasEmpty) { 11620 // An existing dropbox-writing thread is outstanding, so 11621 // we don't need to start it up. The existing thread will 11622 // catch the buffer appends we just did. 11623 return; 11624 } 11625 11626 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11627 // (After this point, we shouldn't access AMS internal data structures.) 11628 new Thread("Error dump: " + dropboxTag) { 11629 @Override 11630 public void run() { 11631 // 5 second sleep to let stacks arrive and be batched together 11632 try { 11633 Thread.sleep(5000); // 5 seconds 11634 } catch (InterruptedException e) {} 11635 11636 String errorReport; 11637 synchronized (mStrictModeBuffer) { 11638 errorReport = mStrictModeBuffer.toString(); 11639 if (errorReport.length() == 0) { 11640 return; 11641 } 11642 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11643 mStrictModeBuffer.trimToSize(); 11644 } 11645 dbox.addText(dropboxTag, errorReport); 11646 } 11647 }.start(); 11648 } 11649 11650 /** 11651 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11652 * @param app object of the crashing app, null for the system server 11653 * @param tag reported by the caller 11654 * @param system whether this wtf is coming from the system 11655 * @param crashInfo describing the context of the error 11656 * @return true if the process should exit immediately (WTF is fatal) 11657 */ 11658 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11659 final ApplicationErrorReport.CrashInfo crashInfo) { 11660 final int callingUid = Binder.getCallingUid(); 11661 final int callingPid = Binder.getCallingPid(); 11662 11663 if (system) { 11664 // If this is coming from the system, we could very well have low-level 11665 // system locks held, so we want to do this all asynchronously. And we 11666 // never want this to become fatal, so there is that too. 11667 mHandler.post(new Runnable() { 11668 @Override public void run() { 11669 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11670 } 11671 }); 11672 return false; 11673 } 11674 11675 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11676 crashInfo); 11677 11678 if (r != null && r.pid != Process.myPid() && 11679 Settings.Global.getInt(mContext.getContentResolver(), 11680 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11681 crashApplication(r, crashInfo); 11682 return true; 11683 } else { 11684 return false; 11685 } 11686 } 11687 11688 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11689 final ApplicationErrorReport.CrashInfo crashInfo) { 11690 final ProcessRecord r = findAppProcess(app, "WTF"); 11691 final String processName = app == null ? "system_server" 11692 : (r == null ? "unknown" : r.processName); 11693 11694 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11695 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11696 11697 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11698 11699 return r; 11700 } 11701 11702 /** 11703 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11704 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11705 */ 11706 private ProcessRecord findAppProcess(IBinder app, String reason) { 11707 if (app == null) { 11708 return null; 11709 } 11710 11711 synchronized (this) { 11712 final int NP = mProcessNames.getMap().size(); 11713 for (int ip=0; ip<NP; ip++) { 11714 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11715 final int NA = apps.size(); 11716 for (int ia=0; ia<NA; ia++) { 11717 ProcessRecord p = apps.valueAt(ia); 11718 if (p.thread != null && p.thread.asBinder() == app) { 11719 return p; 11720 } 11721 } 11722 } 11723 11724 Slog.w(TAG, "Can't find mystery application for " + reason 11725 + " from pid=" + Binder.getCallingPid() 11726 + " uid=" + Binder.getCallingUid() + ": " + app); 11727 return null; 11728 } 11729 } 11730 11731 /** 11732 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11733 * to append various headers to the dropbox log text. 11734 */ 11735 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11736 StringBuilder sb) { 11737 // Watchdog thread ends up invoking this function (with 11738 // a null ProcessRecord) to add the stack file to dropbox. 11739 // Do not acquire a lock on this (am) in such cases, as it 11740 // could cause a potential deadlock, if and when watchdog 11741 // is invoked due to unavailability of lock on am and it 11742 // would prevent watchdog from killing system_server. 11743 if (process == null) { 11744 sb.append("Process: ").append(processName).append("\n"); 11745 return; 11746 } 11747 // Note: ProcessRecord 'process' is guarded by the service 11748 // instance. (notably process.pkgList, which could otherwise change 11749 // concurrently during execution of this method) 11750 synchronized (this) { 11751 sb.append("Process: ").append(processName).append("\n"); 11752 int flags = process.info.flags; 11753 IPackageManager pm = AppGlobals.getPackageManager(); 11754 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11755 for (int ip=0; ip<process.pkgList.size(); ip++) { 11756 String pkg = process.pkgList.keyAt(ip); 11757 sb.append("Package: ").append(pkg); 11758 try { 11759 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11760 if (pi != null) { 11761 sb.append(" v").append(pi.versionCode); 11762 if (pi.versionName != null) { 11763 sb.append(" (").append(pi.versionName).append(")"); 11764 } 11765 } 11766 } catch (RemoteException e) { 11767 Slog.e(TAG, "Error getting package info: " + pkg, e); 11768 } 11769 sb.append("\n"); 11770 } 11771 } 11772 } 11773 11774 private static String processClass(ProcessRecord process) { 11775 if (process == null || process.pid == MY_PID) { 11776 return "system_server"; 11777 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11778 return "system_app"; 11779 } else { 11780 return "data_app"; 11781 } 11782 } 11783 11784 /** 11785 * Write a description of an error (crash, WTF, ANR) to the drop box. 11786 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11787 * @param process which caused the error, null means the system server 11788 * @param activity which triggered the error, null if unknown 11789 * @param parent activity related to the error, null if unknown 11790 * @param subject line related to the error, null if absent 11791 * @param report in long form describing the error, null if absent 11792 * @param logFile to include in the report, null if none 11793 * @param crashInfo giving an application stack trace, null if absent 11794 */ 11795 public void addErrorToDropBox(String eventType, 11796 ProcessRecord process, String processName, ActivityRecord activity, 11797 ActivityRecord parent, String subject, 11798 final String report, final File logFile, 11799 final ApplicationErrorReport.CrashInfo crashInfo) { 11800 // NOTE -- this must never acquire the ActivityManagerService lock, 11801 // otherwise the watchdog may be prevented from resetting the system. 11802 11803 final String dropboxTag = processClass(process) + "_" + eventType; 11804 final DropBoxManager dbox = (DropBoxManager) 11805 mContext.getSystemService(Context.DROPBOX_SERVICE); 11806 11807 // Exit early if the dropbox isn't configured to accept this report type. 11808 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11809 11810 final StringBuilder sb = new StringBuilder(1024); 11811 appendDropBoxProcessHeaders(process, processName, sb); 11812 if (activity != null) { 11813 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11814 } 11815 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11816 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11817 } 11818 if (parent != null && parent != activity) { 11819 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11820 } 11821 if (subject != null) { 11822 sb.append("Subject: ").append(subject).append("\n"); 11823 } 11824 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11825 if (Debug.isDebuggerConnected()) { 11826 sb.append("Debugger: Connected\n"); 11827 } 11828 sb.append("\n"); 11829 11830 // Do the rest in a worker thread to avoid blocking the caller on I/O 11831 // (After this point, we shouldn't access AMS internal data structures.) 11832 Thread worker = new Thread("Error dump: " + dropboxTag) { 11833 @Override 11834 public void run() { 11835 if (report != null) { 11836 sb.append(report); 11837 } 11838 if (logFile != null) { 11839 try { 11840 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11841 "\n\n[[TRUNCATED]]")); 11842 } catch (IOException e) { 11843 Slog.e(TAG, "Error reading " + logFile, e); 11844 } 11845 } 11846 if (crashInfo != null && crashInfo.stackTrace != null) { 11847 sb.append(crashInfo.stackTrace); 11848 } 11849 11850 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11851 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11852 if (lines > 0) { 11853 sb.append("\n"); 11854 11855 // Merge several logcat streams, and take the last N lines 11856 InputStreamReader input = null; 11857 try { 11858 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11859 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11860 "-b", "crash", 11861 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11862 11863 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11864 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11865 input = new InputStreamReader(logcat.getInputStream()); 11866 11867 int num; 11868 char[] buf = new char[8192]; 11869 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11870 } catch (IOException e) { 11871 Slog.e(TAG, "Error running logcat", e); 11872 } finally { 11873 if (input != null) try { input.close(); } catch (IOException e) {} 11874 } 11875 } 11876 11877 dbox.addText(dropboxTag, sb.toString()); 11878 } 11879 }; 11880 11881 if (process == null) { 11882 // If process is null, we are being called from some internal code 11883 // and may be about to die -- run this synchronously. 11884 worker.run(); 11885 } else { 11886 worker.start(); 11887 } 11888 } 11889 11890 /** 11891 * Bring up the "unexpected error" dialog box for a crashing app. 11892 * Deal with edge cases (intercepts from instrumented applications, 11893 * ActivityController, error intent receivers, that sort of thing). 11894 * @param r the application crashing 11895 * @param crashInfo describing the failure 11896 */ 11897 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11898 long timeMillis = System.currentTimeMillis(); 11899 String shortMsg = crashInfo.exceptionClassName; 11900 String longMsg = crashInfo.exceptionMessage; 11901 String stackTrace = crashInfo.stackTrace; 11902 if (shortMsg != null && longMsg != null) { 11903 longMsg = shortMsg + ": " + longMsg; 11904 } else if (shortMsg != null) { 11905 longMsg = shortMsg; 11906 } 11907 11908 AppErrorResult result = new AppErrorResult(); 11909 synchronized (this) { 11910 if (mController != null) { 11911 try { 11912 String name = r != null ? r.processName : null; 11913 int pid = r != null ? r.pid : Binder.getCallingPid(); 11914 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11915 if (!mController.appCrashed(name, pid, 11916 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11917 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11918 && "Native crash".equals(crashInfo.exceptionClassName)) { 11919 Slog.w(TAG, "Skip killing native crashed app " + name 11920 + "(" + pid + ") during testing"); 11921 } else { 11922 Slog.w(TAG, "Force-killing crashed app " + name 11923 + " at watcher's request"); 11924 if (r != null) { 11925 r.kill("crash", true); 11926 } else { 11927 // Huh. 11928 Process.killProcess(pid); 11929 Process.killProcessGroup(uid, pid); 11930 } 11931 } 11932 return; 11933 } 11934 } catch (RemoteException e) { 11935 mController = null; 11936 Watchdog.getInstance().setActivityController(null); 11937 } 11938 } 11939 11940 final long origId = Binder.clearCallingIdentity(); 11941 11942 // If this process is running instrumentation, finish it. 11943 if (r != null && r.instrumentationClass != null) { 11944 Slog.w(TAG, "Error in app " + r.processName 11945 + " running instrumentation " + r.instrumentationClass + ":"); 11946 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11947 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11948 Bundle info = new Bundle(); 11949 info.putString("shortMsg", shortMsg); 11950 info.putString("longMsg", longMsg); 11951 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11952 Binder.restoreCallingIdentity(origId); 11953 return; 11954 } 11955 11956 // If we can't identify the process or it's already exceeded its crash quota, 11957 // quit right away without showing a crash dialog. 11958 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11959 Binder.restoreCallingIdentity(origId); 11960 return; 11961 } 11962 11963 Message msg = Message.obtain(); 11964 msg.what = SHOW_ERROR_MSG; 11965 HashMap data = new HashMap(); 11966 data.put("result", result); 11967 data.put("app", r); 11968 msg.obj = data; 11969 mHandler.sendMessage(msg); 11970 11971 Binder.restoreCallingIdentity(origId); 11972 } 11973 11974 int res = result.get(); 11975 11976 Intent appErrorIntent = null; 11977 synchronized (this) { 11978 if (r != null && !r.isolated) { 11979 // XXX Can't keep track of crash time for isolated processes, 11980 // since they don't have a persistent identity. 11981 mProcessCrashTimes.put(r.info.processName, r.uid, 11982 SystemClock.uptimeMillis()); 11983 } 11984 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11985 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11986 } 11987 } 11988 11989 if (appErrorIntent != null) { 11990 try { 11991 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11992 } catch (ActivityNotFoundException e) { 11993 Slog.w(TAG, "bug report receiver dissappeared", e); 11994 } 11995 } 11996 } 11997 11998 Intent createAppErrorIntentLocked(ProcessRecord r, 11999 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12000 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12001 if (report == null) { 12002 return null; 12003 } 12004 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12005 result.setComponent(r.errorReportReceiver); 12006 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12007 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12008 return result; 12009 } 12010 12011 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12012 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12013 if (r.errorReportReceiver == null) { 12014 return null; 12015 } 12016 12017 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12018 return null; 12019 } 12020 12021 ApplicationErrorReport report = new ApplicationErrorReport(); 12022 report.packageName = r.info.packageName; 12023 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12024 report.processName = r.processName; 12025 report.time = timeMillis; 12026 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12027 12028 if (r.crashing || r.forceCrashReport) { 12029 report.type = ApplicationErrorReport.TYPE_CRASH; 12030 report.crashInfo = crashInfo; 12031 } else if (r.notResponding) { 12032 report.type = ApplicationErrorReport.TYPE_ANR; 12033 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12034 12035 report.anrInfo.activity = r.notRespondingReport.tag; 12036 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12037 report.anrInfo.info = r.notRespondingReport.longMsg; 12038 } 12039 12040 return report; 12041 } 12042 12043 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12044 enforceNotIsolatedCaller("getProcessesInErrorState"); 12045 // assume our apps are happy - lazy create the list 12046 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12047 12048 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12049 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12050 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12051 12052 synchronized (this) { 12053 12054 // iterate across all processes 12055 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12056 ProcessRecord app = mLruProcesses.get(i); 12057 if (!allUsers && app.userId != userId) { 12058 continue; 12059 } 12060 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12061 // This one's in trouble, so we'll generate a report for it 12062 // crashes are higher priority (in case there's a crash *and* an anr) 12063 ActivityManager.ProcessErrorStateInfo report = null; 12064 if (app.crashing) { 12065 report = app.crashingReport; 12066 } else if (app.notResponding) { 12067 report = app.notRespondingReport; 12068 } 12069 12070 if (report != null) { 12071 if (errList == null) { 12072 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12073 } 12074 errList.add(report); 12075 } else { 12076 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12077 " crashing = " + app.crashing + 12078 " notResponding = " + app.notResponding); 12079 } 12080 } 12081 } 12082 } 12083 12084 return errList; 12085 } 12086 12087 static int procStateToImportance(int procState, int memAdj, 12088 ActivityManager.RunningAppProcessInfo currApp) { 12089 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12090 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12091 currApp.lru = memAdj; 12092 } else { 12093 currApp.lru = 0; 12094 } 12095 return imp; 12096 } 12097 12098 private void fillInProcMemInfo(ProcessRecord app, 12099 ActivityManager.RunningAppProcessInfo outInfo) { 12100 outInfo.pid = app.pid; 12101 outInfo.uid = app.info.uid; 12102 if (mHeavyWeightProcess == app) { 12103 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12104 } 12105 if (app.persistent) { 12106 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12107 } 12108 if (app.activities.size() > 0) { 12109 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12110 } 12111 outInfo.lastTrimLevel = app.trimMemoryLevel; 12112 int adj = app.curAdj; 12113 int procState = app.curProcState; 12114 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12115 outInfo.importanceReasonCode = app.adjTypeCode; 12116 outInfo.processState = app.curProcState; 12117 } 12118 12119 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12120 enforceNotIsolatedCaller("getRunningAppProcesses"); 12121 // Lazy instantiation of list 12122 List<ActivityManager.RunningAppProcessInfo> runList = null; 12123 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12124 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12125 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12126 synchronized (this) { 12127 // Iterate across all processes 12128 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12129 ProcessRecord app = mLruProcesses.get(i); 12130 if (!allUsers && app.userId != userId) { 12131 continue; 12132 } 12133 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12134 // Generate process state info for running application 12135 ActivityManager.RunningAppProcessInfo currApp = 12136 new ActivityManager.RunningAppProcessInfo(app.processName, 12137 app.pid, app.getPackageList()); 12138 fillInProcMemInfo(app, currApp); 12139 if (app.adjSource instanceof ProcessRecord) { 12140 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12141 currApp.importanceReasonImportance = 12142 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12143 app.adjSourceProcState); 12144 } else if (app.adjSource instanceof ActivityRecord) { 12145 ActivityRecord r = (ActivityRecord)app.adjSource; 12146 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12147 } 12148 if (app.adjTarget instanceof ComponentName) { 12149 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12150 } 12151 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12152 // + " lru=" + currApp.lru); 12153 if (runList == null) { 12154 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12155 } 12156 runList.add(currApp); 12157 } 12158 } 12159 } 12160 return runList; 12161 } 12162 12163 public List<ApplicationInfo> getRunningExternalApplications() { 12164 enforceNotIsolatedCaller("getRunningExternalApplications"); 12165 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12166 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12167 if (runningApps != null && runningApps.size() > 0) { 12168 Set<String> extList = new HashSet<String>(); 12169 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12170 if (app.pkgList != null) { 12171 for (String pkg : app.pkgList) { 12172 extList.add(pkg); 12173 } 12174 } 12175 } 12176 IPackageManager pm = AppGlobals.getPackageManager(); 12177 for (String pkg : extList) { 12178 try { 12179 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12180 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12181 retList.add(info); 12182 } 12183 } catch (RemoteException e) { 12184 } 12185 } 12186 } 12187 return retList; 12188 } 12189 12190 @Override 12191 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12192 enforceNotIsolatedCaller("getMyMemoryState"); 12193 synchronized (this) { 12194 ProcessRecord proc; 12195 synchronized (mPidsSelfLocked) { 12196 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12197 } 12198 fillInProcMemInfo(proc, outInfo); 12199 } 12200 } 12201 12202 @Override 12203 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12204 if (checkCallingPermission(android.Manifest.permission.DUMP) 12205 != PackageManager.PERMISSION_GRANTED) { 12206 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12207 + Binder.getCallingPid() 12208 + ", uid=" + Binder.getCallingUid() 12209 + " without permission " 12210 + android.Manifest.permission.DUMP); 12211 return; 12212 } 12213 12214 boolean dumpAll = false; 12215 boolean dumpClient = false; 12216 String dumpPackage = null; 12217 12218 int opti = 0; 12219 while (opti < args.length) { 12220 String opt = args[opti]; 12221 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12222 break; 12223 } 12224 opti++; 12225 if ("-a".equals(opt)) { 12226 dumpAll = true; 12227 } else if ("-c".equals(opt)) { 12228 dumpClient = true; 12229 } else if ("-h".equals(opt)) { 12230 pw.println("Activity manager dump options:"); 12231 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12232 pw.println(" cmd may be one of:"); 12233 pw.println(" a[ctivities]: activity stack state"); 12234 pw.println(" r[recents]: recent activities state"); 12235 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12236 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12237 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12238 pw.println(" o[om]: out of memory management"); 12239 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12240 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12241 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12242 pw.println(" service [COMP_SPEC]: service client-side state"); 12243 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12244 pw.println(" all: dump all activities"); 12245 pw.println(" top: dump the top activity"); 12246 pw.println(" write: write all pending state to storage"); 12247 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12248 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12249 pw.println(" a partial substring in a component name, a"); 12250 pw.println(" hex object identifier."); 12251 pw.println(" -a: include all available server state."); 12252 pw.println(" -c: include client state."); 12253 return; 12254 } else { 12255 pw.println("Unknown argument: " + opt + "; use -h for help"); 12256 } 12257 } 12258 12259 long origId = Binder.clearCallingIdentity(); 12260 boolean more = false; 12261 // Is the caller requesting to dump a particular piece of data? 12262 if (opti < args.length) { 12263 String cmd = args[opti]; 12264 opti++; 12265 if ("activities".equals(cmd) || "a".equals(cmd)) { 12266 synchronized (this) { 12267 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12268 } 12269 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12270 synchronized (this) { 12271 dumpRecentsLocked(fd, pw, args, opti, true, null); 12272 } 12273 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12274 String[] newArgs; 12275 String name; 12276 if (opti >= args.length) { 12277 name = null; 12278 newArgs = EMPTY_STRING_ARRAY; 12279 } else { 12280 name = args[opti]; 12281 opti++; 12282 newArgs = new String[args.length - opti]; 12283 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12284 args.length - opti); 12285 } 12286 synchronized (this) { 12287 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12288 } 12289 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12290 String[] newArgs; 12291 String name; 12292 if (opti >= args.length) { 12293 name = null; 12294 newArgs = EMPTY_STRING_ARRAY; 12295 } else { 12296 name = args[opti]; 12297 opti++; 12298 newArgs = new String[args.length - opti]; 12299 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12300 args.length - opti); 12301 } 12302 synchronized (this) { 12303 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12304 } 12305 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12306 String[] newArgs; 12307 String name; 12308 if (opti >= args.length) { 12309 name = null; 12310 newArgs = EMPTY_STRING_ARRAY; 12311 } else { 12312 name = args[opti]; 12313 opti++; 12314 newArgs = new String[args.length - opti]; 12315 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12316 args.length - opti); 12317 } 12318 synchronized (this) { 12319 dumpProcessesLocked(fd, pw, args, opti, true, name); 12320 } 12321 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12322 synchronized (this) { 12323 dumpOomLocked(fd, pw, args, opti, true); 12324 } 12325 } else if ("provider".equals(cmd)) { 12326 String[] newArgs; 12327 String name; 12328 if (opti >= args.length) { 12329 name = null; 12330 newArgs = EMPTY_STRING_ARRAY; 12331 } else { 12332 name = args[opti]; 12333 opti++; 12334 newArgs = new String[args.length - opti]; 12335 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12336 } 12337 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12338 pw.println("No providers match: " + name); 12339 pw.println("Use -h for help."); 12340 } 12341 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12342 synchronized (this) { 12343 dumpProvidersLocked(fd, pw, args, opti, true, null); 12344 } 12345 } else if ("service".equals(cmd)) { 12346 String[] newArgs; 12347 String name; 12348 if (opti >= args.length) { 12349 name = null; 12350 newArgs = EMPTY_STRING_ARRAY; 12351 } else { 12352 name = args[opti]; 12353 opti++; 12354 newArgs = new String[args.length - opti]; 12355 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12356 args.length - opti); 12357 } 12358 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12359 pw.println("No services match: " + name); 12360 pw.println("Use -h for help."); 12361 } 12362 } else if ("package".equals(cmd)) { 12363 String[] newArgs; 12364 if (opti >= args.length) { 12365 pw.println("package: no package name specified"); 12366 pw.println("Use -h for help."); 12367 } else { 12368 dumpPackage = args[opti]; 12369 opti++; 12370 newArgs = new String[args.length - opti]; 12371 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12372 args.length - opti); 12373 args = newArgs; 12374 opti = 0; 12375 more = true; 12376 } 12377 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12378 synchronized (this) { 12379 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12380 } 12381 } else if ("write".equals(cmd)) { 12382 mTaskPersister.flush(); 12383 pw.println("All tasks persisted."); 12384 return; 12385 } else { 12386 // Dumping a single activity? 12387 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12388 pw.println("Bad activity command, or no activities match: " + cmd); 12389 pw.println("Use -h for help."); 12390 } 12391 } 12392 if (!more) { 12393 Binder.restoreCallingIdentity(origId); 12394 return; 12395 } 12396 } 12397 12398 // No piece of data specified, dump everything. 12399 synchronized (this) { 12400 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12401 pw.println(); 12402 if (dumpAll) { 12403 pw.println("-------------------------------------------------------------------------------"); 12404 } 12405 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12406 pw.println(); 12407 if (dumpAll) { 12408 pw.println("-------------------------------------------------------------------------------"); 12409 } 12410 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12411 pw.println(); 12412 if (dumpAll) { 12413 pw.println("-------------------------------------------------------------------------------"); 12414 } 12415 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12416 pw.println(); 12417 if (dumpAll) { 12418 pw.println("-------------------------------------------------------------------------------"); 12419 } 12420 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12421 pw.println(); 12422 if (dumpAll) { 12423 pw.println("-------------------------------------------------------------------------------"); 12424 } 12425 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12426 pw.println(); 12427 if (dumpAll) { 12428 pw.println("-------------------------------------------------------------------------------"); 12429 } 12430 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12431 } 12432 Binder.restoreCallingIdentity(origId); 12433 } 12434 12435 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12436 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12437 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12438 12439 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12440 dumpPackage); 12441 boolean needSep = printedAnything; 12442 12443 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12444 dumpPackage, needSep, " mFocusedActivity: "); 12445 if (printed) { 12446 printedAnything = true; 12447 needSep = false; 12448 } 12449 12450 if (dumpPackage == null) { 12451 if (needSep) { 12452 pw.println(); 12453 } 12454 needSep = true; 12455 printedAnything = true; 12456 mStackSupervisor.dump(pw, " "); 12457 } 12458 12459 if (!printedAnything) { 12460 pw.println(" (nothing)"); 12461 } 12462 } 12463 12464 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12465 int opti, boolean dumpAll, String dumpPackage) { 12466 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12467 12468 boolean printedAnything = false; 12469 12470 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12471 boolean printedHeader = false; 12472 12473 final int N = mRecentTasks.size(); 12474 for (int i=0; i<N; i++) { 12475 TaskRecord tr = mRecentTasks.get(i); 12476 if (dumpPackage != null) { 12477 if (tr.realActivity == null || 12478 !dumpPackage.equals(tr.realActivity)) { 12479 continue; 12480 } 12481 } 12482 if (!printedHeader) { 12483 pw.println(" Recent tasks:"); 12484 printedHeader = true; 12485 printedAnything = true; 12486 } 12487 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12488 pw.println(tr); 12489 if (dumpAll) { 12490 mRecentTasks.get(i).dump(pw, " "); 12491 } 12492 } 12493 } 12494 12495 if (!printedAnything) { 12496 pw.println(" (nothing)"); 12497 } 12498 } 12499 12500 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12501 int opti, boolean dumpAll, String dumpPackage) { 12502 boolean needSep = false; 12503 boolean printedAnything = false; 12504 int numPers = 0; 12505 12506 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12507 12508 if (dumpAll) { 12509 final int NP = mProcessNames.getMap().size(); 12510 for (int ip=0; ip<NP; ip++) { 12511 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12512 final int NA = procs.size(); 12513 for (int ia=0; ia<NA; ia++) { 12514 ProcessRecord r = procs.valueAt(ia); 12515 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12516 continue; 12517 } 12518 if (!needSep) { 12519 pw.println(" All known processes:"); 12520 needSep = true; 12521 printedAnything = true; 12522 } 12523 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12524 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12525 pw.print(" "); pw.println(r); 12526 r.dump(pw, " "); 12527 if (r.persistent) { 12528 numPers++; 12529 } 12530 } 12531 } 12532 } 12533 12534 if (mIsolatedProcesses.size() > 0) { 12535 boolean printed = false; 12536 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12537 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12538 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12539 continue; 12540 } 12541 if (!printed) { 12542 if (needSep) { 12543 pw.println(); 12544 } 12545 pw.println(" Isolated process list (sorted by uid):"); 12546 printedAnything = true; 12547 printed = true; 12548 needSep = true; 12549 } 12550 pw.println(String.format("%sIsolated #%2d: %s", 12551 " ", i, r.toString())); 12552 } 12553 } 12554 12555 if (mLruProcesses.size() > 0) { 12556 if (needSep) { 12557 pw.println(); 12558 } 12559 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12560 pw.print(" total, non-act at "); 12561 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12562 pw.print(", non-svc at "); 12563 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12564 pw.println("):"); 12565 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12566 needSep = true; 12567 printedAnything = true; 12568 } 12569 12570 if (dumpAll || dumpPackage != null) { 12571 synchronized (mPidsSelfLocked) { 12572 boolean printed = false; 12573 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12574 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12575 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12576 continue; 12577 } 12578 if (!printed) { 12579 if (needSep) pw.println(); 12580 needSep = true; 12581 pw.println(" PID mappings:"); 12582 printed = true; 12583 printedAnything = true; 12584 } 12585 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12586 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12587 } 12588 } 12589 } 12590 12591 if (mForegroundProcesses.size() > 0) { 12592 synchronized (mPidsSelfLocked) { 12593 boolean printed = false; 12594 for (int i=0; i<mForegroundProcesses.size(); i++) { 12595 ProcessRecord r = mPidsSelfLocked.get( 12596 mForegroundProcesses.valueAt(i).pid); 12597 if (dumpPackage != null && (r == null 12598 || !r.pkgList.containsKey(dumpPackage))) { 12599 continue; 12600 } 12601 if (!printed) { 12602 if (needSep) pw.println(); 12603 needSep = true; 12604 pw.println(" Foreground Processes:"); 12605 printed = true; 12606 printedAnything = true; 12607 } 12608 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12609 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12610 } 12611 } 12612 } 12613 12614 if (mPersistentStartingProcesses.size() > 0) { 12615 if (needSep) pw.println(); 12616 needSep = true; 12617 printedAnything = true; 12618 pw.println(" Persisent processes that are starting:"); 12619 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12620 "Starting Norm", "Restarting PERS", dumpPackage); 12621 } 12622 12623 if (mRemovedProcesses.size() > 0) { 12624 if (needSep) pw.println(); 12625 needSep = true; 12626 printedAnything = true; 12627 pw.println(" Processes that are being removed:"); 12628 dumpProcessList(pw, this, mRemovedProcesses, " ", 12629 "Removed Norm", "Removed PERS", dumpPackage); 12630 } 12631 12632 if (mProcessesOnHold.size() > 0) { 12633 if (needSep) pw.println(); 12634 needSep = true; 12635 printedAnything = true; 12636 pw.println(" Processes that are on old until the system is ready:"); 12637 dumpProcessList(pw, this, mProcessesOnHold, " ", 12638 "OnHold Norm", "OnHold PERS", dumpPackage); 12639 } 12640 12641 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12642 12643 if (mProcessCrashTimes.getMap().size() > 0) { 12644 boolean printed = false; 12645 long now = SystemClock.uptimeMillis(); 12646 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12647 final int NP = pmap.size(); 12648 for (int ip=0; ip<NP; ip++) { 12649 String pname = pmap.keyAt(ip); 12650 SparseArray<Long> uids = pmap.valueAt(ip); 12651 final int N = uids.size(); 12652 for (int i=0; i<N; i++) { 12653 int puid = uids.keyAt(i); 12654 ProcessRecord r = mProcessNames.get(pname, puid); 12655 if (dumpPackage != null && (r == null 12656 || !r.pkgList.containsKey(dumpPackage))) { 12657 continue; 12658 } 12659 if (!printed) { 12660 if (needSep) pw.println(); 12661 needSep = true; 12662 pw.println(" Time since processes crashed:"); 12663 printed = true; 12664 printedAnything = true; 12665 } 12666 pw.print(" Process "); pw.print(pname); 12667 pw.print(" uid "); pw.print(puid); 12668 pw.print(": last crashed "); 12669 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12670 pw.println(" ago"); 12671 } 12672 } 12673 } 12674 12675 if (mBadProcesses.getMap().size() > 0) { 12676 boolean printed = false; 12677 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12678 final int NP = pmap.size(); 12679 for (int ip=0; ip<NP; ip++) { 12680 String pname = pmap.keyAt(ip); 12681 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12682 final int N = uids.size(); 12683 for (int i=0; i<N; i++) { 12684 int puid = uids.keyAt(i); 12685 ProcessRecord r = mProcessNames.get(pname, puid); 12686 if (dumpPackage != null && (r == null 12687 || !r.pkgList.containsKey(dumpPackage))) { 12688 continue; 12689 } 12690 if (!printed) { 12691 if (needSep) pw.println(); 12692 needSep = true; 12693 pw.println(" Bad processes:"); 12694 printedAnything = true; 12695 } 12696 BadProcessInfo info = uids.valueAt(i); 12697 pw.print(" Bad process "); pw.print(pname); 12698 pw.print(" uid "); pw.print(puid); 12699 pw.print(": crashed at time "); pw.println(info.time); 12700 if (info.shortMsg != null) { 12701 pw.print(" Short msg: "); pw.println(info.shortMsg); 12702 } 12703 if (info.longMsg != null) { 12704 pw.print(" Long msg: "); pw.println(info.longMsg); 12705 } 12706 if (info.stack != null) { 12707 pw.println(" Stack:"); 12708 int lastPos = 0; 12709 for (int pos=0; pos<info.stack.length(); pos++) { 12710 if (info.stack.charAt(pos) == '\n') { 12711 pw.print(" "); 12712 pw.write(info.stack, lastPos, pos-lastPos); 12713 pw.println(); 12714 lastPos = pos+1; 12715 } 12716 } 12717 if (lastPos < info.stack.length()) { 12718 pw.print(" "); 12719 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12720 pw.println(); 12721 } 12722 } 12723 } 12724 } 12725 } 12726 12727 if (dumpPackage == null) { 12728 pw.println(); 12729 needSep = false; 12730 pw.println(" mStartedUsers:"); 12731 for (int i=0; i<mStartedUsers.size(); i++) { 12732 UserStartedState uss = mStartedUsers.valueAt(i); 12733 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12734 pw.print(": "); uss.dump("", pw); 12735 } 12736 pw.print(" mStartedUserArray: ["); 12737 for (int i=0; i<mStartedUserArray.length; i++) { 12738 if (i > 0) pw.print(", "); 12739 pw.print(mStartedUserArray[i]); 12740 } 12741 pw.println("]"); 12742 pw.print(" mUserLru: ["); 12743 for (int i=0; i<mUserLru.size(); i++) { 12744 if (i > 0) pw.print(", "); 12745 pw.print(mUserLru.get(i)); 12746 } 12747 pw.println("]"); 12748 if (dumpAll) { 12749 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12750 } 12751 synchronized (mUserProfileGroupIdsSelfLocked) { 12752 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12753 pw.println(" mUserProfileGroupIds:"); 12754 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12755 pw.print(" User #"); 12756 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12757 pw.print(" -> profile #"); 12758 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12759 } 12760 } 12761 } 12762 } 12763 if (mHomeProcess != null && (dumpPackage == null 12764 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12765 if (needSep) { 12766 pw.println(); 12767 needSep = false; 12768 } 12769 pw.println(" mHomeProcess: " + mHomeProcess); 12770 } 12771 if (mPreviousProcess != null && (dumpPackage == null 12772 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12773 if (needSep) { 12774 pw.println(); 12775 needSep = false; 12776 } 12777 pw.println(" mPreviousProcess: " + mPreviousProcess); 12778 } 12779 if (dumpAll) { 12780 StringBuilder sb = new StringBuilder(128); 12781 sb.append(" mPreviousProcessVisibleTime: "); 12782 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12783 pw.println(sb); 12784 } 12785 if (mHeavyWeightProcess != null && (dumpPackage == null 12786 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12787 if (needSep) { 12788 pw.println(); 12789 needSep = false; 12790 } 12791 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12792 } 12793 if (dumpPackage == null) { 12794 pw.println(" mConfiguration: " + mConfiguration); 12795 } 12796 if (dumpAll) { 12797 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12798 if (mCompatModePackages.getPackages().size() > 0) { 12799 boolean printed = false; 12800 for (Map.Entry<String, Integer> entry 12801 : mCompatModePackages.getPackages().entrySet()) { 12802 String pkg = entry.getKey(); 12803 int mode = entry.getValue(); 12804 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12805 continue; 12806 } 12807 if (!printed) { 12808 pw.println(" mScreenCompatPackages:"); 12809 printed = true; 12810 } 12811 pw.print(" "); pw.print(pkg); pw.print(": "); 12812 pw.print(mode); pw.println(); 12813 } 12814 } 12815 } 12816 if (dumpPackage == null) { 12817 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12818 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12819 + " mLockScreenShown " + lockScreenShownToString()); 12820 } 12821 if (mShuttingDown || mRunningVoice) { 12822 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12823 } 12824 } 12825 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12826 || mOrigWaitForDebugger) { 12827 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12828 || dumpPackage.equals(mOrigDebugApp)) { 12829 if (needSep) { 12830 pw.println(); 12831 needSep = false; 12832 } 12833 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12834 + " mDebugTransient=" + mDebugTransient 12835 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12836 } 12837 } 12838 if (mOpenGlTraceApp != null) { 12839 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12840 if (needSep) { 12841 pw.println(); 12842 needSep = false; 12843 } 12844 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12845 } 12846 } 12847 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12848 || mProfileFd != null) { 12849 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12850 if (needSep) { 12851 pw.println(); 12852 needSep = false; 12853 } 12854 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12855 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12856 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12857 + mAutoStopProfiler); 12858 pw.println(" mProfileType=" + mProfileType); 12859 } 12860 } 12861 if (dumpPackage == null) { 12862 if (mAlwaysFinishActivities || mController != null) { 12863 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12864 + " mController=" + mController); 12865 } 12866 if (dumpAll) { 12867 pw.println(" Total persistent processes: " + numPers); 12868 pw.println(" mProcessesReady=" + mProcessesReady 12869 + " mSystemReady=" + mSystemReady 12870 + " mBooted=" + mBooted 12871 + " mFactoryTest=" + mFactoryTest); 12872 pw.println(" mBooting=" + mBooting 12873 + " mCallFinishBooting=" + mCallFinishBooting 12874 + " mBootAnimationComplete=" + mBootAnimationComplete); 12875 pw.print(" mLastPowerCheckRealtime="); 12876 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12877 pw.println(""); 12878 pw.print(" mLastPowerCheckUptime="); 12879 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12880 pw.println(""); 12881 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12882 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12883 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12884 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12885 + " (" + mLruProcesses.size() + " total)" 12886 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12887 + " mNumServiceProcs=" + mNumServiceProcs 12888 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12889 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12890 + " mLastMemoryLevel" + mLastMemoryLevel 12891 + " mLastNumProcesses" + mLastNumProcesses); 12892 long now = SystemClock.uptimeMillis(); 12893 pw.print(" mLastIdleTime="); 12894 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12895 pw.print(" mLowRamSinceLastIdle="); 12896 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12897 pw.println(); 12898 } 12899 } 12900 12901 if (!printedAnything) { 12902 pw.println(" (nothing)"); 12903 } 12904 } 12905 12906 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12907 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12908 if (mProcessesToGc.size() > 0) { 12909 boolean printed = false; 12910 long now = SystemClock.uptimeMillis(); 12911 for (int i=0; i<mProcessesToGc.size(); i++) { 12912 ProcessRecord proc = mProcessesToGc.get(i); 12913 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12914 continue; 12915 } 12916 if (!printed) { 12917 if (needSep) pw.println(); 12918 needSep = true; 12919 pw.println(" Processes that are waiting to GC:"); 12920 printed = true; 12921 } 12922 pw.print(" Process "); pw.println(proc); 12923 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12924 pw.print(", last gced="); 12925 pw.print(now-proc.lastRequestedGc); 12926 pw.print(" ms ago, last lowMem="); 12927 pw.print(now-proc.lastLowMemory); 12928 pw.println(" ms ago"); 12929 12930 } 12931 } 12932 return needSep; 12933 } 12934 12935 void printOomLevel(PrintWriter pw, String name, int adj) { 12936 pw.print(" "); 12937 if (adj >= 0) { 12938 pw.print(' '); 12939 if (adj < 10) pw.print(' '); 12940 } else { 12941 if (adj > -10) pw.print(' '); 12942 } 12943 pw.print(adj); 12944 pw.print(": "); 12945 pw.print(name); 12946 pw.print(" ("); 12947 pw.print(mProcessList.getMemLevel(adj)/1024); 12948 pw.println(" kB)"); 12949 } 12950 12951 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12952 int opti, boolean dumpAll) { 12953 boolean needSep = false; 12954 12955 if (mLruProcesses.size() > 0) { 12956 if (needSep) pw.println(); 12957 needSep = true; 12958 pw.println(" OOM levels:"); 12959 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12960 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12961 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12962 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12963 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12964 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12965 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12966 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12967 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12968 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12969 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12970 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12971 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12972 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12973 12974 if (needSep) pw.println(); 12975 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12976 pw.print(" total, non-act at "); 12977 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12978 pw.print(", non-svc at "); 12979 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12980 pw.println("):"); 12981 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12982 needSep = true; 12983 } 12984 12985 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12986 12987 pw.println(); 12988 pw.println(" mHomeProcess: " + mHomeProcess); 12989 pw.println(" mPreviousProcess: " + mPreviousProcess); 12990 if (mHeavyWeightProcess != null) { 12991 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12992 } 12993 12994 return true; 12995 } 12996 12997 /** 12998 * There are three ways to call this: 12999 * - no provider specified: dump all the providers 13000 * - a flattened component name that matched an existing provider was specified as the 13001 * first arg: dump that one provider 13002 * - the first arg isn't the flattened component name of an existing provider: 13003 * dump all providers whose component contains the first arg as a substring 13004 */ 13005 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13006 int opti, boolean dumpAll) { 13007 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13008 } 13009 13010 static class ItemMatcher { 13011 ArrayList<ComponentName> components; 13012 ArrayList<String> strings; 13013 ArrayList<Integer> objects; 13014 boolean all; 13015 13016 ItemMatcher() { 13017 all = true; 13018 } 13019 13020 void build(String name) { 13021 ComponentName componentName = ComponentName.unflattenFromString(name); 13022 if (componentName != null) { 13023 if (components == null) { 13024 components = new ArrayList<ComponentName>(); 13025 } 13026 components.add(componentName); 13027 all = false; 13028 } else { 13029 int objectId = 0; 13030 // Not a '/' separated full component name; maybe an object ID? 13031 try { 13032 objectId = Integer.parseInt(name, 16); 13033 if (objects == null) { 13034 objects = new ArrayList<Integer>(); 13035 } 13036 objects.add(objectId); 13037 all = false; 13038 } catch (RuntimeException e) { 13039 // Not an integer; just do string match. 13040 if (strings == null) { 13041 strings = new ArrayList<String>(); 13042 } 13043 strings.add(name); 13044 all = false; 13045 } 13046 } 13047 } 13048 13049 int build(String[] args, int opti) { 13050 for (; opti<args.length; opti++) { 13051 String name = args[opti]; 13052 if ("--".equals(name)) { 13053 return opti+1; 13054 } 13055 build(name); 13056 } 13057 return opti; 13058 } 13059 13060 boolean match(Object object, ComponentName comp) { 13061 if (all) { 13062 return true; 13063 } 13064 if (components != null) { 13065 for (int i=0; i<components.size(); i++) { 13066 if (components.get(i).equals(comp)) { 13067 return true; 13068 } 13069 } 13070 } 13071 if (objects != null) { 13072 for (int i=0; i<objects.size(); i++) { 13073 if (System.identityHashCode(object) == objects.get(i)) { 13074 return true; 13075 } 13076 } 13077 } 13078 if (strings != null) { 13079 String flat = comp.flattenToString(); 13080 for (int i=0; i<strings.size(); i++) { 13081 if (flat.contains(strings.get(i))) { 13082 return true; 13083 } 13084 } 13085 } 13086 return false; 13087 } 13088 } 13089 13090 /** 13091 * There are three things that cmd can be: 13092 * - a flattened component name that matches an existing activity 13093 * - the cmd arg isn't the flattened component name of an existing activity: 13094 * dump all activity whose component contains the cmd as a substring 13095 * - A hex number of the ActivityRecord object instance. 13096 */ 13097 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13098 int opti, boolean dumpAll) { 13099 ArrayList<ActivityRecord> activities; 13100 13101 synchronized (this) { 13102 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13103 } 13104 13105 if (activities.size() <= 0) { 13106 return false; 13107 } 13108 13109 String[] newArgs = new String[args.length - opti]; 13110 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13111 13112 TaskRecord lastTask = null; 13113 boolean needSep = false; 13114 for (int i=activities.size()-1; i>=0; i--) { 13115 ActivityRecord r = activities.get(i); 13116 if (needSep) { 13117 pw.println(); 13118 } 13119 needSep = true; 13120 synchronized (this) { 13121 if (lastTask != r.task) { 13122 lastTask = r.task; 13123 pw.print("TASK "); pw.print(lastTask.affinity); 13124 pw.print(" id="); pw.println(lastTask.taskId); 13125 if (dumpAll) { 13126 lastTask.dump(pw, " "); 13127 } 13128 } 13129 } 13130 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13131 } 13132 return true; 13133 } 13134 13135 /** 13136 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13137 * there is a thread associated with the activity. 13138 */ 13139 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13140 final ActivityRecord r, String[] args, boolean dumpAll) { 13141 String innerPrefix = prefix + " "; 13142 synchronized (this) { 13143 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13144 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13145 pw.print(" pid="); 13146 if (r.app != null) pw.println(r.app.pid); 13147 else pw.println("(not running)"); 13148 if (dumpAll) { 13149 r.dump(pw, innerPrefix); 13150 } 13151 } 13152 if (r.app != null && r.app.thread != null) { 13153 // flush anything that is already in the PrintWriter since the thread is going 13154 // to write to the file descriptor directly 13155 pw.flush(); 13156 try { 13157 TransferPipe tp = new TransferPipe(); 13158 try { 13159 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13160 r.appToken, innerPrefix, args); 13161 tp.go(fd); 13162 } finally { 13163 tp.kill(); 13164 } 13165 } catch (IOException e) { 13166 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13167 } catch (RemoteException e) { 13168 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13169 } 13170 } 13171 } 13172 13173 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13174 int opti, boolean dumpAll, String dumpPackage) { 13175 boolean needSep = false; 13176 boolean onlyHistory = false; 13177 boolean printedAnything = false; 13178 13179 if ("history".equals(dumpPackage)) { 13180 if (opti < args.length && "-s".equals(args[opti])) { 13181 dumpAll = false; 13182 } 13183 onlyHistory = true; 13184 dumpPackage = null; 13185 } 13186 13187 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13188 if (!onlyHistory && dumpAll) { 13189 if (mRegisteredReceivers.size() > 0) { 13190 boolean printed = false; 13191 Iterator it = mRegisteredReceivers.values().iterator(); 13192 while (it.hasNext()) { 13193 ReceiverList r = (ReceiverList)it.next(); 13194 if (dumpPackage != null && (r.app == null || 13195 !dumpPackage.equals(r.app.info.packageName))) { 13196 continue; 13197 } 13198 if (!printed) { 13199 pw.println(" Registered Receivers:"); 13200 needSep = true; 13201 printed = true; 13202 printedAnything = true; 13203 } 13204 pw.print(" * "); pw.println(r); 13205 r.dump(pw, " "); 13206 } 13207 } 13208 13209 if (mReceiverResolver.dump(pw, needSep ? 13210 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13211 " ", dumpPackage, false)) { 13212 needSep = true; 13213 printedAnything = true; 13214 } 13215 } 13216 13217 for (BroadcastQueue q : mBroadcastQueues) { 13218 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13219 printedAnything |= needSep; 13220 } 13221 13222 needSep = true; 13223 13224 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13225 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13226 if (needSep) { 13227 pw.println(); 13228 } 13229 needSep = true; 13230 printedAnything = true; 13231 pw.print(" Sticky broadcasts for user "); 13232 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13233 StringBuilder sb = new StringBuilder(128); 13234 for (Map.Entry<String, ArrayList<Intent>> ent 13235 : mStickyBroadcasts.valueAt(user).entrySet()) { 13236 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13237 if (dumpAll) { 13238 pw.println(":"); 13239 ArrayList<Intent> intents = ent.getValue(); 13240 final int N = intents.size(); 13241 for (int i=0; i<N; i++) { 13242 sb.setLength(0); 13243 sb.append(" Intent: "); 13244 intents.get(i).toShortString(sb, false, true, false, false); 13245 pw.println(sb.toString()); 13246 Bundle bundle = intents.get(i).getExtras(); 13247 if (bundle != null) { 13248 pw.print(" "); 13249 pw.println(bundle.toString()); 13250 } 13251 } 13252 } else { 13253 pw.println(""); 13254 } 13255 } 13256 } 13257 } 13258 13259 if (!onlyHistory && dumpAll) { 13260 pw.println(); 13261 for (BroadcastQueue queue : mBroadcastQueues) { 13262 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13263 + queue.mBroadcastsScheduled); 13264 } 13265 pw.println(" mHandler:"); 13266 mHandler.dump(new PrintWriterPrinter(pw), " "); 13267 needSep = true; 13268 printedAnything = true; 13269 } 13270 13271 if (!printedAnything) { 13272 pw.println(" (nothing)"); 13273 } 13274 } 13275 13276 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13277 int opti, boolean dumpAll, String dumpPackage) { 13278 boolean needSep; 13279 boolean printedAnything = false; 13280 13281 ItemMatcher matcher = new ItemMatcher(); 13282 matcher.build(args, opti); 13283 13284 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13285 13286 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13287 printedAnything |= needSep; 13288 13289 if (mLaunchingProviders.size() > 0) { 13290 boolean printed = false; 13291 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13292 ContentProviderRecord r = mLaunchingProviders.get(i); 13293 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13294 continue; 13295 } 13296 if (!printed) { 13297 if (needSep) pw.println(); 13298 needSep = true; 13299 pw.println(" Launching content providers:"); 13300 printed = true; 13301 printedAnything = true; 13302 } 13303 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13304 pw.println(r); 13305 } 13306 } 13307 13308 if (mGrantedUriPermissions.size() > 0) { 13309 boolean printed = false; 13310 int dumpUid = -2; 13311 if (dumpPackage != null) { 13312 try { 13313 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13314 } catch (NameNotFoundException e) { 13315 dumpUid = -1; 13316 } 13317 } 13318 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13319 int uid = mGrantedUriPermissions.keyAt(i); 13320 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13321 continue; 13322 } 13323 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13324 if (!printed) { 13325 if (needSep) pw.println(); 13326 needSep = true; 13327 pw.println(" Granted Uri Permissions:"); 13328 printed = true; 13329 printedAnything = true; 13330 } 13331 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13332 for (UriPermission perm : perms.values()) { 13333 pw.print(" "); pw.println(perm); 13334 if (dumpAll) { 13335 perm.dump(pw, " "); 13336 } 13337 } 13338 } 13339 } 13340 13341 if (!printedAnything) { 13342 pw.println(" (nothing)"); 13343 } 13344 } 13345 13346 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13347 int opti, boolean dumpAll, String dumpPackage) { 13348 boolean printed = false; 13349 13350 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13351 13352 if (mIntentSenderRecords.size() > 0) { 13353 Iterator<WeakReference<PendingIntentRecord>> it 13354 = mIntentSenderRecords.values().iterator(); 13355 while (it.hasNext()) { 13356 WeakReference<PendingIntentRecord> ref = it.next(); 13357 PendingIntentRecord rec = ref != null ? ref.get(): null; 13358 if (dumpPackage != null && (rec == null 13359 || !dumpPackage.equals(rec.key.packageName))) { 13360 continue; 13361 } 13362 printed = true; 13363 if (rec != null) { 13364 pw.print(" * "); pw.println(rec); 13365 if (dumpAll) { 13366 rec.dump(pw, " "); 13367 } 13368 } else { 13369 pw.print(" * "); pw.println(ref); 13370 } 13371 } 13372 } 13373 13374 if (!printed) { 13375 pw.println(" (nothing)"); 13376 } 13377 } 13378 13379 private static final int dumpProcessList(PrintWriter pw, 13380 ActivityManagerService service, List list, 13381 String prefix, String normalLabel, String persistentLabel, 13382 String dumpPackage) { 13383 int numPers = 0; 13384 final int N = list.size()-1; 13385 for (int i=N; i>=0; i--) { 13386 ProcessRecord r = (ProcessRecord)list.get(i); 13387 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13388 continue; 13389 } 13390 pw.println(String.format("%s%s #%2d: %s", 13391 prefix, (r.persistent ? persistentLabel : normalLabel), 13392 i, r.toString())); 13393 if (r.persistent) { 13394 numPers++; 13395 } 13396 } 13397 return numPers; 13398 } 13399 13400 private static final boolean dumpProcessOomList(PrintWriter pw, 13401 ActivityManagerService service, List<ProcessRecord> origList, 13402 String prefix, String normalLabel, String persistentLabel, 13403 boolean inclDetails, String dumpPackage) { 13404 13405 ArrayList<Pair<ProcessRecord, Integer>> list 13406 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13407 for (int i=0; i<origList.size(); i++) { 13408 ProcessRecord r = origList.get(i); 13409 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13410 continue; 13411 } 13412 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13413 } 13414 13415 if (list.size() <= 0) { 13416 return false; 13417 } 13418 13419 Comparator<Pair<ProcessRecord, Integer>> comparator 13420 = new Comparator<Pair<ProcessRecord, Integer>>() { 13421 @Override 13422 public int compare(Pair<ProcessRecord, Integer> object1, 13423 Pair<ProcessRecord, Integer> object2) { 13424 if (object1.first.setAdj != object2.first.setAdj) { 13425 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13426 } 13427 if (object1.second.intValue() != object2.second.intValue()) { 13428 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13429 } 13430 return 0; 13431 } 13432 }; 13433 13434 Collections.sort(list, comparator); 13435 13436 final long curRealtime = SystemClock.elapsedRealtime(); 13437 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13438 final long curUptime = SystemClock.uptimeMillis(); 13439 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13440 13441 for (int i=list.size()-1; i>=0; i--) { 13442 ProcessRecord r = list.get(i).first; 13443 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13444 char schedGroup; 13445 switch (r.setSchedGroup) { 13446 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13447 schedGroup = 'B'; 13448 break; 13449 case Process.THREAD_GROUP_DEFAULT: 13450 schedGroup = 'F'; 13451 break; 13452 default: 13453 schedGroup = '?'; 13454 break; 13455 } 13456 char foreground; 13457 if (r.foregroundActivities) { 13458 foreground = 'A'; 13459 } else if (r.foregroundServices) { 13460 foreground = 'S'; 13461 } else { 13462 foreground = ' '; 13463 } 13464 String procState = ProcessList.makeProcStateString(r.curProcState); 13465 pw.print(prefix); 13466 pw.print(r.persistent ? persistentLabel : normalLabel); 13467 pw.print(" #"); 13468 int num = (origList.size()-1)-list.get(i).second; 13469 if (num < 10) pw.print(' '); 13470 pw.print(num); 13471 pw.print(": "); 13472 pw.print(oomAdj); 13473 pw.print(' '); 13474 pw.print(schedGroup); 13475 pw.print('/'); 13476 pw.print(foreground); 13477 pw.print('/'); 13478 pw.print(procState); 13479 pw.print(" trm:"); 13480 if (r.trimMemoryLevel < 10) pw.print(' '); 13481 pw.print(r.trimMemoryLevel); 13482 pw.print(' '); 13483 pw.print(r.toShortString()); 13484 pw.print(" ("); 13485 pw.print(r.adjType); 13486 pw.println(')'); 13487 if (r.adjSource != null || r.adjTarget != null) { 13488 pw.print(prefix); 13489 pw.print(" "); 13490 if (r.adjTarget instanceof ComponentName) { 13491 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13492 } else if (r.adjTarget != null) { 13493 pw.print(r.adjTarget.toString()); 13494 } else { 13495 pw.print("{null}"); 13496 } 13497 pw.print("<="); 13498 if (r.adjSource instanceof ProcessRecord) { 13499 pw.print("Proc{"); 13500 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13501 pw.println("}"); 13502 } else if (r.adjSource != null) { 13503 pw.println(r.adjSource.toString()); 13504 } else { 13505 pw.println("{null}"); 13506 } 13507 } 13508 if (inclDetails) { 13509 pw.print(prefix); 13510 pw.print(" "); 13511 pw.print("oom: max="); pw.print(r.maxAdj); 13512 pw.print(" curRaw="); pw.print(r.curRawAdj); 13513 pw.print(" setRaw="); pw.print(r.setRawAdj); 13514 pw.print(" cur="); pw.print(r.curAdj); 13515 pw.print(" set="); pw.println(r.setAdj); 13516 pw.print(prefix); 13517 pw.print(" "); 13518 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13519 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13520 pw.print(" lastPss="); pw.print(r.lastPss); 13521 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13522 pw.print(prefix); 13523 pw.print(" "); 13524 pw.print("cached="); pw.print(r.cached); 13525 pw.print(" empty="); pw.print(r.empty); 13526 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13527 13528 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13529 if (r.lastWakeTime != 0) { 13530 long wtime; 13531 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13532 synchronized (stats) { 13533 wtime = stats.getProcessWakeTime(r.info.uid, 13534 r.pid, curRealtime); 13535 } 13536 long timeUsed = wtime - r.lastWakeTime; 13537 pw.print(prefix); 13538 pw.print(" "); 13539 pw.print("keep awake over "); 13540 TimeUtils.formatDuration(realtimeSince, pw); 13541 pw.print(" used "); 13542 TimeUtils.formatDuration(timeUsed, pw); 13543 pw.print(" ("); 13544 pw.print((timeUsed*100)/realtimeSince); 13545 pw.println("%)"); 13546 } 13547 if (r.lastCpuTime != 0) { 13548 long timeUsed = r.curCpuTime - r.lastCpuTime; 13549 pw.print(prefix); 13550 pw.print(" "); 13551 pw.print("run cpu over "); 13552 TimeUtils.formatDuration(uptimeSince, pw); 13553 pw.print(" used "); 13554 TimeUtils.formatDuration(timeUsed, pw); 13555 pw.print(" ("); 13556 pw.print((timeUsed*100)/uptimeSince); 13557 pw.println("%)"); 13558 } 13559 } 13560 } 13561 } 13562 return true; 13563 } 13564 13565 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13566 String[] args) { 13567 ArrayList<ProcessRecord> procs; 13568 synchronized (this) { 13569 if (args != null && args.length > start 13570 && args[start].charAt(0) != '-') { 13571 procs = new ArrayList<ProcessRecord>(); 13572 int pid = -1; 13573 try { 13574 pid = Integer.parseInt(args[start]); 13575 } catch (NumberFormatException e) { 13576 } 13577 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13578 ProcessRecord proc = mLruProcesses.get(i); 13579 if (proc.pid == pid) { 13580 procs.add(proc); 13581 } else if (allPkgs && proc.pkgList != null 13582 && proc.pkgList.containsKey(args[start])) { 13583 procs.add(proc); 13584 } else if (proc.processName.equals(args[start])) { 13585 procs.add(proc); 13586 } 13587 } 13588 if (procs.size() <= 0) { 13589 return null; 13590 } 13591 } else { 13592 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13593 } 13594 } 13595 return procs; 13596 } 13597 13598 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13599 PrintWriter pw, String[] args) { 13600 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13601 if (procs == null) { 13602 pw.println("No process found for: " + args[0]); 13603 return; 13604 } 13605 13606 long uptime = SystemClock.uptimeMillis(); 13607 long realtime = SystemClock.elapsedRealtime(); 13608 pw.println("Applications Graphics Acceleration Info:"); 13609 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13610 13611 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13612 ProcessRecord r = procs.get(i); 13613 if (r.thread != null) { 13614 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13615 pw.flush(); 13616 try { 13617 TransferPipe tp = new TransferPipe(); 13618 try { 13619 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13620 tp.go(fd); 13621 } finally { 13622 tp.kill(); 13623 } 13624 } catch (IOException e) { 13625 pw.println("Failure while dumping the app: " + r); 13626 pw.flush(); 13627 } catch (RemoteException e) { 13628 pw.println("Got a RemoteException while dumping the app " + r); 13629 pw.flush(); 13630 } 13631 } 13632 } 13633 } 13634 13635 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13636 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13637 if (procs == null) { 13638 pw.println("No process found for: " + args[0]); 13639 return; 13640 } 13641 13642 pw.println("Applications Database Info:"); 13643 13644 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13645 ProcessRecord r = procs.get(i); 13646 if (r.thread != null) { 13647 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13648 pw.flush(); 13649 try { 13650 TransferPipe tp = new TransferPipe(); 13651 try { 13652 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13653 tp.go(fd); 13654 } finally { 13655 tp.kill(); 13656 } 13657 } catch (IOException e) { 13658 pw.println("Failure while dumping the app: " + r); 13659 pw.flush(); 13660 } catch (RemoteException e) { 13661 pw.println("Got a RemoteException while dumping the app " + r); 13662 pw.flush(); 13663 } 13664 } 13665 } 13666 } 13667 13668 final static class MemItem { 13669 final boolean isProc; 13670 final String label; 13671 final String shortLabel; 13672 final long pss; 13673 final int id; 13674 final boolean hasActivities; 13675 ArrayList<MemItem> subitems; 13676 13677 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13678 boolean _hasActivities) { 13679 isProc = true; 13680 label = _label; 13681 shortLabel = _shortLabel; 13682 pss = _pss; 13683 id = _id; 13684 hasActivities = _hasActivities; 13685 } 13686 13687 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13688 isProc = false; 13689 label = _label; 13690 shortLabel = _shortLabel; 13691 pss = _pss; 13692 id = _id; 13693 hasActivities = false; 13694 } 13695 } 13696 13697 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13698 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13699 if (sort && !isCompact) { 13700 Collections.sort(items, new Comparator<MemItem>() { 13701 @Override 13702 public int compare(MemItem lhs, MemItem rhs) { 13703 if (lhs.pss < rhs.pss) { 13704 return 1; 13705 } else if (lhs.pss > rhs.pss) { 13706 return -1; 13707 } 13708 return 0; 13709 } 13710 }); 13711 } 13712 13713 for (int i=0; i<items.size(); i++) { 13714 MemItem mi = items.get(i); 13715 if (!isCompact) { 13716 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13717 } else if (mi.isProc) { 13718 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13719 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13720 pw.println(mi.hasActivities ? ",a" : ",e"); 13721 } else { 13722 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13723 pw.println(mi.pss); 13724 } 13725 if (mi.subitems != null) { 13726 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13727 true, isCompact); 13728 } 13729 } 13730 } 13731 13732 // These are in KB. 13733 static final long[] DUMP_MEM_BUCKETS = new long[] { 13734 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13735 120*1024, 160*1024, 200*1024, 13736 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13737 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13738 }; 13739 13740 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13741 boolean stackLike) { 13742 int start = label.lastIndexOf('.'); 13743 if (start >= 0) start++; 13744 else start = 0; 13745 int end = label.length(); 13746 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13747 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13748 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13749 out.append(bucket); 13750 out.append(stackLike ? "MB." : "MB "); 13751 out.append(label, start, end); 13752 return; 13753 } 13754 } 13755 out.append(memKB/1024); 13756 out.append(stackLike ? "MB." : "MB "); 13757 out.append(label, start, end); 13758 } 13759 13760 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13761 ProcessList.NATIVE_ADJ, 13762 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13763 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13764 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13765 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13766 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13767 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13768 }; 13769 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13770 "Native", 13771 "System", "Persistent", "Persistent Service", "Foreground", 13772 "Visible", "Perceptible", 13773 "Heavy Weight", "Backup", 13774 "A Services", "Home", 13775 "Previous", "B Services", "Cached" 13776 }; 13777 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13778 "native", 13779 "sys", "pers", "persvc", "fore", 13780 "vis", "percept", 13781 "heavy", "backup", 13782 "servicea", "home", 13783 "prev", "serviceb", "cached" 13784 }; 13785 13786 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13787 long realtime, boolean isCheckinRequest, boolean isCompact) { 13788 if (isCheckinRequest || isCompact) { 13789 // short checkin version 13790 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13791 } else { 13792 pw.println("Applications Memory Usage (kB):"); 13793 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13794 } 13795 } 13796 13797 private static final int KSM_SHARED = 0; 13798 private static final int KSM_SHARING = 1; 13799 private static final int KSM_UNSHARED = 2; 13800 private static final int KSM_VOLATILE = 3; 13801 13802 private final long[] getKsmInfo() { 13803 long[] longOut = new long[4]; 13804 final int[] SINGLE_LONG_FORMAT = new int[] { 13805 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13806 }; 13807 long[] longTmp = new long[1]; 13808 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13809 SINGLE_LONG_FORMAT, null, longTmp, null); 13810 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13811 longTmp[0] = 0; 13812 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13813 SINGLE_LONG_FORMAT, null, longTmp, null); 13814 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13815 longTmp[0] = 0; 13816 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13817 SINGLE_LONG_FORMAT, null, longTmp, null); 13818 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13819 longTmp[0] = 0; 13820 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13821 SINGLE_LONG_FORMAT, null, longTmp, null); 13822 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13823 return longOut; 13824 } 13825 13826 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13827 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13828 boolean dumpDetails = false; 13829 boolean dumpFullDetails = false; 13830 boolean dumpDalvik = false; 13831 boolean oomOnly = false; 13832 boolean isCompact = false; 13833 boolean localOnly = false; 13834 boolean packages = false; 13835 13836 int opti = 0; 13837 while (opti < args.length) { 13838 String opt = args[opti]; 13839 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13840 break; 13841 } 13842 opti++; 13843 if ("-a".equals(opt)) { 13844 dumpDetails = true; 13845 dumpFullDetails = true; 13846 dumpDalvik = true; 13847 } else if ("-d".equals(opt)) { 13848 dumpDalvik = true; 13849 } else if ("-c".equals(opt)) { 13850 isCompact = true; 13851 } else if ("--oom".equals(opt)) { 13852 oomOnly = true; 13853 } else if ("--local".equals(opt)) { 13854 localOnly = true; 13855 } else if ("--package".equals(opt)) { 13856 packages = true; 13857 } else if ("-h".equals(opt)) { 13858 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13859 pw.println(" -a: include all available information for each process."); 13860 pw.println(" -d: include dalvik details when dumping process details."); 13861 pw.println(" -c: dump in a compact machine-parseable representation."); 13862 pw.println(" --oom: only show processes organized by oom adj."); 13863 pw.println(" --local: only collect details locally, don't call process."); 13864 pw.println(" --package: interpret process arg as package, dumping all"); 13865 pw.println(" processes that have loaded that package."); 13866 pw.println("If [process] is specified it can be the name or "); 13867 pw.println("pid of a specific process to dump."); 13868 return; 13869 } else { 13870 pw.println("Unknown argument: " + opt + "; use -h for help"); 13871 } 13872 } 13873 13874 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13875 long uptime = SystemClock.uptimeMillis(); 13876 long realtime = SystemClock.elapsedRealtime(); 13877 final long[] tmpLong = new long[1]; 13878 13879 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13880 if (procs == null) { 13881 // No Java processes. Maybe they want to print a native process. 13882 if (args != null && args.length > opti 13883 && args[opti].charAt(0) != '-') { 13884 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13885 = new ArrayList<ProcessCpuTracker.Stats>(); 13886 updateCpuStatsNow(); 13887 int findPid = -1; 13888 try { 13889 findPid = Integer.parseInt(args[opti]); 13890 } catch (NumberFormatException e) { 13891 } 13892 synchronized (mProcessCpuTracker) { 13893 final int N = mProcessCpuTracker.countStats(); 13894 for (int i=0; i<N; i++) { 13895 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13896 if (st.pid == findPid || (st.baseName != null 13897 && st.baseName.equals(args[opti]))) { 13898 nativeProcs.add(st); 13899 } 13900 } 13901 } 13902 if (nativeProcs.size() > 0) { 13903 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13904 isCompact); 13905 Debug.MemoryInfo mi = null; 13906 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13907 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13908 final int pid = r.pid; 13909 if (!isCheckinRequest && dumpDetails) { 13910 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13911 } 13912 if (mi == null) { 13913 mi = new Debug.MemoryInfo(); 13914 } 13915 if (dumpDetails || (!brief && !oomOnly)) { 13916 Debug.getMemoryInfo(pid, mi); 13917 } else { 13918 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13919 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13920 } 13921 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13922 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13923 if (isCheckinRequest) { 13924 pw.println(); 13925 } 13926 } 13927 return; 13928 } 13929 } 13930 pw.println("No process found for: " + args[opti]); 13931 return; 13932 } 13933 13934 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13935 dumpDetails = true; 13936 } 13937 13938 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13939 13940 String[] innerArgs = new String[args.length-opti]; 13941 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13942 13943 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13944 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13945 long nativePss = 0; 13946 long dalvikPss = 0; 13947 long otherPss = 0; 13948 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13949 13950 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13951 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13952 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13953 13954 long totalPss = 0; 13955 long cachedPss = 0; 13956 13957 Debug.MemoryInfo mi = null; 13958 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13959 final ProcessRecord r = procs.get(i); 13960 final IApplicationThread thread; 13961 final int pid; 13962 final int oomAdj; 13963 final boolean hasActivities; 13964 synchronized (this) { 13965 thread = r.thread; 13966 pid = r.pid; 13967 oomAdj = r.getSetAdjWithServices(); 13968 hasActivities = r.activities.size() > 0; 13969 } 13970 if (thread != null) { 13971 if (!isCheckinRequest && dumpDetails) { 13972 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13973 } 13974 if (mi == null) { 13975 mi = new Debug.MemoryInfo(); 13976 } 13977 if (dumpDetails || (!brief && !oomOnly)) { 13978 Debug.getMemoryInfo(pid, mi); 13979 } else { 13980 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13981 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13982 } 13983 if (dumpDetails) { 13984 if (localOnly) { 13985 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13986 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13987 if (isCheckinRequest) { 13988 pw.println(); 13989 } 13990 } else { 13991 try { 13992 pw.flush(); 13993 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13994 dumpDalvik, innerArgs); 13995 } catch (RemoteException e) { 13996 if (!isCheckinRequest) { 13997 pw.println("Got RemoteException!"); 13998 pw.flush(); 13999 } 14000 } 14001 } 14002 } 14003 14004 final long myTotalPss = mi.getTotalPss(); 14005 final long myTotalUss = mi.getTotalUss(); 14006 14007 synchronized (this) { 14008 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14009 // Record this for posterity if the process has been stable. 14010 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14011 } 14012 } 14013 14014 if (!isCheckinRequest && mi != null) { 14015 totalPss += myTotalPss; 14016 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14017 (hasActivities ? " / activities)" : ")"), 14018 r.processName, myTotalPss, pid, hasActivities); 14019 procMems.add(pssItem); 14020 procMemsMap.put(pid, pssItem); 14021 14022 nativePss += mi.nativePss; 14023 dalvikPss += mi.dalvikPss; 14024 otherPss += mi.otherPss; 14025 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14026 long mem = mi.getOtherPss(j); 14027 miscPss[j] += mem; 14028 otherPss -= mem; 14029 } 14030 14031 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14032 cachedPss += myTotalPss; 14033 } 14034 14035 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14036 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14037 || oomIndex == (oomPss.length-1)) { 14038 oomPss[oomIndex] += myTotalPss; 14039 if (oomProcs[oomIndex] == null) { 14040 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14041 } 14042 oomProcs[oomIndex].add(pssItem); 14043 break; 14044 } 14045 } 14046 } 14047 } 14048 } 14049 14050 long nativeProcTotalPss = 0; 14051 14052 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14053 // If we are showing aggregations, also look for native processes to 14054 // include so that our aggregations are more accurate. 14055 updateCpuStatsNow(); 14056 synchronized (mProcessCpuTracker) { 14057 final int N = mProcessCpuTracker.countStats(); 14058 for (int i=0; i<N; i++) { 14059 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14060 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14061 if (mi == null) { 14062 mi = new Debug.MemoryInfo(); 14063 } 14064 if (!brief && !oomOnly) { 14065 Debug.getMemoryInfo(st.pid, mi); 14066 } else { 14067 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14068 mi.nativePrivateDirty = (int)tmpLong[0]; 14069 } 14070 14071 final long myTotalPss = mi.getTotalPss(); 14072 totalPss += myTotalPss; 14073 nativeProcTotalPss += myTotalPss; 14074 14075 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14076 st.name, myTotalPss, st.pid, false); 14077 procMems.add(pssItem); 14078 14079 nativePss += mi.nativePss; 14080 dalvikPss += mi.dalvikPss; 14081 otherPss += mi.otherPss; 14082 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14083 long mem = mi.getOtherPss(j); 14084 miscPss[j] += mem; 14085 otherPss -= mem; 14086 } 14087 oomPss[0] += myTotalPss; 14088 if (oomProcs[0] == null) { 14089 oomProcs[0] = new ArrayList<MemItem>(); 14090 } 14091 oomProcs[0].add(pssItem); 14092 } 14093 } 14094 } 14095 14096 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14097 14098 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14099 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14100 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14101 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14102 String label = Debug.MemoryInfo.getOtherLabel(j); 14103 catMems.add(new MemItem(label, label, miscPss[j], j)); 14104 } 14105 14106 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14107 for (int j=0; j<oomPss.length; j++) { 14108 if (oomPss[j] != 0) { 14109 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14110 : DUMP_MEM_OOM_LABEL[j]; 14111 MemItem item = new MemItem(label, label, oomPss[j], 14112 DUMP_MEM_OOM_ADJ[j]); 14113 item.subitems = oomProcs[j]; 14114 oomMems.add(item); 14115 } 14116 } 14117 14118 if (!brief && !oomOnly && !isCompact) { 14119 pw.println(); 14120 pw.println("Total PSS by process:"); 14121 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14122 pw.println(); 14123 } 14124 if (!isCompact) { 14125 pw.println("Total PSS by OOM adjustment:"); 14126 } 14127 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14128 if (!brief && !oomOnly) { 14129 PrintWriter out = categoryPw != null ? categoryPw : pw; 14130 if (!isCompact) { 14131 out.println(); 14132 out.println("Total PSS by category:"); 14133 } 14134 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14135 } 14136 if (!isCompact) { 14137 pw.println(); 14138 } 14139 MemInfoReader memInfo = new MemInfoReader(); 14140 memInfo.readMemInfo(); 14141 if (nativeProcTotalPss > 0) { 14142 synchronized (this) { 14143 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14144 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14145 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14146 } 14147 } 14148 if (!brief) { 14149 if (!isCompact) { 14150 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14151 pw.print(" kB (status "); 14152 switch (mLastMemoryLevel) { 14153 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14154 pw.println("normal)"); 14155 break; 14156 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14157 pw.println("moderate)"); 14158 break; 14159 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14160 pw.println("low)"); 14161 break; 14162 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14163 pw.println("critical)"); 14164 break; 14165 default: 14166 pw.print(mLastMemoryLevel); 14167 pw.println(")"); 14168 break; 14169 } 14170 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14171 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14172 pw.print(cachedPss); pw.print(" cached pss + "); 14173 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14174 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14175 } else { 14176 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14177 pw.print(cachedPss + memInfo.getCachedSizeKb() 14178 + memInfo.getFreeSizeKb()); pw.print(","); 14179 pw.println(totalPss - cachedPss); 14180 } 14181 } 14182 if (!isCompact) { 14183 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14184 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14185 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14186 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14187 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14188 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14189 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14190 } 14191 if (!brief) { 14192 if (memInfo.getZramTotalSizeKb() != 0) { 14193 if (!isCompact) { 14194 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14195 pw.print(" kB physical used for "); 14196 pw.print(memInfo.getSwapTotalSizeKb() 14197 - memInfo.getSwapFreeSizeKb()); 14198 pw.print(" kB in swap ("); 14199 pw.print(memInfo.getSwapTotalSizeKb()); 14200 pw.println(" kB total swap)"); 14201 } else { 14202 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14203 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14204 pw.println(memInfo.getSwapFreeSizeKb()); 14205 } 14206 } 14207 final long[] ksm = getKsmInfo(); 14208 if (!isCompact) { 14209 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14210 || ksm[KSM_VOLATILE] != 0) { 14211 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14212 pw.print(" kB saved from shared "); 14213 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14214 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14215 pw.print(" kB unshared; "); 14216 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14217 } 14218 pw.print(" Tuning: "); 14219 pw.print(ActivityManager.staticGetMemoryClass()); 14220 pw.print(" (large "); 14221 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14222 pw.print("), oom "); 14223 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14224 pw.print(" kB"); 14225 pw.print(", restore limit "); 14226 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14227 pw.print(" kB"); 14228 if (ActivityManager.isLowRamDeviceStatic()) { 14229 pw.print(" (low-ram)"); 14230 } 14231 if (ActivityManager.isHighEndGfx()) { 14232 pw.print(" (high-end-gfx)"); 14233 } 14234 pw.println(); 14235 } else { 14236 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14237 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14238 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14239 pw.print("tuning,"); 14240 pw.print(ActivityManager.staticGetMemoryClass()); 14241 pw.print(','); 14242 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14243 pw.print(','); 14244 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14245 if (ActivityManager.isLowRamDeviceStatic()) { 14246 pw.print(",low-ram"); 14247 } 14248 if (ActivityManager.isHighEndGfx()) { 14249 pw.print(",high-end-gfx"); 14250 } 14251 pw.println(); 14252 } 14253 } 14254 } 14255 } 14256 14257 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14258 String name) { 14259 sb.append(" "); 14260 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14261 sb.append(' '); 14262 sb.append(ProcessList.makeProcStateString(procState)); 14263 sb.append(' '); 14264 ProcessList.appendRamKb(sb, pss); 14265 sb.append(" kB: "); 14266 sb.append(name); 14267 } 14268 14269 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14270 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14271 sb.append(" ("); 14272 sb.append(mi.pid); 14273 sb.append(") "); 14274 sb.append(mi.adjType); 14275 sb.append('\n'); 14276 if (mi.adjReason != null) { 14277 sb.append(" "); 14278 sb.append(mi.adjReason); 14279 sb.append('\n'); 14280 } 14281 } 14282 14283 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14284 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14285 for (int i=0, N=memInfos.size(); i<N; i++) { 14286 ProcessMemInfo mi = memInfos.get(i); 14287 infoMap.put(mi.pid, mi); 14288 } 14289 updateCpuStatsNow(); 14290 synchronized (mProcessCpuTracker) { 14291 final int N = mProcessCpuTracker.countStats(); 14292 for (int i=0; i<N; i++) { 14293 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14294 if (st.vsize > 0) { 14295 long pss = Debug.getPss(st.pid, null); 14296 if (pss > 0) { 14297 if (infoMap.indexOfKey(st.pid) < 0) { 14298 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14299 ProcessList.NATIVE_ADJ, -1, "native", null); 14300 mi.pss = pss; 14301 memInfos.add(mi); 14302 } 14303 } 14304 } 14305 } 14306 } 14307 14308 long totalPss = 0; 14309 for (int i=0, N=memInfos.size(); i<N; i++) { 14310 ProcessMemInfo mi = memInfos.get(i); 14311 if (mi.pss == 0) { 14312 mi.pss = Debug.getPss(mi.pid, null); 14313 } 14314 totalPss += mi.pss; 14315 } 14316 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14317 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14318 if (lhs.oomAdj != rhs.oomAdj) { 14319 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14320 } 14321 if (lhs.pss != rhs.pss) { 14322 return lhs.pss < rhs.pss ? 1 : -1; 14323 } 14324 return 0; 14325 } 14326 }); 14327 14328 StringBuilder tag = new StringBuilder(128); 14329 StringBuilder stack = new StringBuilder(128); 14330 tag.append("Low on memory -- "); 14331 appendMemBucket(tag, totalPss, "total", false); 14332 appendMemBucket(stack, totalPss, "total", true); 14333 14334 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14335 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14336 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14337 14338 boolean firstLine = true; 14339 int lastOomAdj = Integer.MIN_VALUE; 14340 long extraNativeRam = 0; 14341 long cachedPss = 0; 14342 for (int i=0, N=memInfos.size(); i<N; i++) { 14343 ProcessMemInfo mi = memInfos.get(i); 14344 14345 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14346 cachedPss += mi.pss; 14347 } 14348 14349 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14350 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14351 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14352 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14353 if (lastOomAdj != mi.oomAdj) { 14354 lastOomAdj = mi.oomAdj; 14355 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14356 tag.append(" / "); 14357 } 14358 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14359 if (firstLine) { 14360 stack.append(":"); 14361 firstLine = false; 14362 } 14363 stack.append("\n\t at "); 14364 } else { 14365 stack.append("$"); 14366 } 14367 } else { 14368 tag.append(" "); 14369 stack.append("$"); 14370 } 14371 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14372 appendMemBucket(tag, mi.pss, mi.name, false); 14373 } 14374 appendMemBucket(stack, mi.pss, mi.name, true); 14375 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14376 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14377 stack.append("("); 14378 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14379 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14380 stack.append(DUMP_MEM_OOM_LABEL[k]); 14381 stack.append(":"); 14382 stack.append(DUMP_MEM_OOM_ADJ[k]); 14383 } 14384 } 14385 stack.append(")"); 14386 } 14387 } 14388 14389 appendMemInfo(fullNativeBuilder, mi); 14390 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14391 // The short form only has native processes that are >= 1MB. 14392 if (mi.pss >= 1000) { 14393 appendMemInfo(shortNativeBuilder, mi); 14394 } else { 14395 extraNativeRam += mi.pss; 14396 } 14397 } else { 14398 // Short form has all other details, but if we have collected RAM 14399 // from smaller native processes let's dump a summary of that. 14400 if (extraNativeRam > 0) { 14401 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14402 -1, extraNativeRam, "(Other native)"); 14403 shortNativeBuilder.append('\n'); 14404 extraNativeRam = 0; 14405 } 14406 appendMemInfo(fullJavaBuilder, mi); 14407 } 14408 } 14409 14410 fullJavaBuilder.append(" "); 14411 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14412 fullJavaBuilder.append(" kB: TOTAL\n"); 14413 14414 MemInfoReader memInfo = new MemInfoReader(); 14415 memInfo.readMemInfo(); 14416 final long[] infos = memInfo.getRawInfo(); 14417 14418 StringBuilder memInfoBuilder = new StringBuilder(1024); 14419 Debug.getMemInfo(infos); 14420 memInfoBuilder.append(" MemInfo: "); 14421 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14422 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14423 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14424 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14425 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14426 memInfoBuilder.append(" "); 14427 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14428 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14429 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14430 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14431 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14432 memInfoBuilder.append(" ZRAM: "); 14433 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14434 memInfoBuilder.append(" kB RAM, "); 14435 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14436 memInfoBuilder.append(" kB swap total, "); 14437 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14438 memInfoBuilder.append(" kB swap free\n"); 14439 } 14440 final long[] ksm = getKsmInfo(); 14441 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14442 || ksm[KSM_VOLATILE] != 0) { 14443 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14444 memInfoBuilder.append(" kB saved from shared "); 14445 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14446 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14447 memInfoBuilder.append(" kB unshared; "); 14448 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14449 } 14450 memInfoBuilder.append(" Free RAM: "); 14451 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14452 + memInfo.getFreeSizeKb()); 14453 memInfoBuilder.append(" kB\n"); 14454 memInfoBuilder.append(" Used RAM: "); 14455 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14456 memInfoBuilder.append(" kB\n"); 14457 memInfoBuilder.append(" Lost RAM: "); 14458 memInfoBuilder.append(memInfo.getTotalSizeKb() 14459 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14460 - memInfo.getKernelUsedSizeKb()); 14461 memInfoBuilder.append(" kB\n"); 14462 Slog.i(TAG, "Low on memory:"); 14463 Slog.i(TAG, shortNativeBuilder.toString()); 14464 Slog.i(TAG, fullJavaBuilder.toString()); 14465 Slog.i(TAG, memInfoBuilder.toString()); 14466 14467 StringBuilder dropBuilder = new StringBuilder(1024); 14468 /* 14469 StringWriter oomSw = new StringWriter(); 14470 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14471 StringWriter catSw = new StringWriter(); 14472 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14473 String[] emptyArgs = new String[] { }; 14474 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14475 oomPw.flush(); 14476 String oomString = oomSw.toString(); 14477 */ 14478 dropBuilder.append("Low on memory:"); 14479 dropBuilder.append(stack); 14480 dropBuilder.append('\n'); 14481 dropBuilder.append(fullNativeBuilder); 14482 dropBuilder.append(fullJavaBuilder); 14483 dropBuilder.append('\n'); 14484 dropBuilder.append(memInfoBuilder); 14485 dropBuilder.append('\n'); 14486 /* 14487 dropBuilder.append(oomString); 14488 dropBuilder.append('\n'); 14489 */ 14490 StringWriter catSw = new StringWriter(); 14491 synchronized (ActivityManagerService.this) { 14492 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14493 String[] emptyArgs = new String[] { }; 14494 catPw.println(); 14495 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14496 catPw.println(); 14497 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14498 false, false, null); 14499 catPw.println(); 14500 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14501 catPw.flush(); 14502 } 14503 dropBuilder.append(catSw.toString()); 14504 addErrorToDropBox("lowmem", null, "system_server", null, 14505 null, tag.toString(), dropBuilder.toString(), null, null); 14506 //Slog.i(TAG, "Sent to dropbox:"); 14507 //Slog.i(TAG, dropBuilder.toString()); 14508 synchronized (ActivityManagerService.this) { 14509 long now = SystemClock.uptimeMillis(); 14510 if (mLastMemUsageReportTime < now) { 14511 mLastMemUsageReportTime = now; 14512 } 14513 } 14514 } 14515 14516 /** 14517 * Searches array of arguments for the specified string 14518 * @param args array of argument strings 14519 * @param value value to search for 14520 * @return true if the value is contained in the array 14521 */ 14522 private static boolean scanArgs(String[] args, String value) { 14523 if (args != null) { 14524 for (String arg : args) { 14525 if (value.equals(arg)) { 14526 return true; 14527 } 14528 } 14529 } 14530 return false; 14531 } 14532 14533 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14534 ContentProviderRecord cpr, boolean always) { 14535 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14536 14537 if (!inLaunching || always) { 14538 synchronized (cpr) { 14539 cpr.launchingApp = null; 14540 cpr.notifyAll(); 14541 } 14542 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14543 String names[] = cpr.info.authority.split(";"); 14544 for (int j = 0; j < names.length; j++) { 14545 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14546 } 14547 } 14548 14549 for (int i=0; i<cpr.connections.size(); i++) { 14550 ContentProviderConnection conn = cpr.connections.get(i); 14551 if (conn.waiting) { 14552 // If this connection is waiting for the provider, then we don't 14553 // need to mess with its process unless we are always removing 14554 // or for some reason the provider is not currently launching. 14555 if (inLaunching && !always) { 14556 continue; 14557 } 14558 } 14559 ProcessRecord capp = conn.client; 14560 conn.dead = true; 14561 if (conn.stableCount > 0) { 14562 if (!capp.persistent && capp.thread != null 14563 && capp.pid != 0 14564 && capp.pid != MY_PID) { 14565 capp.kill("depends on provider " 14566 + cpr.name.flattenToShortString() 14567 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14568 } 14569 } else if (capp.thread != null && conn.provider.provider != null) { 14570 try { 14571 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14572 } catch (RemoteException e) { 14573 } 14574 // In the protocol here, we don't expect the client to correctly 14575 // clean up this connection, we'll just remove it. 14576 cpr.connections.remove(i); 14577 conn.client.conProviders.remove(conn); 14578 } 14579 } 14580 14581 if (inLaunching && always) { 14582 mLaunchingProviders.remove(cpr); 14583 } 14584 return inLaunching; 14585 } 14586 14587 /** 14588 * Main code for cleaning up a process when it has gone away. This is 14589 * called both as a result of the process dying, or directly when stopping 14590 * a process when running in single process mode. 14591 * 14592 * @return Returns true if the given process has been restarted, so the 14593 * app that was passed in must remain on the process lists. 14594 */ 14595 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14596 boolean restarting, boolean allowRestart, int index) { 14597 if (index >= 0) { 14598 removeLruProcessLocked(app); 14599 ProcessList.remove(app.pid); 14600 } 14601 14602 mProcessesToGc.remove(app); 14603 mPendingPssProcesses.remove(app); 14604 14605 // Dismiss any open dialogs. 14606 if (app.crashDialog != null && !app.forceCrashReport) { 14607 app.crashDialog.dismiss(); 14608 app.crashDialog = null; 14609 } 14610 if (app.anrDialog != null) { 14611 app.anrDialog.dismiss(); 14612 app.anrDialog = null; 14613 } 14614 if (app.waitDialog != null) { 14615 app.waitDialog.dismiss(); 14616 app.waitDialog = null; 14617 } 14618 14619 app.crashing = false; 14620 app.notResponding = false; 14621 14622 app.resetPackageList(mProcessStats); 14623 app.unlinkDeathRecipient(); 14624 app.makeInactive(mProcessStats); 14625 app.waitingToKill = null; 14626 app.forcingToForeground = null; 14627 updateProcessForegroundLocked(app, false, false); 14628 app.foregroundActivities = false; 14629 app.hasShownUi = false; 14630 app.treatLikeActivity = false; 14631 app.hasAboveClient = false; 14632 app.hasClientActivities = false; 14633 14634 mServices.killServicesLocked(app, allowRestart); 14635 14636 boolean restart = false; 14637 14638 // Remove published content providers. 14639 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14640 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14641 final boolean always = app.bad || !allowRestart; 14642 if (removeDyingProviderLocked(app, cpr, always) || always) { 14643 // We left the provider in the launching list, need to 14644 // restart it. 14645 restart = true; 14646 } 14647 14648 cpr.provider = null; 14649 cpr.proc = null; 14650 } 14651 app.pubProviders.clear(); 14652 14653 // Take care of any launching providers waiting for this process. 14654 if (checkAppInLaunchingProvidersLocked(app, false)) { 14655 restart = true; 14656 } 14657 14658 // Unregister from connected content providers. 14659 if (!app.conProviders.isEmpty()) { 14660 for (int i=0; i<app.conProviders.size(); i++) { 14661 ContentProviderConnection conn = app.conProviders.get(i); 14662 conn.provider.connections.remove(conn); 14663 } 14664 app.conProviders.clear(); 14665 } 14666 14667 // At this point there may be remaining entries in mLaunchingProviders 14668 // where we were the only one waiting, so they are no longer of use. 14669 // Look for these and clean up if found. 14670 // XXX Commented out for now. Trying to figure out a way to reproduce 14671 // the actual situation to identify what is actually going on. 14672 if (false) { 14673 for (int i=0; i<mLaunchingProviders.size(); i++) { 14674 ContentProviderRecord cpr = (ContentProviderRecord) 14675 mLaunchingProviders.get(i); 14676 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14677 synchronized (cpr) { 14678 cpr.launchingApp = null; 14679 cpr.notifyAll(); 14680 } 14681 } 14682 } 14683 } 14684 14685 skipCurrentReceiverLocked(app); 14686 14687 // Unregister any receivers. 14688 for (int i=app.receivers.size()-1; i>=0; i--) { 14689 removeReceiverLocked(app.receivers.valueAt(i)); 14690 } 14691 app.receivers.clear(); 14692 14693 // If the app is undergoing backup, tell the backup manager about it 14694 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14695 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14696 + mBackupTarget.appInfo + " died during backup"); 14697 try { 14698 IBackupManager bm = IBackupManager.Stub.asInterface( 14699 ServiceManager.getService(Context.BACKUP_SERVICE)); 14700 bm.agentDisconnected(app.info.packageName); 14701 } catch (RemoteException e) { 14702 // can't happen; backup manager is local 14703 } 14704 } 14705 14706 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14707 ProcessChangeItem item = mPendingProcessChanges.get(i); 14708 if (item.pid == app.pid) { 14709 mPendingProcessChanges.remove(i); 14710 mAvailProcessChanges.add(item); 14711 } 14712 } 14713 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14714 14715 // If the caller is restarting this app, then leave it in its 14716 // current lists and let the caller take care of it. 14717 if (restarting) { 14718 return false; 14719 } 14720 14721 if (!app.persistent || app.isolated) { 14722 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14723 "Removing non-persistent process during cleanup: " + app); 14724 mProcessNames.remove(app.processName, app.uid); 14725 mIsolatedProcesses.remove(app.uid); 14726 if (mHeavyWeightProcess == app) { 14727 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14728 mHeavyWeightProcess.userId, 0)); 14729 mHeavyWeightProcess = null; 14730 } 14731 } else if (!app.removed) { 14732 // This app is persistent, so we need to keep its record around. 14733 // If it is not already on the pending app list, add it there 14734 // and start a new process for it. 14735 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14736 mPersistentStartingProcesses.add(app); 14737 restart = true; 14738 } 14739 } 14740 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14741 "Clean-up removing on hold: " + app); 14742 mProcessesOnHold.remove(app); 14743 14744 if (app == mHomeProcess) { 14745 mHomeProcess = null; 14746 } 14747 if (app == mPreviousProcess) { 14748 mPreviousProcess = null; 14749 } 14750 14751 if (restart && !app.isolated) { 14752 // We have components that still need to be running in the 14753 // process, so re-launch it. 14754 if (index < 0) { 14755 ProcessList.remove(app.pid); 14756 } 14757 mProcessNames.put(app.processName, app.uid, app); 14758 startProcessLocked(app, "restart", app.processName); 14759 return true; 14760 } else if (app.pid > 0 && app.pid != MY_PID) { 14761 // Goodbye! 14762 boolean removed; 14763 synchronized (mPidsSelfLocked) { 14764 mPidsSelfLocked.remove(app.pid); 14765 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14766 } 14767 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14768 if (app.isolated) { 14769 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14770 } 14771 app.setPid(0); 14772 } 14773 return false; 14774 } 14775 14776 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14777 // Look through the content providers we are waiting to have launched, 14778 // and if any run in this process then either schedule a restart of 14779 // the process or kill the client waiting for it if this process has 14780 // gone bad. 14781 int NL = mLaunchingProviders.size(); 14782 boolean restart = false; 14783 for (int i=0; i<NL; i++) { 14784 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14785 if (cpr.launchingApp == app) { 14786 if (!alwaysBad && !app.bad) { 14787 restart = true; 14788 } else { 14789 removeDyingProviderLocked(app, cpr, true); 14790 // cpr should have been removed from mLaunchingProviders 14791 NL = mLaunchingProviders.size(); 14792 i--; 14793 } 14794 } 14795 } 14796 return restart; 14797 } 14798 14799 // ========================================================= 14800 // SERVICES 14801 // ========================================================= 14802 14803 @Override 14804 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14805 int flags) { 14806 enforceNotIsolatedCaller("getServices"); 14807 synchronized (this) { 14808 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14809 } 14810 } 14811 14812 @Override 14813 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14814 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14815 synchronized (this) { 14816 return mServices.getRunningServiceControlPanelLocked(name); 14817 } 14818 } 14819 14820 @Override 14821 public ComponentName startService(IApplicationThread caller, Intent service, 14822 String resolvedType, int userId) { 14823 enforceNotIsolatedCaller("startService"); 14824 // Refuse possible leaked file descriptors 14825 if (service != null && service.hasFileDescriptors() == true) { 14826 throw new IllegalArgumentException("File descriptors passed in Intent"); 14827 } 14828 14829 if (DEBUG_SERVICE) 14830 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14831 synchronized(this) { 14832 final int callingPid = Binder.getCallingPid(); 14833 final int callingUid = Binder.getCallingUid(); 14834 final long origId = Binder.clearCallingIdentity(); 14835 ComponentName res = mServices.startServiceLocked(caller, service, 14836 resolvedType, callingPid, callingUid, userId); 14837 Binder.restoreCallingIdentity(origId); 14838 return res; 14839 } 14840 } 14841 14842 ComponentName startServiceInPackage(int uid, 14843 Intent service, String resolvedType, int userId) { 14844 synchronized(this) { 14845 if (DEBUG_SERVICE) 14846 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14847 final long origId = Binder.clearCallingIdentity(); 14848 ComponentName res = mServices.startServiceLocked(null, service, 14849 resolvedType, -1, uid, userId); 14850 Binder.restoreCallingIdentity(origId); 14851 return res; 14852 } 14853 } 14854 14855 @Override 14856 public int stopService(IApplicationThread caller, Intent service, 14857 String resolvedType, int userId) { 14858 enforceNotIsolatedCaller("stopService"); 14859 // Refuse possible leaked file descriptors 14860 if (service != null && service.hasFileDescriptors() == true) { 14861 throw new IllegalArgumentException("File descriptors passed in Intent"); 14862 } 14863 14864 synchronized(this) { 14865 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14866 } 14867 } 14868 14869 @Override 14870 public IBinder peekService(Intent service, String resolvedType) { 14871 enforceNotIsolatedCaller("peekService"); 14872 // Refuse possible leaked file descriptors 14873 if (service != null && service.hasFileDescriptors() == true) { 14874 throw new IllegalArgumentException("File descriptors passed in Intent"); 14875 } 14876 synchronized(this) { 14877 return mServices.peekServiceLocked(service, resolvedType); 14878 } 14879 } 14880 14881 @Override 14882 public boolean stopServiceToken(ComponentName className, IBinder token, 14883 int startId) { 14884 synchronized(this) { 14885 return mServices.stopServiceTokenLocked(className, token, startId); 14886 } 14887 } 14888 14889 @Override 14890 public void setServiceForeground(ComponentName className, IBinder token, 14891 int id, Notification notification, boolean removeNotification) { 14892 synchronized(this) { 14893 mServices.setServiceForegroundLocked(className, token, id, notification, 14894 removeNotification); 14895 } 14896 } 14897 14898 @Override 14899 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14900 boolean requireFull, String name, String callerPackage) { 14901 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14902 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14903 } 14904 14905 int unsafeConvertIncomingUser(int userId) { 14906 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14907 ? mCurrentUserId : userId; 14908 } 14909 14910 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14911 int allowMode, String name, String callerPackage) { 14912 final int callingUserId = UserHandle.getUserId(callingUid); 14913 if (callingUserId == userId) { 14914 return userId; 14915 } 14916 14917 // Note that we may be accessing mCurrentUserId outside of a lock... 14918 // shouldn't be a big deal, if this is being called outside 14919 // of a locked context there is intrinsically a race with 14920 // the value the caller will receive and someone else changing it. 14921 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14922 // we will switch to the calling user if access to the current user fails. 14923 int targetUserId = unsafeConvertIncomingUser(userId); 14924 14925 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14926 final boolean allow; 14927 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14928 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14929 // If the caller has this permission, they always pass go. And collect $200. 14930 allow = true; 14931 } else if (allowMode == ALLOW_FULL_ONLY) { 14932 // We require full access, sucks to be you. 14933 allow = false; 14934 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14935 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14936 // If the caller does not have either permission, they are always doomed. 14937 allow = false; 14938 } else if (allowMode == ALLOW_NON_FULL) { 14939 // We are blanket allowing non-full access, you lucky caller! 14940 allow = true; 14941 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14942 // We may or may not allow this depending on whether the two users are 14943 // in the same profile. 14944 synchronized (mUserProfileGroupIdsSelfLocked) { 14945 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14946 UserInfo.NO_PROFILE_GROUP_ID); 14947 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14948 UserInfo.NO_PROFILE_GROUP_ID); 14949 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14950 && callingProfile == targetProfile; 14951 } 14952 } else { 14953 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14954 } 14955 if (!allow) { 14956 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14957 // In this case, they would like to just execute as their 14958 // owner user instead of failing. 14959 targetUserId = callingUserId; 14960 } else { 14961 StringBuilder builder = new StringBuilder(128); 14962 builder.append("Permission Denial: "); 14963 builder.append(name); 14964 if (callerPackage != null) { 14965 builder.append(" from "); 14966 builder.append(callerPackage); 14967 } 14968 builder.append(" asks to run as user "); 14969 builder.append(userId); 14970 builder.append(" but is calling from user "); 14971 builder.append(UserHandle.getUserId(callingUid)); 14972 builder.append("; this requires "); 14973 builder.append(INTERACT_ACROSS_USERS_FULL); 14974 if (allowMode != ALLOW_FULL_ONLY) { 14975 builder.append(" or "); 14976 builder.append(INTERACT_ACROSS_USERS); 14977 } 14978 String msg = builder.toString(); 14979 Slog.w(TAG, msg); 14980 throw new SecurityException(msg); 14981 } 14982 } 14983 } 14984 if (!allowAll && targetUserId < 0) { 14985 throw new IllegalArgumentException( 14986 "Call does not support special user #" + targetUserId); 14987 } 14988 // Check shell permission 14989 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14990 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14991 targetUserId)) { 14992 throw new SecurityException("Shell does not have permission to access user " 14993 + targetUserId + "\n " + Debug.getCallers(3)); 14994 } 14995 } 14996 return targetUserId; 14997 } 14998 14999 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15000 String className, int flags) { 15001 boolean result = false; 15002 // For apps that don't have pre-defined UIDs, check for permission 15003 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15004 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15005 if (ActivityManager.checkUidPermission( 15006 INTERACT_ACROSS_USERS, 15007 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15008 ComponentName comp = new ComponentName(aInfo.packageName, className); 15009 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15010 + " requests FLAG_SINGLE_USER, but app does not hold " 15011 + INTERACT_ACROSS_USERS; 15012 Slog.w(TAG, msg); 15013 throw new SecurityException(msg); 15014 } 15015 // Permission passed 15016 result = true; 15017 } 15018 } else if ("system".equals(componentProcessName)) { 15019 result = true; 15020 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15021 // Phone app and persistent apps are allowed to export singleuser providers. 15022 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15023 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15024 } 15025 if (DEBUG_MU) { 15026 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15027 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15028 } 15029 return result; 15030 } 15031 15032 /** 15033 * Checks to see if the caller is in the same app as the singleton 15034 * component, or the component is in a special app. It allows special apps 15035 * to export singleton components but prevents exporting singleton 15036 * components for regular apps. 15037 */ 15038 boolean isValidSingletonCall(int callingUid, int componentUid) { 15039 int componentAppId = UserHandle.getAppId(componentUid); 15040 return UserHandle.isSameApp(callingUid, componentUid) 15041 || componentAppId == Process.SYSTEM_UID 15042 || componentAppId == Process.PHONE_UID 15043 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15044 == PackageManager.PERMISSION_GRANTED; 15045 } 15046 15047 public int bindService(IApplicationThread caller, IBinder token, 15048 Intent service, String resolvedType, 15049 IServiceConnection connection, int flags, int userId) { 15050 enforceNotIsolatedCaller("bindService"); 15051 15052 // Refuse possible leaked file descriptors 15053 if (service != null && service.hasFileDescriptors() == true) { 15054 throw new IllegalArgumentException("File descriptors passed in Intent"); 15055 } 15056 15057 synchronized(this) { 15058 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15059 connection, flags, userId); 15060 } 15061 } 15062 15063 public boolean unbindService(IServiceConnection connection) { 15064 synchronized (this) { 15065 return mServices.unbindServiceLocked(connection); 15066 } 15067 } 15068 15069 public void publishService(IBinder token, Intent intent, IBinder service) { 15070 // Refuse possible leaked file descriptors 15071 if (intent != null && intent.hasFileDescriptors() == true) { 15072 throw new IllegalArgumentException("File descriptors passed in Intent"); 15073 } 15074 15075 synchronized(this) { 15076 if (!(token instanceof ServiceRecord)) { 15077 throw new IllegalArgumentException("Invalid service token"); 15078 } 15079 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15080 } 15081 } 15082 15083 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15084 // Refuse possible leaked file descriptors 15085 if (intent != null && intent.hasFileDescriptors() == true) { 15086 throw new IllegalArgumentException("File descriptors passed in Intent"); 15087 } 15088 15089 synchronized(this) { 15090 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15091 } 15092 } 15093 15094 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15095 synchronized(this) { 15096 if (!(token instanceof ServiceRecord)) { 15097 throw new IllegalArgumentException("Invalid service token"); 15098 } 15099 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15100 } 15101 } 15102 15103 // ========================================================= 15104 // BACKUP AND RESTORE 15105 // ========================================================= 15106 15107 // Cause the target app to be launched if necessary and its backup agent 15108 // instantiated. The backup agent will invoke backupAgentCreated() on the 15109 // activity manager to announce its creation. 15110 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15111 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15112 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15113 15114 synchronized(this) { 15115 // !!! TODO: currently no check here that we're already bound 15116 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15117 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15118 synchronized (stats) { 15119 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15120 } 15121 15122 // Backup agent is now in use, its package can't be stopped. 15123 try { 15124 AppGlobals.getPackageManager().setPackageStoppedState( 15125 app.packageName, false, UserHandle.getUserId(app.uid)); 15126 } catch (RemoteException e) { 15127 } catch (IllegalArgumentException e) { 15128 Slog.w(TAG, "Failed trying to unstop package " 15129 + app.packageName + ": " + e); 15130 } 15131 15132 BackupRecord r = new BackupRecord(ss, app, backupMode); 15133 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15134 ? new ComponentName(app.packageName, app.backupAgentName) 15135 : new ComponentName("android", "FullBackupAgent"); 15136 // startProcessLocked() returns existing proc's record if it's already running 15137 ProcessRecord proc = startProcessLocked(app.processName, app, 15138 false, 0, "backup", hostingName, false, false, false); 15139 if (proc == null) { 15140 Slog.e(TAG, "Unable to start backup agent process " + r); 15141 return false; 15142 } 15143 15144 r.app = proc; 15145 mBackupTarget = r; 15146 mBackupAppName = app.packageName; 15147 15148 // Try not to kill the process during backup 15149 updateOomAdjLocked(proc); 15150 15151 // If the process is already attached, schedule the creation of the backup agent now. 15152 // If it is not yet live, this will be done when it attaches to the framework. 15153 if (proc.thread != null) { 15154 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15155 try { 15156 proc.thread.scheduleCreateBackupAgent(app, 15157 compatibilityInfoForPackageLocked(app), backupMode); 15158 } catch (RemoteException e) { 15159 // Will time out on the backup manager side 15160 } 15161 } else { 15162 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15163 } 15164 // Invariants: at this point, the target app process exists and the application 15165 // is either already running or in the process of coming up. mBackupTarget and 15166 // mBackupAppName describe the app, so that when it binds back to the AM we 15167 // know that it's scheduled for a backup-agent operation. 15168 } 15169 15170 return true; 15171 } 15172 15173 @Override 15174 public void clearPendingBackup() { 15175 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15176 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15177 15178 synchronized (this) { 15179 mBackupTarget = null; 15180 mBackupAppName = null; 15181 } 15182 } 15183 15184 // A backup agent has just come up 15185 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15186 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15187 + " = " + agent); 15188 15189 synchronized(this) { 15190 if (!agentPackageName.equals(mBackupAppName)) { 15191 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15192 return; 15193 } 15194 } 15195 15196 long oldIdent = Binder.clearCallingIdentity(); 15197 try { 15198 IBackupManager bm = IBackupManager.Stub.asInterface( 15199 ServiceManager.getService(Context.BACKUP_SERVICE)); 15200 bm.agentConnected(agentPackageName, agent); 15201 } catch (RemoteException e) { 15202 // can't happen; the backup manager service is local 15203 } catch (Exception e) { 15204 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15205 e.printStackTrace(); 15206 } finally { 15207 Binder.restoreCallingIdentity(oldIdent); 15208 } 15209 } 15210 15211 // done with this agent 15212 public void unbindBackupAgent(ApplicationInfo appInfo) { 15213 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15214 if (appInfo == null) { 15215 Slog.w(TAG, "unbind backup agent for null app"); 15216 return; 15217 } 15218 15219 synchronized(this) { 15220 try { 15221 if (mBackupAppName == null) { 15222 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15223 return; 15224 } 15225 15226 if (!mBackupAppName.equals(appInfo.packageName)) { 15227 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15228 return; 15229 } 15230 15231 // Not backing this app up any more; reset its OOM adjustment 15232 final ProcessRecord proc = mBackupTarget.app; 15233 updateOomAdjLocked(proc); 15234 15235 // If the app crashed during backup, 'thread' will be null here 15236 if (proc.thread != null) { 15237 try { 15238 proc.thread.scheduleDestroyBackupAgent(appInfo, 15239 compatibilityInfoForPackageLocked(appInfo)); 15240 } catch (Exception e) { 15241 Slog.e(TAG, "Exception when unbinding backup agent:"); 15242 e.printStackTrace(); 15243 } 15244 } 15245 } finally { 15246 mBackupTarget = null; 15247 mBackupAppName = null; 15248 } 15249 } 15250 } 15251 // ========================================================= 15252 // BROADCASTS 15253 // ========================================================= 15254 15255 private final List getStickiesLocked(String action, IntentFilter filter, 15256 List cur, int userId) { 15257 final ContentResolver resolver = mContext.getContentResolver(); 15258 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15259 if (stickies == null) { 15260 return cur; 15261 } 15262 final ArrayList<Intent> list = stickies.get(action); 15263 if (list == null) { 15264 return cur; 15265 } 15266 int N = list.size(); 15267 for (int i=0; i<N; i++) { 15268 Intent intent = list.get(i); 15269 if (filter.match(resolver, intent, true, TAG) >= 0) { 15270 if (cur == null) { 15271 cur = new ArrayList<Intent>(); 15272 } 15273 cur.add(intent); 15274 } 15275 } 15276 return cur; 15277 } 15278 15279 boolean isPendingBroadcastProcessLocked(int pid) { 15280 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15281 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15282 } 15283 15284 void skipPendingBroadcastLocked(int pid) { 15285 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15286 for (BroadcastQueue queue : mBroadcastQueues) { 15287 queue.skipPendingBroadcastLocked(pid); 15288 } 15289 } 15290 15291 // The app just attached; send any pending broadcasts that it should receive 15292 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15293 boolean didSomething = false; 15294 for (BroadcastQueue queue : mBroadcastQueues) { 15295 didSomething |= queue.sendPendingBroadcastsLocked(app); 15296 } 15297 return didSomething; 15298 } 15299 15300 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15301 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15302 enforceNotIsolatedCaller("registerReceiver"); 15303 int callingUid; 15304 int callingPid; 15305 synchronized(this) { 15306 ProcessRecord callerApp = null; 15307 if (caller != null) { 15308 callerApp = getRecordForAppLocked(caller); 15309 if (callerApp == null) { 15310 throw new SecurityException( 15311 "Unable to find app for caller " + caller 15312 + " (pid=" + Binder.getCallingPid() 15313 + ") when registering receiver " + receiver); 15314 } 15315 if (callerApp.info.uid != Process.SYSTEM_UID && 15316 !callerApp.pkgList.containsKey(callerPackage) && 15317 !"android".equals(callerPackage)) { 15318 throw new SecurityException("Given caller package " + callerPackage 15319 + " is not running in process " + callerApp); 15320 } 15321 callingUid = callerApp.info.uid; 15322 callingPid = callerApp.pid; 15323 } else { 15324 callerPackage = null; 15325 callingUid = Binder.getCallingUid(); 15326 callingPid = Binder.getCallingPid(); 15327 } 15328 15329 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15330 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15331 15332 List allSticky = null; 15333 15334 // Look for any matching sticky broadcasts... 15335 Iterator actions = filter.actionsIterator(); 15336 if (actions != null) { 15337 while (actions.hasNext()) { 15338 String action = (String)actions.next(); 15339 allSticky = getStickiesLocked(action, filter, allSticky, 15340 UserHandle.USER_ALL); 15341 allSticky = getStickiesLocked(action, filter, allSticky, 15342 UserHandle.getUserId(callingUid)); 15343 } 15344 } else { 15345 allSticky = getStickiesLocked(null, filter, allSticky, 15346 UserHandle.USER_ALL); 15347 allSticky = getStickiesLocked(null, filter, allSticky, 15348 UserHandle.getUserId(callingUid)); 15349 } 15350 15351 // The first sticky in the list is returned directly back to 15352 // the client. 15353 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15354 15355 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15356 + ": " + sticky); 15357 15358 if (receiver == null) { 15359 return sticky; 15360 } 15361 15362 ReceiverList rl 15363 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15364 if (rl == null) { 15365 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15366 userId, receiver); 15367 if (rl.app != null) { 15368 rl.app.receivers.add(rl); 15369 } else { 15370 try { 15371 receiver.asBinder().linkToDeath(rl, 0); 15372 } catch (RemoteException e) { 15373 return sticky; 15374 } 15375 rl.linkedToDeath = true; 15376 } 15377 mRegisteredReceivers.put(receiver.asBinder(), rl); 15378 } else if (rl.uid != callingUid) { 15379 throw new IllegalArgumentException( 15380 "Receiver requested to register for uid " + callingUid 15381 + " was previously registered for uid " + rl.uid); 15382 } else if (rl.pid != callingPid) { 15383 throw new IllegalArgumentException( 15384 "Receiver requested to register for pid " + callingPid 15385 + " was previously registered for pid " + rl.pid); 15386 } else if (rl.userId != userId) { 15387 throw new IllegalArgumentException( 15388 "Receiver requested to register for user " + userId 15389 + " was previously registered for user " + rl.userId); 15390 } 15391 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15392 permission, callingUid, userId); 15393 rl.add(bf); 15394 if (!bf.debugCheck()) { 15395 Slog.w(TAG, "==> For Dynamic broadast"); 15396 } 15397 mReceiverResolver.addFilter(bf); 15398 15399 // Enqueue broadcasts for all existing stickies that match 15400 // this filter. 15401 if (allSticky != null) { 15402 ArrayList receivers = new ArrayList(); 15403 receivers.add(bf); 15404 15405 int N = allSticky.size(); 15406 for (int i=0; i<N; i++) { 15407 Intent intent = (Intent)allSticky.get(i); 15408 BroadcastQueue queue = broadcastQueueForIntent(intent); 15409 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15410 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15411 null, null, false, true, true, -1); 15412 queue.enqueueParallelBroadcastLocked(r); 15413 queue.scheduleBroadcastsLocked(); 15414 } 15415 } 15416 15417 return sticky; 15418 } 15419 } 15420 15421 public void unregisterReceiver(IIntentReceiver receiver) { 15422 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15423 15424 final long origId = Binder.clearCallingIdentity(); 15425 try { 15426 boolean doTrim = false; 15427 15428 synchronized(this) { 15429 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15430 if (rl != null) { 15431 if (rl.curBroadcast != null) { 15432 BroadcastRecord r = rl.curBroadcast; 15433 final boolean doNext = finishReceiverLocked( 15434 receiver.asBinder(), r.resultCode, r.resultData, 15435 r.resultExtras, r.resultAbort); 15436 if (doNext) { 15437 doTrim = true; 15438 r.queue.processNextBroadcast(false); 15439 } 15440 } 15441 15442 if (rl.app != null) { 15443 rl.app.receivers.remove(rl); 15444 } 15445 removeReceiverLocked(rl); 15446 if (rl.linkedToDeath) { 15447 rl.linkedToDeath = false; 15448 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15449 } 15450 } 15451 } 15452 15453 // If we actually concluded any broadcasts, we might now be able 15454 // to trim the recipients' apps from our working set 15455 if (doTrim) { 15456 trimApplications(); 15457 return; 15458 } 15459 15460 } finally { 15461 Binder.restoreCallingIdentity(origId); 15462 } 15463 } 15464 15465 void removeReceiverLocked(ReceiverList rl) { 15466 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15467 int N = rl.size(); 15468 for (int i=0; i<N; i++) { 15469 mReceiverResolver.removeFilter(rl.get(i)); 15470 } 15471 } 15472 15473 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15474 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15475 ProcessRecord r = mLruProcesses.get(i); 15476 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15477 try { 15478 r.thread.dispatchPackageBroadcast(cmd, packages); 15479 } catch (RemoteException ex) { 15480 } 15481 } 15482 } 15483 } 15484 15485 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15486 int callingUid, int[] users) { 15487 List<ResolveInfo> receivers = null; 15488 try { 15489 HashSet<ComponentName> singleUserReceivers = null; 15490 boolean scannedFirstReceivers = false; 15491 for (int user : users) { 15492 // Skip users that have Shell restrictions 15493 if (callingUid == Process.SHELL_UID 15494 && getUserManagerLocked().hasUserRestriction( 15495 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15496 continue; 15497 } 15498 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15499 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15500 if (user != 0 && newReceivers != null) { 15501 // If this is not the primary user, we need to check for 15502 // any receivers that should be filtered out. 15503 for (int i=0; i<newReceivers.size(); i++) { 15504 ResolveInfo ri = newReceivers.get(i); 15505 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15506 newReceivers.remove(i); 15507 i--; 15508 } 15509 } 15510 } 15511 if (newReceivers != null && newReceivers.size() == 0) { 15512 newReceivers = null; 15513 } 15514 if (receivers == null) { 15515 receivers = newReceivers; 15516 } else if (newReceivers != null) { 15517 // We need to concatenate the additional receivers 15518 // found with what we have do far. This would be easy, 15519 // but we also need to de-dup any receivers that are 15520 // singleUser. 15521 if (!scannedFirstReceivers) { 15522 // Collect any single user receivers we had already retrieved. 15523 scannedFirstReceivers = true; 15524 for (int i=0; i<receivers.size(); i++) { 15525 ResolveInfo ri = receivers.get(i); 15526 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15527 ComponentName cn = new ComponentName( 15528 ri.activityInfo.packageName, ri.activityInfo.name); 15529 if (singleUserReceivers == null) { 15530 singleUserReceivers = new HashSet<ComponentName>(); 15531 } 15532 singleUserReceivers.add(cn); 15533 } 15534 } 15535 } 15536 // Add the new results to the existing results, tracking 15537 // and de-dupping single user receivers. 15538 for (int i=0; i<newReceivers.size(); i++) { 15539 ResolveInfo ri = newReceivers.get(i); 15540 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15541 ComponentName cn = new ComponentName( 15542 ri.activityInfo.packageName, ri.activityInfo.name); 15543 if (singleUserReceivers == null) { 15544 singleUserReceivers = new HashSet<ComponentName>(); 15545 } 15546 if (!singleUserReceivers.contains(cn)) { 15547 singleUserReceivers.add(cn); 15548 receivers.add(ri); 15549 } 15550 } else { 15551 receivers.add(ri); 15552 } 15553 } 15554 } 15555 } 15556 } catch (RemoteException ex) { 15557 // pm is in same process, this will never happen. 15558 } 15559 return receivers; 15560 } 15561 15562 private final int broadcastIntentLocked(ProcessRecord callerApp, 15563 String callerPackage, Intent intent, String resolvedType, 15564 IIntentReceiver resultTo, int resultCode, String resultData, 15565 Bundle map, String requiredPermission, int appOp, 15566 boolean ordered, boolean sticky, int callingPid, int callingUid, 15567 int userId) { 15568 intent = new Intent(intent); 15569 15570 // By default broadcasts do not go to stopped apps. 15571 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15572 15573 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15574 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15575 + " ordered=" + ordered + " userid=" + userId); 15576 if ((resultTo != null) && !ordered) { 15577 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15578 } 15579 15580 userId = handleIncomingUser(callingPid, callingUid, userId, 15581 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15582 15583 // Make sure that the user who is receiving this broadcast is started. 15584 // If not, we will just skip it. 15585 15586 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15587 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15588 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15589 Slog.w(TAG, "Skipping broadcast of " + intent 15590 + ": user " + userId + " is stopped"); 15591 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15592 } 15593 } 15594 15595 /* 15596 * Prevent non-system code (defined here to be non-persistent 15597 * processes) from sending protected broadcasts. 15598 */ 15599 int callingAppId = UserHandle.getAppId(callingUid); 15600 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15601 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15602 || callingAppId == Process.NFC_UID || callingUid == 0) { 15603 // Always okay. 15604 } else if (callerApp == null || !callerApp.persistent) { 15605 try { 15606 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15607 intent.getAction())) { 15608 String msg = "Permission Denial: not allowed to send broadcast " 15609 + intent.getAction() + " from pid=" 15610 + callingPid + ", uid=" + callingUid; 15611 Slog.w(TAG, msg); 15612 throw new SecurityException(msg); 15613 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15614 // Special case for compatibility: we don't want apps to send this, 15615 // but historically it has not been protected and apps may be using it 15616 // to poke their own app widget. So, instead of making it protected, 15617 // just limit it to the caller. 15618 if (callerApp == null) { 15619 String msg = "Permission Denial: not allowed to send broadcast " 15620 + intent.getAction() + " from unknown caller."; 15621 Slog.w(TAG, msg); 15622 throw new SecurityException(msg); 15623 } else if (intent.getComponent() != null) { 15624 // They are good enough to send to an explicit component... verify 15625 // it is being sent to the calling app. 15626 if (!intent.getComponent().getPackageName().equals( 15627 callerApp.info.packageName)) { 15628 String msg = "Permission Denial: not allowed to send broadcast " 15629 + intent.getAction() + " to " 15630 + intent.getComponent().getPackageName() + " from " 15631 + callerApp.info.packageName; 15632 Slog.w(TAG, msg); 15633 throw new SecurityException(msg); 15634 } 15635 } else { 15636 // Limit broadcast to their own package. 15637 intent.setPackage(callerApp.info.packageName); 15638 } 15639 } 15640 } catch (RemoteException e) { 15641 Slog.w(TAG, "Remote exception", e); 15642 return ActivityManager.BROADCAST_SUCCESS; 15643 } 15644 } 15645 15646 final String action = intent.getAction(); 15647 if (action != null) { 15648 switch (action) { 15649 case Intent.ACTION_UID_REMOVED: 15650 case Intent.ACTION_PACKAGE_REMOVED: 15651 case Intent.ACTION_PACKAGE_CHANGED: 15652 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15653 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15654 // Handle special intents: if this broadcast is from the package 15655 // manager about a package being removed, we need to remove all of 15656 // its activities from the history stack. 15657 if (checkComponentPermission( 15658 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15659 callingPid, callingUid, -1, true) 15660 != PackageManager.PERMISSION_GRANTED) { 15661 String msg = "Permission Denial: " + intent.getAction() 15662 + " broadcast from " + callerPackage + " (pid=" + callingPid 15663 + ", uid=" + callingUid + ")" 15664 + " requires " 15665 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15666 Slog.w(TAG, msg); 15667 throw new SecurityException(msg); 15668 } 15669 switch (action) { 15670 case Intent.ACTION_UID_REMOVED: 15671 final Bundle intentExtras = intent.getExtras(); 15672 final int uid = intentExtras != null 15673 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15674 if (uid >= 0) { 15675 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15676 synchronized (bs) { 15677 bs.removeUidStatsLocked(uid); 15678 } 15679 mAppOpsService.uidRemoved(uid); 15680 } 15681 break; 15682 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15683 // If resources are unavailable just force stop all those packages 15684 // and flush the attribute cache as well. 15685 String list[] = 15686 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15687 if (list != null && list.length > 0) { 15688 for (int i = 0; i < list.length; i++) { 15689 forceStopPackageLocked(list[i], -1, false, true, true, 15690 false, false, userId, "storage unmount"); 15691 } 15692 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15693 sendPackageBroadcastLocked( 15694 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15695 userId); 15696 } 15697 break; 15698 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15699 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15700 break; 15701 case Intent.ACTION_PACKAGE_REMOVED: 15702 case Intent.ACTION_PACKAGE_CHANGED: 15703 Uri data = intent.getData(); 15704 String ssp; 15705 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15706 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15707 boolean fullUninstall = removed && 15708 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15709 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15710 forceStopPackageLocked(ssp, UserHandle.getAppId( 15711 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15712 false, true, true, false, fullUninstall, userId, 15713 removed ? "pkg removed" : "pkg changed"); 15714 } 15715 if (removed) { 15716 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15717 new String[] {ssp}, userId); 15718 if (fullUninstall) { 15719 mAppOpsService.packageRemoved( 15720 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15721 15722 // Remove all permissions granted from/to this package 15723 removeUriPermissionsForPackageLocked(ssp, userId, true); 15724 15725 removeTasksByPackageNameLocked(ssp, userId); 15726 } 15727 } else { 15728 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15729 } 15730 } 15731 break; 15732 } 15733 break; 15734 case Intent.ACTION_PACKAGE_ADDED: 15735 // Special case for adding a package: by default turn on compatibility mode. 15736 Uri data = intent.getData(); 15737 String ssp; 15738 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15739 final boolean replacing = 15740 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15741 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15742 15743 if (replacing) { 15744 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15745 } 15746 } 15747 break; 15748 case Intent.ACTION_TIMEZONE_CHANGED: 15749 // If this is the time zone changed action, queue up a message that will reset 15750 // the timezone of all currently running processes. This message will get 15751 // queued up before the broadcast happens. 15752 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15753 break; 15754 case Intent.ACTION_TIME_CHANGED: 15755 // If the user set the time, let all running processes know. 15756 final int is24Hour = 15757 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15758 : 0; 15759 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15760 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15761 synchronized (stats) { 15762 stats.noteCurrentTimeChangedLocked(); 15763 } 15764 break; 15765 case Intent.ACTION_CLEAR_DNS_CACHE: 15766 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15767 break; 15768 case Proxy.PROXY_CHANGE_ACTION: 15769 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15770 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15771 break; 15772 } 15773 } 15774 15775 // Add to the sticky list if requested. 15776 if (sticky) { 15777 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15778 callingPid, callingUid) 15779 != PackageManager.PERMISSION_GRANTED) { 15780 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15781 + callingPid + ", uid=" + callingUid 15782 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15783 Slog.w(TAG, msg); 15784 throw new SecurityException(msg); 15785 } 15786 if (requiredPermission != null) { 15787 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15788 + " and enforce permission " + requiredPermission); 15789 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15790 } 15791 if (intent.getComponent() != null) { 15792 throw new SecurityException( 15793 "Sticky broadcasts can't target a specific component"); 15794 } 15795 // We use userId directly here, since the "all" target is maintained 15796 // as a separate set of sticky broadcasts. 15797 if (userId != UserHandle.USER_ALL) { 15798 // But first, if this is not a broadcast to all users, then 15799 // make sure it doesn't conflict with an existing broadcast to 15800 // all users. 15801 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15802 UserHandle.USER_ALL); 15803 if (stickies != null) { 15804 ArrayList<Intent> list = stickies.get(intent.getAction()); 15805 if (list != null) { 15806 int N = list.size(); 15807 int i; 15808 for (i=0; i<N; i++) { 15809 if (intent.filterEquals(list.get(i))) { 15810 throw new IllegalArgumentException( 15811 "Sticky broadcast " + intent + " for user " 15812 + userId + " conflicts with existing global broadcast"); 15813 } 15814 } 15815 } 15816 } 15817 } 15818 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15819 if (stickies == null) { 15820 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15821 mStickyBroadcasts.put(userId, stickies); 15822 } 15823 ArrayList<Intent> list = stickies.get(intent.getAction()); 15824 if (list == null) { 15825 list = new ArrayList<Intent>(); 15826 stickies.put(intent.getAction(), list); 15827 } 15828 int N = list.size(); 15829 int i; 15830 for (i=0; i<N; i++) { 15831 if (intent.filterEquals(list.get(i))) { 15832 // This sticky already exists, replace it. 15833 list.set(i, new Intent(intent)); 15834 break; 15835 } 15836 } 15837 if (i >= N) { 15838 list.add(new Intent(intent)); 15839 } 15840 } 15841 15842 int[] users; 15843 if (userId == UserHandle.USER_ALL) { 15844 // Caller wants broadcast to go to all started users. 15845 users = mStartedUserArray; 15846 } else { 15847 // Caller wants broadcast to go to one specific user. 15848 users = new int[] {userId}; 15849 } 15850 15851 // Figure out who all will receive this broadcast. 15852 List receivers = null; 15853 List<BroadcastFilter> registeredReceivers = null; 15854 // Need to resolve the intent to interested receivers... 15855 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15856 == 0) { 15857 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15858 } 15859 if (intent.getComponent() == null) { 15860 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15861 // Query one target user at a time, excluding shell-restricted users 15862 UserManagerService ums = getUserManagerLocked(); 15863 for (int i = 0; i < users.length; i++) { 15864 if (ums.hasUserRestriction( 15865 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15866 continue; 15867 } 15868 List<BroadcastFilter> registeredReceiversForUser = 15869 mReceiverResolver.queryIntent(intent, 15870 resolvedType, false, users[i]); 15871 if (registeredReceivers == null) { 15872 registeredReceivers = registeredReceiversForUser; 15873 } else if (registeredReceiversForUser != null) { 15874 registeredReceivers.addAll(registeredReceiversForUser); 15875 } 15876 } 15877 } else { 15878 registeredReceivers = mReceiverResolver.queryIntent(intent, 15879 resolvedType, false, userId); 15880 } 15881 } 15882 15883 final boolean replacePending = 15884 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15885 15886 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15887 + " replacePending=" + replacePending); 15888 15889 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15890 if (!ordered && NR > 0) { 15891 // If we are not serializing this broadcast, then send the 15892 // registered receivers separately so they don't wait for the 15893 // components to be launched. 15894 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15895 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15896 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15897 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15898 ordered, sticky, false, userId); 15899 if (DEBUG_BROADCAST) Slog.v( 15900 TAG, "Enqueueing parallel broadcast " + r); 15901 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15902 if (!replaced) { 15903 queue.enqueueParallelBroadcastLocked(r); 15904 queue.scheduleBroadcastsLocked(); 15905 } 15906 registeredReceivers = null; 15907 NR = 0; 15908 } 15909 15910 // Merge into one list. 15911 int ir = 0; 15912 if (receivers != null) { 15913 // A special case for PACKAGE_ADDED: do not allow the package 15914 // being added to see this broadcast. This prevents them from 15915 // using this as a back door to get run as soon as they are 15916 // installed. Maybe in the future we want to have a special install 15917 // broadcast or such for apps, but we'd like to deliberately make 15918 // this decision. 15919 String skipPackages[] = null; 15920 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15921 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15922 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15923 Uri data = intent.getData(); 15924 if (data != null) { 15925 String pkgName = data.getSchemeSpecificPart(); 15926 if (pkgName != null) { 15927 skipPackages = new String[] { pkgName }; 15928 } 15929 } 15930 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15931 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15932 } 15933 if (skipPackages != null && (skipPackages.length > 0)) { 15934 for (String skipPackage : skipPackages) { 15935 if (skipPackage != null) { 15936 int NT = receivers.size(); 15937 for (int it=0; it<NT; it++) { 15938 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15939 if (curt.activityInfo.packageName.equals(skipPackage)) { 15940 receivers.remove(it); 15941 it--; 15942 NT--; 15943 } 15944 } 15945 } 15946 } 15947 } 15948 15949 int NT = receivers != null ? receivers.size() : 0; 15950 int it = 0; 15951 ResolveInfo curt = null; 15952 BroadcastFilter curr = null; 15953 while (it < NT && ir < NR) { 15954 if (curt == null) { 15955 curt = (ResolveInfo)receivers.get(it); 15956 } 15957 if (curr == null) { 15958 curr = registeredReceivers.get(ir); 15959 } 15960 if (curr.getPriority() >= curt.priority) { 15961 // Insert this broadcast record into the final list. 15962 receivers.add(it, curr); 15963 ir++; 15964 curr = null; 15965 it++; 15966 NT++; 15967 } else { 15968 // Skip to the next ResolveInfo in the final list. 15969 it++; 15970 curt = null; 15971 } 15972 } 15973 } 15974 while (ir < NR) { 15975 if (receivers == null) { 15976 receivers = new ArrayList(); 15977 } 15978 receivers.add(registeredReceivers.get(ir)); 15979 ir++; 15980 } 15981 15982 if ((receivers != null && receivers.size() > 0) 15983 || resultTo != null) { 15984 BroadcastQueue queue = broadcastQueueForIntent(intent); 15985 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15986 callerPackage, callingPid, callingUid, resolvedType, 15987 requiredPermission, appOp, receivers, resultTo, resultCode, 15988 resultData, map, ordered, sticky, false, userId); 15989 if (DEBUG_BROADCAST) Slog.v( 15990 TAG, "Enqueueing ordered broadcast " + r 15991 + ": prev had " + queue.mOrderedBroadcasts.size()); 15992 if (DEBUG_BROADCAST) { 15993 int seq = r.intent.getIntExtra("seq", -1); 15994 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15995 } 15996 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15997 if (!replaced) { 15998 queue.enqueueOrderedBroadcastLocked(r); 15999 queue.scheduleBroadcastsLocked(); 16000 } 16001 } 16002 16003 return ActivityManager.BROADCAST_SUCCESS; 16004 } 16005 16006 final Intent verifyBroadcastLocked(Intent intent) { 16007 // Refuse possible leaked file descriptors 16008 if (intent != null && intent.hasFileDescriptors() == true) { 16009 throw new IllegalArgumentException("File descriptors passed in Intent"); 16010 } 16011 16012 int flags = intent.getFlags(); 16013 16014 if (!mProcessesReady) { 16015 // if the caller really truly claims to know what they're doing, go 16016 // ahead and allow the broadcast without launching any receivers 16017 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16018 intent = new Intent(intent); 16019 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16020 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16021 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16022 + " before boot completion"); 16023 throw new IllegalStateException("Cannot broadcast before boot completed"); 16024 } 16025 } 16026 16027 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16028 throw new IllegalArgumentException( 16029 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16030 } 16031 16032 return intent; 16033 } 16034 16035 public final int broadcastIntent(IApplicationThread caller, 16036 Intent intent, String resolvedType, IIntentReceiver resultTo, 16037 int resultCode, String resultData, Bundle map, 16038 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16039 enforceNotIsolatedCaller("broadcastIntent"); 16040 synchronized(this) { 16041 intent = verifyBroadcastLocked(intent); 16042 16043 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16044 final int callingPid = Binder.getCallingPid(); 16045 final int callingUid = Binder.getCallingUid(); 16046 final long origId = Binder.clearCallingIdentity(); 16047 int res = broadcastIntentLocked(callerApp, 16048 callerApp != null ? callerApp.info.packageName : null, 16049 intent, resolvedType, resultTo, 16050 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16051 callingPid, callingUid, userId); 16052 Binder.restoreCallingIdentity(origId); 16053 return res; 16054 } 16055 } 16056 16057 int broadcastIntentInPackage(String packageName, int uid, 16058 Intent intent, String resolvedType, IIntentReceiver resultTo, 16059 int resultCode, String resultData, Bundle map, 16060 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16061 synchronized(this) { 16062 intent = verifyBroadcastLocked(intent); 16063 16064 final long origId = Binder.clearCallingIdentity(); 16065 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16066 resultTo, resultCode, resultData, map, requiredPermission, 16067 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16068 Binder.restoreCallingIdentity(origId); 16069 return res; 16070 } 16071 } 16072 16073 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 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 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16080 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16081 16082 synchronized(this) { 16083 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16084 != PackageManager.PERMISSION_GRANTED) { 16085 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16086 + Binder.getCallingPid() 16087 + ", uid=" + Binder.getCallingUid() 16088 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16089 Slog.w(TAG, msg); 16090 throw new SecurityException(msg); 16091 } 16092 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16093 if (stickies != null) { 16094 ArrayList<Intent> list = stickies.get(intent.getAction()); 16095 if (list != null) { 16096 int N = list.size(); 16097 int i; 16098 for (i=0; i<N; i++) { 16099 if (intent.filterEquals(list.get(i))) { 16100 list.remove(i); 16101 break; 16102 } 16103 } 16104 if (list.size() <= 0) { 16105 stickies.remove(intent.getAction()); 16106 } 16107 } 16108 if (stickies.size() <= 0) { 16109 mStickyBroadcasts.remove(userId); 16110 } 16111 } 16112 } 16113 } 16114 16115 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16116 String resultData, Bundle resultExtras, boolean resultAbort) { 16117 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16118 if (r == null) { 16119 Slog.w(TAG, "finishReceiver called but not found on queue"); 16120 return false; 16121 } 16122 16123 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16124 } 16125 16126 void backgroundServicesFinishedLocked(int userId) { 16127 for (BroadcastQueue queue : mBroadcastQueues) { 16128 queue.backgroundServicesFinishedLocked(userId); 16129 } 16130 } 16131 16132 public void finishReceiver(IBinder who, int resultCode, String resultData, 16133 Bundle resultExtras, boolean resultAbort) { 16134 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16135 16136 // Refuse possible leaked file descriptors 16137 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16138 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16139 } 16140 16141 final long origId = Binder.clearCallingIdentity(); 16142 try { 16143 boolean doNext = false; 16144 BroadcastRecord r; 16145 16146 synchronized(this) { 16147 r = broadcastRecordForReceiverLocked(who); 16148 if (r != null) { 16149 doNext = r.queue.finishReceiverLocked(r, resultCode, 16150 resultData, resultExtras, resultAbort, true); 16151 } 16152 } 16153 16154 if (doNext) { 16155 r.queue.processNextBroadcast(false); 16156 } 16157 trimApplications(); 16158 } finally { 16159 Binder.restoreCallingIdentity(origId); 16160 } 16161 } 16162 16163 // ========================================================= 16164 // INSTRUMENTATION 16165 // ========================================================= 16166 16167 public boolean startInstrumentation(ComponentName className, 16168 String profileFile, int flags, Bundle arguments, 16169 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16170 int userId, String abiOverride) { 16171 enforceNotIsolatedCaller("startInstrumentation"); 16172 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16173 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16174 // Refuse possible leaked file descriptors 16175 if (arguments != null && arguments.hasFileDescriptors()) { 16176 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16177 } 16178 16179 synchronized(this) { 16180 InstrumentationInfo ii = null; 16181 ApplicationInfo ai = null; 16182 try { 16183 ii = mContext.getPackageManager().getInstrumentationInfo( 16184 className, STOCK_PM_FLAGS); 16185 ai = AppGlobals.getPackageManager().getApplicationInfo( 16186 ii.targetPackage, STOCK_PM_FLAGS, userId); 16187 } catch (PackageManager.NameNotFoundException e) { 16188 } catch (RemoteException e) { 16189 } 16190 if (ii == null) { 16191 reportStartInstrumentationFailure(watcher, className, 16192 "Unable to find instrumentation info for: " + className); 16193 return false; 16194 } 16195 if (ai == null) { 16196 reportStartInstrumentationFailure(watcher, className, 16197 "Unable to find instrumentation target package: " + ii.targetPackage); 16198 return false; 16199 } 16200 16201 int match = mContext.getPackageManager().checkSignatures( 16202 ii.targetPackage, ii.packageName); 16203 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16204 String msg = "Permission Denial: starting instrumentation " 16205 + className + " from pid=" 16206 + Binder.getCallingPid() 16207 + ", uid=" + Binder.getCallingPid() 16208 + " not allowed because package " + ii.packageName 16209 + " does not have a signature matching the target " 16210 + ii.targetPackage; 16211 reportStartInstrumentationFailure(watcher, className, msg); 16212 throw new SecurityException(msg); 16213 } 16214 16215 final long origId = Binder.clearCallingIdentity(); 16216 // Instrumentation can kill and relaunch even persistent processes 16217 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16218 "start instr"); 16219 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16220 app.instrumentationClass = className; 16221 app.instrumentationInfo = ai; 16222 app.instrumentationProfileFile = profileFile; 16223 app.instrumentationArguments = arguments; 16224 app.instrumentationWatcher = watcher; 16225 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16226 app.instrumentationResultClass = className; 16227 Binder.restoreCallingIdentity(origId); 16228 } 16229 16230 return true; 16231 } 16232 16233 /** 16234 * Report errors that occur while attempting to start Instrumentation. Always writes the 16235 * error to the logs, but if somebody is watching, send the report there too. This enables 16236 * the "am" command to report errors with more information. 16237 * 16238 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16239 * @param cn The component name of the instrumentation. 16240 * @param report The error report. 16241 */ 16242 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16243 ComponentName cn, String report) { 16244 Slog.w(TAG, report); 16245 try { 16246 if (watcher != null) { 16247 Bundle results = new Bundle(); 16248 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16249 results.putString("Error", report); 16250 watcher.instrumentationStatus(cn, -1, results); 16251 } 16252 } catch (RemoteException e) { 16253 Slog.w(TAG, e); 16254 } 16255 } 16256 16257 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16258 if (app.instrumentationWatcher != null) { 16259 try { 16260 // NOTE: IInstrumentationWatcher *must* be oneway here 16261 app.instrumentationWatcher.instrumentationFinished( 16262 app.instrumentationClass, 16263 resultCode, 16264 results); 16265 } catch (RemoteException e) { 16266 } 16267 } 16268 if (app.instrumentationUiAutomationConnection != null) { 16269 try { 16270 app.instrumentationUiAutomationConnection.shutdown(); 16271 } catch (RemoteException re) { 16272 /* ignore */ 16273 } 16274 // Only a UiAutomation can set this flag and now that 16275 // it is finished we make sure it is reset to its default. 16276 mUserIsMonkey = false; 16277 } 16278 app.instrumentationWatcher = null; 16279 app.instrumentationUiAutomationConnection = null; 16280 app.instrumentationClass = null; 16281 app.instrumentationInfo = null; 16282 app.instrumentationProfileFile = null; 16283 app.instrumentationArguments = null; 16284 16285 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16286 "finished inst"); 16287 } 16288 16289 public void finishInstrumentation(IApplicationThread target, 16290 int resultCode, Bundle results) { 16291 int userId = UserHandle.getCallingUserId(); 16292 // Refuse possible leaked file descriptors 16293 if (results != null && results.hasFileDescriptors()) { 16294 throw new IllegalArgumentException("File descriptors passed in Intent"); 16295 } 16296 16297 synchronized(this) { 16298 ProcessRecord app = getRecordForAppLocked(target); 16299 if (app == null) { 16300 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16301 return; 16302 } 16303 final long origId = Binder.clearCallingIdentity(); 16304 finishInstrumentationLocked(app, resultCode, results); 16305 Binder.restoreCallingIdentity(origId); 16306 } 16307 } 16308 16309 // ========================================================= 16310 // CONFIGURATION 16311 // ========================================================= 16312 16313 public ConfigurationInfo getDeviceConfigurationInfo() { 16314 ConfigurationInfo config = new ConfigurationInfo(); 16315 synchronized (this) { 16316 config.reqTouchScreen = mConfiguration.touchscreen; 16317 config.reqKeyboardType = mConfiguration.keyboard; 16318 config.reqNavigation = mConfiguration.navigation; 16319 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16320 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16321 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16322 } 16323 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16324 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16325 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16326 } 16327 config.reqGlEsVersion = GL_ES_VERSION; 16328 } 16329 return config; 16330 } 16331 16332 ActivityStack getFocusedStack() { 16333 return mStackSupervisor.getFocusedStack(); 16334 } 16335 16336 public Configuration getConfiguration() { 16337 Configuration ci; 16338 synchronized(this) { 16339 ci = new Configuration(mConfiguration); 16340 } 16341 return ci; 16342 } 16343 16344 public void updatePersistentConfiguration(Configuration values) { 16345 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16346 "updateConfiguration()"); 16347 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16348 "updateConfiguration()"); 16349 if (values == null) { 16350 throw new NullPointerException("Configuration must not be null"); 16351 } 16352 16353 synchronized(this) { 16354 final long origId = Binder.clearCallingIdentity(); 16355 updateConfigurationLocked(values, null, true, false); 16356 Binder.restoreCallingIdentity(origId); 16357 } 16358 } 16359 16360 public void updateConfiguration(Configuration values) { 16361 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16362 "updateConfiguration()"); 16363 16364 synchronized(this) { 16365 if (values == null && mWindowManager != null) { 16366 // sentinel: fetch the current configuration from the window manager 16367 values = mWindowManager.computeNewConfiguration(); 16368 } 16369 16370 if (mWindowManager != null) { 16371 mProcessList.applyDisplaySize(mWindowManager); 16372 } 16373 16374 final long origId = Binder.clearCallingIdentity(); 16375 if (values != null) { 16376 Settings.System.clearConfiguration(values); 16377 } 16378 updateConfigurationLocked(values, null, false, false); 16379 Binder.restoreCallingIdentity(origId); 16380 } 16381 } 16382 16383 /** 16384 * Do either or both things: (1) change the current configuration, and (2) 16385 * make sure the given activity is running with the (now) current 16386 * configuration. Returns true if the activity has been left running, or 16387 * false if <var>starting</var> is being destroyed to match the new 16388 * configuration. 16389 * @param persistent TODO 16390 */ 16391 boolean updateConfigurationLocked(Configuration values, 16392 ActivityRecord starting, boolean persistent, boolean initLocale) { 16393 int changes = 0; 16394 16395 if (values != null) { 16396 Configuration newConfig = new Configuration(mConfiguration); 16397 changes = newConfig.updateFrom(values); 16398 if (changes != 0) { 16399 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16400 Slog.i(TAG, "Updating configuration to: " + values); 16401 } 16402 16403 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16404 16405 if (values.locale != null && !initLocale) { 16406 saveLocaleLocked(values.locale, 16407 !values.locale.equals(mConfiguration.locale), 16408 values.userSetLocale); 16409 } 16410 16411 mConfigurationSeq++; 16412 if (mConfigurationSeq <= 0) { 16413 mConfigurationSeq = 1; 16414 } 16415 newConfig.seq = mConfigurationSeq; 16416 mConfiguration = newConfig; 16417 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16418 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16419 //mUsageStatsService.noteStartConfig(newConfig); 16420 16421 final Configuration configCopy = new Configuration(mConfiguration); 16422 16423 // TODO: If our config changes, should we auto dismiss any currently 16424 // showing dialogs? 16425 mShowDialogs = shouldShowDialogs(newConfig); 16426 16427 AttributeCache ac = AttributeCache.instance(); 16428 if (ac != null) { 16429 ac.updateConfiguration(configCopy); 16430 } 16431 16432 // Make sure all resources in our process are updated 16433 // right now, so that anyone who is going to retrieve 16434 // resource values after we return will be sure to get 16435 // the new ones. This is especially important during 16436 // boot, where the first config change needs to guarantee 16437 // all resources have that config before following boot 16438 // code is executed. 16439 mSystemThread.applyConfigurationToResources(configCopy); 16440 16441 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16442 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16443 msg.obj = new Configuration(configCopy); 16444 mHandler.sendMessage(msg); 16445 } 16446 16447 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16448 ProcessRecord app = mLruProcesses.get(i); 16449 try { 16450 if (app.thread != null) { 16451 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16452 + app.processName + " new config " + mConfiguration); 16453 app.thread.scheduleConfigurationChanged(configCopy); 16454 } 16455 } catch (Exception e) { 16456 } 16457 } 16458 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16459 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16460 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16461 | Intent.FLAG_RECEIVER_FOREGROUND); 16462 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16463 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16464 Process.SYSTEM_UID, UserHandle.USER_ALL); 16465 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16466 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16467 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16468 broadcastIntentLocked(null, null, intent, 16469 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16470 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16471 } 16472 } 16473 } 16474 16475 boolean kept = true; 16476 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16477 // mainStack is null during startup. 16478 if (mainStack != null) { 16479 if (changes != 0 && starting == null) { 16480 // If the configuration changed, and the caller is not already 16481 // in the process of starting an activity, then find the top 16482 // activity to check if its configuration needs to change. 16483 starting = mainStack.topRunningActivityLocked(null); 16484 } 16485 16486 if (starting != null) { 16487 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16488 // And we need to make sure at this point that all other activities 16489 // are made visible with the correct configuration. 16490 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16491 } 16492 } 16493 16494 if (values != null && mWindowManager != null) { 16495 mWindowManager.setNewConfiguration(mConfiguration); 16496 } 16497 16498 return kept; 16499 } 16500 16501 /** 16502 * Decide based on the configuration whether we should shouw the ANR, 16503 * crash, etc dialogs. The idea is that if there is no affordnace to 16504 * press the on-screen buttons, we shouldn't show the dialog. 16505 * 16506 * A thought: SystemUI might also want to get told about this, the Power 16507 * dialog / global actions also might want different behaviors. 16508 */ 16509 private static final boolean shouldShowDialogs(Configuration config) { 16510 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16511 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16512 } 16513 16514 /** 16515 * Save the locale. You must be inside a synchronized (this) block. 16516 */ 16517 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16518 if(isDiff) { 16519 SystemProperties.set("user.language", l.getLanguage()); 16520 SystemProperties.set("user.region", l.getCountry()); 16521 } 16522 16523 if(isPersist) { 16524 SystemProperties.set("persist.sys.language", l.getLanguage()); 16525 SystemProperties.set("persist.sys.country", l.getCountry()); 16526 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16527 16528 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16529 } 16530 } 16531 16532 @Override 16533 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16534 synchronized (this) { 16535 ActivityRecord srec = ActivityRecord.forToken(token); 16536 if (srec.task != null && srec.task.stack != null) { 16537 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16538 } 16539 } 16540 return false; 16541 } 16542 16543 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16544 Intent resultData) { 16545 16546 synchronized (this) { 16547 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16548 if (stack != null) { 16549 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16550 } 16551 return false; 16552 } 16553 } 16554 16555 public int getLaunchedFromUid(IBinder activityToken) { 16556 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16557 if (srec == null) { 16558 return -1; 16559 } 16560 return srec.launchedFromUid; 16561 } 16562 16563 public String getLaunchedFromPackage(IBinder activityToken) { 16564 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16565 if (srec == null) { 16566 return null; 16567 } 16568 return srec.launchedFromPackage; 16569 } 16570 16571 // ========================================================= 16572 // LIFETIME MANAGEMENT 16573 // ========================================================= 16574 16575 // Returns which broadcast queue the app is the current [or imminent] receiver 16576 // on, or 'null' if the app is not an active broadcast recipient. 16577 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16578 BroadcastRecord r = app.curReceiver; 16579 if (r != null) { 16580 return r.queue; 16581 } 16582 16583 // It's not the current receiver, but it might be starting up to become one 16584 synchronized (this) { 16585 for (BroadcastQueue queue : mBroadcastQueues) { 16586 r = queue.mPendingBroadcast; 16587 if (r != null && r.curApp == app) { 16588 // found it; report which queue it's in 16589 return queue; 16590 } 16591 } 16592 } 16593 16594 return null; 16595 } 16596 16597 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16598 boolean doingAll, long now) { 16599 if (mAdjSeq == app.adjSeq) { 16600 // This adjustment has already been computed. 16601 return app.curRawAdj; 16602 } 16603 16604 if (app.thread == null) { 16605 app.adjSeq = mAdjSeq; 16606 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16607 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16608 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16609 } 16610 16611 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16612 app.adjSource = null; 16613 app.adjTarget = null; 16614 app.empty = false; 16615 app.cached = false; 16616 16617 final int activitiesSize = app.activities.size(); 16618 16619 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16620 // The max adjustment doesn't allow this app to be anything 16621 // below foreground, so it is not worth doing work for it. 16622 app.adjType = "fixed"; 16623 app.adjSeq = mAdjSeq; 16624 app.curRawAdj = app.maxAdj; 16625 app.foregroundActivities = false; 16626 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16627 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16628 // System processes can do UI, and when they do we want to have 16629 // them trim their memory after the user leaves the UI. To 16630 // facilitate this, here we need to determine whether or not it 16631 // is currently showing UI. 16632 app.systemNoUi = true; 16633 if (app == TOP_APP) { 16634 app.systemNoUi = false; 16635 } else if (activitiesSize > 0) { 16636 for (int j = 0; j < activitiesSize; j++) { 16637 final ActivityRecord r = app.activities.get(j); 16638 if (r.visible) { 16639 app.systemNoUi = false; 16640 } 16641 } 16642 } 16643 if (!app.systemNoUi) { 16644 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16645 } 16646 return (app.curAdj=app.maxAdj); 16647 } 16648 16649 app.systemNoUi = false; 16650 16651 // Determine the importance of the process, starting with most 16652 // important to least, and assign an appropriate OOM adjustment. 16653 int adj; 16654 int schedGroup; 16655 int procState; 16656 boolean foregroundActivities = false; 16657 BroadcastQueue queue; 16658 if (app == TOP_APP) { 16659 // The last app on the list is the foreground app. 16660 adj = ProcessList.FOREGROUND_APP_ADJ; 16661 schedGroup = Process.THREAD_GROUP_DEFAULT; 16662 app.adjType = "top-activity"; 16663 foregroundActivities = true; 16664 procState = ActivityManager.PROCESS_STATE_TOP; 16665 } else if (app.instrumentationClass != null) { 16666 // Don't want to kill running instrumentation. 16667 adj = ProcessList.FOREGROUND_APP_ADJ; 16668 schedGroup = Process.THREAD_GROUP_DEFAULT; 16669 app.adjType = "instrumentation"; 16670 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16671 } else if ((queue = isReceivingBroadcast(app)) != null) { 16672 // An app that is currently receiving a broadcast also 16673 // counts as being in the foreground for OOM killer purposes. 16674 // It's placed in a sched group based on the nature of the 16675 // broadcast as reflected by which queue it's active in. 16676 adj = ProcessList.FOREGROUND_APP_ADJ; 16677 schedGroup = (queue == mFgBroadcastQueue) 16678 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16679 app.adjType = "broadcast"; 16680 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16681 } else if (app.executingServices.size() > 0) { 16682 // An app that is currently executing a service callback also 16683 // counts as being in the foreground. 16684 adj = ProcessList.FOREGROUND_APP_ADJ; 16685 schedGroup = app.execServicesFg ? 16686 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16687 app.adjType = "exec-service"; 16688 procState = ActivityManager.PROCESS_STATE_SERVICE; 16689 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16690 } else { 16691 // As far as we know the process is empty. We may change our mind later. 16692 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16693 // At this point we don't actually know the adjustment. Use the cached adj 16694 // value that the caller wants us to. 16695 adj = cachedAdj; 16696 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16697 app.cached = true; 16698 app.empty = true; 16699 app.adjType = "cch-empty"; 16700 } 16701 16702 // Examine all activities if not already foreground. 16703 if (!foregroundActivities && activitiesSize > 0) { 16704 for (int j = 0; j < activitiesSize; j++) { 16705 final ActivityRecord r = app.activities.get(j); 16706 if (r.app != app) { 16707 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16708 + app + "?!?"); 16709 continue; 16710 } 16711 if (r.visible) { 16712 // App has a visible activity; only upgrade adjustment. 16713 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16714 adj = ProcessList.VISIBLE_APP_ADJ; 16715 app.adjType = "visible"; 16716 } 16717 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16718 procState = ActivityManager.PROCESS_STATE_TOP; 16719 } 16720 schedGroup = Process.THREAD_GROUP_DEFAULT; 16721 app.cached = false; 16722 app.empty = false; 16723 foregroundActivities = true; 16724 break; 16725 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16726 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16727 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16728 app.adjType = "pausing"; 16729 } 16730 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16731 procState = ActivityManager.PROCESS_STATE_TOP; 16732 } 16733 schedGroup = Process.THREAD_GROUP_DEFAULT; 16734 app.cached = false; 16735 app.empty = false; 16736 foregroundActivities = true; 16737 } else if (r.state == ActivityState.STOPPING) { 16738 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16739 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16740 app.adjType = "stopping"; 16741 } 16742 // For the process state, we will at this point consider the 16743 // process to be cached. It will be cached either as an activity 16744 // or empty depending on whether the activity is finishing. We do 16745 // this so that we can treat the process as cached for purposes of 16746 // memory trimming (determing current memory level, trim command to 16747 // send to process) since there can be an arbitrary number of stopping 16748 // processes and they should soon all go into the cached state. 16749 if (!r.finishing) { 16750 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16751 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16752 } 16753 } 16754 app.cached = false; 16755 app.empty = false; 16756 foregroundActivities = true; 16757 } else { 16758 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16759 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16760 app.adjType = "cch-act"; 16761 } 16762 } 16763 } 16764 } 16765 16766 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16767 if (app.foregroundServices) { 16768 // The user is aware of this app, so make it visible. 16769 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16770 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16771 app.cached = false; 16772 app.adjType = "fg-service"; 16773 schedGroup = Process.THREAD_GROUP_DEFAULT; 16774 } else if (app.forcingToForeground != null) { 16775 // The user is aware of this app, so make it visible. 16776 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16777 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16778 app.cached = false; 16779 app.adjType = "force-fg"; 16780 app.adjSource = app.forcingToForeground; 16781 schedGroup = Process.THREAD_GROUP_DEFAULT; 16782 } 16783 } 16784 16785 if (app == mHeavyWeightProcess) { 16786 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16787 // We don't want to kill the current heavy-weight process. 16788 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16789 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16790 app.cached = false; 16791 app.adjType = "heavy"; 16792 } 16793 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16794 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16795 } 16796 } 16797 16798 if (app == mHomeProcess) { 16799 if (adj > ProcessList.HOME_APP_ADJ) { 16800 // This process is hosting what we currently consider to be the 16801 // home app, so we don't want to let it go into the background. 16802 adj = ProcessList.HOME_APP_ADJ; 16803 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16804 app.cached = false; 16805 app.adjType = "home"; 16806 } 16807 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16808 procState = ActivityManager.PROCESS_STATE_HOME; 16809 } 16810 } 16811 16812 if (app == mPreviousProcess && app.activities.size() > 0) { 16813 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16814 // This was the previous process that showed UI to the user. 16815 // We want to try to keep it around more aggressively, to give 16816 // a good experience around switching between two apps. 16817 adj = ProcessList.PREVIOUS_APP_ADJ; 16818 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16819 app.cached = false; 16820 app.adjType = "previous"; 16821 } 16822 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16823 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16824 } 16825 } 16826 16827 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16828 + " reason=" + app.adjType); 16829 16830 // By default, we use the computed adjustment. It may be changed if 16831 // there are applications dependent on our services or providers, but 16832 // this gives us a baseline and makes sure we don't get into an 16833 // infinite recursion. 16834 app.adjSeq = mAdjSeq; 16835 app.curRawAdj = adj; 16836 app.hasStartedServices = false; 16837 16838 if (mBackupTarget != null && app == mBackupTarget.app) { 16839 // If possible we want to avoid killing apps while they're being backed up 16840 if (adj > ProcessList.BACKUP_APP_ADJ) { 16841 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16842 adj = ProcessList.BACKUP_APP_ADJ; 16843 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16844 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16845 } 16846 app.adjType = "backup"; 16847 app.cached = false; 16848 } 16849 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16850 procState = ActivityManager.PROCESS_STATE_BACKUP; 16851 } 16852 } 16853 16854 boolean mayBeTop = false; 16855 16856 for (int is = app.services.size()-1; 16857 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16858 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16859 || procState > ActivityManager.PROCESS_STATE_TOP); 16860 is--) { 16861 ServiceRecord s = app.services.valueAt(is); 16862 if (s.startRequested) { 16863 app.hasStartedServices = true; 16864 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16865 procState = ActivityManager.PROCESS_STATE_SERVICE; 16866 } 16867 if (app.hasShownUi && app != mHomeProcess) { 16868 // If this process has shown some UI, let it immediately 16869 // go to the LRU list because it may be pretty heavy with 16870 // UI stuff. We'll tag it with a label just to help 16871 // debug and understand what is going on. 16872 if (adj > ProcessList.SERVICE_ADJ) { 16873 app.adjType = "cch-started-ui-services"; 16874 } 16875 } else { 16876 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16877 // This service has seen some activity within 16878 // recent memory, so we will keep its process ahead 16879 // of the background processes. 16880 if (adj > ProcessList.SERVICE_ADJ) { 16881 adj = ProcessList.SERVICE_ADJ; 16882 app.adjType = "started-services"; 16883 app.cached = false; 16884 } 16885 } 16886 // If we have let the service slide into the background 16887 // state, still have some text describing what it is doing 16888 // even though the service no longer has an impact. 16889 if (adj > ProcessList.SERVICE_ADJ) { 16890 app.adjType = "cch-started-services"; 16891 } 16892 } 16893 } 16894 for (int conni = s.connections.size()-1; 16895 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16896 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16897 || procState > ActivityManager.PROCESS_STATE_TOP); 16898 conni--) { 16899 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16900 for (int i = 0; 16901 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16902 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16903 || procState > ActivityManager.PROCESS_STATE_TOP); 16904 i++) { 16905 // XXX should compute this based on the max of 16906 // all connected clients. 16907 ConnectionRecord cr = clist.get(i); 16908 if (cr.binding.client == app) { 16909 // Binding to ourself is not interesting. 16910 continue; 16911 } 16912 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16913 ProcessRecord client = cr.binding.client; 16914 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16915 TOP_APP, doingAll, now); 16916 int clientProcState = client.curProcState; 16917 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16918 // If the other app is cached for any reason, for purposes here 16919 // we are going to consider it empty. The specific cached state 16920 // doesn't propagate except under certain conditions. 16921 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16922 } 16923 String adjType = null; 16924 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16925 // Not doing bind OOM management, so treat 16926 // this guy more like a started service. 16927 if (app.hasShownUi && app != mHomeProcess) { 16928 // If this process has shown some UI, let it immediately 16929 // go to the LRU list because it may be pretty heavy with 16930 // UI stuff. We'll tag it with a label just to help 16931 // debug and understand what is going on. 16932 if (adj > clientAdj) { 16933 adjType = "cch-bound-ui-services"; 16934 } 16935 app.cached = false; 16936 clientAdj = adj; 16937 clientProcState = procState; 16938 } else { 16939 if (now >= (s.lastActivity 16940 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16941 // This service has not seen activity within 16942 // recent memory, so allow it to drop to the 16943 // LRU list if there is no other reason to keep 16944 // it around. We'll also tag it with a label just 16945 // to help debug and undertand what is going on. 16946 if (adj > clientAdj) { 16947 adjType = "cch-bound-services"; 16948 } 16949 clientAdj = adj; 16950 } 16951 } 16952 } 16953 if (adj > clientAdj) { 16954 // If this process has recently shown UI, and 16955 // the process that is binding to it is less 16956 // important than being visible, then we don't 16957 // care about the binding as much as we care 16958 // about letting this process get into the LRU 16959 // list to be killed and restarted if needed for 16960 // memory. 16961 if (app.hasShownUi && app != mHomeProcess 16962 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16963 adjType = "cch-bound-ui-services"; 16964 } else { 16965 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16966 |Context.BIND_IMPORTANT)) != 0) { 16967 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16968 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16969 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16970 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16971 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16972 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16973 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16974 adj = clientAdj; 16975 } else { 16976 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16977 adj = ProcessList.VISIBLE_APP_ADJ; 16978 } 16979 } 16980 if (!client.cached) { 16981 app.cached = false; 16982 } 16983 adjType = "service"; 16984 } 16985 } 16986 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16987 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16988 schedGroup = Process.THREAD_GROUP_DEFAULT; 16989 } 16990 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16991 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16992 // Special handling of clients who are in the top state. 16993 // We *may* want to consider this process to be in the 16994 // top state as well, but only if there is not another 16995 // reason for it to be running. Being on the top is a 16996 // special state, meaning you are specifically running 16997 // for the current top app. If the process is already 16998 // running in the background for some other reason, it 16999 // is more important to continue considering it to be 17000 // in the background state. 17001 mayBeTop = true; 17002 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17003 } else { 17004 // Special handling for above-top states (persistent 17005 // processes). These should not bring the current process 17006 // into the top state, since they are not on top. Instead 17007 // give them the best state after that. 17008 clientProcState = 17009 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17010 } 17011 } 17012 } else { 17013 if (clientProcState < 17014 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17015 clientProcState = 17016 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17017 } 17018 } 17019 if (procState > clientProcState) { 17020 procState = clientProcState; 17021 } 17022 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17023 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17024 app.pendingUiClean = true; 17025 } 17026 if (adjType != null) { 17027 app.adjType = adjType; 17028 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17029 .REASON_SERVICE_IN_USE; 17030 app.adjSource = cr.binding.client; 17031 app.adjSourceProcState = clientProcState; 17032 app.adjTarget = s.name; 17033 } 17034 } 17035 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17036 app.treatLikeActivity = true; 17037 } 17038 final ActivityRecord a = cr.activity; 17039 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17040 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17041 (a.visible || a.state == ActivityState.RESUMED 17042 || a.state == ActivityState.PAUSING)) { 17043 adj = ProcessList.FOREGROUND_APP_ADJ; 17044 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17045 schedGroup = Process.THREAD_GROUP_DEFAULT; 17046 } 17047 app.cached = false; 17048 app.adjType = "service"; 17049 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17050 .REASON_SERVICE_IN_USE; 17051 app.adjSource = a; 17052 app.adjSourceProcState = procState; 17053 app.adjTarget = s.name; 17054 } 17055 } 17056 } 17057 } 17058 } 17059 17060 for (int provi = app.pubProviders.size()-1; 17061 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17062 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17063 || procState > ActivityManager.PROCESS_STATE_TOP); 17064 provi--) { 17065 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17066 for (int i = cpr.connections.size()-1; 17067 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17068 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17069 || procState > ActivityManager.PROCESS_STATE_TOP); 17070 i--) { 17071 ContentProviderConnection conn = cpr.connections.get(i); 17072 ProcessRecord client = conn.client; 17073 if (client == app) { 17074 // Being our own client is not interesting. 17075 continue; 17076 } 17077 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17078 int clientProcState = client.curProcState; 17079 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17080 // If the other app is cached for any reason, for purposes here 17081 // we are going to consider it empty. 17082 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17083 } 17084 if (adj > clientAdj) { 17085 if (app.hasShownUi && app != mHomeProcess 17086 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17087 app.adjType = "cch-ui-provider"; 17088 } else { 17089 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17090 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17091 app.adjType = "provider"; 17092 } 17093 app.cached &= client.cached; 17094 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17095 .REASON_PROVIDER_IN_USE; 17096 app.adjSource = client; 17097 app.adjSourceProcState = clientProcState; 17098 app.adjTarget = cpr.name; 17099 } 17100 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17101 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17102 // Special handling of clients who are in the top state. 17103 // We *may* want to consider this process to be in the 17104 // top state as well, but only if there is not another 17105 // reason for it to be running. Being on the top is a 17106 // special state, meaning you are specifically running 17107 // for the current top app. If the process is already 17108 // running in the background for some other reason, it 17109 // is more important to continue considering it to be 17110 // in the background state. 17111 mayBeTop = true; 17112 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17113 } else { 17114 // Special handling for above-top states (persistent 17115 // processes). These should not bring the current process 17116 // into the top state, since they are not on top. Instead 17117 // give them the best state after that. 17118 clientProcState = 17119 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17120 } 17121 } 17122 if (procState > clientProcState) { 17123 procState = clientProcState; 17124 } 17125 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17126 schedGroup = Process.THREAD_GROUP_DEFAULT; 17127 } 17128 } 17129 // If the provider has external (non-framework) process 17130 // dependencies, ensure that its adjustment is at least 17131 // FOREGROUND_APP_ADJ. 17132 if (cpr.hasExternalProcessHandles()) { 17133 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17134 adj = ProcessList.FOREGROUND_APP_ADJ; 17135 schedGroup = Process.THREAD_GROUP_DEFAULT; 17136 app.cached = false; 17137 app.adjType = "provider"; 17138 app.adjTarget = cpr.name; 17139 } 17140 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17141 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17142 } 17143 } 17144 } 17145 17146 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17147 // A client of one of our services or providers is in the top state. We 17148 // *may* want to be in the top state, but not if we are already running in 17149 // the background for some other reason. For the decision here, we are going 17150 // to pick out a few specific states that we want to remain in when a client 17151 // is top (states that tend to be longer-term) and otherwise allow it to go 17152 // to the top state. 17153 switch (procState) { 17154 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17155 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17156 case ActivityManager.PROCESS_STATE_SERVICE: 17157 // These all are longer-term states, so pull them up to the top 17158 // of the background states, but not all the way to the top state. 17159 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17160 break; 17161 default: 17162 // Otherwise, top is a better choice, so take it. 17163 procState = ActivityManager.PROCESS_STATE_TOP; 17164 break; 17165 } 17166 } 17167 17168 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17169 if (app.hasClientActivities) { 17170 // This is a cached process, but with client activities. Mark it so. 17171 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17172 app.adjType = "cch-client-act"; 17173 } else if (app.treatLikeActivity) { 17174 // This is a cached process, but somebody wants us to treat it like it has 17175 // an activity, okay! 17176 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17177 app.adjType = "cch-as-act"; 17178 } 17179 } 17180 17181 if (adj == ProcessList.SERVICE_ADJ) { 17182 if (doingAll) { 17183 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17184 mNewNumServiceProcs++; 17185 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17186 if (!app.serviceb) { 17187 // This service isn't far enough down on the LRU list to 17188 // normally be a B service, but if we are low on RAM and it 17189 // is large we want to force it down since we would prefer to 17190 // keep launcher over it. 17191 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17192 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17193 app.serviceHighRam = true; 17194 app.serviceb = true; 17195 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17196 } else { 17197 mNewNumAServiceProcs++; 17198 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17199 } 17200 } else { 17201 app.serviceHighRam = false; 17202 } 17203 } 17204 if (app.serviceb) { 17205 adj = ProcessList.SERVICE_B_ADJ; 17206 } 17207 } 17208 17209 app.curRawAdj = adj; 17210 17211 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17212 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17213 if (adj > app.maxAdj) { 17214 adj = app.maxAdj; 17215 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17216 schedGroup = Process.THREAD_GROUP_DEFAULT; 17217 } 17218 } 17219 17220 // Do final modification to adj. Everything we do between here and applying 17221 // the final setAdj must be done in this function, because we will also use 17222 // it when computing the final cached adj later. Note that we don't need to 17223 // worry about this for max adj above, since max adj will always be used to 17224 // keep it out of the cached vaues. 17225 app.curAdj = app.modifyRawOomAdj(adj); 17226 app.curSchedGroup = schedGroup; 17227 app.curProcState = procState; 17228 app.foregroundActivities = foregroundActivities; 17229 17230 return app.curRawAdj; 17231 } 17232 17233 /** 17234 * Schedule PSS collection of a process. 17235 */ 17236 void requestPssLocked(ProcessRecord proc, int procState) { 17237 if (mPendingPssProcesses.contains(proc)) { 17238 return; 17239 } 17240 if (mPendingPssProcesses.size() == 0) { 17241 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17242 } 17243 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17244 proc.pssProcState = procState; 17245 mPendingPssProcesses.add(proc); 17246 } 17247 17248 /** 17249 * Schedule PSS collection of all processes. 17250 */ 17251 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17252 if (!always) { 17253 if (now < (mLastFullPssTime + 17254 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17255 return; 17256 } 17257 } 17258 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17259 mLastFullPssTime = now; 17260 mFullPssPending = true; 17261 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17262 mPendingPssProcesses.clear(); 17263 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17264 ProcessRecord app = mLruProcesses.get(i); 17265 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17266 app.pssProcState = app.setProcState; 17267 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17268 isSleeping(), now); 17269 mPendingPssProcesses.add(app); 17270 } 17271 } 17272 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17273 } 17274 17275 /** 17276 * Ask a given process to GC right now. 17277 */ 17278 final void performAppGcLocked(ProcessRecord app) { 17279 try { 17280 app.lastRequestedGc = SystemClock.uptimeMillis(); 17281 if (app.thread != null) { 17282 if (app.reportLowMemory) { 17283 app.reportLowMemory = false; 17284 app.thread.scheduleLowMemory(); 17285 } else { 17286 app.thread.processInBackground(); 17287 } 17288 } 17289 } catch (Exception e) { 17290 // whatever. 17291 } 17292 } 17293 17294 /** 17295 * Returns true if things are idle enough to perform GCs. 17296 */ 17297 private final boolean canGcNowLocked() { 17298 boolean processingBroadcasts = false; 17299 for (BroadcastQueue q : mBroadcastQueues) { 17300 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17301 processingBroadcasts = true; 17302 } 17303 } 17304 return !processingBroadcasts 17305 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17306 } 17307 17308 /** 17309 * Perform GCs on all processes that are waiting for it, but only 17310 * if things are idle. 17311 */ 17312 final void performAppGcsLocked() { 17313 final int N = mProcessesToGc.size(); 17314 if (N <= 0) { 17315 return; 17316 } 17317 if (canGcNowLocked()) { 17318 while (mProcessesToGc.size() > 0) { 17319 ProcessRecord proc = mProcessesToGc.remove(0); 17320 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17321 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17322 <= SystemClock.uptimeMillis()) { 17323 // To avoid spamming the system, we will GC processes one 17324 // at a time, waiting a few seconds between each. 17325 performAppGcLocked(proc); 17326 scheduleAppGcsLocked(); 17327 return; 17328 } else { 17329 // It hasn't been long enough since we last GCed this 17330 // process... put it in the list to wait for its time. 17331 addProcessToGcListLocked(proc); 17332 break; 17333 } 17334 } 17335 } 17336 17337 scheduleAppGcsLocked(); 17338 } 17339 } 17340 17341 /** 17342 * If all looks good, perform GCs on all processes waiting for them. 17343 */ 17344 final void performAppGcsIfAppropriateLocked() { 17345 if (canGcNowLocked()) { 17346 performAppGcsLocked(); 17347 return; 17348 } 17349 // Still not idle, wait some more. 17350 scheduleAppGcsLocked(); 17351 } 17352 17353 /** 17354 * Schedule the execution of all pending app GCs. 17355 */ 17356 final void scheduleAppGcsLocked() { 17357 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17358 17359 if (mProcessesToGc.size() > 0) { 17360 // Schedule a GC for the time to the next process. 17361 ProcessRecord proc = mProcessesToGc.get(0); 17362 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17363 17364 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17365 long now = SystemClock.uptimeMillis(); 17366 if (when < (now+GC_TIMEOUT)) { 17367 when = now + GC_TIMEOUT; 17368 } 17369 mHandler.sendMessageAtTime(msg, when); 17370 } 17371 } 17372 17373 /** 17374 * Add a process to the array of processes waiting to be GCed. Keeps the 17375 * list in sorted order by the last GC time. The process can't already be 17376 * on the list. 17377 */ 17378 final void addProcessToGcListLocked(ProcessRecord proc) { 17379 boolean added = false; 17380 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17381 if (mProcessesToGc.get(i).lastRequestedGc < 17382 proc.lastRequestedGc) { 17383 added = true; 17384 mProcessesToGc.add(i+1, proc); 17385 break; 17386 } 17387 } 17388 if (!added) { 17389 mProcessesToGc.add(0, proc); 17390 } 17391 } 17392 17393 /** 17394 * Set up to ask a process to GC itself. This will either do it 17395 * immediately, or put it on the list of processes to gc the next 17396 * time things are idle. 17397 */ 17398 final void scheduleAppGcLocked(ProcessRecord app) { 17399 long now = SystemClock.uptimeMillis(); 17400 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17401 return; 17402 } 17403 if (!mProcessesToGc.contains(app)) { 17404 addProcessToGcListLocked(app); 17405 scheduleAppGcsLocked(); 17406 } 17407 } 17408 17409 final void checkExcessivePowerUsageLocked(boolean doKills) { 17410 updateCpuStatsNow(); 17411 17412 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17413 boolean doWakeKills = doKills; 17414 boolean doCpuKills = doKills; 17415 if (mLastPowerCheckRealtime == 0) { 17416 doWakeKills = false; 17417 } 17418 if (mLastPowerCheckUptime == 0) { 17419 doCpuKills = false; 17420 } 17421 if (stats.isScreenOn()) { 17422 doWakeKills = false; 17423 } 17424 final long curRealtime = SystemClock.elapsedRealtime(); 17425 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17426 final long curUptime = SystemClock.uptimeMillis(); 17427 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17428 mLastPowerCheckRealtime = curRealtime; 17429 mLastPowerCheckUptime = curUptime; 17430 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17431 doWakeKills = false; 17432 } 17433 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17434 doCpuKills = false; 17435 } 17436 int i = mLruProcesses.size(); 17437 while (i > 0) { 17438 i--; 17439 ProcessRecord app = mLruProcesses.get(i); 17440 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17441 long wtime; 17442 synchronized (stats) { 17443 wtime = stats.getProcessWakeTime(app.info.uid, 17444 app.pid, curRealtime); 17445 } 17446 long wtimeUsed = wtime - app.lastWakeTime; 17447 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17448 if (DEBUG_POWER) { 17449 StringBuilder sb = new StringBuilder(128); 17450 sb.append("Wake for "); 17451 app.toShortString(sb); 17452 sb.append(": over "); 17453 TimeUtils.formatDuration(realtimeSince, sb); 17454 sb.append(" used "); 17455 TimeUtils.formatDuration(wtimeUsed, sb); 17456 sb.append(" ("); 17457 sb.append((wtimeUsed*100)/realtimeSince); 17458 sb.append("%)"); 17459 Slog.i(TAG, sb.toString()); 17460 sb.setLength(0); 17461 sb.append("CPU for "); 17462 app.toShortString(sb); 17463 sb.append(": over "); 17464 TimeUtils.formatDuration(uptimeSince, sb); 17465 sb.append(" used "); 17466 TimeUtils.formatDuration(cputimeUsed, sb); 17467 sb.append(" ("); 17468 sb.append((cputimeUsed*100)/uptimeSince); 17469 sb.append("%)"); 17470 Slog.i(TAG, sb.toString()); 17471 } 17472 // If a process has held a wake lock for more 17473 // than 50% of the time during this period, 17474 // that sounds bad. Kill! 17475 if (doWakeKills && realtimeSince > 0 17476 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17477 synchronized (stats) { 17478 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17479 realtimeSince, wtimeUsed); 17480 } 17481 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17482 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17483 } else if (doCpuKills && uptimeSince > 0 17484 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17485 synchronized (stats) { 17486 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17487 uptimeSince, cputimeUsed); 17488 } 17489 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17490 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17491 } else { 17492 app.lastWakeTime = wtime; 17493 app.lastCpuTime = app.curCpuTime; 17494 } 17495 } 17496 } 17497 } 17498 17499 private final boolean applyOomAdjLocked(ProcessRecord app, 17500 ProcessRecord TOP_APP, boolean doingAll, long now) { 17501 boolean success = true; 17502 17503 if (app.curRawAdj != app.setRawAdj) { 17504 app.setRawAdj = app.curRawAdj; 17505 } 17506 17507 int changes = 0; 17508 17509 if (app.curAdj != app.setAdj) { 17510 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17511 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17512 TAG, "Set " + app.pid + " " + app.processName + 17513 " adj " + app.curAdj + ": " + app.adjType); 17514 app.setAdj = app.curAdj; 17515 } 17516 17517 if (app.setSchedGroup != app.curSchedGroup) { 17518 app.setSchedGroup = app.curSchedGroup; 17519 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17520 "Setting process group of " + app.processName 17521 + " to " + app.curSchedGroup); 17522 if (app.waitingToKill != null && 17523 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17524 app.kill(app.waitingToKill, true); 17525 success = false; 17526 } else { 17527 if (true) { 17528 long oldId = Binder.clearCallingIdentity(); 17529 try { 17530 Process.setProcessGroup(app.pid, app.curSchedGroup); 17531 } catch (Exception e) { 17532 Slog.w(TAG, "Failed setting process group of " + app.pid 17533 + " to " + app.curSchedGroup); 17534 e.printStackTrace(); 17535 } finally { 17536 Binder.restoreCallingIdentity(oldId); 17537 } 17538 } else { 17539 if (app.thread != null) { 17540 try { 17541 app.thread.setSchedulingGroup(app.curSchedGroup); 17542 } catch (RemoteException e) { 17543 } 17544 } 17545 } 17546 Process.setSwappiness(app.pid, 17547 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17548 } 17549 } 17550 if (app.repForegroundActivities != app.foregroundActivities) { 17551 app.repForegroundActivities = app.foregroundActivities; 17552 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17553 } 17554 if (app.repProcState != app.curProcState) { 17555 app.repProcState = app.curProcState; 17556 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17557 if (app.thread != null) { 17558 try { 17559 if (false) { 17560 //RuntimeException h = new RuntimeException("here"); 17561 Slog.i(TAG, "Sending new process state " + app.repProcState 17562 + " to " + app /*, h*/); 17563 } 17564 app.thread.setProcessState(app.repProcState); 17565 } catch (RemoteException e) { 17566 } 17567 } 17568 } 17569 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17570 app.setProcState)) { 17571 app.lastStateTime = now; 17572 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17573 isSleeping(), now); 17574 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17575 + ProcessList.makeProcStateString(app.setProcState) + " to " 17576 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17577 + (app.nextPssTime-now) + ": " + app); 17578 } else { 17579 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17580 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17581 requestPssLocked(app, app.setProcState); 17582 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17583 isSleeping(), now); 17584 } else if (false && DEBUG_PSS) { 17585 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17586 } 17587 } 17588 if (app.setProcState != app.curProcState) { 17589 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17590 "Proc state change of " + app.processName 17591 + " to " + app.curProcState); 17592 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17593 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17594 if (setImportant && !curImportant) { 17595 // This app is no longer something we consider important enough to allow to 17596 // use arbitrary amounts of battery power. Note 17597 // its current wake lock time to later know to kill it if 17598 // it is not behaving well. 17599 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17600 synchronized (stats) { 17601 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17602 app.pid, SystemClock.elapsedRealtime()); 17603 } 17604 app.lastCpuTime = app.curCpuTime; 17605 17606 } 17607 app.setProcState = app.curProcState; 17608 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17609 app.notCachedSinceIdle = false; 17610 } 17611 if (!doingAll) { 17612 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17613 } else { 17614 app.procStateChanged = true; 17615 } 17616 } 17617 17618 if (changes != 0) { 17619 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17620 int i = mPendingProcessChanges.size()-1; 17621 ProcessChangeItem item = null; 17622 while (i >= 0) { 17623 item = mPendingProcessChanges.get(i); 17624 if (item.pid == app.pid) { 17625 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17626 break; 17627 } 17628 i--; 17629 } 17630 if (i < 0) { 17631 // No existing item in pending changes; need a new one. 17632 final int NA = mAvailProcessChanges.size(); 17633 if (NA > 0) { 17634 item = mAvailProcessChanges.remove(NA-1); 17635 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17636 } else { 17637 item = new ProcessChangeItem(); 17638 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17639 } 17640 item.changes = 0; 17641 item.pid = app.pid; 17642 item.uid = app.info.uid; 17643 if (mPendingProcessChanges.size() == 0) { 17644 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17645 "*** Enqueueing dispatch processes changed!"); 17646 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17647 } 17648 mPendingProcessChanges.add(item); 17649 } 17650 item.changes |= changes; 17651 item.processState = app.repProcState; 17652 item.foregroundActivities = app.repForegroundActivities; 17653 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17654 + Integer.toHexString(System.identityHashCode(item)) 17655 + " " + app.toShortString() + ": changes=" + item.changes 17656 + " procState=" + item.processState 17657 + " foreground=" + item.foregroundActivities 17658 + " type=" + app.adjType + " source=" + app.adjSource 17659 + " target=" + app.adjTarget); 17660 } 17661 17662 return success; 17663 } 17664 17665 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17666 if (proc.thread != null) { 17667 if (proc.baseProcessTracker != null) { 17668 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17669 } 17670 if (proc.repProcState >= 0) { 17671 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17672 proc.repProcState); 17673 } 17674 } 17675 } 17676 17677 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17678 ProcessRecord TOP_APP, boolean doingAll, long now) { 17679 if (app.thread == null) { 17680 return false; 17681 } 17682 17683 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17684 17685 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17686 } 17687 17688 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17689 boolean oomAdj) { 17690 if (isForeground != proc.foregroundServices) { 17691 proc.foregroundServices = isForeground; 17692 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17693 proc.info.uid); 17694 if (isForeground) { 17695 if (curProcs == null) { 17696 curProcs = new ArrayList<ProcessRecord>(); 17697 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17698 } 17699 if (!curProcs.contains(proc)) { 17700 curProcs.add(proc); 17701 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17702 proc.info.packageName, proc.info.uid); 17703 } 17704 } else { 17705 if (curProcs != null) { 17706 if (curProcs.remove(proc)) { 17707 mBatteryStatsService.noteEvent( 17708 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17709 proc.info.packageName, proc.info.uid); 17710 if (curProcs.size() <= 0) { 17711 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17712 } 17713 } 17714 } 17715 } 17716 if (oomAdj) { 17717 updateOomAdjLocked(); 17718 } 17719 } 17720 } 17721 17722 private final ActivityRecord resumedAppLocked() { 17723 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17724 String pkg; 17725 int uid; 17726 if (act != null) { 17727 pkg = act.packageName; 17728 uid = act.info.applicationInfo.uid; 17729 } else { 17730 pkg = null; 17731 uid = -1; 17732 } 17733 // Has the UID or resumed package name changed? 17734 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17735 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17736 if (mCurResumedPackage != null) { 17737 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17738 mCurResumedPackage, mCurResumedUid); 17739 } 17740 mCurResumedPackage = pkg; 17741 mCurResumedUid = uid; 17742 if (mCurResumedPackage != null) { 17743 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17744 mCurResumedPackage, mCurResumedUid); 17745 } 17746 } 17747 return act; 17748 } 17749 17750 final boolean updateOomAdjLocked(ProcessRecord app) { 17751 final ActivityRecord TOP_ACT = resumedAppLocked(); 17752 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17753 final boolean wasCached = app.cached; 17754 17755 mAdjSeq++; 17756 17757 // This is the desired cached adjusment we want to tell it to use. 17758 // If our app is currently cached, we know it, and that is it. Otherwise, 17759 // we don't know it yet, and it needs to now be cached we will then 17760 // need to do a complete oom adj. 17761 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17762 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17763 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17764 SystemClock.uptimeMillis()); 17765 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17766 // Changed to/from cached state, so apps after it in the LRU 17767 // list may also be changed. 17768 updateOomAdjLocked(); 17769 } 17770 return success; 17771 } 17772 17773 final void updateOomAdjLocked() { 17774 final ActivityRecord TOP_ACT = resumedAppLocked(); 17775 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17776 final long now = SystemClock.uptimeMillis(); 17777 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17778 final int N = mLruProcesses.size(); 17779 17780 if (false) { 17781 RuntimeException e = new RuntimeException(); 17782 e.fillInStackTrace(); 17783 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17784 } 17785 17786 mAdjSeq++; 17787 mNewNumServiceProcs = 0; 17788 mNewNumAServiceProcs = 0; 17789 17790 final int emptyProcessLimit; 17791 final int cachedProcessLimit; 17792 if (mProcessLimit <= 0) { 17793 emptyProcessLimit = cachedProcessLimit = 0; 17794 } else if (mProcessLimit == 1) { 17795 emptyProcessLimit = 1; 17796 cachedProcessLimit = 0; 17797 } else { 17798 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17799 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17800 } 17801 17802 // Let's determine how many processes we have running vs. 17803 // how many slots we have for background processes; we may want 17804 // to put multiple processes in a slot of there are enough of 17805 // them. 17806 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17807 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17808 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17809 if (numEmptyProcs > cachedProcessLimit) { 17810 // If there are more empty processes than our limit on cached 17811 // processes, then use the cached process limit for the factor. 17812 // This ensures that the really old empty processes get pushed 17813 // down to the bottom, so if we are running low on memory we will 17814 // have a better chance at keeping around more cached processes 17815 // instead of a gazillion empty processes. 17816 numEmptyProcs = cachedProcessLimit; 17817 } 17818 int emptyFactor = numEmptyProcs/numSlots; 17819 if (emptyFactor < 1) emptyFactor = 1; 17820 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17821 if (cachedFactor < 1) cachedFactor = 1; 17822 int stepCached = 0; 17823 int stepEmpty = 0; 17824 int numCached = 0; 17825 int numEmpty = 0; 17826 int numTrimming = 0; 17827 17828 mNumNonCachedProcs = 0; 17829 mNumCachedHiddenProcs = 0; 17830 17831 // First update the OOM adjustment for each of the 17832 // application processes based on their current state. 17833 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17834 int nextCachedAdj = curCachedAdj+1; 17835 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17836 int nextEmptyAdj = curEmptyAdj+2; 17837 for (int i=N-1; i>=0; i--) { 17838 ProcessRecord app = mLruProcesses.get(i); 17839 if (!app.killedByAm && app.thread != null) { 17840 app.procStateChanged = false; 17841 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17842 17843 // If we haven't yet assigned the final cached adj 17844 // to the process, do that now. 17845 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17846 switch (app.curProcState) { 17847 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17848 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17849 // This process is a cached process holding activities... 17850 // assign it the next cached value for that type, and then 17851 // step that cached level. 17852 app.curRawAdj = curCachedAdj; 17853 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17854 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17855 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17856 + ")"); 17857 if (curCachedAdj != nextCachedAdj) { 17858 stepCached++; 17859 if (stepCached >= cachedFactor) { 17860 stepCached = 0; 17861 curCachedAdj = nextCachedAdj; 17862 nextCachedAdj += 2; 17863 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17864 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17865 } 17866 } 17867 } 17868 break; 17869 default: 17870 // For everything else, assign next empty cached process 17871 // level and bump that up. Note that this means that 17872 // long-running services that have dropped down to the 17873 // cached level will be treated as empty (since their process 17874 // state is still as a service), which is what we want. 17875 app.curRawAdj = curEmptyAdj; 17876 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17877 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17878 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17879 + ")"); 17880 if (curEmptyAdj != nextEmptyAdj) { 17881 stepEmpty++; 17882 if (stepEmpty >= emptyFactor) { 17883 stepEmpty = 0; 17884 curEmptyAdj = nextEmptyAdj; 17885 nextEmptyAdj += 2; 17886 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17887 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17888 } 17889 } 17890 } 17891 break; 17892 } 17893 } 17894 17895 applyOomAdjLocked(app, TOP_APP, true, now); 17896 17897 // Count the number of process types. 17898 switch (app.curProcState) { 17899 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17900 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17901 mNumCachedHiddenProcs++; 17902 numCached++; 17903 if (numCached > cachedProcessLimit) { 17904 app.kill("cached #" + numCached, true); 17905 } 17906 break; 17907 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17908 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17909 && app.lastActivityTime < oldTime) { 17910 app.kill("empty for " 17911 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17912 / 1000) + "s", true); 17913 } else { 17914 numEmpty++; 17915 if (numEmpty > emptyProcessLimit) { 17916 app.kill("empty #" + numEmpty, true); 17917 } 17918 } 17919 break; 17920 default: 17921 mNumNonCachedProcs++; 17922 break; 17923 } 17924 17925 if (app.isolated && app.services.size() <= 0) { 17926 // If this is an isolated process, and there are no 17927 // services running in it, then the process is no longer 17928 // needed. We agressively kill these because we can by 17929 // definition not re-use the same process again, and it is 17930 // good to avoid having whatever code was running in them 17931 // left sitting around after no longer needed. 17932 app.kill("isolated not needed", true); 17933 } 17934 17935 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17936 && !app.killedByAm) { 17937 numTrimming++; 17938 } 17939 } 17940 } 17941 17942 mNumServiceProcs = mNewNumServiceProcs; 17943 17944 // Now determine the memory trimming level of background processes. 17945 // Unfortunately we need to start at the back of the list to do this 17946 // properly. We only do this if the number of background apps we 17947 // are managing to keep around is less than half the maximum we desire; 17948 // if we are keeping a good number around, we'll let them use whatever 17949 // memory they want. 17950 final int numCachedAndEmpty = numCached + numEmpty; 17951 int memFactor; 17952 if (numCached <= ProcessList.TRIM_CACHED_APPS 17953 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17954 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17955 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17956 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17957 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17958 } else { 17959 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17960 } 17961 } else { 17962 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17963 } 17964 // We always allow the memory level to go up (better). We only allow it to go 17965 // down if we are in a state where that is allowed, *and* the total number of processes 17966 // has gone down since last time. 17967 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17968 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17969 + " last=" + mLastNumProcesses); 17970 if (memFactor > mLastMemoryLevel) { 17971 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17972 memFactor = mLastMemoryLevel; 17973 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17974 } 17975 } 17976 mLastMemoryLevel = memFactor; 17977 mLastNumProcesses = mLruProcesses.size(); 17978 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17979 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17980 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17981 if (mLowRamStartTime == 0) { 17982 mLowRamStartTime = now; 17983 } 17984 int step = 0; 17985 int fgTrimLevel; 17986 switch (memFactor) { 17987 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17988 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17989 break; 17990 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17991 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17992 break; 17993 default: 17994 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17995 break; 17996 } 17997 int factor = numTrimming/3; 17998 int minFactor = 2; 17999 if (mHomeProcess != null) minFactor++; 18000 if (mPreviousProcess != null) minFactor++; 18001 if (factor < minFactor) factor = minFactor; 18002 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18003 for (int i=N-1; i>=0; i--) { 18004 ProcessRecord app = mLruProcesses.get(i); 18005 if (allChanged || app.procStateChanged) { 18006 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18007 app.procStateChanged = false; 18008 } 18009 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18010 && !app.killedByAm) { 18011 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18012 try { 18013 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18014 "Trimming memory of " + app.processName 18015 + " to " + curLevel); 18016 app.thread.scheduleTrimMemory(curLevel); 18017 } catch (RemoteException e) { 18018 } 18019 if (false) { 18020 // For now we won't do this; our memory trimming seems 18021 // to be good enough at this point that destroying 18022 // activities causes more harm than good. 18023 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18024 && app != mHomeProcess && app != mPreviousProcess) { 18025 // Need to do this on its own message because the stack may not 18026 // be in a consistent state at this point. 18027 // For these apps we will also finish their activities 18028 // to help them free memory. 18029 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18030 } 18031 } 18032 } 18033 app.trimMemoryLevel = curLevel; 18034 step++; 18035 if (step >= factor) { 18036 step = 0; 18037 switch (curLevel) { 18038 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18039 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18040 break; 18041 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18042 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18043 break; 18044 } 18045 } 18046 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18047 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18048 && app.thread != null) { 18049 try { 18050 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18051 "Trimming memory of heavy-weight " + app.processName 18052 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18053 app.thread.scheduleTrimMemory( 18054 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18055 } catch (RemoteException e) { 18056 } 18057 } 18058 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18059 } else { 18060 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18061 || app.systemNoUi) && app.pendingUiClean) { 18062 // If this application is now in the background and it 18063 // had done UI, then give it the special trim level to 18064 // have it free UI resources. 18065 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18066 if (app.trimMemoryLevel < level && app.thread != null) { 18067 try { 18068 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18069 "Trimming memory of bg-ui " + app.processName 18070 + " to " + level); 18071 app.thread.scheduleTrimMemory(level); 18072 } catch (RemoteException e) { 18073 } 18074 } 18075 app.pendingUiClean = false; 18076 } 18077 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18078 try { 18079 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18080 "Trimming memory of fg " + app.processName 18081 + " to " + fgTrimLevel); 18082 app.thread.scheduleTrimMemory(fgTrimLevel); 18083 } catch (RemoteException e) { 18084 } 18085 } 18086 app.trimMemoryLevel = fgTrimLevel; 18087 } 18088 } 18089 } else { 18090 if (mLowRamStartTime != 0) { 18091 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18092 mLowRamStartTime = 0; 18093 } 18094 for (int i=N-1; i>=0; i--) { 18095 ProcessRecord app = mLruProcesses.get(i); 18096 if (allChanged || app.procStateChanged) { 18097 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18098 app.procStateChanged = false; 18099 } 18100 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18101 || app.systemNoUi) && app.pendingUiClean) { 18102 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18103 && app.thread != null) { 18104 try { 18105 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18106 "Trimming memory of ui hidden " + app.processName 18107 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18108 app.thread.scheduleTrimMemory( 18109 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18110 } catch (RemoteException e) { 18111 } 18112 } 18113 app.pendingUiClean = false; 18114 } 18115 app.trimMemoryLevel = 0; 18116 } 18117 } 18118 18119 if (mAlwaysFinishActivities) { 18120 // Need to do this on its own message because the stack may not 18121 // be in a consistent state at this point. 18122 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18123 } 18124 18125 if (allChanged) { 18126 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18127 } 18128 18129 if (mProcessStats.shouldWriteNowLocked(now)) { 18130 mHandler.post(new Runnable() { 18131 @Override public void run() { 18132 synchronized (ActivityManagerService.this) { 18133 mProcessStats.writeStateAsyncLocked(); 18134 } 18135 } 18136 }); 18137 } 18138 18139 if (DEBUG_OOM_ADJ) { 18140 if (false) { 18141 RuntimeException here = new RuntimeException("here"); 18142 here.fillInStackTrace(); 18143 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18144 } else { 18145 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18146 } 18147 } 18148 } 18149 18150 final void trimApplications() { 18151 synchronized (this) { 18152 int i; 18153 18154 // First remove any unused application processes whose package 18155 // has been removed. 18156 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18157 final ProcessRecord app = mRemovedProcesses.get(i); 18158 if (app.activities.size() == 0 18159 && app.curReceiver == null && app.services.size() == 0) { 18160 Slog.i( 18161 TAG, "Exiting empty application process " 18162 + app.processName + " (" 18163 + (app.thread != null ? app.thread.asBinder() : null) 18164 + ")\n"); 18165 if (app.pid > 0 && app.pid != MY_PID) { 18166 app.kill("empty", false); 18167 } else { 18168 try { 18169 app.thread.scheduleExit(); 18170 } catch (Exception e) { 18171 // Ignore exceptions. 18172 } 18173 } 18174 cleanUpApplicationRecordLocked(app, false, true, -1); 18175 mRemovedProcesses.remove(i); 18176 18177 if (app.persistent) { 18178 addAppLocked(app.info, false, null /* ABI override */); 18179 } 18180 } 18181 } 18182 18183 // Now update the oom adj for all processes. 18184 updateOomAdjLocked(); 18185 } 18186 } 18187 18188 /** This method sends the specified signal to each of the persistent apps */ 18189 public void signalPersistentProcesses(int sig) throws RemoteException { 18190 if (sig != Process.SIGNAL_USR1) { 18191 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18192 } 18193 18194 synchronized (this) { 18195 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18196 != PackageManager.PERMISSION_GRANTED) { 18197 throw new SecurityException("Requires permission " 18198 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18199 } 18200 18201 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18202 ProcessRecord r = mLruProcesses.get(i); 18203 if (r.thread != null && r.persistent) { 18204 Process.sendSignal(r.pid, sig); 18205 } 18206 } 18207 } 18208 } 18209 18210 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18211 if (proc == null || proc == mProfileProc) { 18212 proc = mProfileProc; 18213 profileType = mProfileType; 18214 clearProfilerLocked(); 18215 } 18216 if (proc == null) { 18217 return; 18218 } 18219 try { 18220 proc.thread.profilerControl(false, null, profileType); 18221 } catch (RemoteException e) { 18222 throw new IllegalStateException("Process disappeared"); 18223 } 18224 } 18225 18226 private void clearProfilerLocked() { 18227 if (mProfileFd != null) { 18228 try { 18229 mProfileFd.close(); 18230 } catch (IOException e) { 18231 } 18232 } 18233 mProfileApp = null; 18234 mProfileProc = null; 18235 mProfileFile = null; 18236 mProfileType = 0; 18237 mAutoStopProfiler = false; 18238 mSamplingInterval = 0; 18239 } 18240 18241 public boolean profileControl(String process, int userId, boolean start, 18242 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18243 18244 try { 18245 synchronized (this) { 18246 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18247 // its own permission. 18248 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18249 != PackageManager.PERMISSION_GRANTED) { 18250 throw new SecurityException("Requires permission " 18251 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18252 } 18253 18254 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18255 throw new IllegalArgumentException("null profile info or fd"); 18256 } 18257 18258 ProcessRecord proc = null; 18259 if (process != null) { 18260 proc = findProcessLocked(process, userId, "profileControl"); 18261 } 18262 18263 if (start && (proc == null || proc.thread == null)) { 18264 throw new IllegalArgumentException("Unknown process: " + process); 18265 } 18266 18267 if (start) { 18268 stopProfilerLocked(null, 0); 18269 setProfileApp(proc.info, proc.processName, profilerInfo); 18270 mProfileProc = proc; 18271 mProfileType = profileType; 18272 ParcelFileDescriptor fd = profilerInfo.profileFd; 18273 try { 18274 fd = fd.dup(); 18275 } catch (IOException e) { 18276 fd = null; 18277 } 18278 profilerInfo.profileFd = fd; 18279 proc.thread.profilerControl(start, profilerInfo, profileType); 18280 fd = null; 18281 mProfileFd = null; 18282 } else { 18283 stopProfilerLocked(proc, profileType); 18284 if (profilerInfo != null && profilerInfo.profileFd != null) { 18285 try { 18286 profilerInfo.profileFd.close(); 18287 } catch (IOException e) { 18288 } 18289 } 18290 } 18291 18292 return true; 18293 } 18294 } catch (RemoteException e) { 18295 throw new IllegalStateException("Process disappeared"); 18296 } finally { 18297 if (profilerInfo != null && profilerInfo.profileFd != null) { 18298 try { 18299 profilerInfo.profileFd.close(); 18300 } catch (IOException e) { 18301 } 18302 } 18303 } 18304 } 18305 18306 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18308 userId, true, ALLOW_FULL_ONLY, callName, null); 18309 ProcessRecord proc = null; 18310 try { 18311 int pid = Integer.parseInt(process); 18312 synchronized (mPidsSelfLocked) { 18313 proc = mPidsSelfLocked.get(pid); 18314 } 18315 } catch (NumberFormatException e) { 18316 } 18317 18318 if (proc == null) { 18319 ArrayMap<String, SparseArray<ProcessRecord>> all 18320 = mProcessNames.getMap(); 18321 SparseArray<ProcessRecord> procs = all.get(process); 18322 if (procs != null && procs.size() > 0) { 18323 proc = procs.valueAt(0); 18324 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18325 for (int i=1; i<procs.size(); i++) { 18326 ProcessRecord thisProc = procs.valueAt(i); 18327 if (thisProc.userId == userId) { 18328 proc = thisProc; 18329 break; 18330 } 18331 } 18332 } 18333 } 18334 } 18335 18336 return proc; 18337 } 18338 18339 public boolean dumpHeap(String process, int userId, boolean managed, 18340 String path, ParcelFileDescriptor fd) throws RemoteException { 18341 18342 try { 18343 synchronized (this) { 18344 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18345 // its own permission (same as profileControl). 18346 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18347 != PackageManager.PERMISSION_GRANTED) { 18348 throw new SecurityException("Requires permission " 18349 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18350 } 18351 18352 if (fd == null) { 18353 throw new IllegalArgumentException("null fd"); 18354 } 18355 18356 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18357 if (proc == null || proc.thread == null) { 18358 throw new IllegalArgumentException("Unknown process: " + process); 18359 } 18360 18361 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18362 if (!isDebuggable) { 18363 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18364 throw new SecurityException("Process not debuggable: " + proc); 18365 } 18366 } 18367 18368 proc.thread.dumpHeap(managed, path, fd); 18369 fd = null; 18370 return true; 18371 } 18372 } catch (RemoteException e) { 18373 throw new IllegalStateException("Process disappeared"); 18374 } finally { 18375 if (fd != null) { 18376 try { 18377 fd.close(); 18378 } catch (IOException e) { 18379 } 18380 } 18381 } 18382 } 18383 18384 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18385 public void monitor() { 18386 synchronized (this) { } 18387 } 18388 18389 void onCoreSettingsChange(Bundle settings) { 18390 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18391 ProcessRecord processRecord = mLruProcesses.get(i); 18392 try { 18393 if (processRecord.thread != null) { 18394 processRecord.thread.setCoreSettings(settings); 18395 } 18396 } catch (RemoteException re) { 18397 /* ignore */ 18398 } 18399 } 18400 } 18401 18402 // Multi-user methods 18403 18404 /** 18405 * Start user, if its not already running, but don't bring it to foreground. 18406 */ 18407 @Override 18408 public boolean startUserInBackground(final int userId) { 18409 return startUser(userId, /* foreground */ false); 18410 } 18411 18412 /** 18413 * Start user, if its not already running, and bring it to foreground. 18414 */ 18415 boolean startUserInForeground(final int userId, Dialog dlg) { 18416 boolean result = startUser(userId, /* foreground */ true); 18417 dlg.dismiss(); 18418 return result; 18419 } 18420 18421 /** 18422 * Refreshes the list of users related to the current user when either a 18423 * user switch happens or when a new related user is started in the 18424 * background. 18425 */ 18426 private void updateCurrentProfileIdsLocked() { 18427 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18428 mCurrentUserId, false /* enabledOnly */); 18429 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18430 for (int i = 0; i < currentProfileIds.length; i++) { 18431 currentProfileIds[i] = profiles.get(i).id; 18432 } 18433 mCurrentProfileIds = currentProfileIds; 18434 18435 synchronized (mUserProfileGroupIdsSelfLocked) { 18436 mUserProfileGroupIdsSelfLocked.clear(); 18437 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18438 for (int i = 0; i < users.size(); i++) { 18439 UserInfo user = users.get(i); 18440 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18441 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18442 } 18443 } 18444 } 18445 } 18446 18447 private Set getProfileIdsLocked(int userId) { 18448 Set userIds = new HashSet<Integer>(); 18449 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18450 userId, false /* enabledOnly */); 18451 for (UserInfo user : profiles) { 18452 userIds.add(Integer.valueOf(user.id)); 18453 } 18454 return userIds; 18455 } 18456 18457 @Override 18458 public boolean switchUser(final int userId) { 18459 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18460 String userName; 18461 synchronized (this) { 18462 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18463 if (userInfo == null) { 18464 Slog.w(TAG, "No user info for user #" + userId); 18465 return false; 18466 } 18467 if (userInfo.isManagedProfile()) { 18468 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18469 return false; 18470 } 18471 userName = userInfo.name; 18472 mTargetUserId = userId; 18473 } 18474 mHandler.removeMessages(START_USER_SWITCH_MSG); 18475 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18476 return true; 18477 } 18478 18479 private void showUserSwitchDialog(int userId, String userName) { 18480 // The dialog will show and then initiate the user switch by calling startUserInForeground 18481 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18482 true /* above system */); 18483 d.show(); 18484 } 18485 18486 private boolean startUser(final int userId, final boolean foreground) { 18487 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18488 != PackageManager.PERMISSION_GRANTED) { 18489 String msg = "Permission Denial: switchUser() from pid=" 18490 + Binder.getCallingPid() 18491 + ", uid=" + Binder.getCallingUid() 18492 + " requires " + INTERACT_ACROSS_USERS_FULL; 18493 Slog.w(TAG, msg); 18494 throw new SecurityException(msg); 18495 } 18496 18497 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18498 18499 final long ident = Binder.clearCallingIdentity(); 18500 try { 18501 synchronized (this) { 18502 final int oldUserId = mCurrentUserId; 18503 if (oldUserId == userId) { 18504 return true; 18505 } 18506 18507 mStackSupervisor.setLockTaskModeLocked(null, false); 18508 18509 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18510 if (userInfo == null) { 18511 Slog.w(TAG, "No user info for user #" + userId); 18512 return false; 18513 } 18514 if (foreground && userInfo.isManagedProfile()) { 18515 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18516 return false; 18517 } 18518 18519 if (foreground) { 18520 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18521 R.anim.screen_user_enter); 18522 } 18523 18524 boolean needStart = false; 18525 18526 // If the user we are switching to is not currently started, then 18527 // we need to start it now. 18528 if (mStartedUsers.get(userId) == null) { 18529 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18530 updateStartedUserArrayLocked(); 18531 needStart = true; 18532 } 18533 18534 final Integer userIdInt = Integer.valueOf(userId); 18535 mUserLru.remove(userIdInt); 18536 mUserLru.add(userIdInt); 18537 18538 if (foreground) { 18539 mCurrentUserId = userId; 18540 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18541 updateCurrentProfileIdsLocked(); 18542 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18543 // Once the internal notion of the active user has switched, we lock the device 18544 // with the option to show the user switcher on the keyguard. 18545 mWindowManager.lockNow(null); 18546 } else { 18547 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18548 updateCurrentProfileIdsLocked(); 18549 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18550 mUserLru.remove(currentUserIdInt); 18551 mUserLru.add(currentUserIdInt); 18552 } 18553 18554 final UserStartedState uss = mStartedUsers.get(userId); 18555 18556 // Make sure user is in the started state. If it is currently 18557 // stopping, we need to knock that off. 18558 if (uss.mState == UserStartedState.STATE_STOPPING) { 18559 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18560 // so we can just fairly silently bring the user back from 18561 // the almost-dead. 18562 uss.mState = UserStartedState.STATE_RUNNING; 18563 updateStartedUserArrayLocked(); 18564 needStart = true; 18565 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18566 // This means ACTION_SHUTDOWN has been sent, so we will 18567 // need to treat this as a new boot of the user. 18568 uss.mState = UserStartedState.STATE_BOOTING; 18569 updateStartedUserArrayLocked(); 18570 needStart = true; 18571 } 18572 18573 if (uss.mState == UserStartedState.STATE_BOOTING) { 18574 // Booting up a new user, need to tell system services about it. 18575 // Note that this is on the same handler as scheduling of broadcasts, 18576 // which is important because it needs to go first. 18577 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18578 } 18579 18580 if (foreground) { 18581 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18582 oldUserId)); 18583 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18584 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18585 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18586 oldUserId, userId, uss)); 18587 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18588 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18589 } 18590 18591 if (needStart) { 18592 // Send USER_STARTED broadcast 18593 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18594 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18595 | Intent.FLAG_RECEIVER_FOREGROUND); 18596 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18597 broadcastIntentLocked(null, null, intent, 18598 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18599 false, false, MY_PID, Process.SYSTEM_UID, userId); 18600 } 18601 18602 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18603 if (userId != UserHandle.USER_OWNER) { 18604 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18605 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18606 broadcastIntentLocked(null, null, intent, null, 18607 new IIntentReceiver.Stub() { 18608 public void performReceive(Intent intent, int resultCode, 18609 String data, Bundle extras, boolean ordered, 18610 boolean sticky, int sendingUser) { 18611 onUserInitialized(uss, foreground, oldUserId, userId); 18612 } 18613 }, 0, null, null, null, AppOpsManager.OP_NONE, 18614 true, false, MY_PID, Process.SYSTEM_UID, 18615 userId); 18616 uss.initializing = true; 18617 } else { 18618 getUserManagerLocked().makeInitialized(userInfo.id); 18619 } 18620 } 18621 18622 if (foreground) { 18623 if (!uss.initializing) { 18624 moveUserToForeground(uss, oldUserId, userId); 18625 } 18626 } else { 18627 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18628 } 18629 18630 if (needStart) { 18631 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18632 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18633 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18634 broadcastIntentLocked(null, null, intent, 18635 null, new IIntentReceiver.Stub() { 18636 @Override 18637 public void performReceive(Intent intent, int resultCode, String data, 18638 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18639 throws RemoteException { 18640 } 18641 }, 0, null, null, 18642 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18643 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18644 } 18645 } 18646 } finally { 18647 Binder.restoreCallingIdentity(ident); 18648 } 18649 18650 return true; 18651 } 18652 18653 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18654 long ident = Binder.clearCallingIdentity(); 18655 try { 18656 Intent intent; 18657 if (oldUserId >= 0) { 18658 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18659 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18660 int count = profiles.size(); 18661 for (int i = 0; i < count; i++) { 18662 int profileUserId = profiles.get(i).id; 18663 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18664 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18665 | Intent.FLAG_RECEIVER_FOREGROUND); 18666 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18667 broadcastIntentLocked(null, null, intent, 18668 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18669 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18670 } 18671 } 18672 if (newUserId >= 0) { 18673 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18674 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18675 int count = profiles.size(); 18676 for (int i = 0; i < count; i++) { 18677 int profileUserId = profiles.get(i).id; 18678 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18679 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18680 | Intent.FLAG_RECEIVER_FOREGROUND); 18681 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18682 broadcastIntentLocked(null, null, intent, 18683 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18684 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18685 } 18686 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18688 | Intent.FLAG_RECEIVER_FOREGROUND); 18689 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18690 broadcastIntentLocked(null, null, intent, 18691 null, null, 0, null, null, 18692 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18693 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18694 } 18695 } finally { 18696 Binder.restoreCallingIdentity(ident); 18697 } 18698 } 18699 18700 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18701 final int newUserId) { 18702 final int N = mUserSwitchObservers.beginBroadcast(); 18703 if (N > 0) { 18704 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18705 int mCount = 0; 18706 @Override 18707 public void sendResult(Bundle data) throws RemoteException { 18708 synchronized (ActivityManagerService.this) { 18709 if (mCurUserSwitchCallback == this) { 18710 mCount++; 18711 if (mCount == N) { 18712 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18713 } 18714 } 18715 } 18716 } 18717 }; 18718 synchronized (this) { 18719 uss.switching = true; 18720 mCurUserSwitchCallback = callback; 18721 } 18722 for (int i=0; i<N; i++) { 18723 try { 18724 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18725 newUserId, callback); 18726 } catch (RemoteException e) { 18727 } 18728 } 18729 } else { 18730 synchronized (this) { 18731 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18732 } 18733 } 18734 mUserSwitchObservers.finishBroadcast(); 18735 } 18736 18737 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18738 synchronized (this) { 18739 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18740 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18741 } 18742 } 18743 18744 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18745 mCurUserSwitchCallback = null; 18746 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18747 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18748 oldUserId, newUserId, uss)); 18749 } 18750 18751 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18752 synchronized (this) { 18753 if (foreground) { 18754 moveUserToForeground(uss, oldUserId, newUserId); 18755 } 18756 } 18757 18758 completeSwitchAndInitalize(uss, newUserId, true, false); 18759 } 18760 18761 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18762 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18763 if (homeInFront) { 18764 startHomeActivityLocked(newUserId); 18765 } else { 18766 mStackSupervisor.resumeTopActivitiesLocked(); 18767 } 18768 EventLogTags.writeAmSwitchUser(newUserId); 18769 getUserManagerLocked().userForeground(newUserId); 18770 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18771 } 18772 18773 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18774 completeSwitchAndInitalize(uss, newUserId, false, true); 18775 } 18776 18777 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18778 boolean clearInitializing, boolean clearSwitching) { 18779 boolean unfrozen = false; 18780 synchronized (this) { 18781 if (clearInitializing) { 18782 uss.initializing = false; 18783 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18784 } 18785 if (clearSwitching) { 18786 uss.switching = false; 18787 } 18788 if (!uss.switching && !uss.initializing) { 18789 mWindowManager.stopFreezingScreen(); 18790 unfrozen = true; 18791 } 18792 } 18793 if (unfrozen) { 18794 final int N = mUserSwitchObservers.beginBroadcast(); 18795 for (int i=0; i<N; i++) { 18796 try { 18797 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18798 } catch (RemoteException e) { 18799 } 18800 } 18801 mUserSwitchObservers.finishBroadcast(); 18802 } 18803 } 18804 18805 void scheduleStartProfilesLocked() { 18806 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18807 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18808 DateUtils.SECOND_IN_MILLIS); 18809 } 18810 } 18811 18812 void startProfilesLocked() { 18813 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18814 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18815 mCurrentUserId, false /* enabledOnly */); 18816 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18817 for (UserInfo user : profiles) { 18818 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18819 && user.id != mCurrentUserId) { 18820 toStart.add(user); 18821 } 18822 } 18823 final int n = toStart.size(); 18824 int i = 0; 18825 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18826 startUserInBackground(toStart.get(i).id); 18827 } 18828 if (i < n) { 18829 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18830 } 18831 } 18832 18833 void finishUserBoot(UserStartedState uss) { 18834 synchronized (this) { 18835 if (uss.mState == UserStartedState.STATE_BOOTING 18836 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18837 uss.mState = UserStartedState.STATE_RUNNING; 18838 final int userId = uss.mHandle.getIdentifier(); 18839 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18840 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18841 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18842 broadcastIntentLocked(null, null, intent, 18843 null, null, 0, null, null, 18844 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18845 true, false, MY_PID, Process.SYSTEM_UID, userId); 18846 } 18847 } 18848 } 18849 18850 void finishUserSwitch(UserStartedState uss) { 18851 synchronized (this) { 18852 finishUserBoot(uss); 18853 18854 startProfilesLocked(); 18855 18856 int num = mUserLru.size(); 18857 int i = 0; 18858 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18859 Integer oldUserId = mUserLru.get(i); 18860 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18861 if (oldUss == null) { 18862 // Shouldn't happen, but be sane if it does. 18863 mUserLru.remove(i); 18864 num--; 18865 continue; 18866 } 18867 if (oldUss.mState == UserStartedState.STATE_STOPPING 18868 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18869 // This user is already stopping, doesn't count. 18870 num--; 18871 i++; 18872 continue; 18873 } 18874 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18875 // Owner and current can't be stopped, but count as running. 18876 i++; 18877 continue; 18878 } 18879 // This is a user to be stopped. 18880 stopUserLocked(oldUserId, null); 18881 num--; 18882 i++; 18883 } 18884 } 18885 } 18886 18887 @Override 18888 public int stopUser(final int userId, final IStopUserCallback callback) { 18889 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18890 != PackageManager.PERMISSION_GRANTED) { 18891 String msg = "Permission Denial: switchUser() from pid=" 18892 + Binder.getCallingPid() 18893 + ", uid=" + Binder.getCallingUid() 18894 + " requires " + INTERACT_ACROSS_USERS_FULL; 18895 Slog.w(TAG, msg); 18896 throw new SecurityException(msg); 18897 } 18898 if (userId <= 0) { 18899 throw new IllegalArgumentException("Can't stop primary user " + userId); 18900 } 18901 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18902 synchronized (this) { 18903 return stopUserLocked(userId, callback); 18904 } 18905 } 18906 18907 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18908 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18909 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18910 return ActivityManager.USER_OP_IS_CURRENT; 18911 } 18912 18913 final UserStartedState uss = mStartedUsers.get(userId); 18914 if (uss == null) { 18915 // User is not started, nothing to do... but we do need to 18916 // callback if requested. 18917 if (callback != null) { 18918 mHandler.post(new Runnable() { 18919 @Override 18920 public void run() { 18921 try { 18922 callback.userStopped(userId); 18923 } catch (RemoteException e) { 18924 } 18925 } 18926 }); 18927 } 18928 return ActivityManager.USER_OP_SUCCESS; 18929 } 18930 18931 if (callback != null) { 18932 uss.mStopCallbacks.add(callback); 18933 } 18934 18935 if (uss.mState != UserStartedState.STATE_STOPPING 18936 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18937 uss.mState = UserStartedState.STATE_STOPPING; 18938 updateStartedUserArrayLocked(); 18939 18940 long ident = Binder.clearCallingIdentity(); 18941 try { 18942 // We are going to broadcast ACTION_USER_STOPPING and then 18943 // once that is done send a final ACTION_SHUTDOWN and then 18944 // stop the user. 18945 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18946 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18947 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18948 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18949 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18950 // This is the result receiver for the final shutdown broadcast. 18951 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18952 @Override 18953 public void performReceive(Intent intent, int resultCode, String data, 18954 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18955 finishUserStop(uss); 18956 } 18957 }; 18958 // This is the result receiver for the initial stopping broadcast. 18959 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18960 @Override 18961 public void performReceive(Intent intent, int resultCode, String data, 18962 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18963 // On to the next. 18964 synchronized (ActivityManagerService.this) { 18965 if (uss.mState != UserStartedState.STATE_STOPPING) { 18966 // Whoops, we are being started back up. Abort, abort! 18967 return; 18968 } 18969 uss.mState = UserStartedState.STATE_SHUTDOWN; 18970 } 18971 mBatteryStatsService.noteEvent( 18972 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18973 Integer.toString(userId), userId); 18974 mSystemServiceManager.stopUser(userId); 18975 broadcastIntentLocked(null, null, shutdownIntent, 18976 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18977 true, false, MY_PID, Process.SYSTEM_UID, userId); 18978 } 18979 }; 18980 // Kick things off. 18981 broadcastIntentLocked(null, null, stoppingIntent, 18982 null, stoppingReceiver, 0, null, null, 18983 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18984 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18985 } finally { 18986 Binder.restoreCallingIdentity(ident); 18987 } 18988 } 18989 18990 return ActivityManager.USER_OP_SUCCESS; 18991 } 18992 18993 void finishUserStop(UserStartedState uss) { 18994 final int userId = uss.mHandle.getIdentifier(); 18995 boolean stopped; 18996 ArrayList<IStopUserCallback> callbacks; 18997 synchronized (this) { 18998 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18999 if (mStartedUsers.get(userId) != uss) { 19000 stopped = false; 19001 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19002 stopped = false; 19003 } else { 19004 stopped = true; 19005 // User can no longer run. 19006 mStartedUsers.remove(userId); 19007 mUserLru.remove(Integer.valueOf(userId)); 19008 updateStartedUserArrayLocked(); 19009 19010 // Clean up all state and processes associated with the user. 19011 // Kill all the processes for the user. 19012 forceStopUserLocked(userId, "finish user"); 19013 } 19014 19015 // Explicitly remove the old information in mRecentTasks. 19016 removeRecentTasksForUserLocked(userId); 19017 } 19018 19019 for (int i=0; i<callbacks.size(); i++) { 19020 try { 19021 if (stopped) callbacks.get(i).userStopped(userId); 19022 else callbacks.get(i).userStopAborted(userId); 19023 } catch (RemoteException e) { 19024 } 19025 } 19026 19027 if (stopped) { 19028 mSystemServiceManager.cleanupUser(userId); 19029 synchronized (this) { 19030 mStackSupervisor.removeUserLocked(userId); 19031 } 19032 } 19033 } 19034 19035 @Override 19036 public UserInfo getCurrentUser() { 19037 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19038 != PackageManager.PERMISSION_GRANTED) && ( 19039 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19040 != PackageManager.PERMISSION_GRANTED)) { 19041 String msg = "Permission Denial: getCurrentUser() from pid=" 19042 + Binder.getCallingPid() 19043 + ", uid=" + Binder.getCallingUid() 19044 + " requires " + INTERACT_ACROSS_USERS; 19045 Slog.w(TAG, msg); 19046 throw new SecurityException(msg); 19047 } 19048 synchronized (this) { 19049 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19050 return getUserManagerLocked().getUserInfo(userId); 19051 } 19052 } 19053 19054 int getCurrentUserIdLocked() { 19055 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19056 } 19057 19058 @Override 19059 public boolean isUserRunning(int userId, boolean orStopped) { 19060 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19061 != PackageManager.PERMISSION_GRANTED) { 19062 String msg = "Permission Denial: isUserRunning() from pid=" 19063 + Binder.getCallingPid() 19064 + ", uid=" + Binder.getCallingUid() 19065 + " requires " + INTERACT_ACROSS_USERS; 19066 Slog.w(TAG, msg); 19067 throw new SecurityException(msg); 19068 } 19069 synchronized (this) { 19070 return isUserRunningLocked(userId, orStopped); 19071 } 19072 } 19073 19074 boolean isUserRunningLocked(int userId, boolean orStopped) { 19075 UserStartedState state = mStartedUsers.get(userId); 19076 if (state == null) { 19077 return false; 19078 } 19079 if (orStopped) { 19080 return true; 19081 } 19082 return state.mState != UserStartedState.STATE_STOPPING 19083 && state.mState != UserStartedState.STATE_SHUTDOWN; 19084 } 19085 19086 @Override 19087 public int[] getRunningUserIds() { 19088 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19089 != PackageManager.PERMISSION_GRANTED) { 19090 String msg = "Permission Denial: isUserRunning() from pid=" 19091 + Binder.getCallingPid() 19092 + ", uid=" + Binder.getCallingUid() 19093 + " requires " + INTERACT_ACROSS_USERS; 19094 Slog.w(TAG, msg); 19095 throw new SecurityException(msg); 19096 } 19097 synchronized (this) { 19098 return mStartedUserArray; 19099 } 19100 } 19101 19102 private void updateStartedUserArrayLocked() { 19103 int num = 0; 19104 for (int i=0; i<mStartedUsers.size(); i++) { 19105 UserStartedState uss = mStartedUsers.valueAt(i); 19106 // This list does not include stopping users. 19107 if (uss.mState != UserStartedState.STATE_STOPPING 19108 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19109 num++; 19110 } 19111 } 19112 mStartedUserArray = new int[num]; 19113 num = 0; 19114 for (int i=0; i<mStartedUsers.size(); i++) { 19115 UserStartedState uss = mStartedUsers.valueAt(i); 19116 if (uss.mState != UserStartedState.STATE_STOPPING 19117 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19118 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19119 num++; 19120 } 19121 } 19122 } 19123 19124 @Override 19125 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19126 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19127 != PackageManager.PERMISSION_GRANTED) { 19128 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19129 + Binder.getCallingPid() 19130 + ", uid=" + Binder.getCallingUid() 19131 + " requires " + INTERACT_ACROSS_USERS_FULL; 19132 Slog.w(TAG, msg); 19133 throw new SecurityException(msg); 19134 } 19135 19136 mUserSwitchObservers.register(observer); 19137 } 19138 19139 @Override 19140 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19141 mUserSwitchObservers.unregister(observer); 19142 } 19143 19144 private boolean userExists(int userId) { 19145 if (userId == 0) { 19146 return true; 19147 } 19148 UserManagerService ums = getUserManagerLocked(); 19149 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19150 } 19151 19152 int[] getUsersLocked() { 19153 UserManagerService ums = getUserManagerLocked(); 19154 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19155 } 19156 19157 UserManagerService getUserManagerLocked() { 19158 if (mUserManager == null) { 19159 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19160 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19161 } 19162 return mUserManager; 19163 } 19164 19165 private int applyUserId(int uid, int userId) { 19166 return UserHandle.getUid(userId, uid); 19167 } 19168 19169 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19170 if (info == null) return null; 19171 ApplicationInfo newInfo = new ApplicationInfo(info); 19172 newInfo.uid = applyUserId(info.uid, userId); 19173 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19174 + info.packageName; 19175 return newInfo; 19176 } 19177 19178 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19179 if (aInfo == null 19180 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19181 return aInfo; 19182 } 19183 19184 ActivityInfo info = new ActivityInfo(aInfo); 19185 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19186 return info; 19187 } 19188 19189 private final class LocalService extends ActivityManagerInternal { 19190 @Override 19191 public void goingToSleep() { 19192 ActivityManagerService.this.goingToSleep(); 19193 } 19194 19195 @Override 19196 public void wakingUp() { 19197 ActivityManagerService.this.wakingUp(); 19198 } 19199 19200 @Override 19201 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19202 String processName, String abiOverride, int uid, Runnable crashHandler) { 19203 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19204 processName, abiOverride, uid, crashHandler); 19205 } 19206 } 19207 19208 /** 19209 * An implementation of IAppTask, that allows an app to manage its own tasks via 19210 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19211 * only the process that calls getAppTasks() can call the AppTask methods. 19212 */ 19213 class AppTaskImpl extends IAppTask.Stub { 19214 private int mTaskId; 19215 private int mCallingUid; 19216 19217 public AppTaskImpl(int taskId, int callingUid) { 19218 mTaskId = taskId; 19219 mCallingUid = callingUid; 19220 } 19221 19222 private void checkCaller() { 19223 if (mCallingUid != Binder.getCallingUid()) { 19224 throw new SecurityException("Caller " + mCallingUid 19225 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19226 } 19227 } 19228 19229 @Override 19230 public void finishAndRemoveTask() { 19231 checkCaller(); 19232 19233 synchronized (ActivityManagerService.this) { 19234 long origId = Binder.clearCallingIdentity(); 19235 try { 19236 if (!removeTaskByIdLocked(mTaskId, false)) { 19237 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19238 } 19239 } finally { 19240 Binder.restoreCallingIdentity(origId); 19241 } 19242 } 19243 } 19244 19245 @Override 19246 public ActivityManager.RecentTaskInfo getTaskInfo() { 19247 checkCaller(); 19248 19249 synchronized (ActivityManagerService.this) { 19250 long origId = Binder.clearCallingIdentity(); 19251 try { 19252 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19253 if (tr == null) { 19254 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19255 } 19256 return createRecentTaskInfoFromTaskRecord(tr); 19257 } finally { 19258 Binder.restoreCallingIdentity(origId); 19259 } 19260 } 19261 } 19262 19263 @Override 19264 public void moveToFront() { 19265 checkCaller(); 19266 19267 final TaskRecord tr; 19268 synchronized (ActivityManagerService.this) { 19269 tr = recentTaskForIdLocked(mTaskId); 19270 if (tr == null) { 19271 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19272 } 19273 if (tr.getRootActivity() != null) { 19274 moveTaskToFrontLocked(tr.taskId, 0, null); 19275 return; 19276 } 19277 } 19278 19279 startActivityFromRecentsInner(tr.taskId, null); 19280 } 19281 19282 @Override 19283 public int startActivity(IBinder whoThread, String callingPackage, 19284 Intent intent, String resolvedType, Bundle options) { 19285 checkCaller(); 19286 19287 int callingUser = UserHandle.getCallingUserId(); 19288 TaskRecord tr; 19289 IApplicationThread appThread; 19290 synchronized (ActivityManagerService.this) { 19291 tr = recentTaskForIdLocked(mTaskId); 19292 if (tr == null) { 19293 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19294 } 19295 appThread = ApplicationThreadNative.asInterface(whoThread); 19296 if (appThread == null) { 19297 throw new IllegalArgumentException("Bad app thread " + appThread); 19298 } 19299 } 19300 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19301 resolvedType, null, null, null, null, 0, 0, null, null, 19302 null, options, callingUser, null, tr); 19303 } 19304 19305 @Override 19306 public void setExcludeFromRecents(boolean exclude) { 19307 checkCaller(); 19308 19309 synchronized (ActivityManagerService.this) { 19310 long origId = Binder.clearCallingIdentity(); 19311 try { 19312 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19313 if (tr == null) { 19314 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19315 } 19316 Intent intent = tr.getBaseIntent(); 19317 if (exclude) { 19318 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19319 } else { 19320 intent.setFlags(intent.getFlags() 19321 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19322 } 19323 } finally { 19324 Binder.restoreCallingIdentity(origId); 19325 } 19326 } 19327 } 19328 } 19329} 19330