ActivityManagerService.java revision 5565cb42f2ac07fcdbe3aab2503de07fbeb39504
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.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.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 /** Run all ActivityStacks through this */ 376 ActivityStackSupervisor mStackSupervisor; 377 378 public IntentFirewall mIntentFirewall; 379 380 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 381 // default actuion automatically. Important for devices without direct input 382 // devices. 383 private boolean mShowDialogs = true; 384 385 BroadcastQueue mFgBroadcastQueue; 386 BroadcastQueue mBgBroadcastQueue; 387 // Convenient for easy iteration over the queues. Foreground is first 388 // so that dispatch of foreground broadcasts gets precedence. 389 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 390 391 BroadcastQueue broadcastQueueForIntent(Intent intent) { 392 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 393 if (DEBUG_BACKGROUND_BROADCAST) { 394 Slog.i(TAG, "Broadcast intent " + intent + " on " 395 + (isFg ? "foreground" : "background") 396 + " queue"); 397 } 398 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 399 } 400 401 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 402 for (BroadcastQueue queue : mBroadcastQueues) { 403 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 404 if (r != null) { 405 return r; 406 } 407 } 408 return null; 409 } 410 411 /** 412 * Activity we have told the window manager to have key focus. 413 */ 414 ActivityRecord mFocusedActivity = null; 415 416 /** 417 * List of intents that were used to start the most recent tasks. 418 */ 419 ArrayList<TaskRecord> mRecentTasks; 420 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 421 422 /** 423 * For addAppTask: cached of the last activity component that was added. 424 */ 425 ComponentName mLastAddedTaskComponent; 426 427 /** 428 * For addAppTask: cached of the last activity uid that was added. 429 */ 430 int mLastAddedTaskUid; 431 432 /** 433 * For addAppTask: cached of the last ActivityInfo that was added. 434 */ 435 ActivityInfo mLastAddedTaskActivity; 436 437 public class PendingAssistExtras extends Binder implements Runnable { 438 public final ActivityRecord activity; 439 public final Bundle extras; 440 public final Intent intent; 441 public final String hint; 442 public final int userHandle; 443 public boolean haveResult = false; 444 public Bundle result = null; 445 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 446 String _hint, int _userHandle) { 447 activity = _activity; 448 extras = _extras; 449 intent = _intent; 450 hint = _hint; 451 userHandle = _userHandle; 452 } 453 @Override 454 public void run() { 455 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 456 synchronized (this) { 457 haveResult = true; 458 notifyAll(); 459 } 460 } 461 } 462 463 final ArrayList<PendingAssistExtras> mPendingAssistExtras 464 = new ArrayList<PendingAssistExtras>(); 465 466 /** 467 * Process management. 468 */ 469 final ProcessList mProcessList = new ProcessList(); 470 471 /** 472 * All of the applications we currently have running organized by name. 473 * The keys are strings of the application package name (as 474 * returned by the package manager), and the keys are ApplicationRecord 475 * objects. 476 */ 477 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 478 479 /** 480 * Tracking long-term execution of processes to look for abuse and other 481 * bad app behavior. 482 */ 483 final ProcessStatsService mProcessStats; 484 485 /** 486 * The currently running isolated processes. 487 */ 488 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 489 490 /** 491 * Counter for assigning isolated process uids, to avoid frequently reusing the 492 * same ones. 493 */ 494 int mNextIsolatedProcessUid = 0; 495 496 /** 497 * The currently running heavy-weight process, if any. 498 */ 499 ProcessRecord mHeavyWeightProcess = null; 500 501 /** 502 * The last time that various processes have crashed. 503 */ 504 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 505 506 /** 507 * Information about a process that is currently marked as bad. 508 */ 509 static final class BadProcessInfo { 510 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 511 this.time = time; 512 this.shortMsg = shortMsg; 513 this.longMsg = longMsg; 514 this.stack = stack; 515 } 516 517 final long time; 518 final String shortMsg; 519 final String longMsg; 520 final String stack; 521 } 522 523 /** 524 * Set of applications that we consider to be bad, and will reject 525 * incoming broadcasts from (which the user has no control over). 526 * Processes are added to this set when they have crashed twice within 527 * a minimum amount of time; they are removed from it when they are 528 * later restarted (hopefully due to some user action). The value is the 529 * time it was added to the list. 530 */ 531 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 532 533 /** 534 * All of the processes we currently have running organized by pid. 535 * The keys are the pid running the application. 536 * 537 * <p>NOTE: This object is protected by its own lock, NOT the global 538 * activity manager lock! 539 */ 540 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 541 542 /** 543 * All of the processes that have been forced to be foreground. The key 544 * is the pid of the caller who requested it (we hold a death 545 * link on it). 546 */ 547 abstract class ForegroundToken implements IBinder.DeathRecipient { 548 int pid; 549 IBinder token; 550 } 551 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 552 553 /** 554 * List of records for processes that someone had tried to start before the 555 * system was ready. We don't start them at that point, but ensure they 556 * are started by the time booting is complete. 557 */ 558 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 559 560 /** 561 * List of persistent applications that are in the process 562 * of being started. 563 */ 564 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 565 566 /** 567 * Processes that are being forcibly torn down. 568 */ 569 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 570 571 /** 572 * List of running applications, sorted by recent usage. 573 * The first entry in the list is the least recently used. 574 */ 575 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 576 577 /** 578 * Where in mLruProcesses that the processes hosting activities start. 579 */ 580 int mLruProcessActivityStart = 0; 581 582 /** 583 * Where in mLruProcesses that the processes hosting services start. 584 * This is after (lower index) than mLruProcessesActivityStart. 585 */ 586 int mLruProcessServiceStart = 0; 587 588 /** 589 * List of processes that should gc as soon as things are idle. 590 */ 591 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 592 593 /** 594 * Processes we want to collect PSS data from. 595 */ 596 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 597 598 /** 599 * Last time we requested PSS data of all processes. 600 */ 601 long mLastFullPssTime = SystemClock.uptimeMillis(); 602 603 /** 604 * If set, the next time we collect PSS data we should do a full collection 605 * with data from native processes and the kernel. 606 */ 607 boolean mFullPssPending = false; 608 609 /** 610 * This is the process holding what we currently consider to be 611 * the "home" activity. 612 */ 613 ProcessRecord mHomeProcess; 614 615 /** 616 * This is the process holding the activity the user last visited that 617 * is in a different process from the one they are currently in. 618 */ 619 ProcessRecord mPreviousProcess; 620 621 /** 622 * The time at which the previous process was last visible. 623 */ 624 long mPreviousProcessVisibleTime; 625 626 /** 627 * Which uses have been started, so are allowed to run code. 628 */ 629 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 630 631 /** 632 * LRU list of history of current users. Most recently current is at the end. 633 */ 634 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 635 636 /** 637 * Constant array of the users that are currently started. 638 */ 639 int[] mStartedUserArray = new int[] { 0 }; 640 641 /** 642 * Registered observers of the user switching mechanics. 643 */ 644 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 645 = new RemoteCallbackList<IUserSwitchObserver>(); 646 647 /** 648 * Currently active user switch. 649 */ 650 Object mCurUserSwitchCallback; 651 652 /** 653 * Packages that the user has asked to have run in screen size 654 * compatibility mode instead of filling the screen. 655 */ 656 final CompatModePackages mCompatModePackages; 657 658 /** 659 * Set of IntentSenderRecord objects that are currently active. 660 */ 661 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 662 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 663 664 /** 665 * Fingerprints (hashCode()) of stack traces that we've 666 * already logged DropBox entries for. Guarded by itself. If 667 * something (rogue user app) forces this over 668 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 669 */ 670 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 671 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 672 673 /** 674 * Strict Mode background batched logging state. 675 * 676 * The string buffer is guarded by itself, and its lock is also 677 * used to determine if another batched write is already 678 * in-flight. 679 */ 680 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 681 682 /** 683 * Keeps track of all IIntentReceivers that have been registered for 684 * broadcasts. Hash keys are the receiver IBinder, hash value is 685 * a ReceiverList. 686 */ 687 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 688 new HashMap<IBinder, ReceiverList>(); 689 690 /** 691 * Resolver for broadcast intents to registered receivers. 692 * Holds BroadcastFilter (subclass of IntentFilter). 693 */ 694 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 695 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 696 @Override 697 protected boolean allowFilterResult( 698 BroadcastFilter filter, List<BroadcastFilter> dest) { 699 IBinder target = filter.receiverList.receiver.asBinder(); 700 for (int i=dest.size()-1; i>=0; i--) { 701 if (dest.get(i).receiverList.receiver.asBinder() == target) { 702 return false; 703 } 704 } 705 return true; 706 } 707 708 @Override 709 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 710 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 711 || userId == filter.owningUserId) { 712 return super.newResult(filter, match, userId); 713 } 714 return null; 715 } 716 717 @Override 718 protected BroadcastFilter[] newArray(int size) { 719 return new BroadcastFilter[size]; 720 } 721 722 @Override 723 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 724 return packageName.equals(filter.packageName); 725 } 726 }; 727 728 /** 729 * State of all active sticky broadcasts per user. Keys are the action of the 730 * sticky Intent, values are an ArrayList of all broadcasted intents with 731 * that action (which should usually be one). The SparseArray is keyed 732 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 733 * for stickies that are sent to all users. 734 */ 735 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 736 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 737 738 final ActiveServices mServices; 739 740 /** 741 * Backup/restore process management 742 */ 743 String mBackupAppName = null; 744 BackupRecord mBackupTarget = null; 745 746 final ProviderMap mProviderMap; 747 748 /** 749 * List of content providers who have clients waiting for them. The 750 * application is currently being launched and the provider will be 751 * removed from this list once it is published. 752 */ 753 final ArrayList<ContentProviderRecord> mLaunchingProviders 754 = new ArrayList<ContentProviderRecord>(); 755 756 /** 757 * File storing persisted {@link #mGrantedUriPermissions}. 758 */ 759 private final AtomicFile mGrantFile; 760 761 /** XML constants used in {@link #mGrantFile} */ 762 private static final String TAG_URI_GRANTS = "uri-grants"; 763 private static final String TAG_URI_GRANT = "uri-grant"; 764 private static final String ATTR_USER_HANDLE = "userHandle"; 765 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 766 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 767 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 768 private static final String ATTR_TARGET_PKG = "targetPkg"; 769 private static final String ATTR_URI = "uri"; 770 private static final String ATTR_MODE_FLAGS = "modeFlags"; 771 private static final String ATTR_CREATED_TIME = "createdTime"; 772 private static final String ATTR_PREFIX = "prefix"; 773 774 /** 775 * Global set of specific {@link Uri} permissions that have been granted. 776 * This optimized lookup structure maps from {@link UriPermission#targetUid} 777 * to {@link UriPermission#uri} to {@link UriPermission}. 778 */ 779 @GuardedBy("this") 780 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 781 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 782 783 public static class GrantUri { 784 public final int sourceUserId; 785 public final Uri uri; 786 public boolean prefix; 787 788 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 789 this.sourceUserId = sourceUserId; 790 this.uri = uri; 791 this.prefix = prefix; 792 } 793 794 @Override 795 public int hashCode() { 796 return toString().hashCode(); 797 } 798 799 @Override 800 public boolean equals(Object o) { 801 if (o instanceof GrantUri) { 802 GrantUri other = (GrantUri) o; 803 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 804 && prefix == other.prefix; 805 } 806 return false; 807 } 808 809 @Override 810 public String toString() { 811 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 812 if (prefix) result += " [prefix]"; 813 return result; 814 } 815 816 public String toSafeString() { 817 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 818 if (prefix) result += " [prefix]"; 819 return result; 820 } 821 822 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 823 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 824 ContentProvider.getUriWithoutUserId(uri), false); 825 } 826 } 827 828 CoreSettingsObserver mCoreSettingsObserver; 829 830 /** 831 * Thread-local storage used to carry caller permissions over through 832 * indirect content-provider access. 833 */ 834 private class Identity { 835 public int pid; 836 public int uid; 837 838 Identity(int _pid, int _uid) { 839 pid = _pid; 840 uid = _uid; 841 } 842 } 843 844 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 845 846 /** 847 * All information we have collected about the runtime performance of 848 * any user id that can impact battery performance. 849 */ 850 final BatteryStatsService mBatteryStatsService; 851 852 /** 853 * Information about component usage 854 */ 855 UsageStatsManagerInternal mUsageStatsService; 856 857 /** 858 * Information about and control over application operations 859 */ 860 final AppOpsService mAppOpsService; 861 862 /** 863 * Save recent tasks information across reboots. 864 */ 865 final TaskPersister mTaskPersister; 866 867 /** 868 * Current configuration information. HistoryRecord objects are given 869 * a reference to this object to indicate which configuration they are 870 * currently running in, so this object must be kept immutable. 871 */ 872 Configuration mConfiguration = new Configuration(); 873 874 /** 875 * Current sequencing integer of the configuration, for skipping old 876 * configurations. 877 */ 878 int mConfigurationSeq = 0; 879 880 /** 881 * Hardware-reported OpenGLES version. 882 */ 883 final int GL_ES_VERSION; 884 885 /** 886 * List of initialization arguments to pass to all processes when binding applications to them. 887 * For example, references to the commonly used services. 888 */ 889 HashMap<String, IBinder> mAppBindArgs; 890 891 /** 892 * Temporary to avoid allocations. Protected by main lock. 893 */ 894 final StringBuilder mStringBuilder = new StringBuilder(256); 895 896 /** 897 * Used to control how we initialize the service. 898 */ 899 ComponentName mTopComponent; 900 String mTopAction = Intent.ACTION_MAIN; 901 String mTopData; 902 boolean mProcessesReady = false; 903 boolean mSystemReady = false; 904 boolean mBooting = false; 905 boolean mCallFinishBooting = false; 906 boolean mBootAnimationComplete = false; 907 boolean mWaitingUpdate = false; 908 boolean mDidUpdate = false; 909 boolean mOnBattery = false; 910 boolean mLaunchWarningShown = false; 911 912 Context mContext; 913 914 int mFactoryTest; 915 916 boolean mCheckedForSetup; 917 918 /** 919 * The time at which we will allow normal application switches again, 920 * after a call to {@link #stopAppSwitches()}. 921 */ 922 long mAppSwitchesAllowedTime; 923 924 /** 925 * This is set to true after the first switch after mAppSwitchesAllowedTime 926 * is set; any switches after that will clear the time. 927 */ 928 boolean mDidAppSwitch; 929 930 /** 931 * Last time (in realtime) at which we checked for power usage. 932 */ 933 long mLastPowerCheckRealtime; 934 935 /** 936 * Last time (in uptime) at which we checked for power usage. 937 */ 938 long mLastPowerCheckUptime; 939 940 /** 941 * Set while we are wanting to sleep, to prevent any 942 * activities from being started/resumed. 943 */ 944 private boolean mSleeping = false; 945 946 /** 947 * Set while we are running a voice interaction. This overrides 948 * sleeping while it is active. 949 */ 950 private boolean mRunningVoice = false; 951 952 /** 953 * State of external calls telling us if the device is asleep. 954 */ 955 private boolean mWentToSleep = false; 956 957 /** 958 * State of external call telling us if the lock screen is shown. 959 */ 960 private boolean mLockScreenShown = false; 961 962 /** 963 * Set if we are shutting down the system, similar to sleeping. 964 */ 965 boolean mShuttingDown = false; 966 967 /** 968 * Current sequence id for oom_adj computation traversal. 969 */ 970 int mAdjSeq = 0; 971 972 /** 973 * Current sequence id for process LRU updating. 974 */ 975 int mLruSeq = 0; 976 977 /** 978 * Keep track of the non-cached/empty process we last found, to help 979 * determine how to distribute cached/empty processes next time. 980 */ 981 int mNumNonCachedProcs = 0; 982 983 /** 984 * Keep track of the number of cached hidden procs, to balance oom adj 985 * distribution between those and empty procs. 986 */ 987 int mNumCachedHiddenProcs = 0; 988 989 /** 990 * Keep track of the number of service processes we last found, to 991 * determine on the next iteration which should be B services. 992 */ 993 int mNumServiceProcs = 0; 994 int mNewNumAServiceProcs = 0; 995 int mNewNumServiceProcs = 0; 996 997 /** 998 * Allow the current computed overall memory level of the system to go down? 999 * This is set to false when we are killing processes for reasons other than 1000 * memory management, so that the now smaller process list will not be taken as 1001 * an indication that memory is tighter. 1002 */ 1003 boolean mAllowLowerMemLevel = false; 1004 1005 /** 1006 * The last computed memory level, for holding when we are in a state that 1007 * processes are going away for other reasons. 1008 */ 1009 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1010 1011 /** 1012 * The last total number of process we have, to determine if changes actually look 1013 * like a shrinking number of process due to lower RAM. 1014 */ 1015 int mLastNumProcesses; 1016 1017 /** 1018 * The uptime of the last time we performed idle maintenance. 1019 */ 1020 long mLastIdleTime = SystemClock.uptimeMillis(); 1021 1022 /** 1023 * Total time spent with RAM that has been added in the past since the last idle time. 1024 */ 1025 long mLowRamTimeSinceLastIdle = 0; 1026 1027 /** 1028 * If RAM is currently low, when that horrible situation started. 1029 */ 1030 long mLowRamStartTime = 0; 1031 1032 /** 1033 * For reporting to battery stats the current top application. 1034 */ 1035 private String mCurResumedPackage = null; 1036 private int mCurResumedUid = -1; 1037 1038 /** 1039 * For reporting to battery stats the apps currently running foreground 1040 * service. The ProcessMap is package/uid tuples; each of these contain 1041 * an array of the currently foreground processes. 1042 */ 1043 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1044 = new ProcessMap<ArrayList<ProcessRecord>>(); 1045 1046 /** 1047 * This is set if we had to do a delayed dexopt of an app before launching 1048 * it, to increase the ANR timeouts in that case. 1049 */ 1050 boolean mDidDexOpt; 1051 1052 /** 1053 * Set if the systemServer made a call to enterSafeMode. 1054 */ 1055 boolean mSafeMode; 1056 1057 String mDebugApp = null; 1058 boolean mWaitForDebugger = false; 1059 boolean mDebugTransient = false; 1060 String mOrigDebugApp = null; 1061 boolean mOrigWaitForDebugger = false; 1062 boolean mAlwaysFinishActivities = false; 1063 IActivityController mController = null; 1064 String mProfileApp = null; 1065 ProcessRecord mProfileProc = null; 1066 String mProfileFile; 1067 ParcelFileDescriptor mProfileFd; 1068 int mSamplingInterval = 0; 1069 boolean mAutoStopProfiler = false; 1070 int mProfileType = 0; 1071 String mOpenGlTraceApp = null; 1072 1073 static class ProcessChangeItem { 1074 static final int CHANGE_ACTIVITIES = 1<<0; 1075 static final int CHANGE_PROCESS_STATE = 1<<1; 1076 int changes; 1077 int uid; 1078 int pid; 1079 int processState; 1080 boolean foregroundActivities; 1081 } 1082 1083 final RemoteCallbackList<IProcessObserver> mProcessObservers 1084 = new RemoteCallbackList<IProcessObserver>(); 1085 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1086 1087 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1090 = new ArrayList<ProcessChangeItem>(); 1091 1092 /** 1093 * Runtime CPU use collection thread. This object's lock is used to 1094 * perform synchronization with the thread (notifying it to run). 1095 */ 1096 final Thread mProcessCpuThread; 1097 1098 /** 1099 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1100 * Must acquire this object's lock when accessing it. 1101 * NOTE: this lock will be held while doing long operations (trawling 1102 * through all processes in /proc), so it should never be acquired by 1103 * any critical paths such as when holding the main activity manager lock. 1104 */ 1105 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1106 MONITOR_THREAD_CPU_USAGE); 1107 final AtomicLong mLastCpuTime = new AtomicLong(0); 1108 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1109 1110 long mLastWriteTime = 0; 1111 1112 /** 1113 * Used to retain an update lock when the foreground activity is in 1114 * immersive mode. 1115 */ 1116 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1117 1118 /** 1119 * Set to true after the system has finished booting. 1120 */ 1121 boolean mBooted = false; 1122 1123 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1124 int mProcessLimitOverride = -1; 1125 1126 WindowManagerService mWindowManager; 1127 1128 final ActivityThread mSystemThread; 1129 1130 // Holds the current foreground user's id 1131 int mCurrentUserId = 0; 1132 // Holds the target user's id during a user switch 1133 int mTargetUserId = UserHandle.USER_NULL; 1134 // If there are multiple profiles for the current user, their ids are here 1135 // Currently only the primary user can have managed profiles 1136 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1137 1138 /** 1139 * Mapping from each known user ID to the profile group ID it is associated with. 1140 */ 1141 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1142 1143 private UserManagerService mUserManager; 1144 1145 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1146 final ProcessRecord mApp; 1147 final int mPid; 1148 final IApplicationThread mAppThread; 1149 1150 AppDeathRecipient(ProcessRecord app, int pid, 1151 IApplicationThread thread) { 1152 if (localLOGV) Slog.v( 1153 TAG, "New death recipient " + this 1154 + " for thread " + thread.asBinder()); 1155 mApp = app; 1156 mPid = pid; 1157 mAppThread = thread; 1158 } 1159 1160 @Override 1161 public void binderDied() { 1162 if (localLOGV) Slog.v( 1163 TAG, "Death received in " + this 1164 + " for thread " + mAppThread.asBinder()); 1165 synchronized(ActivityManagerService.this) { 1166 appDiedLocked(mApp, mPid, mAppThread); 1167 } 1168 } 1169 } 1170 1171 static final int SHOW_ERROR_MSG = 1; 1172 static final int SHOW_NOT_RESPONDING_MSG = 2; 1173 static final int SHOW_FACTORY_ERROR_MSG = 3; 1174 static final int UPDATE_CONFIGURATION_MSG = 4; 1175 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1176 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1177 static final int SERVICE_TIMEOUT_MSG = 12; 1178 static final int UPDATE_TIME_ZONE = 13; 1179 static final int SHOW_UID_ERROR_MSG = 14; 1180 static final int IM_FEELING_LUCKY_MSG = 15; 1181 static final int PROC_START_TIMEOUT_MSG = 20; 1182 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1183 static final int KILL_APPLICATION_MSG = 22; 1184 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1185 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1186 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1187 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1188 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1189 static final int CLEAR_DNS_CACHE_MSG = 28; 1190 static final int UPDATE_HTTP_PROXY_MSG = 29; 1191 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1192 static final int DISPATCH_PROCESSES_CHANGED = 31; 1193 static final int DISPATCH_PROCESS_DIED = 32; 1194 static final int REPORT_MEM_USAGE_MSG = 33; 1195 static final int REPORT_USER_SWITCH_MSG = 34; 1196 static final int CONTINUE_USER_SWITCH_MSG = 35; 1197 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1198 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1199 static final int PERSIST_URI_GRANTS_MSG = 38; 1200 static final int REQUEST_ALL_PSS_MSG = 39; 1201 static final int START_PROFILES_MSG = 40; 1202 static final int UPDATE_TIME = 41; 1203 static final int SYSTEM_USER_START_MSG = 42; 1204 static final int SYSTEM_USER_CURRENT_MSG = 43; 1205 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1206 static final int FINISH_BOOTING_MSG = 45; 1207 static final int START_USER_SWITCH_MSG = 46; 1208 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1209 1210 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1211 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1212 static final int FIRST_COMPAT_MODE_MSG = 300; 1213 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1214 1215 AlertDialog mUidAlert; 1216 CompatModeDialog mCompatModeDialog; 1217 long mLastMemUsageReportTime = 0; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 reportMemUsage(memInfos); 1610 } 1611 }; 1612 thread.start(); 1613 break; 1614 } 1615 case START_USER_SWITCH_MSG: { 1616 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1617 break; 1618 } 1619 case REPORT_USER_SWITCH_MSG: { 1620 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1621 break; 1622 } 1623 case CONTINUE_USER_SWITCH_MSG: { 1624 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1625 break; 1626 } 1627 case USER_SWITCH_TIMEOUT_MSG: { 1628 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1629 break; 1630 } 1631 case IMMERSIVE_MODE_LOCK_MSG: { 1632 final boolean nextState = (msg.arg1 != 0); 1633 if (mUpdateLock.isHeld() != nextState) { 1634 if (DEBUG_IMMERSIVE) { 1635 final ActivityRecord r = (ActivityRecord) msg.obj; 1636 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1637 } 1638 if (nextState) { 1639 mUpdateLock.acquire(); 1640 } else { 1641 mUpdateLock.release(); 1642 } 1643 } 1644 break; 1645 } 1646 case PERSIST_URI_GRANTS_MSG: { 1647 writeGrantedUriPermissions(); 1648 break; 1649 } 1650 case REQUEST_ALL_PSS_MSG: { 1651 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1652 break; 1653 } 1654 case START_PROFILES_MSG: { 1655 synchronized (ActivityManagerService.this) { 1656 startProfilesLocked(); 1657 } 1658 break; 1659 } 1660 case UPDATE_TIME: { 1661 synchronized (ActivityManagerService.this) { 1662 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1663 ProcessRecord r = mLruProcesses.get(i); 1664 if (r.thread != null) { 1665 try { 1666 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1667 } catch (RemoteException ex) { 1668 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1669 } 1670 } 1671 } 1672 } 1673 break; 1674 } 1675 case SYSTEM_USER_START_MSG: { 1676 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1677 Integer.toString(msg.arg1), msg.arg1); 1678 mSystemServiceManager.startUser(msg.arg1); 1679 break; 1680 } 1681 case SYSTEM_USER_CURRENT_MSG: { 1682 mBatteryStatsService.noteEvent( 1683 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1684 Integer.toString(msg.arg2), msg.arg2); 1685 mBatteryStatsService.noteEvent( 1686 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1687 Integer.toString(msg.arg1), msg.arg1); 1688 mSystemServiceManager.switchUser(msg.arg1); 1689 break; 1690 } 1691 case ENTER_ANIMATION_COMPLETE_MSG: { 1692 synchronized (ActivityManagerService.this) { 1693 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1694 if (r != null && r.app != null && r.app.thread != null) { 1695 try { 1696 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1697 } catch (RemoteException e) { 1698 } 1699 } 1700 } 1701 break; 1702 } 1703 case FINISH_BOOTING_MSG: { 1704 if (msg.arg1 != 0) { 1705 finishBooting(); 1706 } 1707 if (msg.arg2 != 0) { 1708 enableScreenAfterBoot(); 1709 } 1710 break; 1711 } 1712 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1713 try { 1714 Locale l = (Locale) msg.obj; 1715 IBinder service = ServiceManager.getService("mount"); 1716 IMountService mountService = IMountService.Stub.asInterface(service); 1717 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1718 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1719 } catch (RemoteException e) { 1720 Log.e(TAG, "Error storing locale for decryption UI", e); 1721 } 1722 break; 1723 } 1724 } 1725 } 1726 }; 1727 1728 static final int COLLECT_PSS_BG_MSG = 1; 1729 1730 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1731 @Override 1732 public void handleMessage(Message msg) { 1733 switch (msg.what) { 1734 case COLLECT_PSS_BG_MSG: { 1735 long start = SystemClock.uptimeMillis(); 1736 MemInfoReader memInfo = null; 1737 synchronized (ActivityManagerService.this) { 1738 if (mFullPssPending) { 1739 mFullPssPending = false; 1740 memInfo = new MemInfoReader(); 1741 } 1742 } 1743 if (memInfo != null) { 1744 updateCpuStatsNow(); 1745 long nativeTotalPss = 0; 1746 synchronized (mProcessCpuTracker) { 1747 final int N = mProcessCpuTracker.countStats(); 1748 for (int j=0; j<N; j++) { 1749 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1750 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1751 // This is definitely an application process; skip it. 1752 continue; 1753 } 1754 synchronized (mPidsSelfLocked) { 1755 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1756 // This is one of our own processes; skip it. 1757 continue; 1758 } 1759 } 1760 nativeTotalPss += Debug.getPss(st.pid, null); 1761 } 1762 } 1763 memInfo.readMemInfo(); 1764 synchronized (ActivityManagerService.this) { 1765 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1766 + (SystemClock.uptimeMillis()-start) + "ms"); 1767 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1768 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1769 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1770 } 1771 } 1772 1773 int i=0, num=0; 1774 long[] tmp = new long[1]; 1775 do { 1776 ProcessRecord proc; 1777 int procState; 1778 int pid; 1779 synchronized (ActivityManagerService.this) { 1780 if (i >= mPendingPssProcesses.size()) { 1781 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1782 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1783 mPendingPssProcesses.clear(); 1784 return; 1785 } 1786 proc = mPendingPssProcesses.get(i); 1787 procState = proc.pssProcState; 1788 if (proc.thread != null && procState == proc.setProcState) { 1789 pid = proc.pid; 1790 } else { 1791 proc = null; 1792 pid = 0; 1793 } 1794 i++; 1795 } 1796 if (proc != null) { 1797 long pss = Debug.getPss(pid, tmp); 1798 synchronized (ActivityManagerService.this) { 1799 if (proc.thread != null && proc.setProcState == procState 1800 && proc.pid == pid) { 1801 num++; 1802 proc.lastPssTime = SystemClock.uptimeMillis(); 1803 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1804 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1805 + ": " + pss + " lastPss=" + proc.lastPss 1806 + " state=" + ProcessList.makeProcStateString(procState)); 1807 if (proc.initialIdlePss == 0) { 1808 proc.initialIdlePss = pss; 1809 } 1810 proc.lastPss = pss; 1811 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1812 proc.lastCachedPss = pss; 1813 } 1814 } 1815 } 1816 } 1817 } while (true); 1818 } 1819 } 1820 } 1821 }; 1822 1823 /** 1824 * Monitor for package changes and update our internal state. 1825 */ 1826 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1827 @Override 1828 public void onPackageRemoved(String packageName, int uid) { 1829 // Remove all tasks with activities in the specified package from the list of recent tasks 1830 final int eventUserId = getChangingUserId(); 1831 synchronized (ActivityManagerService.this) { 1832 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1833 TaskRecord tr = mRecentTasks.get(i); 1834 if (tr.userId != eventUserId) continue; 1835 1836 ComponentName cn = tr.intent.getComponent(); 1837 if (cn != null && cn.getPackageName().equals(packageName)) { 1838 // If the package name matches, remove the task 1839 removeTaskByIdLocked(tr.taskId, true); 1840 } 1841 } 1842 } 1843 } 1844 1845 @Override 1846 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1847 onPackageModified(packageName); 1848 return true; 1849 } 1850 1851 @Override 1852 public void onPackageModified(String packageName) { 1853 final int eventUserId = getChangingUserId(); 1854 final IPackageManager pm = AppGlobals.getPackageManager(); 1855 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1856 new ArrayList<Pair<Intent, Integer>>(); 1857 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1858 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1859 // Copy the list of recent tasks so that we don't hold onto the lock on 1860 // ActivityManagerService for long periods while checking if components exist. 1861 synchronized (ActivityManagerService.this) { 1862 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1863 TaskRecord tr = mRecentTasks.get(i); 1864 if (tr.userId != eventUserId) continue; 1865 1866 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1867 } 1868 } 1869 // Check the recent tasks and filter out all tasks with components that no longer exist. 1870 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1871 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1872 ComponentName cn = p.first.getComponent(); 1873 if (cn != null && cn.getPackageName().equals(packageName)) { 1874 if (componentsKnownToExist.contains(cn)) { 1875 // If we know that the component still exists in the package, then skip 1876 continue; 1877 } 1878 try { 1879 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1880 if (info != null) { 1881 componentsKnownToExist.add(cn); 1882 } else { 1883 tasksToRemove.add(p.second); 1884 } 1885 } catch (RemoteException e) { 1886 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1887 } 1888 } 1889 } 1890 // Prune all the tasks with removed components from the list of recent tasks 1891 synchronized (ActivityManagerService.this) { 1892 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1893 removeTaskByIdLocked(tasksToRemove.get(i), false); 1894 } 1895 } 1896 } 1897 1898 @Override 1899 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1900 // Force stop the specified packages 1901 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1902 if (packages != null) { 1903 for (String pkg : packages) { 1904 synchronized (ActivityManagerService.this) { 1905 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1906 userId, "finished booting")) { 1907 return true; 1908 } 1909 } 1910 } 1911 } 1912 return false; 1913 } 1914 }; 1915 1916 public void setSystemProcess() { 1917 try { 1918 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1919 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1920 ServiceManager.addService("meminfo", new MemBinder(this)); 1921 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1922 ServiceManager.addService("dbinfo", new DbBinder(this)); 1923 if (MONITOR_CPU_USAGE) { 1924 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1925 } 1926 ServiceManager.addService("permission", new PermissionController(this)); 1927 1928 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1929 "android", STOCK_PM_FLAGS); 1930 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1931 1932 synchronized (this) { 1933 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1934 app.persistent = true; 1935 app.pid = MY_PID; 1936 app.maxAdj = ProcessList.SYSTEM_ADJ; 1937 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1938 mProcessNames.put(app.processName, app.uid, app); 1939 synchronized (mPidsSelfLocked) { 1940 mPidsSelfLocked.put(app.pid, app); 1941 } 1942 updateLruProcessLocked(app, false, null); 1943 updateOomAdjLocked(); 1944 } 1945 } catch (PackageManager.NameNotFoundException e) { 1946 throw new RuntimeException( 1947 "Unable to find android system package", e); 1948 } 1949 } 1950 1951 public void setWindowManager(WindowManagerService wm) { 1952 mWindowManager = wm; 1953 mStackSupervisor.setWindowManager(wm); 1954 } 1955 1956 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1957 mUsageStatsService = usageStatsManager; 1958 } 1959 1960 public void startObservingNativeCrashes() { 1961 final NativeCrashListener ncl = new NativeCrashListener(this); 1962 ncl.start(); 1963 } 1964 1965 public IAppOpsService getAppOpsService() { 1966 return mAppOpsService; 1967 } 1968 1969 static class MemBinder extends Binder { 1970 ActivityManagerService mActivityManagerService; 1971 MemBinder(ActivityManagerService activityManagerService) { 1972 mActivityManagerService = activityManagerService; 1973 } 1974 1975 @Override 1976 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1977 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1978 != PackageManager.PERMISSION_GRANTED) { 1979 pw.println("Permission Denial: can't dump meminfo from from pid=" 1980 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1981 + " without permission " + android.Manifest.permission.DUMP); 1982 return; 1983 } 1984 1985 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1986 } 1987 } 1988 1989 static class GraphicsBinder extends Binder { 1990 ActivityManagerService mActivityManagerService; 1991 GraphicsBinder(ActivityManagerService activityManagerService) { 1992 mActivityManagerService = activityManagerService; 1993 } 1994 1995 @Override 1996 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1997 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1998 != PackageManager.PERMISSION_GRANTED) { 1999 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2000 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2001 + " without permission " + android.Manifest.permission.DUMP); 2002 return; 2003 } 2004 2005 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2006 } 2007 } 2008 2009 static class DbBinder extends Binder { 2010 ActivityManagerService mActivityManagerService; 2011 DbBinder(ActivityManagerService activityManagerService) { 2012 mActivityManagerService = activityManagerService; 2013 } 2014 2015 @Override 2016 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2017 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2018 != PackageManager.PERMISSION_GRANTED) { 2019 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2020 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2021 + " without permission " + android.Manifest.permission.DUMP); 2022 return; 2023 } 2024 2025 mActivityManagerService.dumpDbInfo(fd, pw, args); 2026 } 2027 } 2028 2029 static class CpuBinder extends Binder { 2030 ActivityManagerService mActivityManagerService; 2031 CpuBinder(ActivityManagerService activityManagerService) { 2032 mActivityManagerService = activityManagerService; 2033 } 2034 2035 @Override 2036 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2037 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2038 != PackageManager.PERMISSION_GRANTED) { 2039 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2040 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2041 + " without permission " + android.Manifest.permission.DUMP); 2042 return; 2043 } 2044 2045 synchronized (mActivityManagerService.mProcessCpuTracker) { 2046 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2047 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2048 SystemClock.uptimeMillis())); 2049 } 2050 } 2051 } 2052 2053 public static final class Lifecycle extends SystemService { 2054 private final ActivityManagerService mService; 2055 2056 public Lifecycle(Context context) { 2057 super(context); 2058 mService = new ActivityManagerService(context); 2059 } 2060 2061 @Override 2062 public void onStart() { 2063 mService.start(); 2064 } 2065 2066 public ActivityManagerService getService() { 2067 return mService; 2068 } 2069 } 2070 2071 // Note: This method is invoked on the main thread but may need to attach various 2072 // handlers to other threads. So take care to be explicit about the looper. 2073 public ActivityManagerService(Context systemContext) { 2074 mContext = systemContext; 2075 mFactoryTest = FactoryTest.getMode(); 2076 mSystemThread = ActivityThread.currentActivityThread(); 2077 2078 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2079 2080 mHandlerThread = new ServiceThread(TAG, 2081 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2082 mHandlerThread.start(); 2083 mHandler = new MainHandler(mHandlerThread.getLooper()); 2084 2085 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2086 "foreground", BROADCAST_FG_TIMEOUT, false); 2087 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2088 "background", BROADCAST_BG_TIMEOUT, true); 2089 mBroadcastQueues[0] = mFgBroadcastQueue; 2090 mBroadcastQueues[1] = mBgBroadcastQueue; 2091 2092 mServices = new ActiveServices(this); 2093 mProviderMap = new ProviderMap(this); 2094 2095 // TODO: Move creation of battery stats service outside of activity manager service. 2096 File dataDir = Environment.getDataDirectory(); 2097 File systemDir = new File(dataDir, "system"); 2098 systemDir.mkdirs(); 2099 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2100 mBatteryStatsService.getActiveStatistics().readLocked(); 2101 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2102 mOnBattery = DEBUG_POWER ? true 2103 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2104 mBatteryStatsService.getActiveStatistics().setCallback(this); 2105 2106 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2107 2108 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2109 2110 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2111 2112 // User 0 is the first and only user that runs at boot. 2113 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2114 mUserLru.add(Integer.valueOf(0)); 2115 updateStartedUserArrayLocked(); 2116 2117 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2118 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2119 2120 mConfiguration.setToDefaults(); 2121 mConfiguration.setLocale(Locale.getDefault()); 2122 2123 mConfigurationSeq = mConfiguration.seq = 1; 2124 mProcessCpuTracker.init(); 2125 2126 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2127 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2128 mStackSupervisor = new ActivityStackSupervisor(this); 2129 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2130 2131 mProcessCpuThread = new Thread("CpuTracker") { 2132 @Override 2133 public void run() { 2134 while (true) { 2135 try { 2136 try { 2137 synchronized(this) { 2138 final long now = SystemClock.uptimeMillis(); 2139 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2140 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2141 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2142 // + ", write delay=" + nextWriteDelay); 2143 if (nextWriteDelay < nextCpuDelay) { 2144 nextCpuDelay = nextWriteDelay; 2145 } 2146 if (nextCpuDelay > 0) { 2147 mProcessCpuMutexFree.set(true); 2148 this.wait(nextCpuDelay); 2149 } 2150 } 2151 } catch (InterruptedException e) { 2152 } 2153 updateCpuStatsNow(); 2154 } catch (Exception e) { 2155 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2156 } 2157 } 2158 } 2159 }; 2160 2161 Watchdog.getInstance().addMonitor(this); 2162 Watchdog.getInstance().addThread(mHandler); 2163 } 2164 2165 public void setSystemServiceManager(SystemServiceManager mgr) { 2166 mSystemServiceManager = mgr; 2167 } 2168 2169 private void start() { 2170 Process.removeAllProcessGroups(); 2171 mProcessCpuThread.start(); 2172 2173 mBatteryStatsService.publish(mContext); 2174 mAppOpsService.publish(mContext); 2175 Slog.d("AppOps", "AppOpsService published"); 2176 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2177 } 2178 2179 public void initPowerManagement() { 2180 mStackSupervisor.initPowerManagement(); 2181 mBatteryStatsService.initPowerManagement(); 2182 } 2183 2184 @Override 2185 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2186 throws RemoteException { 2187 if (code == SYSPROPS_TRANSACTION) { 2188 // We need to tell all apps about the system property change. 2189 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2190 synchronized(this) { 2191 final int NP = mProcessNames.getMap().size(); 2192 for (int ip=0; ip<NP; ip++) { 2193 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2194 final int NA = apps.size(); 2195 for (int ia=0; ia<NA; ia++) { 2196 ProcessRecord app = apps.valueAt(ia); 2197 if (app.thread != null) { 2198 procs.add(app.thread.asBinder()); 2199 } 2200 } 2201 } 2202 } 2203 2204 int N = procs.size(); 2205 for (int i=0; i<N; i++) { 2206 Parcel data2 = Parcel.obtain(); 2207 try { 2208 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2209 } catch (RemoteException e) { 2210 } 2211 data2.recycle(); 2212 } 2213 } 2214 try { 2215 return super.onTransact(code, data, reply, flags); 2216 } catch (RuntimeException e) { 2217 // The activity manager only throws security exceptions, so let's 2218 // log all others. 2219 if (!(e instanceof SecurityException)) { 2220 Slog.wtf(TAG, "Activity Manager Crash", e); 2221 } 2222 throw e; 2223 } 2224 } 2225 2226 void updateCpuStats() { 2227 final long now = SystemClock.uptimeMillis(); 2228 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2229 return; 2230 } 2231 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2232 synchronized (mProcessCpuThread) { 2233 mProcessCpuThread.notify(); 2234 } 2235 } 2236 } 2237 2238 void updateCpuStatsNow() { 2239 synchronized (mProcessCpuTracker) { 2240 mProcessCpuMutexFree.set(false); 2241 final long now = SystemClock.uptimeMillis(); 2242 boolean haveNewCpuStats = false; 2243 2244 if (MONITOR_CPU_USAGE && 2245 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2246 mLastCpuTime.set(now); 2247 haveNewCpuStats = true; 2248 mProcessCpuTracker.update(); 2249 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2250 //Slog.i(TAG, "Total CPU usage: " 2251 // + mProcessCpu.getTotalCpuPercent() + "%"); 2252 2253 // Slog the cpu usage if the property is set. 2254 if ("true".equals(SystemProperties.get("events.cpu"))) { 2255 int user = mProcessCpuTracker.getLastUserTime(); 2256 int system = mProcessCpuTracker.getLastSystemTime(); 2257 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2258 int irq = mProcessCpuTracker.getLastIrqTime(); 2259 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2260 int idle = mProcessCpuTracker.getLastIdleTime(); 2261 2262 int total = user + system + iowait + irq + softIrq + idle; 2263 if (total == 0) total = 1; 2264 2265 EventLog.writeEvent(EventLogTags.CPU, 2266 ((user+system+iowait+irq+softIrq) * 100) / total, 2267 (user * 100) / total, 2268 (system * 100) / total, 2269 (iowait * 100) / total, 2270 (irq * 100) / total, 2271 (softIrq * 100) / total); 2272 } 2273 } 2274 2275 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2276 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2277 synchronized(bstats) { 2278 synchronized(mPidsSelfLocked) { 2279 if (haveNewCpuStats) { 2280 if (mOnBattery) { 2281 int perc = bstats.startAddingCpuLocked(); 2282 int totalUTime = 0; 2283 int totalSTime = 0; 2284 final int N = mProcessCpuTracker.countStats(); 2285 for (int i=0; i<N; i++) { 2286 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2287 if (!st.working) { 2288 continue; 2289 } 2290 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2291 int otherUTime = (st.rel_utime*perc)/100; 2292 int otherSTime = (st.rel_stime*perc)/100; 2293 totalUTime += otherUTime; 2294 totalSTime += otherSTime; 2295 if (pr != null) { 2296 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2297 if (ps == null || !ps.isActive()) { 2298 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2299 pr.info.uid, pr.processName); 2300 } 2301 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2302 st.rel_stime-otherSTime); 2303 ps.addSpeedStepTimes(cpuSpeedTimes); 2304 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2305 } else { 2306 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2307 if (ps == null || !ps.isActive()) { 2308 st.batteryStats = ps = bstats.getProcessStatsLocked( 2309 bstats.mapUid(st.uid), st.name); 2310 } 2311 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2312 st.rel_stime-otherSTime); 2313 ps.addSpeedStepTimes(cpuSpeedTimes); 2314 } 2315 } 2316 bstats.finishAddingCpuLocked(perc, totalUTime, 2317 totalSTime, cpuSpeedTimes); 2318 } 2319 } 2320 } 2321 2322 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2323 mLastWriteTime = now; 2324 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2325 } 2326 } 2327 } 2328 } 2329 2330 @Override 2331 public void batteryNeedsCpuUpdate() { 2332 updateCpuStatsNow(); 2333 } 2334 2335 @Override 2336 public void batteryPowerChanged(boolean onBattery) { 2337 // When plugging in, update the CPU stats first before changing 2338 // the plug state. 2339 updateCpuStatsNow(); 2340 synchronized (this) { 2341 synchronized(mPidsSelfLocked) { 2342 mOnBattery = DEBUG_POWER ? true : onBattery; 2343 } 2344 } 2345 } 2346 2347 /** 2348 * Initialize the application bind args. These are passed to each 2349 * process when the bindApplication() IPC is sent to the process. They're 2350 * lazily setup to make sure the services are running when they're asked for. 2351 */ 2352 private HashMap<String, IBinder> getCommonServicesLocked() { 2353 if (mAppBindArgs == null) { 2354 mAppBindArgs = new HashMap<String, IBinder>(); 2355 2356 // Setup the application init args 2357 mAppBindArgs.put("package", ServiceManager.getService("package")); 2358 mAppBindArgs.put("window", ServiceManager.getService("window")); 2359 mAppBindArgs.put(Context.ALARM_SERVICE, 2360 ServiceManager.getService(Context.ALARM_SERVICE)); 2361 } 2362 return mAppBindArgs; 2363 } 2364 2365 final void setFocusedActivityLocked(ActivityRecord r) { 2366 if (mFocusedActivity != r) { 2367 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2368 mFocusedActivity = r; 2369 if (r.task != null && r.task.voiceInteractor != null) { 2370 startRunningVoiceLocked(); 2371 } else { 2372 finishRunningVoiceLocked(); 2373 } 2374 mStackSupervisor.setFocusedStack(r); 2375 if (r != null) { 2376 mWindowManager.setFocusedApp(r.appToken, true); 2377 } 2378 applyUpdateLockStateLocked(r); 2379 } 2380 } 2381 2382 final void clearFocusedActivity(ActivityRecord r) { 2383 if (mFocusedActivity == r) { 2384 mFocusedActivity = null; 2385 } 2386 } 2387 2388 @Override 2389 public void setFocusedStack(int stackId) { 2390 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2391 synchronized (ActivityManagerService.this) { 2392 ActivityStack stack = mStackSupervisor.getStack(stackId); 2393 if (stack != null) { 2394 ActivityRecord r = stack.topRunningActivityLocked(null); 2395 if (r != null) { 2396 setFocusedActivityLocked(r); 2397 } 2398 } 2399 } 2400 } 2401 2402 @Override 2403 public void notifyActivityDrawn(IBinder token) { 2404 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2405 synchronized (this) { 2406 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2407 if (r != null) { 2408 r.task.stack.notifyActivityDrawnLocked(r); 2409 } 2410 } 2411 } 2412 2413 final void applyUpdateLockStateLocked(ActivityRecord r) { 2414 // Modifications to the UpdateLock state are done on our handler, outside 2415 // the activity manager's locks. The new state is determined based on the 2416 // state *now* of the relevant activity record. The object is passed to 2417 // the handler solely for logging detail, not to be consulted/modified. 2418 final boolean nextState = r != null && r.immersive; 2419 mHandler.sendMessage( 2420 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2421 } 2422 2423 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2424 Message msg = Message.obtain(); 2425 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2426 msg.obj = r.task.askedCompatMode ? null : r; 2427 mHandler.sendMessage(msg); 2428 } 2429 2430 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2431 String what, Object obj, ProcessRecord srcApp) { 2432 app.lastActivityTime = now; 2433 2434 if (app.activities.size() > 0) { 2435 // Don't want to touch dependent processes that are hosting activities. 2436 return index; 2437 } 2438 2439 int lrui = mLruProcesses.lastIndexOf(app); 2440 if (lrui < 0) { 2441 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2442 + what + " " + obj + " from " + srcApp); 2443 return index; 2444 } 2445 2446 if (lrui >= index) { 2447 // Don't want to cause this to move dependent processes *back* in the 2448 // list as if they were less frequently used. 2449 return index; 2450 } 2451 2452 if (lrui >= mLruProcessActivityStart) { 2453 // Don't want to touch dependent processes that are hosting activities. 2454 return index; 2455 } 2456 2457 mLruProcesses.remove(lrui); 2458 if (index > 0) { 2459 index--; 2460 } 2461 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2462 + " in LRU list: " + app); 2463 mLruProcesses.add(index, app); 2464 return index; 2465 } 2466 2467 final void removeLruProcessLocked(ProcessRecord app) { 2468 int lrui = mLruProcesses.lastIndexOf(app); 2469 if (lrui >= 0) { 2470 if (!app.killed) { 2471 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2472 Process.killProcessQuiet(app.pid); 2473 Process.killProcessGroup(app.info.uid, app.pid); 2474 } 2475 if (lrui <= mLruProcessActivityStart) { 2476 mLruProcessActivityStart--; 2477 } 2478 if (lrui <= mLruProcessServiceStart) { 2479 mLruProcessServiceStart--; 2480 } 2481 mLruProcesses.remove(lrui); 2482 } 2483 } 2484 2485 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2486 ProcessRecord client) { 2487 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2488 || app.treatLikeActivity; 2489 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2490 if (!activityChange && hasActivity) { 2491 // The process has activities, so we are only allowing activity-based adjustments 2492 // to move it. It should be kept in the front of the list with other 2493 // processes that have activities, and we don't want those to change their 2494 // order except due to activity operations. 2495 return; 2496 } 2497 2498 mLruSeq++; 2499 final long now = SystemClock.uptimeMillis(); 2500 app.lastActivityTime = now; 2501 2502 // First a quick reject: if the app is already at the position we will 2503 // put it, then there is nothing to do. 2504 if (hasActivity) { 2505 final int N = mLruProcesses.size(); 2506 if (N > 0 && mLruProcesses.get(N-1) == app) { 2507 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2508 return; 2509 } 2510 } else { 2511 if (mLruProcessServiceStart > 0 2512 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2514 return; 2515 } 2516 } 2517 2518 int lrui = mLruProcesses.lastIndexOf(app); 2519 2520 if (app.persistent && lrui >= 0) { 2521 // We don't care about the position of persistent processes, as long as 2522 // they are in the list. 2523 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2524 return; 2525 } 2526 2527 /* In progress: compute new position first, so we can avoid doing work 2528 if the process is not actually going to move. Not yet working. 2529 int addIndex; 2530 int nextIndex; 2531 boolean inActivity = false, inService = false; 2532 if (hasActivity) { 2533 // Process has activities, put it at the very tipsy-top. 2534 addIndex = mLruProcesses.size(); 2535 nextIndex = mLruProcessServiceStart; 2536 inActivity = true; 2537 } else if (hasService) { 2538 // Process has services, put it at the top of the service list. 2539 addIndex = mLruProcessActivityStart; 2540 nextIndex = mLruProcessServiceStart; 2541 inActivity = true; 2542 inService = true; 2543 } else { 2544 // Process not otherwise of interest, it goes to the top of the non-service area. 2545 addIndex = mLruProcessServiceStart; 2546 if (client != null) { 2547 int clientIndex = mLruProcesses.lastIndexOf(client); 2548 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2549 + app); 2550 if (clientIndex >= 0 && addIndex > clientIndex) { 2551 addIndex = clientIndex; 2552 } 2553 } 2554 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2555 } 2556 2557 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2558 + mLruProcessActivityStart + "): " + app); 2559 */ 2560 2561 if (lrui >= 0) { 2562 if (lrui < mLruProcessActivityStart) { 2563 mLruProcessActivityStart--; 2564 } 2565 if (lrui < mLruProcessServiceStart) { 2566 mLruProcessServiceStart--; 2567 } 2568 /* 2569 if (addIndex > lrui) { 2570 addIndex--; 2571 } 2572 if (nextIndex > lrui) { 2573 nextIndex--; 2574 } 2575 */ 2576 mLruProcesses.remove(lrui); 2577 } 2578 2579 /* 2580 mLruProcesses.add(addIndex, app); 2581 if (inActivity) { 2582 mLruProcessActivityStart++; 2583 } 2584 if (inService) { 2585 mLruProcessActivityStart++; 2586 } 2587 */ 2588 2589 int nextIndex; 2590 if (hasActivity) { 2591 final int N = mLruProcesses.size(); 2592 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2593 // Process doesn't have activities, but has clients with 2594 // activities... move it up, but one below the top (the top 2595 // should always have a real activity). 2596 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2597 mLruProcesses.add(N-1, app); 2598 // To keep it from spamming the LRU list (by making a bunch of clients), 2599 // we will push down any other entries owned by the app. 2600 final int uid = app.info.uid; 2601 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2602 ProcessRecord subProc = mLruProcesses.get(i); 2603 if (subProc.info.uid == uid) { 2604 // We want to push this one down the list. If the process after 2605 // it is for the same uid, however, don't do so, because we don't 2606 // want them internally to be re-ordered. 2607 if (mLruProcesses.get(i-1).info.uid != uid) { 2608 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2609 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2610 ProcessRecord tmp = mLruProcesses.get(i); 2611 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2612 mLruProcesses.set(i-1, tmp); 2613 i--; 2614 } 2615 } else { 2616 // A gap, we can stop here. 2617 break; 2618 } 2619 } 2620 } else { 2621 // Process has activities, put it at the very tipsy-top. 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2623 mLruProcesses.add(app); 2624 } 2625 nextIndex = mLruProcessServiceStart; 2626 } else if (hasService) { 2627 // Process has services, put it at the top of the service list. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2629 mLruProcesses.add(mLruProcessActivityStart, app); 2630 nextIndex = mLruProcessServiceStart; 2631 mLruProcessActivityStart++; 2632 } else { 2633 // Process not otherwise of interest, it goes to the top of the non-service area. 2634 int index = mLruProcessServiceStart; 2635 if (client != null) { 2636 // If there is a client, don't allow the process to be moved up higher 2637 // in the list than that client. 2638 int clientIndex = mLruProcesses.lastIndexOf(client); 2639 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2640 + " when updating " + app); 2641 if (clientIndex <= lrui) { 2642 // Don't allow the client index restriction to push it down farther in the 2643 // list than it already is. 2644 clientIndex = lrui; 2645 } 2646 if (clientIndex >= 0 && index > clientIndex) { 2647 index = clientIndex; 2648 } 2649 } 2650 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2651 mLruProcesses.add(index, app); 2652 nextIndex = index-1; 2653 mLruProcessActivityStart++; 2654 mLruProcessServiceStart++; 2655 } 2656 2657 // If the app is currently using a content provider or service, 2658 // bump those processes as well. 2659 for (int j=app.connections.size()-1; j>=0; j--) { 2660 ConnectionRecord cr = app.connections.valueAt(j); 2661 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2662 && cr.binding.service.app != null 2663 && cr.binding.service.app.lruSeq != mLruSeq 2664 && !cr.binding.service.app.persistent) { 2665 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2666 "service connection", cr, app); 2667 } 2668 } 2669 for (int j=app.conProviders.size()-1; j>=0; j--) { 2670 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2671 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2673 "provider reference", cpr, app); 2674 } 2675 } 2676 } 2677 2678 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2679 if (uid == Process.SYSTEM_UID) { 2680 // The system gets to run in any process. If there are multiple 2681 // processes with the same uid, just pick the first (this 2682 // should never happen). 2683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2684 if (procs == null) return null; 2685 final int N = procs.size(); 2686 for (int i = 0; i < N; i++) { 2687 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2688 } 2689 } 2690 ProcessRecord proc = mProcessNames.get(processName, uid); 2691 if (false && proc != null && !keepIfLarge 2692 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2693 && proc.lastCachedPss >= 4000) { 2694 // Turn this condition on to cause killing to happen regularly, for testing. 2695 if (proc.baseProcessTracker != null) { 2696 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2697 } 2698 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2699 } else if (proc != null && !keepIfLarge 2700 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2701 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2702 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2703 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2704 if (proc.baseProcessTracker != null) { 2705 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2706 } 2707 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2708 } 2709 } 2710 return proc; 2711 } 2712 2713 void ensurePackageDexOpt(String packageName) { 2714 IPackageManager pm = AppGlobals.getPackageManager(); 2715 try { 2716 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2717 mDidDexOpt = true; 2718 } 2719 } catch (RemoteException e) { 2720 } 2721 } 2722 2723 boolean isNextTransitionForward() { 2724 int transit = mWindowManager.getPendingAppTransition(); 2725 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2726 || transit == AppTransition.TRANSIT_TASK_OPEN 2727 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2728 } 2729 2730 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2731 String processName, String abiOverride, int uid, Runnable crashHandler) { 2732 synchronized(this) { 2733 ApplicationInfo info = new ApplicationInfo(); 2734 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2735 // For isolated processes, the former contains the parent's uid and the latter the 2736 // actual uid of the isolated process. 2737 // In the special case introduced by this method (which is, starting an isolated 2738 // process directly from the SystemServer without an actual parent app process) the 2739 // closest thing to a parent's uid is SYSTEM_UID. 2740 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2741 // the |isolated| logic in the ProcessRecord constructor. 2742 info.uid = Process.SYSTEM_UID; 2743 info.processName = processName; 2744 info.className = entryPoint; 2745 info.packageName = "android"; 2746 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2747 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2748 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2749 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2750 crashHandler); 2751 return proc != null ? proc.pid : 0; 2752 } 2753 } 2754 2755 final ProcessRecord startProcessLocked(String processName, 2756 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2757 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2758 boolean isolated, boolean keepIfLarge) { 2759 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2760 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2761 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2762 null /* crashHandler */); 2763 } 2764 2765 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2766 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2767 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2768 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2769 long startTime = SystemClock.elapsedRealtime(); 2770 ProcessRecord app; 2771 if (!isolated) { 2772 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2773 checkTime(startTime, "startProcess: after getProcessRecord"); 2774 } else { 2775 // If this is an isolated process, it can't re-use an existing process. 2776 app = null; 2777 } 2778 // We don't have to do anything more if: 2779 // (1) There is an existing application record; and 2780 // (2) The caller doesn't think it is dead, OR there is no thread 2781 // object attached to it so we know it couldn't have crashed; and 2782 // (3) There is a pid assigned to it, so it is either starting or 2783 // already running. 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2785 + " app=" + app + " knownToBeDead=" + knownToBeDead 2786 + " thread=" + (app != null ? app.thread : null) 2787 + " pid=" + (app != null ? app.pid : -1)); 2788 if (app != null && app.pid > 0) { 2789 if (!knownToBeDead || app.thread == null) { 2790 // We already have the app running, or are waiting for it to 2791 // come up (we have a pid but not yet its thread), so keep it. 2792 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2793 // If this is a new package in the process, add the package to the list 2794 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2795 checkTime(startTime, "startProcess: done, added package to proc"); 2796 return app; 2797 } 2798 2799 // An application record is attached to a previous process, 2800 // clean it up now. 2801 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2802 checkTime(startTime, "startProcess: bad proc running, killing"); 2803 Process.killProcessGroup(app.info.uid, app.pid); 2804 handleAppDiedLocked(app, true, true); 2805 checkTime(startTime, "startProcess: done killing old proc"); 2806 } 2807 2808 String hostingNameStr = hostingName != null 2809 ? hostingName.flattenToShortString() : null; 2810 2811 if (!isolated) { 2812 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2813 // If we are in the background, then check to see if this process 2814 // is bad. If so, we will just silently fail. 2815 if (mBadProcesses.get(info.processName, info.uid) != null) { 2816 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2817 + "/" + info.processName); 2818 return null; 2819 } 2820 } else { 2821 // When the user is explicitly starting a process, then clear its 2822 // crash count so that we won't make it bad until they see at 2823 // least one crash dialog again, and make the process good again 2824 // if it had been bad. 2825 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2826 + "/" + info.processName); 2827 mProcessCrashTimes.remove(info.processName, info.uid); 2828 if (mBadProcesses.get(info.processName, info.uid) != null) { 2829 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2830 UserHandle.getUserId(info.uid), info.uid, 2831 info.processName); 2832 mBadProcesses.remove(info.processName, info.uid); 2833 if (app != null) { 2834 app.bad = false; 2835 } 2836 } 2837 } 2838 } 2839 2840 if (app == null) { 2841 checkTime(startTime, "startProcess: creating new process record"); 2842 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2843 app.crashHandler = crashHandler; 2844 if (app == null) { 2845 Slog.w(TAG, "Failed making new process record for " 2846 + processName + "/" + info.uid + " isolated=" + isolated); 2847 return null; 2848 } 2849 mProcessNames.put(processName, app.uid, app); 2850 if (isolated) { 2851 mIsolatedProcesses.put(app.uid, app); 2852 } 2853 checkTime(startTime, "startProcess: done creating new process record"); 2854 } else { 2855 // If this is a new package in the process, add the package to the list 2856 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2857 checkTime(startTime, "startProcess: added package to existing proc"); 2858 } 2859 2860 // If the system is not ready yet, then hold off on starting this 2861 // process until it is. 2862 if (!mProcessesReady 2863 && !isAllowedWhileBooting(info) 2864 && !allowWhileBooting) { 2865 if (!mProcessesOnHold.contains(app)) { 2866 mProcessesOnHold.add(app); 2867 } 2868 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2869 checkTime(startTime, "startProcess: returning with proc on hold"); 2870 return app; 2871 } 2872 2873 checkTime(startTime, "startProcess: stepping in to startProcess"); 2874 startProcessLocked( 2875 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2876 checkTime(startTime, "startProcess: done starting proc!"); 2877 return (app.pid != 0) ? app : null; 2878 } 2879 2880 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2881 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2882 } 2883 2884 private final void startProcessLocked(ProcessRecord app, 2885 String hostingType, String hostingNameStr) { 2886 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2887 null /* entryPoint */, null /* entryPointArgs */); 2888 } 2889 2890 private final void startProcessLocked(ProcessRecord app, String hostingType, 2891 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2892 long startTime = SystemClock.elapsedRealtime(); 2893 if (app.pid > 0 && app.pid != MY_PID) { 2894 checkTime(startTime, "startProcess: removing from pids map"); 2895 synchronized (mPidsSelfLocked) { 2896 mPidsSelfLocked.remove(app.pid); 2897 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2898 } 2899 checkTime(startTime, "startProcess: done removing from pids map"); 2900 app.setPid(0); 2901 } 2902 2903 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2904 "startProcessLocked removing on hold: " + app); 2905 mProcessesOnHold.remove(app); 2906 2907 checkTime(startTime, "startProcess: starting to update cpu stats"); 2908 updateCpuStats(); 2909 checkTime(startTime, "startProcess: done updating cpu stats"); 2910 2911 try { 2912 int uid = app.uid; 2913 2914 int[] gids = null; 2915 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2916 if (!app.isolated) { 2917 int[] permGids = null; 2918 try { 2919 checkTime(startTime, "startProcess: getting gids from package manager"); 2920 final PackageManager pm = mContext.getPackageManager(); 2921 permGids = pm.getPackageGids(app.info.packageName); 2922 2923 if (Environment.isExternalStorageEmulated()) { 2924 checkTime(startTime, "startProcess: checking external storage perm"); 2925 if (pm.checkPermission( 2926 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2927 app.info.packageName) == PERMISSION_GRANTED) { 2928 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2929 } else { 2930 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2931 } 2932 } 2933 } catch (PackageManager.NameNotFoundException e) { 2934 Slog.w(TAG, "Unable to retrieve gids", e); 2935 } 2936 2937 /* 2938 * Add shared application and profile GIDs so applications can share some 2939 * resources like shared libraries and access user-wide resources 2940 */ 2941 if (permGids == null) { 2942 gids = new int[2]; 2943 } else { 2944 gids = new int[permGids.length + 2]; 2945 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2946 } 2947 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2948 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2949 } 2950 checkTime(startTime, "startProcess: building args"); 2951 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2952 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2953 && mTopComponent != null 2954 && app.processName.equals(mTopComponent.getPackageName())) { 2955 uid = 0; 2956 } 2957 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2958 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2959 uid = 0; 2960 } 2961 } 2962 int debugFlags = 0; 2963 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2964 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2965 // Also turn on CheckJNI for debuggable apps. It's quite 2966 // awkward to turn on otherwise. 2967 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2968 } 2969 // Run the app in safe mode if its manifest requests so or the 2970 // system is booted in safe mode. 2971 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2972 mSafeMode == true) { 2973 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2974 } 2975 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2976 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2977 } 2978 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.assert"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2983 } 2984 2985 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2986 if (requiredAbi == null) { 2987 requiredAbi = Build.SUPPORTED_ABIS[0]; 2988 } 2989 2990 String instructionSet = null; 2991 if (app.info.primaryCpuAbi != null) { 2992 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2993 } 2994 2995 // Start the process. It will either succeed and return a result containing 2996 // the PID of the new process, or else throw a RuntimeException. 2997 boolean isActivityProcess = (entryPoint == null); 2998 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2999 checkTime(startTime, "startProcess: asking zygote to start proc"); 3000 Process.ProcessStartResult startResult = Process.start(entryPoint, 3001 app.processName, uid, uid, gids, debugFlags, mountExternal, 3002 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3003 app.info.dataDir, entryPointArgs); 3004 checkTime(startTime, "startProcess: returned from zygote!"); 3005 3006 if (app.isolated) { 3007 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3008 } 3009 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3010 checkTime(startTime, "startProcess: done updating battery stats"); 3011 3012 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3013 UserHandle.getUserId(uid), startResult.pid, uid, 3014 app.processName, hostingType, 3015 hostingNameStr != null ? hostingNameStr : ""); 3016 3017 if (app.persistent) { 3018 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3019 } 3020 3021 checkTime(startTime, "startProcess: building log message"); 3022 StringBuilder buf = mStringBuilder; 3023 buf.setLength(0); 3024 buf.append("Start proc "); 3025 buf.append(app.processName); 3026 if (!isActivityProcess) { 3027 buf.append(" ["); 3028 buf.append(entryPoint); 3029 buf.append("]"); 3030 } 3031 buf.append(" for "); 3032 buf.append(hostingType); 3033 if (hostingNameStr != null) { 3034 buf.append(" "); 3035 buf.append(hostingNameStr); 3036 } 3037 buf.append(": pid="); 3038 buf.append(startResult.pid); 3039 buf.append(" uid="); 3040 buf.append(uid); 3041 buf.append(" gids={"); 3042 if (gids != null) { 3043 for (int gi=0; gi<gids.length; gi++) { 3044 if (gi != 0) buf.append(", "); 3045 buf.append(gids[gi]); 3046 3047 } 3048 } 3049 buf.append("}"); 3050 if (requiredAbi != null) { 3051 buf.append(" abi="); 3052 buf.append(requiredAbi); 3053 } 3054 Slog.i(TAG, buf.toString()); 3055 app.setPid(startResult.pid); 3056 app.usingWrapper = startResult.usingWrapper; 3057 app.removed = false; 3058 app.killed = false; 3059 app.killedByAm = false; 3060 checkTime(startTime, "startProcess: starting to update pids map"); 3061 synchronized (mPidsSelfLocked) { 3062 this.mPidsSelfLocked.put(startResult.pid, app); 3063 if (isActivityProcess) { 3064 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3065 msg.obj = app; 3066 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3067 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3068 } 3069 } 3070 checkTime(startTime, "startProcess: done updating pids map"); 3071 } catch (RuntimeException e) { 3072 // XXX do better error recovery. 3073 app.setPid(0); 3074 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3075 if (app.isolated) { 3076 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3077 } 3078 Slog.e(TAG, "Failure starting process " + app.processName, e); 3079 } 3080 } 3081 3082 void updateUsageStats(ActivityRecord component, boolean resumed) { 3083 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3084 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3085 if (resumed) { 3086 if (mUsageStatsService != null) { 3087 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3088 UsageEvents.Event.MOVE_TO_FOREGROUND); 3089 } 3090 synchronized (stats) { 3091 stats.noteActivityResumedLocked(component.app.uid); 3092 } 3093 } else { 3094 if (mUsageStatsService != null) { 3095 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3096 UsageEvents.Event.MOVE_TO_BACKGROUND); 3097 } 3098 synchronized (stats) { 3099 stats.noteActivityPausedLocked(component.app.uid); 3100 } 3101 } 3102 } 3103 3104 Intent getHomeIntent() { 3105 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3106 intent.setComponent(mTopComponent); 3107 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3108 intent.addCategory(Intent.CATEGORY_HOME); 3109 } 3110 return intent; 3111 } 3112 3113 boolean startHomeActivityLocked(int userId) { 3114 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3115 && mTopAction == null) { 3116 // We are running in factory test mode, but unable to find 3117 // the factory test app, so just sit around displaying the 3118 // error message and don't try to start anything. 3119 return false; 3120 } 3121 Intent intent = getHomeIntent(); 3122 ActivityInfo aInfo = 3123 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3124 if (aInfo != null) { 3125 intent.setComponent(new ComponentName( 3126 aInfo.applicationInfo.packageName, aInfo.name)); 3127 // Don't do this if the home app is currently being 3128 // instrumented. 3129 aInfo = new ActivityInfo(aInfo); 3130 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3131 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3132 aInfo.applicationInfo.uid, true); 3133 if (app == null || app.instrumentationClass == null) { 3134 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3135 mStackSupervisor.startHomeActivity(intent, aInfo); 3136 } 3137 } 3138 3139 return true; 3140 } 3141 3142 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3143 ActivityInfo ai = null; 3144 ComponentName comp = intent.getComponent(); 3145 try { 3146 if (comp != null) { 3147 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3148 } else { 3149 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3150 intent, 3151 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3152 flags, userId); 3153 3154 if (info != null) { 3155 ai = info.activityInfo; 3156 } 3157 } 3158 } catch (RemoteException e) { 3159 // ignore 3160 } 3161 3162 return ai; 3163 } 3164 3165 /** 3166 * Starts the "new version setup screen" if appropriate. 3167 */ 3168 void startSetupActivityLocked() { 3169 // Only do this once per boot. 3170 if (mCheckedForSetup) { 3171 return; 3172 } 3173 3174 // We will show this screen if the current one is a different 3175 // version than the last one shown, and we are not running in 3176 // low-level factory test mode. 3177 final ContentResolver resolver = mContext.getContentResolver(); 3178 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3179 Settings.Global.getInt(resolver, 3180 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3181 mCheckedForSetup = true; 3182 3183 // See if we should be showing the platform update setup UI. 3184 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3185 List<ResolveInfo> ris = mContext.getPackageManager() 3186 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3187 3188 // We don't allow third party apps to replace this. 3189 ResolveInfo ri = null; 3190 for (int i=0; ris != null && i<ris.size(); i++) { 3191 if ((ris.get(i).activityInfo.applicationInfo.flags 3192 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3193 ri = ris.get(i); 3194 break; 3195 } 3196 } 3197 3198 if (ri != null) { 3199 String vers = ri.activityInfo.metaData != null 3200 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3201 : null; 3202 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3203 vers = ri.activityInfo.applicationInfo.metaData.getString( 3204 Intent.METADATA_SETUP_VERSION); 3205 } 3206 String lastVers = Settings.Secure.getString( 3207 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3208 if (vers != null && !vers.equals(lastVers)) { 3209 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3210 intent.setComponent(new ComponentName( 3211 ri.activityInfo.packageName, ri.activityInfo.name)); 3212 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3213 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3214 null); 3215 } 3216 } 3217 } 3218 } 3219 3220 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3221 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3222 } 3223 3224 void enforceNotIsolatedCaller(String caller) { 3225 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3226 throw new SecurityException("Isolated process not allowed to call " + caller); 3227 } 3228 } 3229 3230 void enforceShellRestriction(String restriction, int userHandle) { 3231 if (Binder.getCallingUid() == Process.SHELL_UID) { 3232 if (userHandle < 0 3233 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3234 throw new SecurityException("Shell does not have permission to access user " 3235 + userHandle); 3236 } 3237 } 3238 } 3239 3240 @Override 3241 public int getFrontActivityScreenCompatMode() { 3242 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3243 synchronized (this) { 3244 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3245 } 3246 } 3247 3248 @Override 3249 public void setFrontActivityScreenCompatMode(int mode) { 3250 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3251 "setFrontActivityScreenCompatMode"); 3252 synchronized (this) { 3253 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3254 } 3255 } 3256 3257 @Override 3258 public int getPackageScreenCompatMode(String packageName) { 3259 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3260 synchronized (this) { 3261 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3262 } 3263 } 3264 3265 @Override 3266 public void setPackageScreenCompatMode(String packageName, int mode) { 3267 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3268 "setPackageScreenCompatMode"); 3269 synchronized (this) { 3270 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3271 } 3272 } 3273 3274 @Override 3275 public boolean getPackageAskScreenCompat(String packageName) { 3276 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3277 synchronized (this) { 3278 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3279 } 3280 } 3281 3282 @Override 3283 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3284 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3285 "setPackageAskScreenCompat"); 3286 synchronized (this) { 3287 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3288 } 3289 } 3290 3291 private void dispatchProcessesChanged() { 3292 int N; 3293 synchronized (this) { 3294 N = mPendingProcessChanges.size(); 3295 if (mActiveProcessChanges.length < N) { 3296 mActiveProcessChanges = new ProcessChangeItem[N]; 3297 } 3298 mPendingProcessChanges.toArray(mActiveProcessChanges); 3299 mAvailProcessChanges.addAll(mPendingProcessChanges); 3300 mPendingProcessChanges.clear(); 3301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3302 } 3303 3304 int i = mProcessObservers.beginBroadcast(); 3305 while (i > 0) { 3306 i--; 3307 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3308 if (observer != null) { 3309 try { 3310 for (int j=0; j<N; j++) { 3311 ProcessChangeItem item = mActiveProcessChanges[j]; 3312 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3313 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3314 + item.pid + " uid=" + item.uid + ": " 3315 + item.foregroundActivities); 3316 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3317 item.foregroundActivities); 3318 } 3319 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3320 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3321 + item.pid + " uid=" + item.uid + ": " + item.processState); 3322 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3323 } 3324 } 3325 } catch (RemoteException e) { 3326 } 3327 } 3328 } 3329 mProcessObservers.finishBroadcast(); 3330 } 3331 3332 private void dispatchProcessDied(int pid, int uid) { 3333 int i = mProcessObservers.beginBroadcast(); 3334 while (i > 0) { 3335 i--; 3336 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3337 if (observer != null) { 3338 try { 3339 observer.onProcessDied(pid, uid); 3340 } catch (RemoteException e) { 3341 } 3342 } 3343 } 3344 mProcessObservers.finishBroadcast(); 3345 } 3346 3347 @Override 3348 public final int startActivity(IApplicationThread caller, String callingPackage, 3349 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3350 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3351 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3352 resultWho, requestCode, startFlags, profilerInfo, options, 3353 UserHandle.getCallingUserId()); 3354 } 3355 3356 @Override 3357 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3358 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3359 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3360 enforceNotIsolatedCaller("startActivity"); 3361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3362 false, ALLOW_FULL_ONLY, "startActivity", null); 3363 // TODO: Switch to user app stacks here. 3364 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3365 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3366 profilerInfo, null, null, options, userId, null, null); 3367 } 3368 3369 @Override 3370 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3371 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3372 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3373 3374 // This is very dangerous -- it allows you to perform a start activity (including 3375 // permission grants) as any app that may launch one of your own activities. So 3376 // we will only allow this to be done from activities that are part of the core framework, 3377 // and then only when they are running as the system. 3378 final ActivityRecord sourceRecord; 3379 final int targetUid; 3380 final String targetPackage; 3381 synchronized (this) { 3382 if (resultTo == null) { 3383 throw new SecurityException("Must be called from an activity"); 3384 } 3385 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3386 if (sourceRecord == null) { 3387 throw new SecurityException("Called with bad activity token: " + resultTo); 3388 } 3389 if (!sourceRecord.info.packageName.equals("android")) { 3390 throw new SecurityException( 3391 "Must be called from an activity that is declared in the android package"); 3392 } 3393 if (sourceRecord.app == null) { 3394 throw new SecurityException("Called without a process attached to activity"); 3395 } 3396 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3397 // This is still okay, as long as this activity is running under the 3398 // uid of the original calling activity. 3399 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3400 throw new SecurityException( 3401 "Calling activity in uid " + sourceRecord.app.uid 3402 + " must be system uid or original calling uid " 3403 + sourceRecord.launchedFromUid); 3404 } 3405 } 3406 targetUid = sourceRecord.launchedFromUid; 3407 targetPackage = sourceRecord.launchedFromPackage; 3408 } 3409 3410 if (userId == UserHandle.USER_NULL) { 3411 userId = UserHandle.getUserId(sourceRecord.app.uid); 3412 } 3413 3414 // TODO: Switch to user app stacks here. 3415 try { 3416 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3417 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3418 null, null, options, userId, null, null); 3419 return ret; 3420 } catch (SecurityException e) { 3421 // XXX need to figure out how to propagate to original app. 3422 // A SecurityException here is generally actually a fault of the original 3423 // calling activity (such as a fairly granting permissions), so propagate it 3424 // back to them. 3425 /* 3426 StringBuilder msg = new StringBuilder(); 3427 msg.append("While launching"); 3428 msg.append(intent.toString()); 3429 msg.append(": "); 3430 msg.append(e.getMessage()); 3431 */ 3432 throw e; 3433 } 3434 } 3435 3436 @Override 3437 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3438 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3439 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3440 enforceNotIsolatedCaller("startActivityAndWait"); 3441 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3442 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3443 WaitResult res = new WaitResult(); 3444 // TODO: Switch to user app stacks here. 3445 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3446 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3447 options, userId, null, null); 3448 return res; 3449 } 3450 3451 @Override 3452 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3453 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3454 int startFlags, Configuration config, Bundle options, int userId) { 3455 enforceNotIsolatedCaller("startActivityWithConfig"); 3456 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3457 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3458 // TODO: Switch to user app stacks here. 3459 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3460 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3461 null, null, config, options, userId, null, null); 3462 return ret; 3463 } 3464 3465 @Override 3466 public int startActivityIntentSender(IApplicationThread caller, 3467 IntentSender intent, Intent fillInIntent, String resolvedType, 3468 IBinder resultTo, String resultWho, int requestCode, 3469 int flagsMask, int flagsValues, Bundle options) { 3470 enforceNotIsolatedCaller("startActivityIntentSender"); 3471 // Refuse possible leaked file descriptors 3472 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3473 throw new IllegalArgumentException("File descriptors passed in Intent"); 3474 } 3475 3476 IIntentSender sender = intent.getTarget(); 3477 if (!(sender instanceof PendingIntentRecord)) { 3478 throw new IllegalArgumentException("Bad PendingIntent object"); 3479 } 3480 3481 PendingIntentRecord pir = (PendingIntentRecord)sender; 3482 3483 synchronized (this) { 3484 // If this is coming from the currently resumed activity, it is 3485 // effectively saying that app switches are allowed at this point. 3486 final ActivityStack stack = getFocusedStack(); 3487 if (stack.mResumedActivity != null && 3488 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3489 mAppSwitchesAllowedTime = 0; 3490 } 3491 } 3492 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3493 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3494 return ret; 3495 } 3496 3497 @Override 3498 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3499 Intent intent, String resolvedType, IVoiceInteractionSession session, 3500 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3501 Bundle options, int userId) { 3502 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3503 != PackageManager.PERMISSION_GRANTED) { 3504 String msg = "Permission Denial: startVoiceActivity() from pid=" 3505 + Binder.getCallingPid() 3506 + ", uid=" + Binder.getCallingUid() 3507 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3508 Slog.w(TAG, msg); 3509 throw new SecurityException(msg); 3510 } 3511 if (session == null || interactor == null) { 3512 throw new NullPointerException("null session or interactor"); 3513 } 3514 userId = handleIncomingUser(callingPid, callingUid, userId, 3515 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3516 // TODO: Switch to user app stacks here. 3517 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3518 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3519 null, options, userId, null, null); 3520 } 3521 3522 @Override 3523 public boolean startNextMatchingActivity(IBinder callingActivity, 3524 Intent intent, Bundle options) { 3525 // Refuse possible leaked file descriptors 3526 if (intent != null && intent.hasFileDescriptors() == true) { 3527 throw new IllegalArgumentException("File descriptors passed in Intent"); 3528 } 3529 3530 synchronized (this) { 3531 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3532 if (r == null) { 3533 ActivityOptions.abort(options); 3534 return false; 3535 } 3536 if (r.app == null || r.app.thread == null) { 3537 // The caller is not running... d'oh! 3538 ActivityOptions.abort(options); 3539 return false; 3540 } 3541 intent = new Intent(intent); 3542 // The caller is not allowed to change the data. 3543 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3544 // And we are resetting to find the next component... 3545 intent.setComponent(null); 3546 3547 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3548 3549 ActivityInfo aInfo = null; 3550 try { 3551 List<ResolveInfo> resolves = 3552 AppGlobals.getPackageManager().queryIntentActivities( 3553 intent, r.resolvedType, 3554 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3555 UserHandle.getCallingUserId()); 3556 3557 // Look for the original activity in the list... 3558 final int N = resolves != null ? resolves.size() : 0; 3559 for (int i=0; i<N; i++) { 3560 ResolveInfo rInfo = resolves.get(i); 3561 if (rInfo.activityInfo.packageName.equals(r.packageName) 3562 && rInfo.activityInfo.name.equals(r.info.name)) { 3563 // We found the current one... the next matching is 3564 // after it. 3565 i++; 3566 if (i<N) { 3567 aInfo = resolves.get(i).activityInfo; 3568 } 3569 if (debug) { 3570 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3571 + "/" + r.info.name); 3572 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3573 + "/" + aInfo.name); 3574 } 3575 break; 3576 } 3577 } 3578 } catch (RemoteException e) { 3579 } 3580 3581 if (aInfo == null) { 3582 // Nobody who is next! 3583 ActivityOptions.abort(options); 3584 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3585 return false; 3586 } 3587 3588 intent.setComponent(new ComponentName( 3589 aInfo.applicationInfo.packageName, aInfo.name)); 3590 intent.setFlags(intent.getFlags()&~( 3591 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3592 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3593 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3594 Intent.FLAG_ACTIVITY_NEW_TASK)); 3595 3596 // Okay now we need to start the new activity, replacing the 3597 // currently running activity. This is a little tricky because 3598 // we want to start the new one as if the current one is finished, 3599 // but not finish the current one first so that there is no flicker. 3600 // And thus... 3601 final boolean wasFinishing = r.finishing; 3602 r.finishing = true; 3603 3604 // Propagate reply information over to the new activity. 3605 final ActivityRecord resultTo = r.resultTo; 3606 final String resultWho = r.resultWho; 3607 final int requestCode = r.requestCode; 3608 r.resultTo = null; 3609 if (resultTo != null) { 3610 resultTo.removeResultsLocked(r, resultWho, requestCode); 3611 } 3612 3613 final long origId = Binder.clearCallingIdentity(); 3614 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3615 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3616 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3617 -1, r.launchedFromUid, 0, options, false, null, null, null); 3618 Binder.restoreCallingIdentity(origId); 3619 3620 r.finishing = wasFinishing; 3621 if (res != ActivityManager.START_SUCCESS) { 3622 return false; 3623 } 3624 return true; 3625 } 3626 } 3627 3628 @Override 3629 public final int startActivityFromRecents(int taskId, Bundle options) { 3630 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3631 String msg = "Permission Denial: startActivityFromRecents called without " + 3632 START_TASKS_FROM_RECENTS; 3633 Slog.w(TAG, msg); 3634 throw new SecurityException(msg); 3635 } 3636 return startActivityFromRecentsInner(taskId, options); 3637 } 3638 3639 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3640 final TaskRecord task; 3641 final int callingUid; 3642 final String callingPackage; 3643 final Intent intent; 3644 final int userId; 3645 synchronized (this) { 3646 task = recentTaskForIdLocked(taskId); 3647 if (task == null) { 3648 throw new IllegalArgumentException("Task " + taskId + " not found."); 3649 } 3650 callingUid = task.mCallingUid; 3651 callingPackage = task.mCallingPackage; 3652 intent = task.intent; 3653 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3654 userId = task.userId; 3655 } 3656 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3657 options, userId, null, task); 3658 } 3659 3660 final int startActivityInPackage(int uid, String callingPackage, 3661 Intent intent, String resolvedType, IBinder resultTo, 3662 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3663 IActivityContainer container, TaskRecord inTask) { 3664 3665 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3666 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3667 3668 // TODO: Switch to user app stacks here. 3669 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3670 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3671 null, null, null, options, userId, container, inTask); 3672 return ret; 3673 } 3674 3675 @Override 3676 public final int startActivities(IApplicationThread caller, String callingPackage, 3677 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3678 int userId) { 3679 enforceNotIsolatedCaller("startActivities"); 3680 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3681 false, ALLOW_FULL_ONLY, "startActivity", null); 3682 // TODO: Switch to user app stacks here. 3683 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3684 resolvedTypes, resultTo, options, userId); 3685 return ret; 3686 } 3687 3688 final int startActivitiesInPackage(int uid, String callingPackage, 3689 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3690 Bundle options, int userId) { 3691 3692 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3693 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3694 // TODO: Switch to user app stacks here. 3695 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3696 resultTo, options, userId); 3697 return ret; 3698 } 3699 3700 //explicitly remove thd old information in mRecentTasks when removing existing user. 3701 private void removeRecentTasksForUserLocked(int userId) { 3702 if(userId <= 0) { 3703 Slog.i(TAG, "Can't remove recent task on user " + userId); 3704 return; 3705 } 3706 3707 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3708 TaskRecord tr = mRecentTasks.get(i); 3709 if (tr.userId == userId) { 3710 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3711 + " when finishing user" + userId); 3712 mRecentTasks.remove(i); 3713 tr.removedFromRecents(mTaskPersister); 3714 } 3715 } 3716 3717 // Remove tasks from persistent storage. 3718 mTaskPersister.wakeup(null, true); 3719 } 3720 3721 // Sort by taskId 3722 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3723 @Override 3724 public int compare(TaskRecord lhs, TaskRecord rhs) { 3725 return rhs.taskId - lhs.taskId; 3726 } 3727 }; 3728 3729 // Extract the affiliates of the chain containing mRecentTasks[start]. 3730 private int processNextAffiliateChain(int start) { 3731 final TaskRecord startTask = mRecentTasks.get(start); 3732 final int affiliateId = startTask.mAffiliatedTaskId; 3733 3734 // Quick identification of isolated tasks. I.e. those not launched behind. 3735 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3736 startTask.mNextAffiliate == null) { 3737 // There is still a slim chance that there are other tasks that point to this task 3738 // and that the chain is so messed up that this task no longer points to them but 3739 // the gain of this optimization outweighs the risk. 3740 startTask.inRecents = true; 3741 return start + 1; 3742 } 3743 3744 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3745 mTmpRecents.clear(); 3746 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3747 final TaskRecord task = mRecentTasks.get(i); 3748 if (task.mAffiliatedTaskId == affiliateId) { 3749 mRecentTasks.remove(i); 3750 mTmpRecents.add(task); 3751 } 3752 } 3753 3754 // Sort them all by taskId. That is the order they were create in and that order will 3755 // always be correct. 3756 Collections.sort(mTmpRecents, mTaskRecordComparator); 3757 3758 // Go through and fix up the linked list. 3759 // The first one is the end of the chain and has no next. 3760 final TaskRecord first = mTmpRecents.get(0); 3761 first.inRecents = true; 3762 if (first.mNextAffiliate != null) { 3763 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3764 first.setNextAffiliate(null); 3765 mTaskPersister.wakeup(first, false); 3766 } 3767 // Everything in the middle is doubly linked from next to prev. 3768 final int tmpSize = mTmpRecents.size(); 3769 for (int i = 0; i < tmpSize - 1; ++i) { 3770 final TaskRecord next = mTmpRecents.get(i); 3771 final TaskRecord prev = mTmpRecents.get(i + 1); 3772 if (next.mPrevAffiliate != prev) { 3773 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3774 " setting prev=" + prev); 3775 next.setPrevAffiliate(prev); 3776 mTaskPersister.wakeup(next, false); 3777 } 3778 if (prev.mNextAffiliate != next) { 3779 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3780 " setting next=" + next); 3781 prev.setNextAffiliate(next); 3782 mTaskPersister.wakeup(prev, false); 3783 } 3784 prev.inRecents = true; 3785 } 3786 // The last one is the beginning of the list and has no prev. 3787 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3788 if (last.mPrevAffiliate != null) { 3789 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3790 last.setPrevAffiliate(null); 3791 mTaskPersister.wakeup(last, false); 3792 } 3793 3794 // Insert the group back into mRecentTasks at start. 3795 mRecentTasks.addAll(start, mTmpRecents); 3796 3797 // Let the caller know where we left off. 3798 return start + tmpSize; 3799 } 3800 3801 /** 3802 * Update the recent tasks lists: make sure tasks should still be here (their 3803 * applications / activities still exist), update their availability, fixup ordering 3804 * of affiliations. 3805 */ 3806 void cleanupRecentTasksLocked(int userId) { 3807 if (mRecentTasks == null) { 3808 // Happens when called from the packagemanager broadcast before boot. 3809 return; 3810 } 3811 3812 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3813 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3814 final IPackageManager pm = AppGlobals.getPackageManager(); 3815 final ActivityInfo dummyAct = new ActivityInfo(); 3816 final ApplicationInfo dummyApp = new ApplicationInfo(); 3817 3818 int N = mRecentTasks.size(); 3819 3820 int[] users = userId == UserHandle.USER_ALL 3821 ? getUsersLocked() : new int[] { userId }; 3822 for (int user : users) { 3823 for (int i = 0; i < N; i++) { 3824 TaskRecord task = mRecentTasks.get(i); 3825 if (task.userId != user) { 3826 // Only look at tasks for the user ID of interest. 3827 continue; 3828 } 3829 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3830 // This situation is broken, and we should just get rid of it now. 3831 mRecentTasks.remove(i); 3832 task.removedFromRecents(mTaskPersister); 3833 i--; 3834 N--; 3835 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3836 continue; 3837 } 3838 // Check whether this activity is currently available. 3839 if (task.realActivity != null) { 3840 ActivityInfo ai = availActCache.get(task.realActivity); 3841 if (ai == null) { 3842 try { 3843 ai = pm.getActivityInfo(task.realActivity, 3844 PackageManager.GET_UNINSTALLED_PACKAGES 3845 | PackageManager.GET_DISABLED_COMPONENTS, user); 3846 } catch (RemoteException e) { 3847 // Will never happen. 3848 continue; 3849 } 3850 if (ai == null) { 3851 ai = dummyAct; 3852 } 3853 availActCache.put(task.realActivity, ai); 3854 } 3855 if (ai == dummyAct) { 3856 // This could be either because the activity no longer exists, or the 3857 // app is temporarily gone. For the former we want to remove the recents 3858 // entry; for the latter we want to mark it as unavailable. 3859 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3860 if (app == null) { 3861 try { 3862 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3863 PackageManager.GET_UNINSTALLED_PACKAGES 3864 | PackageManager.GET_DISABLED_COMPONENTS, user); 3865 } catch (RemoteException e) { 3866 // Will never happen. 3867 continue; 3868 } 3869 if (app == null) { 3870 app = dummyApp; 3871 } 3872 availAppCache.put(task.realActivity.getPackageName(), app); 3873 } 3874 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3875 // Doesn't exist any more! Good-bye. 3876 mRecentTasks.remove(i); 3877 task.removedFromRecents(mTaskPersister); 3878 i--; 3879 N--; 3880 Slog.w(TAG, "Removing no longer valid recent: " + task); 3881 continue; 3882 } else { 3883 // Otherwise just not available for now. 3884 if (task.isAvailable) { 3885 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3886 + task); 3887 } 3888 task.isAvailable = false; 3889 } 3890 } else { 3891 if (!ai.enabled || !ai.applicationInfo.enabled 3892 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3893 if (task.isAvailable) { 3894 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3895 + task + " (enabled=" + ai.enabled + "/" 3896 + ai.applicationInfo.enabled + " flags=" 3897 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3898 } 3899 task.isAvailable = false; 3900 } else { 3901 if (!task.isAvailable) { 3902 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3903 + task); 3904 } 3905 task.isAvailable = true; 3906 } 3907 } 3908 } 3909 } 3910 } 3911 3912 // Verify the affiliate chain for each task. 3913 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3914 } 3915 3916 mTmpRecents.clear(); 3917 // mRecentTasks is now in sorted, affiliated order. 3918 } 3919 3920 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3921 int N = mRecentTasks.size(); 3922 TaskRecord top = task; 3923 int topIndex = taskIndex; 3924 while (top.mNextAffiliate != null && topIndex > 0) { 3925 top = top.mNextAffiliate; 3926 topIndex--; 3927 } 3928 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3929 + topIndex + " from intial " + taskIndex); 3930 // Find the end of the chain, doing a sanity check along the way. 3931 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3932 int endIndex = topIndex; 3933 TaskRecord prev = top; 3934 while (endIndex < N) { 3935 TaskRecord cur = mRecentTasks.get(endIndex); 3936 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3937 + endIndex + " " + cur); 3938 if (cur == top) { 3939 // Verify start of the chain. 3940 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3941 Slog.wtf(TAG, "Bad chain @" + endIndex 3942 + ": first task has next affiliate: " + prev); 3943 sane = false; 3944 break; 3945 } 3946 } else { 3947 // Verify middle of the chain's next points back to the one before. 3948 if (cur.mNextAffiliate != prev 3949 || cur.mNextAffiliateTaskId != prev.taskId) { 3950 Slog.wtf(TAG, "Bad chain @" + endIndex 3951 + ": middle task " + cur + " @" + endIndex 3952 + " has bad next affiliate " 3953 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3954 + ", expected " + prev); 3955 sane = false; 3956 break; 3957 } 3958 } 3959 if (cur.mPrevAffiliateTaskId == -1) { 3960 // Chain ends here. 3961 if (cur.mPrevAffiliate != null) { 3962 Slog.wtf(TAG, "Bad chain @" + endIndex 3963 + ": last task " + cur + " has previous affiliate " 3964 + cur.mPrevAffiliate); 3965 sane = false; 3966 } 3967 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3968 break; 3969 } else { 3970 // Verify middle of the chain's prev points to a valid item. 3971 if (cur.mPrevAffiliate == null) { 3972 Slog.wtf(TAG, "Bad chain @" + endIndex 3973 + ": task " + cur + " has previous affiliate " 3974 + cur.mPrevAffiliate + " but should be id " 3975 + cur.mPrevAffiliate); 3976 sane = false; 3977 break; 3978 } 3979 } 3980 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3981 Slog.wtf(TAG, "Bad chain @" + endIndex 3982 + ": task " + cur + " has affiliated id " 3983 + cur.mAffiliatedTaskId + " but should be " 3984 + task.mAffiliatedTaskId); 3985 sane = false; 3986 break; 3987 } 3988 prev = cur; 3989 endIndex++; 3990 if (endIndex >= N) { 3991 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3992 + ": last task " + prev); 3993 sane = false; 3994 break; 3995 } 3996 } 3997 if (sane) { 3998 if (endIndex < taskIndex) { 3999 Slog.wtf(TAG, "Bad chain @" + endIndex 4000 + ": did not extend to task " + task + " @" + taskIndex); 4001 sane = false; 4002 } 4003 } 4004 if (sane) { 4005 // All looks good, we can just move all of the affiliated tasks 4006 // to the top. 4007 for (int i=topIndex; i<=endIndex; i++) { 4008 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4009 + " from " + i + " to " + (i-topIndex)); 4010 TaskRecord cur = mRecentTasks.remove(i); 4011 mRecentTasks.add(i-topIndex, cur); 4012 } 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4014 + " to " + endIndex); 4015 return true; 4016 } 4017 4018 // Whoops, couldn't do it. 4019 return false; 4020 } 4021 4022 final void addRecentTaskLocked(TaskRecord task) { 4023 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4024 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4025 4026 int N = mRecentTasks.size(); 4027 // Quick case: check if the top-most recent task is the same. 4028 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4029 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4030 return; 4031 } 4032 // Another quick case: check if this is part of a set of affiliated 4033 // tasks that are at the top. 4034 if (isAffiliated && N > 0 && task.inRecents 4035 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4036 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4037 + " at top when adding " + task); 4038 return; 4039 } 4040 // Another quick case: never add voice sessions. 4041 if (task.voiceSession != null) { 4042 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4043 return; 4044 } 4045 4046 boolean needAffiliationFix = false; 4047 4048 // Slightly less quick case: the task is already in recents, so all we need 4049 // to do is move it. 4050 if (task.inRecents) { 4051 int taskIndex = mRecentTasks.indexOf(task); 4052 if (taskIndex >= 0) { 4053 if (!isAffiliated) { 4054 // Simple case: this is not an affiliated task, so we just move it to the front. 4055 mRecentTasks.remove(taskIndex); 4056 mRecentTasks.add(0, task); 4057 notifyTaskPersisterLocked(task, false); 4058 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4059 + " from " + taskIndex); 4060 return; 4061 } else { 4062 // More complicated: need to keep all affiliated tasks together. 4063 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4064 // All went well. 4065 return; 4066 } 4067 4068 // Uh oh... something bad in the affiliation chain, try to rebuild 4069 // everything and then go through our general path of adding a new task. 4070 needAffiliationFix = true; 4071 } 4072 } else { 4073 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4074 needAffiliationFix = true; 4075 } 4076 } 4077 4078 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4079 trimRecentsForTask(task, true); 4080 4081 N = mRecentTasks.size(); 4082 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4083 final TaskRecord tr = mRecentTasks.remove(N - 1); 4084 tr.removedFromRecents(mTaskPersister); 4085 N--; 4086 } 4087 task.inRecents = true; 4088 if (!isAffiliated || needAffiliationFix) { 4089 // If this is a simple non-affiliated task, or we had some failure trying to 4090 // handle it as part of an affilated task, then just place it at the top. 4091 mRecentTasks.add(0, task); 4092 } else if (isAffiliated) { 4093 // If this is a new affiliated task, then move all of the affiliated tasks 4094 // to the front and insert this new one. 4095 TaskRecord other = task.mNextAffiliate; 4096 if (other == null) { 4097 other = task.mPrevAffiliate; 4098 } 4099 if (other != null) { 4100 int otherIndex = mRecentTasks.indexOf(other); 4101 if (otherIndex >= 0) { 4102 // Insert new task at appropriate location. 4103 int taskIndex; 4104 if (other == task.mNextAffiliate) { 4105 // We found the index of our next affiliation, which is who is 4106 // before us in the list, so add after that point. 4107 taskIndex = otherIndex+1; 4108 } else { 4109 // We found the index of our previous affiliation, which is who is 4110 // after us in the list, so add at their position. 4111 taskIndex = otherIndex; 4112 } 4113 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4114 + taskIndex + ": " + task); 4115 mRecentTasks.add(taskIndex, task); 4116 4117 // Now move everything to the front. 4118 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4119 // All went well. 4120 return; 4121 } 4122 4123 // Uh oh... something bad in the affiliation chain, try to rebuild 4124 // everything and then go through our general path of adding a new task. 4125 needAffiliationFix = true; 4126 } else { 4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4128 + other); 4129 needAffiliationFix = true; 4130 } 4131 } else { 4132 if (DEBUG_RECENTS) Slog.d(TAG, 4133 "addRecent: adding affiliated task without next/prev:" + task); 4134 needAffiliationFix = true; 4135 } 4136 } 4137 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4138 4139 if (needAffiliationFix) { 4140 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4141 cleanupRecentTasksLocked(task.userId); 4142 } 4143 } 4144 4145 /** 4146 * If needed, remove oldest existing entries in recents that are for the same kind 4147 * of task as the given one. 4148 */ 4149 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4150 int N = mRecentTasks.size(); 4151 final Intent intent = task.intent; 4152 final boolean document = intent != null && intent.isDocument(); 4153 4154 int maxRecents = task.maxRecents - 1; 4155 for (int i=0; i<N; i++) { 4156 final TaskRecord tr = mRecentTasks.get(i); 4157 if (task != tr) { 4158 if (task.userId != tr.userId) { 4159 continue; 4160 } 4161 if (i > MAX_RECENT_BITMAPS) { 4162 tr.freeLastThumbnail(); 4163 } 4164 final Intent trIntent = tr.intent; 4165 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4166 (intent == null || !intent.filterEquals(trIntent))) { 4167 continue; 4168 } 4169 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4170 if (document && trIsDocument) { 4171 // These are the same document activity (not necessarily the same doc). 4172 if (maxRecents > 0) { 4173 --maxRecents; 4174 continue; 4175 } 4176 // Hit the maximum number of documents for this task. Fall through 4177 // and remove this document from recents. 4178 } else if (document || trIsDocument) { 4179 // Only one of these is a document. Not the droid we're looking for. 4180 continue; 4181 } 4182 } 4183 4184 if (!doTrim) { 4185 // If the caller is not actually asking for a trim, just tell them we reached 4186 // a point where the trim would happen. 4187 return i; 4188 } 4189 4190 // Either task and tr are the same or, their affinities match or their intents match 4191 // and neither of them is a document, or they are documents using the same activity 4192 // and their maxRecents has been reached. 4193 tr.disposeThumbnail(); 4194 mRecentTasks.remove(i); 4195 if (task != tr) { 4196 tr.removedFromRecents(mTaskPersister); 4197 } 4198 i--; 4199 N--; 4200 if (task.intent == null) { 4201 // If the new recent task we are adding is not fully 4202 // specified, then replace it with the existing recent task. 4203 task = tr; 4204 } 4205 notifyTaskPersisterLocked(tr, false); 4206 } 4207 4208 return -1; 4209 } 4210 4211 @Override 4212 public void reportActivityFullyDrawn(IBinder token) { 4213 synchronized (this) { 4214 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4215 if (r == null) { 4216 return; 4217 } 4218 r.reportFullyDrawnLocked(); 4219 } 4220 } 4221 4222 @Override 4223 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4224 synchronized (this) { 4225 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4226 if (r == null) { 4227 return; 4228 } 4229 final long origId = Binder.clearCallingIdentity(); 4230 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4231 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4232 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4233 if (config != null) { 4234 r.frozenBeforeDestroy = true; 4235 if (!updateConfigurationLocked(config, r, false, false)) { 4236 mStackSupervisor.resumeTopActivitiesLocked(); 4237 } 4238 } 4239 Binder.restoreCallingIdentity(origId); 4240 } 4241 } 4242 4243 @Override 4244 public int getRequestedOrientation(IBinder token) { 4245 synchronized (this) { 4246 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4247 if (r == null) { 4248 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4249 } 4250 return mWindowManager.getAppOrientation(r.appToken); 4251 } 4252 } 4253 4254 /** 4255 * This is the internal entry point for handling Activity.finish(). 4256 * 4257 * @param token The Binder token referencing the Activity we want to finish. 4258 * @param resultCode Result code, if any, from this Activity. 4259 * @param resultData Result data (Intent), if any, from this Activity. 4260 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4261 * the root Activity in the task. 4262 * 4263 * @return Returns true if the activity successfully finished, or false if it is still running. 4264 */ 4265 @Override 4266 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4267 boolean finishTask) { 4268 // Refuse possible leaked file descriptors 4269 if (resultData != null && resultData.hasFileDescriptors() == true) { 4270 throw new IllegalArgumentException("File descriptors passed in Intent"); 4271 } 4272 4273 synchronized(this) { 4274 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4275 if (r == null) { 4276 return true; 4277 } 4278 // Keep track of the root activity of the task before we finish it 4279 TaskRecord tr = r.task; 4280 ActivityRecord rootR = tr.getRootActivity(); 4281 // Do not allow task to finish in Lock Task mode. 4282 if (tr == mStackSupervisor.mLockTaskModeTask) { 4283 if (rootR == r) { 4284 mStackSupervisor.showLockTaskToast(); 4285 return false; 4286 } 4287 } 4288 if (mController != null) { 4289 // Find the first activity that is not finishing. 4290 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4291 if (next != null) { 4292 // ask watcher if this is allowed 4293 boolean resumeOK = true; 4294 try { 4295 resumeOK = mController.activityResuming(next.packageName); 4296 } catch (RemoteException e) { 4297 mController = null; 4298 Watchdog.getInstance().setActivityController(null); 4299 } 4300 4301 if (!resumeOK) { 4302 return false; 4303 } 4304 } 4305 } 4306 final long origId = Binder.clearCallingIdentity(); 4307 try { 4308 boolean res; 4309 if (finishTask && r == rootR) { 4310 // If requested, remove the task that is associated to this activity only if it 4311 // was the root activity in the task. The result code and data is ignored 4312 // because we don't support returning them across task boundaries. 4313 res = removeTaskByIdLocked(tr.taskId, false); 4314 } else { 4315 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4316 resultData, "app-request", true); 4317 } 4318 return res; 4319 } finally { 4320 Binder.restoreCallingIdentity(origId); 4321 } 4322 } 4323 } 4324 4325 @Override 4326 public final void finishHeavyWeightApp() { 4327 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4328 != PackageManager.PERMISSION_GRANTED) { 4329 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4330 + Binder.getCallingPid() 4331 + ", uid=" + Binder.getCallingUid() 4332 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4333 Slog.w(TAG, msg); 4334 throw new SecurityException(msg); 4335 } 4336 4337 synchronized(this) { 4338 if (mHeavyWeightProcess == null) { 4339 return; 4340 } 4341 4342 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4343 mHeavyWeightProcess.activities); 4344 for (int i=0; i<activities.size(); i++) { 4345 ActivityRecord r = activities.get(i); 4346 if (!r.finishing) { 4347 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4348 null, "finish-heavy", true); 4349 } 4350 } 4351 4352 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4353 mHeavyWeightProcess.userId, 0)); 4354 mHeavyWeightProcess = null; 4355 } 4356 } 4357 4358 @Override 4359 public void crashApplication(int uid, int initialPid, String packageName, 4360 String message) { 4361 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4362 != PackageManager.PERMISSION_GRANTED) { 4363 String msg = "Permission Denial: crashApplication() from pid=" 4364 + Binder.getCallingPid() 4365 + ", uid=" + Binder.getCallingUid() 4366 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4367 Slog.w(TAG, msg); 4368 throw new SecurityException(msg); 4369 } 4370 4371 synchronized(this) { 4372 ProcessRecord proc = null; 4373 4374 // Figure out which process to kill. We don't trust that initialPid 4375 // still has any relation to current pids, so must scan through the 4376 // list. 4377 synchronized (mPidsSelfLocked) { 4378 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4379 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4380 if (p.uid != uid) { 4381 continue; 4382 } 4383 if (p.pid == initialPid) { 4384 proc = p; 4385 break; 4386 } 4387 if (p.pkgList.containsKey(packageName)) { 4388 proc = p; 4389 } 4390 } 4391 } 4392 4393 if (proc == null) { 4394 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4395 + " initialPid=" + initialPid 4396 + " packageName=" + packageName); 4397 return; 4398 } 4399 4400 if (proc.thread != null) { 4401 if (proc.pid == Process.myPid()) { 4402 Log.w(TAG, "crashApplication: trying to crash self!"); 4403 return; 4404 } 4405 long ident = Binder.clearCallingIdentity(); 4406 try { 4407 proc.thread.scheduleCrash(message); 4408 } catch (RemoteException e) { 4409 } 4410 Binder.restoreCallingIdentity(ident); 4411 } 4412 } 4413 } 4414 4415 @Override 4416 public final void finishSubActivity(IBinder token, String resultWho, 4417 int requestCode) { 4418 synchronized(this) { 4419 final long origId = Binder.clearCallingIdentity(); 4420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4421 if (r != null) { 4422 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4423 } 4424 Binder.restoreCallingIdentity(origId); 4425 } 4426 } 4427 4428 @Override 4429 public boolean finishActivityAffinity(IBinder token) { 4430 synchronized(this) { 4431 final long origId = Binder.clearCallingIdentity(); 4432 try { 4433 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4434 4435 ActivityRecord rootR = r.task.getRootActivity(); 4436 // Do not allow task to finish in Lock Task mode. 4437 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4438 if (rootR == r) { 4439 mStackSupervisor.showLockTaskToast(); 4440 return false; 4441 } 4442 } 4443 boolean res = false; 4444 if (r != null) { 4445 res = r.task.stack.finishActivityAffinityLocked(r); 4446 } 4447 return res; 4448 } finally { 4449 Binder.restoreCallingIdentity(origId); 4450 } 4451 } 4452 } 4453 4454 @Override 4455 public void finishVoiceTask(IVoiceInteractionSession session) { 4456 synchronized(this) { 4457 final long origId = Binder.clearCallingIdentity(); 4458 try { 4459 mStackSupervisor.finishVoiceTask(session); 4460 } finally { 4461 Binder.restoreCallingIdentity(origId); 4462 } 4463 } 4464 4465 } 4466 4467 @Override 4468 public boolean releaseActivityInstance(IBinder token) { 4469 synchronized(this) { 4470 final long origId = Binder.clearCallingIdentity(); 4471 try { 4472 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4473 if (r.task == null || r.task.stack == null) { 4474 return false; 4475 } 4476 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4477 } finally { 4478 Binder.restoreCallingIdentity(origId); 4479 } 4480 } 4481 } 4482 4483 @Override 4484 public void releaseSomeActivities(IApplicationThread appInt) { 4485 synchronized(this) { 4486 final long origId = Binder.clearCallingIdentity(); 4487 try { 4488 ProcessRecord app = getRecordForAppLocked(appInt); 4489 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4490 } finally { 4491 Binder.restoreCallingIdentity(origId); 4492 } 4493 } 4494 } 4495 4496 @Override 4497 public boolean willActivityBeVisible(IBinder token) { 4498 synchronized(this) { 4499 ActivityStack stack = ActivityRecord.getStackLocked(token); 4500 if (stack != null) { 4501 return stack.willActivityBeVisibleLocked(token); 4502 } 4503 return false; 4504 } 4505 } 4506 4507 @Override 4508 public void overridePendingTransition(IBinder token, String packageName, 4509 int enterAnim, int exitAnim) { 4510 synchronized(this) { 4511 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4512 if (self == null) { 4513 return; 4514 } 4515 4516 final long origId = Binder.clearCallingIdentity(); 4517 4518 if (self.state == ActivityState.RESUMED 4519 || self.state == ActivityState.PAUSING) { 4520 mWindowManager.overridePendingAppTransition(packageName, 4521 enterAnim, exitAnim, null); 4522 } 4523 4524 Binder.restoreCallingIdentity(origId); 4525 } 4526 } 4527 4528 /** 4529 * Main function for removing an existing process from the activity manager 4530 * as a result of that process going away. Clears out all connections 4531 * to the process. 4532 */ 4533 private final void handleAppDiedLocked(ProcessRecord app, 4534 boolean restarting, boolean allowRestart) { 4535 int pid = app.pid; 4536 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4537 if (!kept && !restarting) { 4538 removeLruProcessLocked(app); 4539 if (pid > 0) { 4540 ProcessList.remove(pid); 4541 } 4542 } 4543 4544 if (mProfileProc == app) { 4545 clearProfilerLocked(); 4546 } 4547 4548 // Remove this application's activities from active lists. 4549 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4550 4551 app.activities.clear(); 4552 4553 if (app.instrumentationClass != null) { 4554 Slog.w(TAG, "Crash of app " + app.processName 4555 + " running instrumentation " + app.instrumentationClass); 4556 Bundle info = new Bundle(); 4557 info.putString("shortMsg", "Process crashed."); 4558 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4559 } 4560 4561 if (!restarting) { 4562 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4563 // If there was nothing to resume, and we are not already 4564 // restarting this process, but there is a visible activity that 4565 // is hosted by the process... then make sure all visible 4566 // activities are running, taking care of restarting this 4567 // process. 4568 if (hasVisibleActivities) { 4569 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4570 } 4571 } 4572 } 4573 } 4574 4575 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4576 IBinder threadBinder = thread.asBinder(); 4577 // Find the application record. 4578 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4579 ProcessRecord rec = mLruProcesses.get(i); 4580 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4581 return i; 4582 } 4583 } 4584 return -1; 4585 } 4586 4587 final ProcessRecord getRecordForAppLocked( 4588 IApplicationThread thread) { 4589 if (thread == null) { 4590 return null; 4591 } 4592 4593 int appIndex = getLRURecordIndexForAppLocked(thread); 4594 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4595 } 4596 4597 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4598 // If there are no longer any background processes running, 4599 // and the app that died was not running instrumentation, 4600 // then tell everyone we are now low on memory. 4601 boolean haveBg = false; 4602 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4603 ProcessRecord rec = mLruProcesses.get(i); 4604 if (rec.thread != null 4605 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4606 haveBg = true; 4607 break; 4608 } 4609 } 4610 4611 if (!haveBg) { 4612 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4613 if (doReport) { 4614 long now = SystemClock.uptimeMillis(); 4615 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4616 doReport = false; 4617 } else { 4618 mLastMemUsageReportTime = now; 4619 } 4620 } 4621 final ArrayList<ProcessMemInfo> memInfos 4622 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4623 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4624 long now = SystemClock.uptimeMillis(); 4625 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4626 ProcessRecord rec = mLruProcesses.get(i); 4627 if (rec == dyingProc || rec.thread == null) { 4628 continue; 4629 } 4630 if (doReport) { 4631 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4632 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4633 } 4634 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4635 // The low memory report is overriding any current 4636 // state for a GC request. Make sure to do 4637 // heavy/important/visible/foreground processes first. 4638 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4639 rec.lastRequestedGc = 0; 4640 } else { 4641 rec.lastRequestedGc = rec.lastLowMemory; 4642 } 4643 rec.reportLowMemory = true; 4644 rec.lastLowMemory = now; 4645 mProcessesToGc.remove(rec); 4646 addProcessToGcListLocked(rec); 4647 } 4648 } 4649 if (doReport) { 4650 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4651 mHandler.sendMessage(msg); 4652 } 4653 scheduleAppGcsLocked(); 4654 } 4655 } 4656 4657 final void appDiedLocked(ProcessRecord app) { 4658 appDiedLocked(app, app.pid, app.thread); 4659 } 4660 4661 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4662 // First check if this ProcessRecord is actually active for the pid. 4663 synchronized (mPidsSelfLocked) { 4664 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4665 if (curProc != app) { 4666 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4667 return; 4668 } 4669 } 4670 4671 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4672 synchronized (stats) { 4673 stats.noteProcessDiedLocked(app.info.uid, pid); 4674 } 4675 4676 Process.killProcessQuiet(pid); 4677 Process.killProcessGroup(app.info.uid, pid); 4678 app.killed = true; 4679 4680 // Clean up already done if the process has been re-started. 4681 if (app.pid == pid && app.thread != null && 4682 app.thread.asBinder() == thread.asBinder()) { 4683 boolean doLowMem = app.instrumentationClass == null; 4684 boolean doOomAdj = doLowMem; 4685 if (!app.killedByAm) { 4686 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4687 + ") has died"); 4688 mAllowLowerMemLevel = true; 4689 } else { 4690 // Note that we always want to do oom adj to update our state with the 4691 // new number of procs. 4692 mAllowLowerMemLevel = false; 4693 doLowMem = false; 4694 } 4695 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4696 if (DEBUG_CLEANUP) Slog.v( 4697 TAG, "Dying app: " + app + ", pid: " + pid 4698 + ", thread: " + thread.asBinder()); 4699 handleAppDiedLocked(app, false, true); 4700 4701 if (doOomAdj) { 4702 updateOomAdjLocked(); 4703 } 4704 if (doLowMem) { 4705 doLowMemReportIfNeededLocked(app); 4706 } 4707 } else if (app.pid != pid) { 4708 // A new process has already been started. 4709 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4710 + ") has died and restarted (pid " + app.pid + ")."); 4711 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4712 } else if (DEBUG_PROCESSES) { 4713 Slog.d(TAG, "Received spurious death notification for thread " 4714 + thread.asBinder()); 4715 } 4716 } 4717 4718 /** 4719 * If a stack trace dump file is configured, dump process stack traces. 4720 * @param clearTraces causes the dump file to be erased prior to the new 4721 * traces being written, if true; when false, the new traces will be 4722 * appended to any existing file content. 4723 * @param firstPids of dalvik VM processes to dump stack traces for first 4724 * @param lastPids of dalvik VM processes to dump stack traces for last 4725 * @param nativeProcs optional list of native process names to dump stack crawls 4726 * @return file containing stack traces, or null if no dump file is configured 4727 */ 4728 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4729 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4730 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4731 if (tracesPath == null || tracesPath.length() == 0) { 4732 return null; 4733 } 4734 4735 File tracesFile = new File(tracesPath); 4736 try { 4737 File tracesDir = tracesFile.getParentFile(); 4738 if (!tracesDir.exists()) { 4739 tracesDir.mkdirs(); 4740 if (!SELinux.restorecon(tracesDir)) { 4741 return null; 4742 } 4743 } 4744 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4745 4746 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4747 tracesFile.createNewFile(); 4748 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4749 } catch (IOException e) { 4750 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4751 return null; 4752 } 4753 4754 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4755 return tracesFile; 4756 } 4757 4758 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4759 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4760 // Use a FileObserver to detect when traces finish writing. 4761 // The order of traces is considered important to maintain for legibility. 4762 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4763 @Override 4764 public synchronized void onEvent(int event, String path) { notify(); } 4765 }; 4766 4767 try { 4768 observer.startWatching(); 4769 4770 // First collect all of the stacks of the most important pids. 4771 if (firstPids != null) { 4772 try { 4773 int num = firstPids.size(); 4774 for (int i = 0; i < num; i++) { 4775 synchronized (observer) { 4776 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4777 observer.wait(200); // Wait for write-close, give up after 200msec 4778 } 4779 } 4780 } catch (InterruptedException e) { 4781 Slog.wtf(TAG, e); 4782 } 4783 } 4784 4785 // Next collect the stacks of the native pids 4786 if (nativeProcs != null) { 4787 int[] pids = Process.getPidsForCommands(nativeProcs); 4788 if (pids != null) { 4789 for (int pid : pids) { 4790 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4791 } 4792 } 4793 } 4794 4795 // Lastly, measure CPU usage. 4796 if (processCpuTracker != null) { 4797 processCpuTracker.init(); 4798 System.gc(); 4799 processCpuTracker.update(); 4800 try { 4801 synchronized (processCpuTracker) { 4802 processCpuTracker.wait(500); // measure over 1/2 second. 4803 } 4804 } catch (InterruptedException e) { 4805 } 4806 processCpuTracker.update(); 4807 4808 // We'll take the stack crawls of just the top apps using CPU. 4809 final int N = processCpuTracker.countWorkingStats(); 4810 int numProcs = 0; 4811 for (int i=0; i<N && numProcs<5; i++) { 4812 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4813 if (lastPids.indexOfKey(stats.pid) >= 0) { 4814 numProcs++; 4815 try { 4816 synchronized (observer) { 4817 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4818 observer.wait(200); // Wait for write-close, give up after 200msec 4819 } 4820 } catch (InterruptedException e) { 4821 Slog.wtf(TAG, e); 4822 } 4823 4824 } 4825 } 4826 } 4827 } finally { 4828 observer.stopWatching(); 4829 } 4830 } 4831 4832 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4833 if (true || IS_USER_BUILD) { 4834 return; 4835 } 4836 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4837 if (tracesPath == null || tracesPath.length() == 0) { 4838 return; 4839 } 4840 4841 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4842 StrictMode.allowThreadDiskWrites(); 4843 try { 4844 final File tracesFile = new File(tracesPath); 4845 final File tracesDir = tracesFile.getParentFile(); 4846 final File tracesTmp = new File(tracesDir, "__tmp__"); 4847 try { 4848 if (!tracesDir.exists()) { 4849 tracesDir.mkdirs(); 4850 if (!SELinux.restorecon(tracesDir.getPath())) { 4851 return; 4852 } 4853 } 4854 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4855 4856 if (tracesFile.exists()) { 4857 tracesTmp.delete(); 4858 tracesFile.renameTo(tracesTmp); 4859 } 4860 StringBuilder sb = new StringBuilder(); 4861 Time tobj = new Time(); 4862 tobj.set(System.currentTimeMillis()); 4863 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4864 sb.append(": "); 4865 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4866 sb.append(" since "); 4867 sb.append(msg); 4868 FileOutputStream fos = new FileOutputStream(tracesFile); 4869 fos.write(sb.toString().getBytes()); 4870 if (app == null) { 4871 fos.write("\n*** No application process!".getBytes()); 4872 } 4873 fos.close(); 4874 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4875 } catch (IOException e) { 4876 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4877 return; 4878 } 4879 4880 if (app != null) { 4881 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4882 firstPids.add(app.pid); 4883 dumpStackTraces(tracesPath, firstPids, null, null, null); 4884 } 4885 4886 File lastTracesFile = null; 4887 File curTracesFile = null; 4888 for (int i=9; i>=0; i--) { 4889 String name = String.format(Locale.US, "slow%02d.txt", i); 4890 curTracesFile = new File(tracesDir, name); 4891 if (curTracesFile.exists()) { 4892 if (lastTracesFile != null) { 4893 curTracesFile.renameTo(lastTracesFile); 4894 } else { 4895 curTracesFile.delete(); 4896 } 4897 } 4898 lastTracesFile = curTracesFile; 4899 } 4900 tracesFile.renameTo(curTracesFile); 4901 if (tracesTmp.exists()) { 4902 tracesTmp.renameTo(tracesFile); 4903 } 4904 } finally { 4905 StrictMode.setThreadPolicy(oldPolicy); 4906 } 4907 } 4908 4909 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4910 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4911 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4912 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4913 4914 if (mController != null) { 4915 try { 4916 // 0 == continue, -1 = kill process immediately 4917 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4918 if (res < 0 && app.pid != MY_PID) { 4919 app.kill("anr", true); 4920 } 4921 } catch (RemoteException e) { 4922 mController = null; 4923 Watchdog.getInstance().setActivityController(null); 4924 } 4925 } 4926 4927 long anrTime = SystemClock.uptimeMillis(); 4928 if (MONITOR_CPU_USAGE) { 4929 updateCpuStatsNow(); 4930 } 4931 4932 synchronized (this) { 4933 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4934 if (mShuttingDown) { 4935 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4936 return; 4937 } else if (app.notResponding) { 4938 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4939 return; 4940 } else if (app.crashing) { 4941 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4942 return; 4943 } 4944 4945 // In case we come through here for the same app before completing 4946 // this one, mark as anring now so we will bail out. 4947 app.notResponding = true; 4948 4949 // Log the ANR to the event log. 4950 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4951 app.processName, app.info.flags, annotation); 4952 4953 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4954 firstPids.add(app.pid); 4955 4956 int parentPid = app.pid; 4957 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4958 if (parentPid != app.pid) firstPids.add(parentPid); 4959 4960 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4961 4962 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4963 ProcessRecord r = mLruProcesses.get(i); 4964 if (r != null && r.thread != null) { 4965 int pid = r.pid; 4966 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4967 if (r.persistent) { 4968 firstPids.add(pid); 4969 } else { 4970 lastPids.put(pid, Boolean.TRUE); 4971 } 4972 } 4973 } 4974 } 4975 } 4976 4977 // Log the ANR to the main log. 4978 StringBuilder info = new StringBuilder(); 4979 info.setLength(0); 4980 info.append("ANR in ").append(app.processName); 4981 if (activity != null && activity.shortComponentName != null) { 4982 info.append(" (").append(activity.shortComponentName).append(")"); 4983 } 4984 info.append("\n"); 4985 info.append("PID: ").append(app.pid).append("\n"); 4986 if (annotation != null) { 4987 info.append("Reason: ").append(annotation).append("\n"); 4988 } 4989 if (parent != null && parent != activity) { 4990 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4991 } 4992 4993 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4994 4995 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4996 NATIVE_STACKS_OF_INTEREST); 4997 4998 String cpuInfo = null; 4999 if (MONITOR_CPU_USAGE) { 5000 updateCpuStatsNow(); 5001 synchronized (mProcessCpuTracker) { 5002 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5003 } 5004 info.append(processCpuTracker.printCurrentLoad()); 5005 info.append(cpuInfo); 5006 } 5007 5008 info.append(processCpuTracker.printCurrentState(anrTime)); 5009 5010 Slog.e(TAG, info.toString()); 5011 if (tracesFile == null) { 5012 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5013 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5014 } 5015 5016 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5017 cpuInfo, tracesFile, null); 5018 5019 if (mController != null) { 5020 try { 5021 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5022 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5023 if (res != 0) { 5024 if (res < 0 && app.pid != MY_PID) { 5025 app.kill("anr", true); 5026 } else { 5027 synchronized (this) { 5028 mServices.scheduleServiceTimeoutLocked(app); 5029 } 5030 } 5031 return; 5032 } 5033 } catch (RemoteException e) { 5034 mController = null; 5035 Watchdog.getInstance().setActivityController(null); 5036 } 5037 } 5038 5039 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5040 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5041 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5042 5043 synchronized (this) { 5044 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5045 app.kill("bg anr", true); 5046 return; 5047 } 5048 5049 // Set the app's notResponding state, and look up the errorReportReceiver 5050 makeAppNotRespondingLocked(app, 5051 activity != null ? activity.shortComponentName : null, 5052 annotation != null ? "ANR " + annotation : "ANR", 5053 info.toString()); 5054 5055 // Bring up the infamous App Not Responding dialog 5056 Message msg = Message.obtain(); 5057 HashMap<String, Object> map = new HashMap<String, Object>(); 5058 msg.what = SHOW_NOT_RESPONDING_MSG; 5059 msg.obj = map; 5060 msg.arg1 = aboveSystem ? 1 : 0; 5061 map.put("app", app); 5062 if (activity != null) { 5063 map.put("activity", activity); 5064 } 5065 5066 mHandler.sendMessage(msg); 5067 } 5068 } 5069 5070 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5071 if (!mLaunchWarningShown) { 5072 mLaunchWarningShown = true; 5073 mHandler.post(new Runnable() { 5074 @Override 5075 public void run() { 5076 synchronized (ActivityManagerService.this) { 5077 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5078 d.show(); 5079 mHandler.postDelayed(new Runnable() { 5080 @Override 5081 public void run() { 5082 synchronized (ActivityManagerService.this) { 5083 d.dismiss(); 5084 mLaunchWarningShown = false; 5085 } 5086 } 5087 }, 4000); 5088 } 5089 } 5090 }); 5091 } 5092 } 5093 5094 @Override 5095 public boolean clearApplicationUserData(final String packageName, 5096 final IPackageDataObserver observer, int userId) { 5097 enforceNotIsolatedCaller("clearApplicationUserData"); 5098 int uid = Binder.getCallingUid(); 5099 int pid = Binder.getCallingPid(); 5100 userId = handleIncomingUser(pid, uid, 5101 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5102 long callingId = Binder.clearCallingIdentity(); 5103 try { 5104 IPackageManager pm = AppGlobals.getPackageManager(); 5105 int pkgUid = -1; 5106 synchronized(this) { 5107 try { 5108 pkgUid = pm.getPackageUid(packageName, userId); 5109 } catch (RemoteException e) { 5110 } 5111 if (pkgUid == -1) { 5112 Slog.w(TAG, "Invalid packageName: " + packageName); 5113 if (observer != null) { 5114 try { 5115 observer.onRemoveCompleted(packageName, false); 5116 } catch (RemoteException e) { 5117 Slog.i(TAG, "Observer no longer exists."); 5118 } 5119 } 5120 return false; 5121 } 5122 if (uid == pkgUid || checkComponentPermission( 5123 android.Manifest.permission.CLEAR_APP_USER_DATA, 5124 pid, uid, -1, true) 5125 == PackageManager.PERMISSION_GRANTED) { 5126 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5127 } else { 5128 throw new SecurityException("PID " + pid + " does not have permission " 5129 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5130 + " of package " + packageName); 5131 } 5132 5133 // Remove all tasks match the cleared application package and user 5134 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5135 final TaskRecord tr = mRecentTasks.get(i); 5136 final String taskPackageName = 5137 tr.getBaseIntent().getComponent().getPackageName(); 5138 if (tr.userId != userId) continue; 5139 if (!taskPackageName.equals(packageName)) continue; 5140 removeTaskByIdLocked(tr.taskId, false); 5141 } 5142 } 5143 5144 try { 5145 // Clear application user data 5146 pm.clearApplicationUserData(packageName, observer, userId); 5147 5148 synchronized(this) { 5149 // Remove all permissions granted from/to this package 5150 removeUriPermissionsForPackageLocked(packageName, userId, true); 5151 } 5152 5153 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5154 Uri.fromParts("package", packageName, null)); 5155 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5156 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5157 null, null, 0, null, null, null, false, false, userId); 5158 } catch (RemoteException e) { 5159 } 5160 } finally { 5161 Binder.restoreCallingIdentity(callingId); 5162 } 5163 return true; 5164 } 5165 5166 @Override 5167 public void killBackgroundProcesses(final String packageName, int userId) { 5168 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5169 != PackageManager.PERMISSION_GRANTED && 5170 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5171 != PackageManager.PERMISSION_GRANTED) { 5172 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5173 + Binder.getCallingPid() 5174 + ", uid=" + Binder.getCallingUid() 5175 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5176 Slog.w(TAG, msg); 5177 throw new SecurityException(msg); 5178 } 5179 5180 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5181 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5182 long callingId = Binder.clearCallingIdentity(); 5183 try { 5184 IPackageManager pm = AppGlobals.getPackageManager(); 5185 synchronized(this) { 5186 int appId = -1; 5187 try { 5188 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5189 } catch (RemoteException e) { 5190 } 5191 if (appId == -1) { 5192 Slog.w(TAG, "Invalid packageName: " + packageName); 5193 return; 5194 } 5195 killPackageProcessesLocked(packageName, appId, userId, 5196 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5197 } 5198 } finally { 5199 Binder.restoreCallingIdentity(callingId); 5200 } 5201 } 5202 5203 @Override 5204 public void killAllBackgroundProcesses() { 5205 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5206 != PackageManager.PERMISSION_GRANTED) { 5207 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5208 + Binder.getCallingPid() 5209 + ", uid=" + Binder.getCallingUid() 5210 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5211 Slog.w(TAG, msg); 5212 throw new SecurityException(msg); 5213 } 5214 5215 long callingId = Binder.clearCallingIdentity(); 5216 try { 5217 synchronized(this) { 5218 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5219 final int NP = mProcessNames.getMap().size(); 5220 for (int ip=0; ip<NP; ip++) { 5221 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5222 final int NA = apps.size(); 5223 for (int ia=0; ia<NA; ia++) { 5224 ProcessRecord app = apps.valueAt(ia); 5225 if (app.persistent) { 5226 // we don't kill persistent processes 5227 continue; 5228 } 5229 if (app.removed) { 5230 procs.add(app); 5231 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5232 app.removed = true; 5233 procs.add(app); 5234 } 5235 } 5236 } 5237 5238 int N = procs.size(); 5239 for (int i=0; i<N; i++) { 5240 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5241 } 5242 mAllowLowerMemLevel = true; 5243 updateOomAdjLocked(); 5244 doLowMemReportIfNeededLocked(null); 5245 } 5246 } finally { 5247 Binder.restoreCallingIdentity(callingId); 5248 } 5249 } 5250 5251 @Override 5252 public void forceStopPackage(final String packageName, int userId) { 5253 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5254 != PackageManager.PERMISSION_GRANTED) { 5255 String msg = "Permission Denial: forceStopPackage() from pid=" 5256 + Binder.getCallingPid() 5257 + ", uid=" + Binder.getCallingUid() 5258 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5259 Slog.w(TAG, msg); 5260 throw new SecurityException(msg); 5261 } 5262 final int callingPid = Binder.getCallingPid(); 5263 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5264 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5265 long callingId = Binder.clearCallingIdentity(); 5266 try { 5267 IPackageManager pm = AppGlobals.getPackageManager(); 5268 synchronized(this) { 5269 int[] users = userId == UserHandle.USER_ALL 5270 ? getUsersLocked() : new int[] { userId }; 5271 for (int user : users) { 5272 int pkgUid = -1; 5273 try { 5274 pkgUid = pm.getPackageUid(packageName, user); 5275 } catch (RemoteException e) { 5276 } 5277 if (pkgUid == -1) { 5278 Slog.w(TAG, "Invalid packageName: " + packageName); 5279 continue; 5280 } 5281 try { 5282 pm.setPackageStoppedState(packageName, true, user); 5283 } catch (RemoteException e) { 5284 } catch (IllegalArgumentException e) { 5285 Slog.w(TAG, "Failed trying to unstop package " 5286 + packageName + ": " + e); 5287 } 5288 if (isUserRunningLocked(user, false)) { 5289 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5290 } 5291 } 5292 } 5293 } finally { 5294 Binder.restoreCallingIdentity(callingId); 5295 } 5296 } 5297 5298 @Override 5299 public void addPackageDependency(String packageName) { 5300 synchronized (this) { 5301 int callingPid = Binder.getCallingPid(); 5302 if (callingPid == Process.myPid()) { 5303 // Yeah, um, no. 5304 Slog.w(TAG, "Can't addPackageDependency on system process"); 5305 return; 5306 } 5307 ProcessRecord proc; 5308 synchronized (mPidsSelfLocked) { 5309 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5310 } 5311 if (proc != null) { 5312 if (proc.pkgDeps == null) { 5313 proc.pkgDeps = new ArraySet<String>(1); 5314 } 5315 proc.pkgDeps.add(packageName); 5316 } 5317 } 5318 } 5319 5320 /* 5321 * The pkg name and app id have to be specified. 5322 */ 5323 @Override 5324 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5325 if (pkg == null) { 5326 return; 5327 } 5328 // Make sure the uid is valid. 5329 if (appid < 0) { 5330 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5331 return; 5332 } 5333 int callerUid = Binder.getCallingUid(); 5334 // Only the system server can kill an application 5335 if (callerUid == Process.SYSTEM_UID) { 5336 // Post an aysnc message to kill the application 5337 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5338 msg.arg1 = appid; 5339 msg.arg2 = 0; 5340 Bundle bundle = new Bundle(); 5341 bundle.putString("pkg", pkg); 5342 bundle.putString("reason", reason); 5343 msg.obj = bundle; 5344 mHandler.sendMessage(msg); 5345 } else { 5346 throw new SecurityException(callerUid + " cannot kill pkg: " + 5347 pkg); 5348 } 5349 } 5350 5351 @Override 5352 public void closeSystemDialogs(String reason) { 5353 enforceNotIsolatedCaller("closeSystemDialogs"); 5354 5355 final int pid = Binder.getCallingPid(); 5356 final int uid = Binder.getCallingUid(); 5357 final long origId = Binder.clearCallingIdentity(); 5358 try { 5359 synchronized (this) { 5360 // Only allow this from foreground processes, so that background 5361 // applications can't abuse it to prevent system UI from being shown. 5362 if (uid >= Process.FIRST_APPLICATION_UID) { 5363 ProcessRecord proc; 5364 synchronized (mPidsSelfLocked) { 5365 proc = mPidsSelfLocked.get(pid); 5366 } 5367 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5368 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5369 + " from background process " + proc); 5370 return; 5371 } 5372 } 5373 closeSystemDialogsLocked(reason); 5374 } 5375 } finally { 5376 Binder.restoreCallingIdentity(origId); 5377 } 5378 } 5379 5380 void closeSystemDialogsLocked(String reason) { 5381 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5382 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5383 | Intent.FLAG_RECEIVER_FOREGROUND); 5384 if (reason != null) { 5385 intent.putExtra("reason", reason); 5386 } 5387 mWindowManager.closeSystemDialogs(reason); 5388 5389 mStackSupervisor.closeSystemDialogsLocked(); 5390 5391 broadcastIntentLocked(null, null, intent, null, 5392 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5393 Process.SYSTEM_UID, UserHandle.USER_ALL); 5394 } 5395 5396 @Override 5397 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5398 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5399 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5400 for (int i=pids.length-1; i>=0; i--) { 5401 ProcessRecord proc; 5402 int oomAdj; 5403 synchronized (this) { 5404 synchronized (mPidsSelfLocked) { 5405 proc = mPidsSelfLocked.get(pids[i]); 5406 oomAdj = proc != null ? proc.setAdj : 0; 5407 } 5408 } 5409 infos[i] = new Debug.MemoryInfo(); 5410 Debug.getMemoryInfo(pids[i], infos[i]); 5411 if (proc != null) { 5412 synchronized (this) { 5413 if (proc.thread != null && proc.setAdj == oomAdj) { 5414 // Record this for posterity if the process has been stable. 5415 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5416 infos[i].getTotalUss(), false, proc.pkgList); 5417 } 5418 } 5419 } 5420 } 5421 return infos; 5422 } 5423 5424 @Override 5425 public long[] getProcessPss(int[] pids) { 5426 enforceNotIsolatedCaller("getProcessPss"); 5427 long[] pss = new long[pids.length]; 5428 for (int i=pids.length-1; i>=0; i--) { 5429 ProcessRecord proc; 5430 int oomAdj; 5431 synchronized (this) { 5432 synchronized (mPidsSelfLocked) { 5433 proc = mPidsSelfLocked.get(pids[i]); 5434 oomAdj = proc != null ? proc.setAdj : 0; 5435 } 5436 } 5437 long[] tmpUss = new long[1]; 5438 pss[i] = Debug.getPss(pids[i], tmpUss); 5439 if (proc != null) { 5440 synchronized (this) { 5441 if (proc.thread != null && proc.setAdj == oomAdj) { 5442 // Record this for posterity if the process has been stable. 5443 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5444 } 5445 } 5446 } 5447 } 5448 return pss; 5449 } 5450 5451 @Override 5452 public void killApplicationProcess(String processName, int uid) { 5453 if (processName == null) { 5454 return; 5455 } 5456 5457 int callerUid = Binder.getCallingUid(); 5458 // Only the system server can kill an application 5459 if (callerUid == Process.SYSTEM_UID) { 5460 synchronized (this) { 5461 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5462 if (app != null && app.thread != null) { 5463 try { 5464 app.thread.scheduleSuicide(); 5465 } catch (RemoteException e) { 5466 // If the other end already died, then our work here is done. 5467 } 5468 } else { 5469 Slog.w(TAG, "Process/uid not found attempting kill of " 5470 + processName + " / " + uid); 5471 } 5472 } 5473 } else { 5474 throw new SecurityException(callerUid + " cannot kill app process: " + 5475 processName); 5476 } 5477 } 5478 5479 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5480 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5481 false, true, false, false, UserHandle.getUserId(uid), reason); 5482 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5483 Uri.fromParts("package", packageName, null)); 5484 if (!mProcessesReady) { 5485 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5486 | Intent.FLAG_RECEIVER_FOREGROUND); 5487 } 5488 intent.putExtra(Intent.EXTRA_UID, uid); 5489 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5490 broadcastIntentLocked(null, null, intent, 5491 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5492 false, false, 5493 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5494 } 5495 5496 private void forceStopUserLocked(int userId, String reason) { 5497 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5498 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5499 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5500 | Intent.FLAG_RECEIVER_FOREGROUND); 5501 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5502 broadcastIntentLocked(null, null, intent, 5503 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5504 false, false, 5505 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5506 } 5507 5508 private final boolean killPackageProcessesLocked(String packageName, int appId, 5509 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5510 boolean doit, boolean evenPersistent, String reason) { 5511 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5512 5513 // Remove all processes this package may have touched: all with the 5514 // same UID (except for the system or root user), and all whose name 5515 // matches the package name. 5516 final int NP = mProcessNames.getMap().size(); 5517 for (int ip=0; ip<NP; ip++) { 5518 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5519 final int NA = apps.size(); 5520 for (int ia=0; ia<NA; ia++) { 5521 ProcessRecord app = apps.valueAt(ia); 5522 if (app.persistent && !evenPersistent) { 5523 // we don't kill persistent processes 5524 continue; 5525 } 5526 if (app.removed) { 5527 if (doit) { 5528 procs.add(app); 5529 } 5530 continue; 5531 } 5532 5533 // Skip process if it doesn't meet our oom adj requirement. 5534 if (app.setAdj < minOomAdj) { 5535 continue; 5536 } 5537 5538 // If no package is specified, we call all processes under the 5539 // give user id. 5540 if (packageName == null) { 5541 if (app.userId != userId) { 5542 continue; 5543 } 5544 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5545 continue; 5546 } 5547 // Package has been specified, we want to hit all processes 5548 // that match it. We need to qualify this by the processes 5549 // that are running under the specified app and user ID. 5550 } else { 5551 final boolean isDep = app.pkgDeps != null 5552 && app.pkgDeps.contains(packageName); 5553 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5554 continue; 5555 } 5556 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5557 continue; 5558 } 5559 if (!app.pkgList.containsKey(packageName) && !isDep) { 5560 continue; 5561 } 5562 } 5563 5564 // Process has passed all conditions, kill it! 5565 if (!doit) { 5566 return true; 5567 } 5568 app.removed = true; 5569 procs.add(app); 5570 } 5571 } 5572 5573 int N = procs.size(); 5574 for (int i=0; i<N; i++) { 5575 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5576 } 5577 updateOomAdjLocked(); 5578 return N > 0; 5579 } 5580 5581 private final boolean forceStopPackageLocked(String name, int appId, 5582 boolean callerWillRestart, boolean purgeCache, boolean doit, 5583 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5584 int i; 5585 int N; 5586 5587 if (userId == UserHandle.USER_ALL && name == null) { 5588 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5589 } 5590 5591 if (appId < 0 && name != null) { 5592 try { 5593 appId = UserHandle.getAppId( 5594 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5595 } catch (RemoteException e) { 5596 } 5597 } 5598 5599 if (doit) { 5600 if (name != null) { 5601 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5602 + " user=" + userId + ": " + reason); 5603 } else { 5604 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5605 } 5606 5607 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5608 for (int ip=pmap.size()-1; ip>=0; ip--) { 5609 SparseArray<Long> ba = pmap.valueAt(ip); 5610 for (i=ba.size()-1; i>=0; i--) { 5611 boolean remove = false; 5612 final int entUid = ba.keyAt(i); 5613 if (name != null) { 5614 if (userId == UserHandle.USER_ALL) { 5615 if (UserHandle.getAppId(entUid) == appId) { 5616 remove = true; 5617 } 5618 } else { 5619 if (entUid == UserHandle.getUid(userId, appId)) { 5620 remove = true; 5621 } 5622 } 5623 } else if (UserHandle.getUserId(entUid) == userId) { 5624 remove = true; 5625 } 5626 if (remove) { 5627 ba.removeAt(i); 5628 } 5629 } 5630 if (ba.size() == 0) { 5631 pmap.removeAt(ip); 5632 } 5633 } 5634 } 5635 5636 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5637 -100, callerWillRestart, true, doit, evenPersistent, 5638 name == null ? ("stop user " + userId) : ("stop " + name)); 5639 5640 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5641 if (!doit) { 5642 return true; 5643 } 5644 didSomething = true; 5645 } 5646 5647 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5648 if (!doit) { 5649 return true; 5650 } 5651 didSomething = true; 5652 } 5653 5654 if (name == null) { 5655 // Remove all sticky broadcasts from this user. 5656 mStickyBroadcasts.remove(userId); 5657 } 5658 5659 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5660 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5661 userId, providers)) { 5662 if (!doit) { 5663 return true; 5664 } 5665 didSomething = true; 5666 } 5667 N = providers.size(); 5668 for (i=0; i<N; i++) { 5669 removeDyingProviderLocked(null, providers.get(i), true); 5670 } 5671 5672 // Remove transient permissions granted from/to this package/user 5673 removeUriPermissionsForPackageLocked(name, userId, false); 5674 5675 if (name == null || uninstalling) { 5676 // Remove pending intents. For now we only do this when force 5677 // stopping users, because we have some problems when doing this 5678 // for packages -- app widgets are not currently cleaned up for 5679 // such packages, so they can be left with bad pending intents. 5680 if (mIntentSenderRecords.size() > 0) { 5681 Iterator<WeakReference<PendingIntentRecord>> it 5682 = mIntentSenderRecords.values().iterator(); 5683 while (it.hasNext()) { 5684 WeakReference<PendingIntentRecord> wpir = it.next(); 5685 if (wpir == null) { 5686 it.remove(); 5687 continue; 5688 } 5689 PendingIntentRecord pir = wpir.get(); 5690 if (pir == null) { 5691 it.remove(); 5692 continue; 5693 } 5694 if (name == null) { 5695 // Stopping user, remove all objects for the user. 5696 if (pir.key.userId != userId) { 5697 // Not the same user, skip it. 5698 continue; 5699 } 5700 } else { 5701 if (UserHandle.getAppId(pir.uid) != appId) { 5702 // Different app id, skip it. 5703 continue; 5704 } 5705 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5706 // Different user, skip it. 5707 continue; 5708 } 5709 if (!pir.key.packageName.equals(name)) { 5710 // Different package, skip it. 5711 continue; 5712 } 5713 } 5714 if (!doit) { 5715 return true; 5716 } 5717 didSomething = true; 5718 it.remove(); 5719 pir.canceled = true; 5720 if (pir.key.activity != null) { 5721 pir.key.activity.pendingResults.remove(pir.ref); 5722 } 5723 } 5724 } 5725 } 5726 5727 if (doit) { 5728 if (purgeCache && name != null) { 5729 AttributeCache ac = AttributeCache.instance(); 5730 if (ac != null) { 5731 ac.removePackage(name); 5732 } 5733 } 5734 if (mBooted) { 5735 mStackSupervisor.resumeTopActivitiesLocked(); 5736 mStackSupervisor.scheduleIdleLocked(); 5737 } 5738 } 5739 5740 return didSomething; 5741 } 5742 5743 private final boolean removeProcessLocked(ProcessRecord app, 5744 boolean callerWillRestart, boolean allowRestart, String reason) { 5745 final String name = app.processName; 5746 final int uid = app.uid; 5747 if (DEBUG_PROCESSES) Slog.d( 5748 TAG, "Force removing proc " + app.toShortString() + " (" + name 5749 + "/" + uid + ")"); 5750 5751 mProcessNames.remove(name, uid); 5752 mIsolatedProcesses.remove(app.uid); 5753 if (mHeavyWeightProcess == app) { 5754 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5755 mHeavyWeightProcess.userId, 0)); 5756 mHeavyWeightProcess = null; 5757 } 5758 boolean needRestart = false; 5759 if (app.pid > 0 && app.pid != MY_PID) { 5760 int pid = app.pid; 5761 synchronized (mPidsSelfLocked) { 5762 mPidsSelfLocked.remove(pid); 5763 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5764 } 5765 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5766 if (app.isolated) { 5767 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5768 } 5769 app.kill(reason, true); 5770 handleAppDiedLocked(app, true, allowRestart); 5771 removeLruProcessLocked(app); 5772 5773 if (app.persistent && !app.isolated) { 5774 if (!callerWillRestart) { 5775 addAppLocked(app.info, false, null /* ABI override */); 5776 } else { 5777 needRestart = true; 5778 } 5779 } 5780 } else { 5781 mRemovedProcesses.add(app); 5782 } 5783 5784 return needRestart; 5785 } 5786 5787 private final void processStartTimedOutLocked(ProcessRecord app) { 5788 final int pid = app.pid; 5789 boolean gone = false; 5790 synchronized (mPidsSelfLocked) { 5791 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5792 if (knownApp != null && knownApp.thread == null) { 5793 mPidsSelfLocked.remove(pid); 5794 gone = true; 5795 } 5796 } 5797 5798 if (gone) { 5799 Slog.w(TAG, "Process " + app + " failed to attach"); 5800 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5801 pid, app.uid, app.processName); 5802 mProcessNames.remove(app.processName, app.uid); 5803 mIsolatedProcesses.remove(app.uid); 5804 if (mHeavyWeightProcess == app) { 5805 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5806 mHeavyWeightProcess.userId, 0)); 5807 mHeavyWeightProcess = null; 5808 } 5809 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5810 if (app.isolated) { 5811 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5812 } 5813 // Take care of any launching providers waiting for this process. 5814 checkAppInLaunchingProvidersLocked(app, true); 5815 // Take care of any services that are waiting for the process. 5816 mServices.processStartTimedOutLocked(app); 5817 app.kill("start timeout", true); 5818 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5819 Slog.w(TAG, "Unattached app died before backup, skipping"); 5820 try { 5821 IBackupManager bm = IBackupManager.Stub.asInterface( 5822 ServiceManager.getService(Context.BACKUP_SERVICE)); 5823 bm.agentDisconnected(app.info.packageName); 5824 } catch (RemoteException e) { 5825 // Can't happen; the backup manager is local 5826 } 5827 } 5828 if (isPendingBroadcastProcessLocked(pid)) { 5829 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5830 skipPendingBroadcastLocked(pid); 5831 } 5832 } else { 5833 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5834 } 5835 } 5836 5837 private final boolean attachApplicationLocked(IApplicationThread thread, 5838 int pid) { 5839 5840 // Find the application record that is being attached... either via 5841 // the pid if we are running in multiple processes, or just pull the 5842 // next app record if we are emulating process with anonymous threads. 5843 ProcessRecord app; 5844 if (pid != MY_PID && pid >= 0) { 5845 synchronized (mPidsSelfLocked) { 5846 app = mPidsSelfLocked.get(pid); 5847 } 5848 } else { 5849 app = null; 5850 } 5851 5852 if (app == null) { 5853 Slog.w(TAG, "No pending application record for pid " + pid 5854 + " (IApplicationThread " + thread + "); dropping process"); 5855 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5856 if (pid > 0 && pid != MY_PID) { 5857 Process.killProcessQuiet(pid); 5858 //TODO: Process.killProcessGroup(app.info.uid, pid); 5859 } else { 5860 try { 5861 thread.scheduleExit(); 5862 } catch (Exception e) { 5863 // Ignore exceptions. 5864 } 5865 } 5866 return false; 5867 } 5868 5869 // If this application record is still attached to a previous 5870 // process, clean it up now. 5871 if (app.thread != null) { 5872 handleAppDiedLocked(app, true, true); 5873 } 5874 5875 // Tell the process all about itself. 5876 5877 if (localLOGV) Slog.v( 5878 TAG, "Binding process pid " + pid + " to record " + app); 5879 5880 final String processName = app.processName; 5881 try { 5882 AppDeathRecipient adr = new AppDeathRecipient( 5883 app, pid, thread); 5884 thread.asBinder().linkToDeath(adr, 0); 5885 app.deathRecipient = adr; 5886 } catch (RemoteException e) { 5887 app.resetPackageList(mProcessStats); 5888 startProcessLocked(app, "link fail", processName); 5889 return false; 5890 } 5891 5892 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5893 5894 app.makeActive(thread, mProcessStats); 5895 app.curAdj = app.setAdj = -100; 5896 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5897 app.forcingToForeground = null; 5898 updateProcessForegroundLocked(app, false, false); 5899 app.hasShownUi = false; 5900 app.debugging = false; 5901 app.cached = false; 5902 5903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5904 5905 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5906 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5907 5908 if (!normalMode) { 5909 Slog.i(TAG, "Launching preboot mode app: " + app); 5910 } 5911 5912 if (localLOGV) Slog.v( 5913 TAG, "New app record " + app 5914 + " thread=" + thread.asBinder() + " pid=" + pid); 5915 try { 5916 int testMode = IApplicationThread.DEBUG_OFF; 5917 if (mDebugApp != null && mDebugApp.equals(processName)) { 5918 testMode = mWaitForDebugger 5919 ? IApplicationThread.DEBUG_WAIT 5920 : IApplicationThread.DEBUG_ON; 5921 app.debugging = true; 5922 if (mDebugTransient) { 5923 mDebugApp = mOrigDebugApp; 5924 mWaitForDebugger = mOrigWaitForDebugger; 5925 } 5926 } 5927 String profileFile = app.instrumentationProfileFile; 5928 ParcelFileDescriptor profileFd = null; 5929 int samplingInterval = 0; 5930 boolean profileAutoStop = false; 5931 if (mProfileApp != null && mProfileApp.equals(processName)) { 5932 mProfileProc = app; 5933 profileFile = mProfileFile; 5934 profileFd = mProfileFd; 5935 samplingInterval = mSamplingInterval; 5936 profileAutoStop = mAutoStopProfiler; 5937 } 5938 boolean enableOpenGlTrace = false; 5939 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5940 enableOpenGlTrace = true; 5941 mOpenGlTraceApp = null; 5942 } 5943 5944 // If the app is being launched for restore or full backup, set it up specially 5945 boolean isRestrictedBackupMode = false; 5946 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5947 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5948 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5949 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5950 } 5951 5952 ensurePackageDexOpt(app.instrumentationInfo != null 5953 ? app.instrumentationInfo.packageName 5954 : app.info.packageName); 5955 if (app.instrumentationClass != null) { 5956 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5957 } 5958 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5959 + processName + " with config " + mConfiguration); 5960 ApplicationInfo appInfo = app.instrumentationInfo != null 5961 ? app.instrumentationInfo : app.info; 5962 app.compat = compatibilityInfoForPackageLocked(appInfo); 5963 if (profileFd != null) { 5964 profileFd = profileFd.dup(); 5965 } 5966 ProfilerInfo profilerInfo = profileFile == null ? null 5967 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5968 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5969 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5970 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5971 isRestrictedBackupMode || !normalMode, app.persistent, 5972 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5973 mCoreSettingsObserver.getCoreSettingsLocked()); 5974 updateLruProcessLocked(app, false, null); 5975 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5976 } catch (Exception e) { 5977 // todo: Yikes! What should we do? For now we will try to 5978 // start another process, but that could easily get us in 5979 // an infinite loop of restarting processes... 5980 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5981 5982 app.resetPackageList(mProcessStats); 5983 app.unlinkDeathRecipient(); 5984 startProcessLocked(app, "bind fail", processName); 5985 return false; 5986 } 5987 5988 // Remove this record from the list of starting applications. 5989 mPersistentStartingProcesses.remove(app); 5990 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5991 "Attach application locked removing on hold: " + app); 5992 mProcessesOnHold.remove(app); 5993 5994 boolean badApp = false; 5995 boolean didSomething = false; 5996 5997 // See if the top visible activity is waiting to run in this process... 5998 if (normalMode) { 5999 try { 6000 if (mStackSupervisor.attachApplicationLocked(app)) { 6001 didSomething = true; 6002 } 6003 } catch (Exception e) { 6004 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6005 badApp = true; 6006 } 6007 } 6008 6009 // Find any services that should be running in this process... 6010 if (!badApp) { 6011 try { 6012 didSomething |= mServices.attachApplicationLocked(app, processName); 6013 } catch (Exception e) { 6014 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6015 badApp = true; 6016 } 6017 } 6018 6019 // Check if a next-broadcast receiver is in this process... 6020 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6021 try { 6022 didSomething |= sendPendingBroadcastsLocked(app); 6023 } catch (Exception e) { 6024 // If the app died trying to launch the receiver we declare it 'bad' 6025 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6026 badApp = true; 6027 } 6028 } 6029 6030 // Check whether the next backup agent is in this process... 6031 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6032 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6033 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6034 try { 6035 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6036 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6037 mBackupTarget.backupMode); 6038 } catch (Exception e) { 6039 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6040 badApp = true; 6041 } 6042 } 6043 6044 if (badApp) { 6045 app.kill("error during init", true); 6046 handleAppDiedLocked(app, false, true); 6047 return false; 6048 } 6049 6050 if (!didSomething) { 6051 updateOomAdjLocked(); 6052 } 6053 6054 return true; 6055 } 6056 6057 @Override 6058 public final void attachApplication(IApplicationThread thread) { 6059 synchronized (this) { 6060 int callingPid = Binder.getCallingPid(); 6061 final long origId = Binder.clearCallingIdentity(); 6062 attachApplicationLocked(thread, callingPid); 6063 Binder.restoreCallingIdentity(origId); 6064 } 6065 } 6066 6067 @Override 6068 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6069 final long origId = Binder.clearCallingIdentity(); 6070 synchronized (this) { 6071 ActivityStack stack = ActivityRecord.getStackLocked(token); 6072 if (stack != null) { 6073 ActivityRecord r = 6074 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6075 if (stopProfiling) { 6076 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6077 try { 6078 mProfileFd.close(); 6079 } catch (IOException e) { 6080 } 6081 clearProfilerLocked(); 6082 } 6083 } 6084 } 6085 } 6086 Binder.restoreCallingIdentity(origId); 6087 } 6088 6089 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6090 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6091 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6092 } 6093 6094 void enableScreenAfterBoot() { 6095 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6096 SystemClock.uptimeMillis()); 6097 mWindowManager.enableScreenAfterBoot(); 6098 6099 synchronized (this) { 6100 updateEventDispatchingLocked(); 6101 } 6102 } 6103 6104 @Override 6105 public void showBootMessage(final CharSequence msg, final boolean always) { 6106 enforceNotIsolatedCaller("showBootMessage"); 6107 mWindowManager.showBootMessage(msg, always); 6108 } 6109 6110 @Override 6111 public void keyguardWaitingForActivityDrawn() { 6112 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6113 final long token = Binder.clearCallingIdentity(); 6114 try { 6115 synchronized (this) { 6116 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6117 mWindowManager.keyguardWaitingForActivityDrawn(); 6118 if (mLockScreenShown) { 6119 mLockScreenShown = false; 6120 comeOutOfSleepIfNeededLocked(); 6121 } 6122 } 6123 } finally { 6124 Binder.restoreCallingIdentity(token); 6125 } 6126 } 6127 6128 final void finishBooting() { 6129 synchronized (this) { 6130 if (!mBootAnimationComplete) { 6131 mCallFinishBooting = true; 6132 return; 6133 } 6134 mCallFinishBooting = false; 6135 } 6136 6137 // Register receivers to handle package update events 6138 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6139 6140 // Let system services know. 6141 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6142 6143 synchronized (this) { 6144 // Ensure that any processes we had put on hold are now started 6145 // up. 6146 final int NP = mProcessesOnHold.size(); 6147 if (NP > 0) { 6148 ArrayList<ProcessRecord> procs = 6149 new ArrayList<ProcessRecord>(mProcessesOnHold); 6150 for (int ip=0; ip<NP; ip++) { 6151 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6152 + procs.get(ip)); 6153 startProcessLocked(procs.get(ip), "on-hold", null); 6154 } 6155 } 6156 6157 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6158 // Start looking for apps that are abusing wake locks. 6159 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6160 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6161 // Tell anyone interested that we are done booting! 6162 SystemProperties.set("sys.boot_completed", "1"); 6163 6164 // And trigger dev.bootcomplete if we are not showing encryption progress 6165 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6166 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6167 SystemProperties.set("dev.bootcomplete", "1"); 6168 } 6169 for (int i=0; i<mStartedUsers.size(); i++) { 6170 UserStartedState uss = mStartedUsers.valueAt(i); 6171 if (uss.mState == UserStartedState.STATE_BOOTING) { 6172 uss.mState = UserStartedState.STATE_RUNNING; 6173 final int userId = mStartedUsers.keyAt(i); 6174 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6175 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6176 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6177 broadcastIntentLocked(null, null, intent, null, 6178 new IIntentReceiver.Stub() { 6179 @Override 6180 public void performReceive(Intent intent, int resultCode, 6181 String data, Bundle extras, boolean ordered, 6182 boolean sticky, int sendingUser) { 6183 synchronized (ActivityManagerService.this) { 6184 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6185 true, false); 6186 } 6187 } 6188 }, 6189 0, null, null, 6190 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6191 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6192 userId); 6193 } 6194 } 6195 scheduleStartProfilesLocked(); 6196 } 6197 } 6198 } 6199 6200 @Override 6201 public void bootAnimationComplete() { 6202 final boolean callFinishBooting; 6203 synchronized (this) { 6204 callFinishBooting = mCallFinishBooting; 6205 mBootAnimationComplete = true; 6206 } 6207 if (callFinishBooting) { 6208 finishBooting(); 6209 } 6210 } 6211 6212 final void ensureBootCompleted() { 6213 boolean booting; 6214 boolean enableScreen; 6215 synchronized (this) { 6216 booting = mBooting; 6217 mBooting = false; 6218 enableScreen = !mBooted; 6219 mBooted = true; 6220 } 6221 6222 if (booting) { 6223 finishBooting(); 6224 } 6225 6226 if (enableScreen) { 6227 enableScreenAfterBoot(); 6228 } 6229 } 6230 6231 @Override 6232 public final void activityResumed(IBinder token) { 6233 final long origId = Binder.clearCallingIdentity(); 6234 synchronized(this) { 6235 ActivityStack stack = ActivityRecord.getStackLocked(token); 6236 if (stack != null) { 6237 ActivityRecord.activityResumedLocked(token); 6238 } 6239 } 6240 Binder.restoreCallingIdentity(origId); 6241 } 6242 6243 @Override 6244 public final void activityPaused(IBinder token) { 6245 final long origId = Binder.clearCallingIdentity(); 6246 synchronized(this) { 6247 ActivityStack stack = ActivityRecord.getStackLocked(token); 6248 if (stack != null) { 6249 stack.activityPausedLocked(token, false); 6250 } 6251 } 6252 Binder.restoreCallingIdentity(origId); 6253 } 6254 6255 @Override 6256 public final void activityStopped(IBinder token, Bundle icicle, 6257 PersistableBundle persistentState, CharSequence description) { 6258 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6259 6260 // Refuse possible leaked file descriptors 6261 if (icicle != null && icicle.hasFileDescriptors()) { 6262 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6263 } 6264 6265 final long origId = Binder.clearCallingIdentity(); 6266 6267 synchronized (this) { 6268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6269 if (r != null) { 6270 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6271 } 6272 } 6273 6274 trimApplications(); 6275 6276 Binder.restoreCallingIdentity(origId); 6277 } 6278 6279 @Override 6280 public final void activityDestroyed(IBinder token) { 6281 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6282 synchronized (this) { 6283 ActivityStack stack = ActivityRecord.getStackLocked(token); 6284 if (stack != null) { 6285 stack.activityDestroyedLocked(token); 6286 } 6287 } 6288 } 6289 6290 @Override 6291 public final void backgroundResourcesReleased(IBinder token) { 6292 final long origId = Binder.clearCallingIdentity(); 6293 try { 6294 synchronized (this) { 6295 ActivityStack stack = ActivityRecord.getStackLocked(token); 6296 if (stack != null) { 6297 stack.backgroundResourcesReleased(token); 6298 } 6299 } 6300 } finally { 6301 Binder.restoreCallingIdentity(origId); 6302 } 6303 } 6304 6305 @Override 6306 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6307 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6308 } 6309 6310 @Override 6311 public final void notifyEnterAnimationComplete(IBinder token) { 6312 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6313 } 6314 6315 @Override 6316 public String getCallingPackage(IBinder token) { 6317 synchronized (this) { 6318 ActivityRecord r = getCallingRecordLocked(token); 6319 return r != null ? r.info.packageName : null; 6320 } 6321 } 6322 6323 @Override 6324 public ComponentName getCallingActivity(IBinder token) { 6325 synchronized (this) { 6326 ActivityRecord r = getCallingRecordLocked(token); 6327 return r != null ? r.intent.getComponent() : null; 6328 } 6329 } 6330 6331 private ActivityRecord getCallingRecordLocked(IBinder token) { 6332 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6333 if (r == null) { 6334 return null; 6335 } 6336 return r.resultTo; 6337 } 6338 6339 @Override 6340 public ComponentName getActivityClassForToken(IBinder token) { 6341 synchronized(this) { 6342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6343 if (r == null) { 6344 return null; 6345 } 6346 return r.intent.getComponent(); 6347 } 6348 } 6349 6350 @Override 6351 public String getPackageForToken(IBinder token) { 6352 synchronized(this) { 6353 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6354 if (r == null) { 6355 return null; 6356 } 6357 return r.packageName; 6358 } 6359 } 6360 6361 @Override 6362 public IIntentSender getIntentSender(int type, 6363 String packageName, IBinder token, String resultWho, 6364 int requestCode, Intent[] intents, String[] resolvedTypes, 6365 int flags, Bundle options, int userId) { 6366 enforceNotIsolatedCaller("getIntentSender"); 6367 // Refuse possible leaked file descriptors 6368 if (intents != null) { 6369 if (intents.length < 1) { 6370 throw new IllegalArgumentException("Intents array length must be >= 1"); 6371 } 6372 for (int i=0; i<intents.length; i++) { 6373 Intent intent = intents[i]; 6374 if (intent != null) { 6375 if (intent.hasFileDescriptors()) { 6376 throw new IllegalArgumentException("File descriptors passed in Intent"); 6377 } 6378 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6379 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6380 throw new IllegalArgumentException( 6381 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6382 } 6383 intents[i] = new Intent(intent); 6384 } 6385 } 6386 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6387 throw new IllegalArgumentException( 6388 "Intent array length does not match resolvedTypes length"); 6389 } 6390 } 6391 if (options != null) { 6392 if (options.hasFileDescriptors()) { 6393 throw new IllegalArgumentException("File descriptors passed in options"); 6394 } 6395 } 6396 6397 synchronized(this) { 6398 int callingUid = Binder.getCallingUid(); 6399 int origUserId = userId; 6400 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6401 type == ActivityManager.INTENT_SENDER_BROADCAST, 6402 ALLOW_NON_FULL, "getIntentSender", null); 6403 if (origUserId == UserHandle.USER_CURRENT) { 6404 // We don't want to evaluate this until the pending intent is 6405 // actually executed. However, we do want to always do the 6406 // security checking for it above. 6407 userId = UserHandle.USER_CURRENT; 6408 } 6409 try { 6410 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6411 int uid = AppGlobals.getPackageManager() 6412 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6413 if (!UserHandle.isSameApp(callingUid, uid)) { 6414 String msg = "Permission Denial: getIntentSender() from pid=" 6415 + Binder.getCallingPid() 6416 + ", uid=" + Binder.getCallingUid() 6417 + ", (need uid=" + uid + ")" 6418 + " is not allowed to send as package " + packageName; 6419 Slog.w(TAG, msg); 6420 throw new SecurityException(msg); 6421 } 6422 } 6423 6424 return getIntentSenderLocked(type, packageName, callingUid, userId, 6425 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6426 6427 } catch (RemoteException e) { 6428 throw new SecurityException(e); 6429 } 6430 } 6431 } 6432 6433 IIntentSender getIntentSenderLocked(int type, String packageName, 6434 int callingUid, int userId, IBinder token, String resultWho, 6435 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6436 Bundle options) { 6437 if (DEBUG_MU) 6438 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6439 ActivityRecord activity = null; 6440 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6441 activity = ActivityRecord.isInStackLocked(token); 6442 if (activity == null) { 6443 return null; 6444 } 6445 if (activity.finishing) { 6446 return null; 6447 } 6448 } 6449 6450 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6451 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6452 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6453 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6454 |PendingIntent.FLAG_UPDATE_CURRENT); 6455 6456 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6457 type, packageName, activity, resultWho, 6458 requestCode, intents, resolvedTypes, flags, options, userId); 6459 WeakReference<PendingIntentRecord> ref; 6460 ref = mIntentSenderRecords.get(key); 6461 PendingIntentRecord rec = ref != null ? ref.get() : null; 6462 if (rec != null) { 6463 if (!cancelCurrent) { 6464 if (updateCurrent) { 6465 if (rec.key.requestIntent != null) { 6466 rec.key.requestIntent.replaceExtras(intents != null ? 6467 intents[intents.length - 1] : null); 6468 } 6469 if (intents != null) { 6470 intents[intents.length-1] = rec.key.requestIntent; 6471 rec.key.allIntents = intents; 6472 rec.key.allResolvedTypes = resolvedTypes; 6473 } else { 6474 rec.key.allIntents = null; 6475 rec.key.allResolvedTypes = null; 6476 } 6477 } 6478 return rec; 6479 } 6480 rec.canceled = true; 6481 mIntentSenderRecords.remove(key); 6482 } 6483 if (noCreate) { 6484 return rec; 6485 } 6486 rec = new PendingIntentRecord(this, key, callingUid); 6487 mIntentSenderRecords.put(key, rec.ref); 6488 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6489 if (activity.pendingResults == null) { 6490 activity.pendingResults 6491 = new HashSet<WeakReference<PendingIntentRecord>>(); 6492 } 6493 activity.pendingResults.add(rec.ref); 6494 } 6495 return rec; 6496 } 6497 6498 @Override 6499 public void cancelIntentSender(IIntentSender sender) { 6500 if (!(sender instanceof PendingIntentRecord)) { 6501 return; 6502 } 6503 synchronized(this) { 6504 PendingIntentRecord rec = (PendingIntentRecord)sender; 6505 try { 6506 int uid = AppGlobals.getPackageManager() 6507 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6508 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6509 String msg = "Permission Denial: cancelIntentSender() from pid=" 6510 + Binder.getCallingPid() 6511 + ", uid=" + Binder.getCallingUid() 6512 + " is not allowed to cancel packges " 6513 + rec.key.packageName; 6514 Slog.w(TAG, msg); 6515 throw new SecurityException(msg); 6516 } 6517 } catch (RemoteException e) { 6518 throw new SecurityException(e); 6519 } 6520 cancelIntentSenderLocked(rec, true); 6521 } 6522 } 6523 6524 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6525 rec.canceled = true; 6526 mIntentSenderRecords.remove(rec.key); 6527 if (cleanActivity && rec.key.activity != null) { 6528 rec.key.activity.pendingResults.remove(rec.ref); 6529 } 6530 } 6531 6532 @Override 6533 public String getPackageForIntentSender(IIntentSender pendingResult) { 6534 if (!(pendingResult instanceof PendingIntentRecord)) { 6535 return null; 6536 } 6537 try { 6538 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6539 return res.key.packageName; 6540 } catch (ClassCastException e) { 6541 } 6542 return null; 6543 } 6544 6545 @Override 6546 public int getUidForIntentSender(IIntentSender sender) { 6547 if (sender instanceof PendingIntentRecord) { 6548 try { 6549 PendingIntentRecord res = (PendingIntentRecord)sender; 6550 return res.uid; 6551 } catch (ClassCastException e) { 6552 } 6553 } 6554 return -1; 6555 } 6556 6557 @Override 6558 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6559 if (!(pendingResult instanceof PendingIntentRecord)) { 6560 return false; 6561 } 6562 try { 6563 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6564 if (res.key.allIntents == null) { 6565 return false; 6566 } 6567 for (int i=0; i<res.key.allIntents.length; i++) { 6568 Intent intent = res.key.allIntents[i]; 6569 if (intent.getPackage() != null && intent.getComponent() != null) { 6570 return false; 6571 } 6572 } 6573 return true; 6574 } catch (ClassCastException e) { 6575 } 6576 return false; 6577 } 6578 6579 @Override 6580 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6581 if (!(pendingResult instanceof PendingIntentRecord)) { 6582 return false; 6583 } 6584 try { 6585 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6586 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6587 return true; 6588 } 6589 return false; 6590 } catch (ClassCastException e) { 6591 } 6592 return false; 6593 } 6594 6595 @Override 6596 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6597 if (!(pendingResult instanceof PendingIntentRecord)) { 6598 return null; 6599 } 6600 try { 6601 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6602 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6603 } catch (ClassCastException e) { 6604 } 6605 return null; 6606 } 6607 6608 @Override 6609 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6610 if (!(pendingResult instanceof PendingIntentRecord)) { 6611 return null; 6612 } 6613 try { 6614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6615 Intent intent = res.key.requestIntent; 6616 if (intent != null) { 6617 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6618 || res.lastTagPrefix.equals(prefix))) { 6619 return res.lastTag; 6620 } 6621 res.lastTagPrefix = prefix; 6622 StringBuilder sb = new StringBuilder(128); 6623 if (prefix != null) { 6624 sb.append(prefix); 6625 } 6626 if (intent.getAction() != null) { 6627 sb.append(intent.getAction()); 6628 } else if (intent.getComponent() != null) { 6629 intent.getComponent().appendShortString(sb); 6630 } else { 6631 sb.append("?"); 6632 } 6633 return res.lastTag = sb.toString(); 6634 } 6635 } catch (ClassCastException e) { 6636 } 6637 return null; 6638 } 6639 6640 @Override 6641 public void setProcessLimit(int max) { 6642 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6643 "setProcessLimit()"); 6644 synchronized (this) { 6645 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6646 mProcessLimitOverride = max; 6647 } 6648 trimApplications(); 6649 } 6650 6651 @Override 6652 public int getProcessLimit() { 6653 synchronized (this) { 6654 return mProcessLimitOverride; 6655 } 6656 } 6657 6658 void foregroundTokenDied(ForegroundToken token) { 6659 synchronized (ActivityManagerService.this) { 6660 synchronized (mPidsSelfLocked) { 6661 ForegroundToken cur 6662 = mForegroundProcesses.get(token.pid); 6663 if (cur != token) { 6664 return; 6665 } 6666 mForegroundProcesses.remove(token.pid); 6667 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6668 if (pr == null) { 6669 return; 6670 } 6671 pr.forcingToForeground = null; 6672 updateProcessForegroundLocked(pr, false, false); 6673 } 6674 updateOomAdjLocked(); 6675 } 6676 } 6677 6678 @Override 6679 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6680 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6681 "setProcessForeground()"); 6682 synchronized(this) { 6683 boolean changed = false; 6684 6685 synchronized (mPidsSelfLocked) { 6686 ProcessRecord pr = mPidsSelfLocked.get(pid); 6687 if (pr == null && isForeground) { 6688 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6689 return; 6690 } 6691 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6692 if (oldToken != null) { 6693 oldToken.token.unlinkToDeath(oldToken, 0); 6694 mForegroundProcesses.remove(pid); 6695 if (pr != null) { 6696 pr.forcingToForeground = null; 6697 } 6698 changed = true; 6699 } 6700 if (isForeground && token != null) { 6701 ForegroundToken newToken = new ForegroundToken() { 6702 @Override 6703 public void binderDied() { 6704 foregroundTokenDied(this); 6705 } 6706 }; 6707 newToken.pid = pid; 6708 newToken.token = token; 6709 try { 6710 token.linkToDeath(newToken, 0); 6711 mForegroundProcesses.put(pid, newToken); 6712 pr.forcingToForeground = token; 6713 changed = true; 6714 } catch (RemoteException e) { 6715 // If the process died while doing this, we will later 6716 // do the cleanup with the process death link. 6717 } 6718 } 6719 } 6720 6721 if (changed) { 6722 updateOomAdjLocked(); 6723 } 6724 } 6725 } 6726 6727 // ========================================================= 6728 // PERMISSIONS 6729 // ========================================================= 6730 6731 static class PermissionController extends IPermissionController.Stub { 6732 ActivityManagerService mActivityManagerService; 6733 PermissionController(ActivityManagerService activityManagerService) { 6734 mActivityManagerService = activityManagerService; 6735 } 6736 6737 @Override 6738 public boolean checkPermission(String permission, int pid, int uid) { 6739 return mActivityManagerService.checkPermission(permission, pid, 6740 uid) == PackageManager.PERMISSION_GRANTED; 6741 } 6742 } 6743 6744 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6745 @Override 6746 public int checkComponentPermission(String permission, int pid, int uid, 6747 int owningUid, boolean exported) { 6748 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6749 owningUid, exported); 6750 } 6751 6752 @Override 6753 public Object getAMSLock() { 6754 return ActivityManagerService.this; 6755 } 6756 } 6757 6758 /** 6759 * This can be called with or without the global lock held. 6760 */ 6761 int checkComponentPermission(String permission, int pid, int uid, 6762 int owningUid, boolean exported) { 6763 // We might be performing an operation on behalf of an indirect binder 6764 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6765 // client identity accordingly before proceeding. 6766 Identity tlsIdentity = sCallerIdentity.get(); 6767 if (tlsIdentity != null) { 6768 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6769 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6770 uid = tlsIdentity.uid; 6771 pid = tlsIdentity.pid; 6772 } 6773 6774 if (pid == MY_PID) { 6775 return PackageManager.PERMISSION_GRANTED; 6776 } 6777 6778 return ActivityManager.checkComponentPermission(permission, uid, 6779 owningUid, exported); 6780 } 6781 6782 /** 6783 * As the only public entry point for permissions checking, this method 6784 * can enforce the semantic that requesting a check on a null global 6785 * permission is automatically denied. (Internally a null permission 6786 * string is used when calling {@link #checkComponentPermission} in cases 6787 * when only uid-based security is needed.) 6788 * 6789 * This can be called with or without the global lock held. 6790 */ 6791 @Override 6792 public int checkPermission(String permission, int pid, int uid) { 6793 if (permission == null) { 6794 return PackageManager.PERMISSION_DENIED; 6795 } 6796 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6797 } 6798 6799 /** 6800 * Binder IPC calls go through the public entry point. 6801 * This can be called with or without the global lock held. 6802 */ 6803 int checkCallingPermission(String permission) { 6804 return checkPermission(permission, 6805 Binder.getCallingPid(), 6806 UserHandle.getAppId(Binder.getCallingUid())); 6807 } 6808 6809 /** 6810 * This can be called with or without the global lock held. 6811 */ 6812 void enforceCallingPermission(String permission, String func) { 6813 if (checkCallingPermission(permission) 6814 == PackageManager.PERMISSION_GRANTED) { 6815 return; 6816 } 6817 6818 String msg = "Permission Denial: " + func + " from pid=" 6819 + Binder.getCallingPid() 6820 + ", uid=" + Binder.getCallingUid() 6821 + " requires " + permission; 6822 Slog.w(TAG, msg); 6823 throw new SecurityException(msg); 6824 } 6825 6826 /** 6827 * Determine if UID is holding permissions required to access {@link Uri} in 6828 * the given {@link ProviderInfo}. Final permission checking is always done 6829 * in {@link ContentProvider}. 6830 */ 6831 private final boolean checkHoldingPermissionsLocked( 6832 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6833 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6834 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6835 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6836 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6837 != PERMISSION_GRANTED) { 6838 return false; 6839 } 6840 } 6841 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6842 } 6843 6844 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6845 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6846 if (pi.applicationInfo.uid == uid) { 6847 return true; 6848 } else if (!pi.exported) { 6849 return false; 6850 } 6851 6852 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6853 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6854 try { 6855 // check if target holds top-level <provider> permissions 6856 if (!readMet && pi.readPermission != null && considerUidPermissions 6857 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6858 readMet = true; 6859 } 6860 if (!writeMet && pi.writePermission != null && considerUidPermissions 6861 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6862 writeMet = true; 6863 } 6864 6865 // track if unprotected read/write is allowed; any denied 6866 // <path-permission> below removes this ability 6867 boolean allowDefaultRead = pi.readPermission == null; 6868 boolean allowDefaultWrite = pi.writePermission == null; 6869 6870 // check if target holds any <path-permission> that match uri 6871 final PathPermission[] pps = pi.pathPermissions; 6872 if (pps != null) { 6873 final String path = grantUri.uri.getPath(); 6874 int i = pps.length; 6875 while (i > 0 && (!readMet || !writeMet)) { 6876 i--; 6877 PathPermission pp = pps[i]; 6878 if (pp.match(path)) { 6879 if (!readMet) { 6880 final String pprperm = pp.getReadPermission(); 6881 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6882 + pprperm + " for " + pp.getPath() 6883 + ": match=" + pp.match(path) 6884 + " check=" + pm.checkUidPermission(pprperm, uid)); 6885 if (pprperm != null) { 6886 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6887 == PERMISSION_GRANTED) { 6888 readMet = true; 6889 } else { 6890 allowDefaultRead = false; 6891 } 6892 } 6893 } 6894 if (!writeMet) { 6895 final String ppwperm = pp.getWritePermission(); 6896 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6897 + ppwperm + " for " + pp.getPath() 6898 + ": match=" + pp.match(path) 6899 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6900 if (ppwperm != null) { 6901 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6902 == PERMISSION_GRANTED) { 6903 writeMet = true; 6904 } else { 6905 allowDefaultWrite = false; 6906 } 6907 } 6908 } 6909 } 6910 } 6911 } 6912 6913 // grant unprotected <provider> read/write, if not blocked by 6914 // <path-permission> above 6915 if (allowDefaultRead) readMet = true; 6916 if (allowDefaultWrite) writeMet = true; 6917 6918 } catch (RemoteException e) { 6919 return false; 6920 } 6921 6922 return readMet && writeMet; 6923 } 6924 6925 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6926 ProviderInfo pi = null; 6927 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6928 if (cpr != null) { 6929 pi = cpr.info; 6930 } else { 6931 try { 6932 pi = AppGlobals.getPackageManager().resolveContentProvider( 6933 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6934 } catch (RemoteException ex) { 6935 } 6936 } 6937 return pi; 6938 } 6939 6940 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6941 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6942 if (targetUris != null) { 6943 return targetUris.get(grantUri); 6944 } 6945 return null; 6946 } 6947 6948 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6949 String targetPkg, int targetUid, GrantUri grantUri) { 6950 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6951 if (targetUris == null) { 6952 targetUris = Maps.newArrayMap(); 6953 mGrantedUriPermissions.put(targetUid, targetUris); 6954 } 6955 6956 UriPermission perm = targetUris.get(grantUri); 6957 if (perm == null) { 6958 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6959 targetUris.put(grantUri, perm); 6960 } 6961 6962 return perm; 6963 } 6964 6965 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6966 final int modeFlags) { 6967 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6968 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6969 : UriPermission.STRENGTH_OWNED; 6970 6971 // Root gets to do everything. 6972 if (uid == 0) { 6973 return true; 6974 } 6975 6976 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6977 if (perms == null) return false; 6978 6979 // First look for exact match 6980 final UriPermission exactPerm = perms.get(grantUri); 6981 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6982 return true; 6983 } 6984 6985 // No exact match, look for prefixes 6986 final int N = perms.size(); 6987 for (int i = 0; i < N; i++) { 6988 final UriPermission perm = perms.valueAt(i); 6989 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6990 && perm.getStrength(modeFlags) >= minStrength) { 6991 return true; 6992 } 6993 } 6994 6995 return false; 6996 } 6997 6998 /** 6999 * @param uri This uri must NOT contain an embedded userId. 7000 * @param userId The userId in which the uri is to be resolved. 7001 */ 7002 @Override 7003 public int checkUriPermission(Uri uri, int pid, int uid, 7004 final int modeFlags, int userId) { 7005 enforceNotIsolatedCaller("checkUriPermission"); 7006 7007 // Another redirected-binder-call permissions check as in 7008 // {@link checkComponentPermission}. 7009 Identity tlsIdentity = sCallerIdentity.get(); 7010 if (tlsIdentity != null) { 7011 uid = tlsIdentity.uid; 7012 pid = tlsIdentity.pid; 7013 } 7014 7015 // Our own process gets to do everything. 7016 if (pid == MY_PID) { 7017 return PackageManager.PERMISSION_GRANTED; 7018 } 7019 synchronized (this) { 7020 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7021 ? PackageManager.PERMISSION_GRANTED 7022 : PackageManager.PERMISSION_DENIED; 7023 } 7024 } 7025 7026 /** 7027 * Check if the targetPkg can be granted permission to access uri by 7028 * the callingUid using the given modeFlags. Throws a security exception 7029 * if callingUid is not allowed to do this. Returns the uid of the target 7030 * if the URI permission grant should be performed; returns -1 if it is not 7031 * needed (for example targetPkg already has permission to access the URI). 7032 * If you already know the uid of the target, you can supply it in 7033 * lastTargetUid else set that to -1. 7034 */ 7035 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7036 final int modeFlags, int lastTargetUid) { 7037 if (!Intent.isAccessUriMode(modeFlags)) { 7038 return -1; 7039 } 7040 7041 if (targetPkg != null) { 7042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7043 "Checking grant " + targetPkg + " permission to " + grantUri); 7044 } 7045 7046 final IPackageManager pm = AppGlobals.getPackageManager(); 7047 7048 // If this is not a content: uri, we can't do anything with it. 7049 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7050 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7051 "Can't grant URI permission for non-content URI: " + grantUri); 7052 return -1; 7053 } 7054 7055 final String authority = grantUri.uri.getAuthority(); 7056 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7057 if (pi == null) { 7058 Slog.w(TAG, "No content provider found for permission check: " + 7059 grantUri.uri.toSafeString()); 7060 return -1; 7061 } 7062 7063 int targetUid = lastTargetUid; 7064 if (targetUid < 0 && targetPkg != null) { 7065 try { 7066 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7067 if (targetUid < 0) { 7068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7069 "Can't grant URI permission no uid for: " + targetPkg); 7070 return -1; 7071 } 7072 } catch (RemoteException ex) { 7073 return -1; 7074 } 7075 } 7076 7077 if (targetUid >= 0) { 7078 // First... does the target actually need this permission? 7079 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7080 // No need to grant the target this permission. 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Target " + targetPkg + " already has full permission to " + grantUri); 7083 return -1; 7084 } 7085 } else { 7086 // First... there is no target package, so can anyone access it? 7087 boolean allowed = pi.exported; 7088 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7089 if (pi.readPermission != null) { 7090 allowed = false; 7091 } 7092 } 7093 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7094 if (pi.writePermission != null) { 7095 allowed = false; 7096 } 7097 } 7098 if (allowed) { 7099 return -1; 7100 } 7101 } 7102 7103 /* There is a special cross user grant if: 7104 * - The target is on another user. 7105 * - Apps on the current user can access the uri without any uid permissions. 7106 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7107 * grant uri permissions. 7108 */ 7109 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7110 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7111 modeFlags, false /*without considering the uid permissions*/); 7112 7113 // Second... is the provider allowing granting of URI permissions? 7114 if (!specialCrossUserGrant) { 7115 if (!pi.grantUriPermissions) { 7116 throw new SecurityException("Provider " + pi.packageName 7117 + "/" + pi.name 7118 + " does not allow granting of Uri permissions (uri " 7119 + grantUri + ")"); 7120 } 7121 if (pi.uriPermissionPatterns != null) { 7122 final int N = pi.uriPermissionPatterns.length; 7123 boolean allowed = false; 7124 for (int i=0; i<N; i++) { 7125 if (pi.uriPermissionPatterns[i] != null 7126 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7127 allowed = true; 7128 break; 7129 } 7130 } 7131 if (!allowed) { 7132 throw new SecurityException("Provider " + pi.packageName 7133 + "/" + pi.name 7134 + " does not allow granting of permission to path of Uri " 7135 + grantUri); 7136 } 7137 } 7138 } 7139 7140 // Third... does the caller itself have permission to access 7141 // this uri? 7142 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7143 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7144 // Require they hold a strong enough Uri permission 7145 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7146 throw new SecurityException("Uid " + callingUid 7147 + " does not have permission to uri " + grantUri); 7148 } 7149 } 7150 } 7151 return targetUid; 7152 } 7153 7154 /** 7155 * @param uri This uri must NOT contain an embedded userId. 7156 * @param userId The userId in which the uri is to be resolved. 7157 */ 7158 @Override 7159 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7160 final int modeFlags, int userId) { 7161 enforceNotIsolatedCaller("checkGrantUriPermission"); 7162 synchronized(this) { 7163 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7164 new GrantUri(userId, uri, false), modeFlags, -1); 7165 } 7166 } 7167 7168 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7169 final int modeFlags, UriPermissionOwner owner) { 7170 if (!Intent.isAccessUriMode(modeFlags)) { 7171 return; 7172 } 7173 7174 // So here we are: the caller has the assumed permission 7175 // to the uri, and the target doesn't. Let's now give this to 7176 // the target. 7177 7178 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7179 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7180 7181 final String authority = grantUri.uri.getAuthority(); 7182 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7183 if (pi == null) { 7184 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7185 return; 7186 } 7187 7188 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7189 grantUri.prefix = true; 7190 } 7191 final UriPermission perm = findOrCreateUriPermissionLocked( 7192 pi.packageName, targetPkg, targetUid, grantUri); 7193 perm.grantModes(modeFlags, owner); 7194 } 7195 7196 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7197 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7198 if (targetPkg == null) { 7199 throw new NullPointerException("targetPkg"); 7200 } 7201 int targetUid; 7202 final IPackageManager pm = AppGlobals.getPackageManager(); 7203 try { 7204 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7205 } catch (RemoteException ex) { 7206 return; 7207 } 7208 7209 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7210 targetUid); 7211 if (targetUid < 0) { 7212 return; 7213 } 7214 7215 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7216 owner); 7217 } 7218 7219 static class NeededUriGrants extends ArrayList<GrantUri> { 7220 final String targetPkg; 7221 final int targetUid; 7222 final int flags; 7223 7224 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7225 this.targetPkg = targetPkg; 7226 this.targetUid = targetUid; 7227 this.flags = flags; 7228 } 7229 } 7230 7231 /** 7232 * Like checkGrantUriPermissionLocked, but takes an Intent. 7233 */ 7234 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7235 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7236 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7237 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7238 + " clip=" + (intent != null ? intent.getClipData() : null) 7239 + " from " + intent + "; flags=0x" 7240 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7241 7242 if (targetPkg == null) { 7243 throw new NullPointerException("targetPkg"); 7244 } 7245 7246 if (intent == null) { 7247 return null; 7248 } 7249 Uri data = intent.getData(); 7250 ClipData clip = intent.getClipData(); 7251 if (data == null && clip == null) { 7252 return null; 7253 } 7254 // Default userId for uris in the intent (if they don't specify it themselves) 7255 int contentUserHint = intent.getContentUserHint(); 7256 if (contentUserHint == UserHandle.USER_CURRENT) { 7257 contentUserHint = UserHandle.getUserId(callingUid); 7258 } 7259 final IPackageManager pm = AppGlobals.getPackageManager(); 7260 int targetUid; 7261 if (needed != null) { 7262 targetUid = needed.targetUid; 7263 } else { 7264 try { 7265 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7266 } catch (RemoteException ex) { 7267 return null; 7268 } 7269 if (targetUid < 0) { 7270 if (DEBUG_URI_PERMISSION) { 7271 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7272 + " on user " + targetUserId); 7273 } 7274 return null; 7275 } 7276 } 7277 if (data != null) { 7278 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7279 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7280 targetUid); 7281 if (targetUid > 0) { 7282 if (needed == null) { 7283 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7284 } 7285 needed.add(grantUri); 7286 } 7287 } 7288 if (clip != null) { 7289 for (int i=0; i<clip.getItemCount(); i++) { 7290 Uri uri = clip.getItemAt(i).getUri(); 7291 if (uri != null) { 7292 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7293 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7294 targetUid); 7295 if (targetUid > 0) { 7296 if (needed == null) { 7297 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7298 } 7299 needed.add(grantUri); 7300 } 7301 } else { 7302 Intent clipIntent = clip.getItemAt(i).getIntent(); 7303 if (clipIntent != null) { 7304 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7305 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7306 if (newNeeded != null) { 7307 needed = newNeeded; 7308 } 7309 } 7310 } 7311 } 7312 } 7313 7314 return needed; 7315 } 7316 7317 /** 7318 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7319 */ 7320 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7321 UriPermissionOwner owner) { 7322 if (needed != null) { 7323 for (int i=0; i<needed.size(); i++) { 7324 GrantUri grantUri = needed.get(i); 7325 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7326 grantUri, needed.flags, owner); 7327 } 7328 } 7329 } 7330 7331 void grantUriPermissionFromIntentLocked(int callingUid, 7332 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7333 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7334 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7335 if (needed == null) { 7336 return; 7337 } 7338 7339 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7340 } 7341 7342 /** 7343 * @param uri This uri must NOT contain an embedded userId. 7344 * @param userId The userId in which the uri is to be resolved. 7345 */ 7346 @Override 7347 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7348 final int modeFlags, int userId) { 7349 enforceNotIsolatedCaller("grantUriPermission"); 7350 GrantUri grantUri = new GrantUri(userId, uri, false); 7351 synchronized(this) { 7352 final ProcessRecord r = getRecordForAppLocked(caller); 7353 if (r == null) { 7354 throw new SecurityException("Unable to find app for caller " 7355 + caller 7356 + " when granting permission to uri " + grantUri); 7357 } 7358 if (targetPkg == null) { 7359 throw new IllegalArgumentException("null target"); 7360 } 7361 if (grantUri == null) { 7362 throw new IllegalArgumentException("null uri"); 7363 } 7364 7365 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7366 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7367 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7368 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7369 7370 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7371 UserHandle.getUserId(r.uid)); 7372 } 7373 } 7374 7375 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7376 if (perm.modeFlags == 0) { 7377 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7378 perm.targetUid); 7379 if (perms != null) { 7380 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7381 "Removing " + perm.targetUid + " permission to " + perm.uri); 7382 7383 perms.remove(perm.uri); 7384 if (perms.isEmpty()) { 7385 mGrantedUriPermissions.remove(perm.targetUid); 7386 } 7387 } 7388 } 7389 } 7390 7391 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7392 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7393 7394 final IPackageManager pm = AppGlobals.getPackageManager(); 7395 final String authority = grantUri.uri.getAuthority(); 7396 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7397 if (pi == null) { 7398 Slog.w(TAG, "No content provider found for permission revoke: " 7399 + grantUri.toSafeString()); 7400 return; 7401 } 7402 7403 // Does the caller have this permission on the URI? 7404 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7405 // If they don't have direct access to the URI, then revoke any 7406 // ownerless URI permissions that have been granted to them. 7407 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7408 if (perms != null) { 7409 boolean persistChanged = false; 7410 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7411 final UriPermission perm = it.next(); 7412 if (perm.uri.sourceUserId == grantUri.sourceUserId 7413 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7414 if (DEBUG_URI_PERMISSION) 7415 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7416 " permission to " + perm.uri); 7417 persistChanged |= perm.revokeModes( 7418 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7419 if (perm.modeFlags == 0) { 7420 it.remove(); 7421 } 7422 } 7423 } 7424 if (perms.isEmpty()) { 7425 mGrantedUriPermissions.remove(callingUid); 7426 } 7427 if (persistChanged) { 7428 schedulePersistUriGrants(); 7429 } 7430 } 7431 return; 7432 } 7433 7434 boolean persistChanged = false; 7435 7436 // Go through all of the permissions and remove any that match. 7437 int N = mGrantedUriPermissions.size(); 7438 for (int i = 0; i < N; i++) { 7439 final int targetUid = mGrantedUriPermissions.keyAt(i); 7440 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7441 7442 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7443 final UriPermission perm = it.next(); 7444 if (perm.uri.sourceUserId == grantUri.sourceUserId 7445 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7446 if (DEBUG_URI_PERMISSION) 7447 Slog.v(TAG, 7448 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7449 persistChanged |= perm.revokeModes( 7450 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7451 if (perm.modeFlags == 0) { 7452 it.remove(); 7453 } 7454 } 7455 } 7456 7457 if (perms.isEmpty()) { 7458 mGrantedUriPermissions.remove(targetUid); 7459 N--; 7460 i--; 7461 } 7462 } 7463 7464 if (persistChanged) { 7465 schedulePersistUriGrants(); 7466 } 7467 } 7468 7469 /** 7470 * @param uri This uri must NOT contain an embedded userId. 7471 * @param userId The userId in which the uri is to be resolved. 7472 */ 7473 @Override 7474 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7475 int userId) { 7476 enforceNotIsolatedCaller("revokeUriPermission"); 7477 synchronized(this) { 7478 final ProcessRecord r = getRecordForAppLocked(caller); 7479 if (r == null) { 7480 throw new SecurityException("Unable to find app for caller " 7481 + caller 7482 + " when revoking permission to uri " + uri); 7483 } 7484 if (uri == null) { 7485 Slog.w(TAG, "revokeUriPermission: null uri"); 7486 return; 7487 } 7488 7489 if (!Intent.isAccessUriMode(modeFlags)) { 7490 return; 7491 } 7492 7493 final IPackageManager pm = AppGlobals.getPackageManager(); 7494 final String authority = uri.getAuthority(); 7495 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7496 if (pi == null) { 7497 Slog.w(TAG, "No content provider found for permission revoke: " 7498 + uri.toSafeString()); 7499 return; 7500 } 7501 7502 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7503 } 7504 } 7505 7506 /** 7507 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7508 * given package. 7509 * 7510 * @param packageName Package name to match, or {@code null} to apply to all 7511 * packages. 7512 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7513 * to all users. 7514 * @param persistable If persistable grants should be removed. 7515 */ 7516 private void removeUriPermissionsForPackageLocked( 7517 String packageName, int userHandle, boolean persistable) { 7518 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7519 throw new IllegalArgumentException("Must narrow by either package or user"); 7520 } 7521 7522 boolean persistChanged = false; 7523 7524 int N = mGrantedUriPermissions.size(); 7525 for (int i = 0; i < N; i++) { 7526 final int targetUid = mGrantedUriPermissions.keyAt(i); 7527 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7528 7529 // Only inspect grants matching user 7530 if (userHandle == UserHandle.USER_ALL 7531 || userHandle == UserHandle.getUserId(targetUid)) { 7532 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7533 final UriPermission perm = it.next(); 7534 7535 // Only inspect grants matching package 7536 if (packageName == null || perm.sourcePkg.equals(packageName) 7537 || perm.targetPkg.equals(packageName)) { 7538 persistChanged |= perm.revokeModes(persistable 7539 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7540 7541 // Only remove when no modes remain; any persisted grants 7542 // will keep this alive. 7543 if (perm.modeFlags == 0) { 7544 it.remove(); 7545 } 7546 } 7547 } 7548 7549 if (perms.isEmpty()) { 7550 mGrantedUriPermissions.remove(targetUid); 7551 N--; 7552 i--; 7553 } 7554 } 7555 } 7556 7557 if (persistChanged) { 7558 schedulePersistUriGrants(); 7559 } 7560 } 7561 7562 @Override 7563 public IBinder newUriPermissionOwner(String name) { 7564 enforceNotIsolatedCaller("newUriPermissionOwner"); 7565 synchronized(this) { 7566 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7567 return owner.getExternalTokenLocked(); 7568 } 7569 } 7570 7571 /** 7572 * @param uri This uri must NOT contain an embedded userId. 7573 * @param sourceUserId The userId in which the uri is to be resolved. 7574 * @param targetUserId The userId of the app that receives the grant. 7575 */ 7576 @Override 7577 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7578 final int modeFlags, int sourceUserId, int targetUserId) { 7579 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7580 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7581 synchronized(this) { 7582 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7583 if (owner == null) { 7584 throw new IllegalArgumentException("Unknown owner: " + token); 7585 } 7586 if (fromUid != Binder.getCallingUid()) { 7587 if (Binder.getCallingUid() != Process.myUid()) { 7588 // Only system code can grant URI permissions on behalf 7589 // of other users. 7590 throw new SecurityException("nice try"); 7591 } 7592 } 7593 if (targetPkg == null) { 7594 throw new IllegalArgumentException("null target"); 7595 } 7596 if (uri == null) { 7597 throw new IllegalArgumentException("null uri"); 7598 } 7599 7600 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7601 modeFlags, owner, targetUserId); 7602 } 7603 } 7604 7605 /** 7606 * @param uri This uri must NOT contain an embedded userId. 7607 * @param userId The userId in which the uri is to be resolved. 7608 */ 7609 @Override 7610 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7611 synchronized(this) { 7612 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7613 if (owner == null) { 7614 throw new IllegalArgumentException("Unknown owner: " + token); 7615 } 7616 7617 if (uri == null) { 7618 owner.removeUriPermissionsLocked(mode); 7619 } else { 7620 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7621 } 7622 } 7623 } 7624 7625 private void schedulePersistUriGrants() { 7626 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7627 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7628 10 * DateUtils.SECOND_IN_MILLIS); 7629 } 7630 } 7631 7632 private void writeGrantedUriPermissions() { 7633 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7634 7635 // Snapshot permissions so we can persist without lock 7636 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7637 synchronized (this) { 7638 final int size = mGrantedUriPermissions.size(); 7639 for (int i = 0; i < size; i++) { 7640 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7641 for (UriPermission perm : perms.values()) { 7642 if (perm.persistedModeFlags != 0) { 7643 persist.add(perm.snapshot()); 7644 } 7645 } 7646 } 7647 } 7648 7649 FileOutputStream fos = null; 7650 try { 7651 fos = mGrantFile.startWrite(); 7652 7653 XmlSerializer out = new FastXmlSerializer(); 7654 out.setOutput(fos, "utf-8"); 7655 out.startDocument(null, true); 7656 out.startTag(null, TAG_URI_GRANTS); 7657 for (UriPermission.Snapshot perm : persist) { 7658 out.startTag(null, TAG_URI_GRANT); 7659 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7660 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7661 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7662 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7663 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7664 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7665 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7666 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7667 out.endTag(null, TAG_URI_GRANT); 7668 } 7669 out.endTag(null, TAG_URI_GRANTS); 7670 out.endDocument(); 7671 7672 mGrantFile.finishWrite(fos); 7673 } catch (IOException e) { 7674 if (fos != null) { 7675 mGrantFile.failWrite(fos); 7676 } 7677 } 7678 } 7679 7680 private void readGrantedUriPermissionsLocked() { 7681 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7682 7683 final long now = System.currentTimeMillis(); 7684 7685 FileInputStream fis = null; 7686 try { 7687 fis = mGrantFile.openRead(); 7688 final XmlPullParser in = Xml.newPullParser(); 7689 in.setInput(fis, null); 7690 7691 int type; 7692 while ((type = in.next()) != END_DOCUMENT) { 7693 final String tag = in.getName(); 7694 if (type == START_TAG) { 7695 if (TAG_URI_GRANT.equals(tag)) { 7696 final int sourceUserId; 7697 final int targetUserId; 7698 final int userHandle = readIntAttribute(in, 7699 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7700 if (userHandle != UserHandle.USER_NULL) { 7701 // For backwards compatibility. 7702 sourceUserId = userHandle; 7703 targetUserId = userHandle; 7704 } else { 7705 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7706 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7707 } 7708 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7709 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7710 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7711 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7712 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7713 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7714 7715 // Sanity check that provider still belongs to source package 7716 final ProviderInfo pi = getProviderInfoLocked( 7717 uri.getAuthority(), sourceUserId); 7718 if (pi != null && sourcePkg.equals(pi.packageName)) { 7719 int targetUid = -1; 7720 try { 7721 targetUid = AppGlobals.getPackageManager() 7722 .getPackageUid(targetPkg, targetUserId); 7723 } catch (RemoteException e) { 7724 } 7725 if (targetUid != -1) { 7726 final UriPermission perm = findOrCreateUriPermissionLocked( 7727 sourcePkg, targetPkg, targetUid, 7728 new GrantUri(sourceUserId, uri, prefix)); 7729 perm.initPersistedModes(modeFlags, createdTime); 7730 } 7731 } else { 7732 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7733 + " but instead found " + pi); 7734 } 7735 } 7736 } 7737 } 7738 } catch (FileNotFoundException e) { 7739 // Missing grants is okay 7740 } catch (IOException e) { 7741 Slog.wtf(TAG, "Failed reading Uri grants", e); 7742 } catch (XmlPullParserException e) { 7743 Slog.wtf(TAG, "Failed reading Uri grants", e); 7744 } finally { 7745 IoUtils.closeQuietly(fis); 7746 } 7747 } 7748 7749 /** 7750 * @param uri This uri must NOT contain an embedded userId. 7751 * @param userId The userId in which the uri is to be resolved. 7752 */ 7753 @Override 7754 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7755 enforceNotIsolatedCaller("takePersistableUriPermission"); 7756 7757 Preconditions.checkFlagsArgument(modeFlags, 7758 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7759 7760 synchronized (this) { 7761 final int callingUid = Binder.getCallingUid(); 7762 boolean persistChanged = false; 7763 GrantUri grantUri = new GrantUri(userId, uri, false); 7764 7765 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7766 new GrantUri(userId, uri, false)); 7767 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7768 new GrantUri(userId, uri, true)); 7769 7770 final boolean exactValid = (exactPerm != null) 7771 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7772 final boolean prefixValid = (prefixPerm != null) 7773 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7774 7775 if (!(exactValid || prefixValid)) { 7776 throw new SecurityException("No persistable permission grants found for UID " 7777 + callingUid + " and Uri " + grantUri.toSafeString()); 7778 } 7779 7780 if (exactValid) { 7781 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7782 } 7783 if (prefixValid) { 7784 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7785 } 7786 7787 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7788 7789 if (persistChanged) { 7790 schedulePersistUriGrants(); 7791 } 7792 } 7793 } 7794 7795 /** 7796 * @param uri This uri must NOT contain an embedded userId. 7797 * @param userId The userId in which the uri is to be resolved. 7798 */ 7799 @Override 7800 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7801 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7802 7803 Preconditions.checkFlagsArgument(modeFlags, 7804 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7805 7806 synchronized (this) { 7807 final int callingUid = Binder.getCallingUid(); 7808 boolean persistChanged = false; 7809 7810 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7811 new GrantUri(userId, uri, false)); 7812 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7813 new GrantUri(userId, uri, true)); 7814 if (exactPerm == null && prefixPerm == null) { 7815 throw new SecurityException("No permission grants found for UID " + callingUid 7816 + " and Uri " + uri.toSafeString()); 7817 } 7818 7819 if (exactPerm != null) { 7820 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7821 removeUriPermissionIfNeededLocked(exactPerm); 7822 } 7823 if (prefixPerm != null) { 7824 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7825 removeUriPermissionIfNeededLocked(prefixPerm); 7826 } 7827 7828 if (persistChanged) { 7829 schedulePersistUriGrants(); 7830 } 7831 } 7832 } 7833 7834 /** 7835 * Prune any older {@link UriPermission} for the given UID until outstanding 7836 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7837 * 7838 * @return if any mutations occured that require persisting. 7839 */ 7840 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7841 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7842 if (perms == null) return false; 7843 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7844 7845 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7846 for (UriPermission perm : perms.values()) { 7847 if (perm.persistedModeFlags != 0) { 7848 persisted.add(perm); 7849 } 7850 } 7851 7852 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7853 if (trimCount <= 0) return false; 7854 7855 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7856 for (int i = 0; i < trimCount; i++) { 7857 final UriPermission perm = persisted.get(i); 7858 7859 if (DEBUG_URI_PERMISSION) { 7860 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7861 } 7862 7863 perm.releasePersistableModes(~0); 7864 removeUriPermissionIfNeededLocked(perm); 7865 } 7866 7867 return true; 7868 } 7869 7870 @Override 7871 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7872 String packageName, boolean incoming) { 7873 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7874 Preconditions.checkNotNull(packageName, "packageName"); 7875 7876 final int callingUid = Binder.getCallingUid(); 7877 final IPackageManager pm = AppGlobals.getPackageManager(); 7878 try { 7879 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7880 if (packageUid != callingUid) { 7881 throw new SecurityException( 7882 "Package " + packageName + " does not belong to calling UID " + callingUid); 7883 } 7884 } catch (RemoteException e) { 7885 throw new SecurityException("Failed to verify package name ownership"); 7886 } 7887 7888 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7889 synchronized (this) { 7890 if (incoming) { 7891 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7892 callingUid); 7893 if (perms == null) { 7894 Slog.w(TAG, "No permission grants found for " + packageName); 7895 } else { 7896 for (UriPermission perm : perms.values()) { 7897 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7898 result.add(perm.buildPersistedPublicApiObject()); 7899 } 7900 } 7901 } 7902 } else { 7903 final int size = mGrantedUriPermissions.size(); 7904 for (int i = 0; i < size; i++) { 7905 final ArrayMap<GrantUri, UriPermission> perms = 7906 mGrantedUriPermissions.valueAt(i); 7907 for (UriPermission perm : perms.values()) { 7908 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7909 result.add(perm.buildPersistedPublicApiObject()); 7910 } 7911 } 7912 } 7913 } 7914 } 7915 return new ParceledListSlice<android.content.UriPermission>(result); 7916 } 7917 7918 @Override 7919 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7920 synchronized (this) { 7921 ProcessRecord app = 7922 who != null ? getRecordForAppLocked(who) : null; 7923 if (app == null) return; 7924 7925 Message msg = Message.obtain(); 7926 msg.what = WAIT_FOR_DEBUGGER_MSG; 7927 msg.obj = app; 7928 msg.arg1 = waiting ? 1 : 0; 7929 mHandler.sendMessage(msg); 7930 } 7931 } 7932 7933 @Override 7934 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7935 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7936 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7937 outInfo.availMem = Process.getFreeMemory(); 7938 outInfo.totalMem = Process.getTotalMemory(); 7939 outInfo.threshold = homeAppMem; 7940 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7941 outInfo.hiddenAppThreshold = cachedAppMem; 7942 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7943 ProcessList.SERVICE_ADJ); 7944 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7945 ProcessList.VISIBLE_APP_ADJ); 7946 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7947 ProcessList.FOREGROUND_APP_ADJ); 7948 } 7949 7950 // ========================================================= 7951 // TASK MANAGEMENT 7952 // ========================================================= 7953 7954 @Override 7955 public List<IAppTask> getAppTasks(String callingPackage) { 7956 int callingUid = Binder.getCallingUid(); 7957 long ident = Binder.clearCallingIdentity(); 7958 7959 synchronized(this) { 7960 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7961 try { 7962 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7963 7964 final int N = mRecentTasks.size(); 7965 for (int i = 0; i < N; i++) { 7966 TaskRecord tr = mRecentTasks.get(i); 7967 // Skip tasks that do not match the caller. We don't need to verify 7968 // callingPackage, because we are also limiting to callingUid and know 7969 // that will limit to the correct security sandbox. 7970 if (tr.effectiveUid != callingUid) { 7971 continue; 7972 } 7973 Intent intent = tr.getBaseIntent(); 7974 if (intent == null || 7975 !callingPackage.equals(intent.getComponent().getPackageName())) { 7976 continue; 7977 } 7978 ActivityManager.RecentTaskInfo taskInfo = 7979 createRecentTaskInfoFromTaskRecord(tr); 7980 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7981 list.add(taskImpl); 7982 } 7983 } finally { 7984 Binder.restoreCallingIdentity(ident); 7985 } 7986 return list; 7987 } 7988 } 7989 7990 @Override 7991 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7992 final int callingUid = Binder.getCallingUid(); 7993 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7994 7995 synchronized(this) { 7996 if (localLOGV) Slog.v( 7997 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7998 7999 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8000 callingUid); 8001 8002 // TODO: Improve with MRU list from all ActivityStacks. 8003 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8004 } 8005 8006 return list; 8007 } 8008 8009 TaskRecord getMostRecentTask() { 8010 return mRecentTasks.get(0); 8011 } 8012 8013 /** 8014 * Creates a new RecentTaskInfo from a TaskRecord. 8015 */ 8016 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8017 // Update the task description to reflect any changes in the task stack 8018 tr.updateTaskDescription(); 8019 8020 // Compose the recent task info 8021 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8022 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8023 rti.persistentId = tr.taskId; 8024 rti.baseIntent = new Intent(tr.getBaseIntent()); 8025 rti.origActivity = tr.origActivity; 8026 rti.description = tr.lastDescription; 8027 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8028 rti.userId = tr.userId; 8029 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8030 rti.firstActiveTime = tr.firstActiveTime; 8031 rti.lastActiveTime = tr.lastActiveTime; 8032 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8033 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8034 return rti; 8035 } 8036 8037 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8038 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8039 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8040 if (!allowed) { 8041 if (checkPermission(android.Manifest.permission.GET_TASKS, 8042 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8043 // Temporary compatibility: some existing apps on the system image may 8044 // still be requesting the old permission and not switched to the new 8045 // one; if so, we'll still allow them full access. This means we need 8046 // to see if they are holding the old permission and are a system app. 8047 try { 8048 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8049 allowed = true; 8050 Slog.w(TAG, caller + ": caller " + callingUid 8051 + " is using old GET_TASKS but privileged; allowing"); 8052 } 8053 } catch (RemoteException e) { 8054 } 8055 } 8056 } 8057 if (!allowed) { 8058 Slog.w(TAG, caller + ": caller " + callingUid 8059 + " does not hold GET_TASKS; limiting output"); 8060 } 8061 return allowed; 8062 } 8063 8064 @Override 8065 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8066 final int callingUid = Binder.getCallingUid(); 8067 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8068 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8069 8070 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8071 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8072 synchronized (this) { 8073 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8074 callingUid); 8075 final boolean detailed = checkCallingPermission( 8076 android.Manifest.permission.GET_DETAILED_TASKS) 8077 == PackageManager.PERMISSION_GRANTED; 8078 8079 final int N = mRecentTasks.size(); 8080 ArrayList<ActivityManager.RecentTaskInfo> res 8081 = new ArrayList<ActivityManager.RecentTaskInfo>( 8082 maxNum < N ? maxNum : N); 8083 8084 final Set<Integer> includedUsers; 8085 if (includeProfiles) { 8086 includedUsers = getProfileIdsLocked(userId); 8087 } else { 8088 includedUsers = new HashSet<Integer>(); 8089 } 8090 includedUsers.add(Integer.valueOf(userId)); 8091 8092 for (int i=0; i<N && maxNum > 0; i++) { 8093 TaskRecord tr = mRecentTasks.get(i); 8094 // Only add calling user or related users recent tasks 8095 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8097 continue; 8098 } 8099 8100 // Return the entry if desired by the caller. We always return 8101 // the first entry, because callers always expect this to be the 8102 // foreground app. We may filter others if the caller has 8103 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8104 // we should exclude the entry. 8105 8106 if (i == 0 8107 || withExcluded 8108 || (tr.intent == null) 8109 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8110 == 0)) { 8111 if (!allowed) { 8112 // If the caller doesn't have the GET_TASKS permission, then only 8113 // allow them to see a small subset of tasks -- their own and home. 8114 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8115 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8116 continue; 8117 } 8118 } 8119 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8120 if (tr.stack != null && tr.stack.isHomeStack()) { 8121 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8122 continue; 8123 } 8124 } 8125 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8126 // Don't include auto remove tasks that are finished or finishing. 8127 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8128 + tr); 8129 continue; 8130 } 8131 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8132 && !tr.isAvailable) { 8133 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8134 continue; 8135 } 8136 8137 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8138 if (!detailed) { 8139 rti.baseIntent.replaceExtras((Bundle)null); 8140 } 8141 8142 res.add(rti); 8143 maxNum--; 8144 } 8145 } 8146 return res; 8147 } 8148 } 8149 8150 private TaskRecord recentTaskForIdLocked(int id) { 8151 final int N = mRecentTasks.size(); 8152 for (int i=0; i<N; i++) { 8153 TaskRecord tr = mRecentTasks.get(i); 8154 if (tr.taskId == id) { 8155 return tr; 8156 } 8157 } 8158 return null; 8159 } 8160 8161 @Override 8162 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8163 synchronized (this) { 8164 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8165 "getTaskThumbnail()"); 8166 TaskRecord tr = recentTaskForIdLocked(id); 8167 if (tr != null) { 8168 return tr.getTaskThumbnailLocked(); 8169 } 8170 } 8171 return null; 8172 } 8173 8174 @Override 8175 public int addAppTask(IBinder activityToken, Intent intent, 8176 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8177 final int callingUid = Binder.getCallingUid(); 8178 final long callingIdent = Binder.clearCallingIdentity(); 8179 8180 try { 8181 synchronized (this) { 8182 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8183 if (r == null) { 8184 throw new IllegalArgumentException("Activity does not exist; token=" 8185 + activityToken); 8186 } 8187 ComponentName comp = intent.getComponent(); 8188 if (comp == null) { 8189 throw new IllegalArgumentException("Intent " + intent 8190 + " must specify explicit component"); 8191 } 8192 if (thumbnail.getWidth() != mThumbnailWidth 8193 || thumbnail.getHeight() != mThumbnailHeight) { 8194 throw new IllegalArgumentException("Bad thumbnail size: got " 8195 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8196 + mThumbnailWidth + "x" + mThumbnailHeight); 8197 } 8198 if (intent.getSelector() != null) { 8199 intent.setSelector(null); 8200 } 8201 if (intent.getSourceBounds() != null) { 8202 intent.setSourceBounds(null); 8203 } 8204 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8205 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8206 // The caller has added this as an auto-remove task... that makes no 8207 // sense, so turn off auto-remove. 8208 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8209 } 8210 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8211 // Must be a new task. 8212 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8213 } 8214 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8215 mLastAddedTaskActivity = null; 8216 } 8217 ActivityInfo ainfo = mLastAddedTaskActivity; 8218 if (ainfo == null) { 8219 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8220 comp, 0, UserHandle.getUserId(callingUid)); 8221 if (ainfo.applicationInfo.uid != callingUid) { 8222 throw new SecurityException( 8223 "Can't add task for another application: target uid=" 8224 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8225 } 8226 } 8227 8228 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8229 intent, description); 8230 8231 int trimIdx = trimRecentsForTask(task, false); 8232 if (trimIdx >= 0) { 8233 // If this would have caused a trim, then we'll abort because that 8234 // means it would be added at the end of the list but then just removed. 8235 return -1; 8236 } 8237 8238 final int N = mRecentTasks.size(); 8239 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8240 final TaskRecord tr = mRecentTasks.remove(N - 1); 8241 tr.removedFromRecents(mTaskPersister); 8242 } 8243 8244 task.inRecents = true; 8245 mRecentTasks.add(task); 8246 r.task.stack.addTask(task, false, false); 8247 8248 task.setLastThumbnail(thumbnail); 8249 task.freeLastThumbnail(); 8250 8251 return task.taskId; 8252 } 8253 } finally { 8254 Binder.restoreCallingIdentity(callingIdent); 8255 } 8256 } 8257 8258 @Override 8259 public Point getAppTaskThumbnailSize() { 8260 synchronized (this) { 8261 return new Point(mThumbnailWidth, mThumbnailHeight); 8262 } 8263 } 8264 8265 @Override 8266 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8267 synchronized (this) { 8268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8269 if (r != null) { 8270 r.setTaskDescription(td); 8271 r.task.updateTaskDescription(); 8272 } 8273 } 8274 } 8275 8276 @Override 8277 public Bitmap getTaskDescriptionIcon(String filename) { 8278 if (!FileUtils.isValidExtFilename(filename) 8279 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8280 throw new IllegalArgumentException("Bad filename: " + filename); 8281 } 8282 return mTaskPersister.getTaskDescriptionIcon(filename); 8283 } 8284 8285 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8286 mRecentTasks.remove(tr); 8287 tr.removedFromRecents(mTaskPersister); 8288 ComponentName component = tr.getBaseIntent().getComponent(); 8289 if (component == null) { 8290 Slog.w(TAG, "No component for base intent of task: " + tr); 8291 return; 8292 } 8293 8294 if (!killProcess) { 8295 return; 8296 } 8297 8298 // Determine if the process(es) for this task should be killed. 8299 final String pkg = component.getPackageName(); 8300 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8301 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8302 for (int i = 0; i < pmap.size(); i++) { 8303 8304 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8305 for (int j = 0; j < uids.size(); j++) { 8306 ProcessRecord proc = uids.valueAt(j); 8307 if (proc.userId != tr.userId) { 8308 // Don't kill process for a different user. 8309 continue; 8310 } 8311 if (proc == mHomeProcess) { 8312 // Don't kill the home process along with tasks from the same package. 8313 continue; 8314 } 8315 if (!proc.pkgList.containsKey(pkg)) { 8316 // Don't kill process that is not associated with this task. 8317 continue; 8318 } 8319 8320 for (int k = 0; k < proc.activities.size(); k++) { 8321 TaskRecord otherTask = proc.activities.get(k).task; 8322 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8323 // Don't kill process(es) that has an activity in a different task that is 8324 // also in recents. 8325 return; 8326 } 8327 } 8328 8329 // Add process to kill list. 8330 procsToKill.add(proc); 8331 } 8332 } 8333 8334 // Find any running services associated with this app and stop if needed. 8335 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8336 8337 // Kill the running processes. 8338 for (int i = 0; i < procsToKill.size(); i++) { 8339 ProcessRecord pr = procsToKill.get(i); 8340 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8341 pr.kill("remove task", true); 8342 } else { 8343 pr.waitingToKill = "remove task"; 8344 } 8345 } 8346 } 8347 8348 /** 8349 * Removes the task with the specified task id. 8350 * 8351 * @param taskId Identifier of the task to be removed. 8352 * @param killProcess Kill any process associated with the task if possible. 8353 * @return Returns true if the given task was found and removed. 8354 */ 8355 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8356 TaskRecord tr = recentTaskForIdLocked(taskId); 8357 if (tr != null) { 8358 tr.removeTaskActivitiesLocked(); 8359 cleanUpRemovedTaskLocked(tr, killProcess); 8360 if (tr.isPersistable) { 8361 notifyTaskPersisterLocked(null, true); 8362 } 8363 return true; 8364 } 8365 return false; 8366 } 8367 8368 @Override 8369 public boolean removeTask(int taskId) { 8370 synchronized (this) { 8371 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8372 "removeTask()"); 8373 long ident = Binder.clearCallingIdentity(); 8374 try { 8375 return removeTaskByIdLocked(taskId, true); 8376 } finally { 8377 Binder.restoreCallingIdentity(ident); 8378 } 8379 } 8380 } 8381 8382 /** 8383 * TODO: Add mController hook 8384 */ 8385 @Override 8386 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8387 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8388 "moveTaskToFront()"); 8389 8390 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8391 synchronized(this) { 8392 moveTaskToFrontLocked(taskId, flags, options); 8393 } 8394 } 8395 8396 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8397 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8398 Binder.getCallingUid(), -1, -1, "Task to front")) { 8399 ActivityOptions.abort(options); 8400 return; 8401 } 8402 final long origId = Binder.clearCallingIdentity(); 8403 try { 8404 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8405 if (task == null) { 8406 return; 8407 } 8408 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8409 mStackSupervisor.showLockTaskToast(); 8410 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8411 return; 8412 } 8413 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8414 if (prev != null && prev.isRecentsActivity()) { 8415 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8416 } 8417 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8418 } finally { 8419 Binder.restoreCallingIdentity(origId); 8420 } 8421 ActivityOptions.abort(options); 8422 } 8423 8424 @Override 8425 public void moveTaskToBack(int taskId) { 8426 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8427 "moveTaskToBack()"); 8428 8429 synchronized(this) { 8430 TaskRecord tr = recentTaskForIdLocked(taskId); 8431 if (tr != null) { 8432 if (tr == mStackSupervisor.mLockTaskModeTask) { 8433 mStackSupervisor.showLockTaskToast(); 8434 return; 8435 } 8436 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8437 ActivityStack stack = tr.stack; 8438 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8439 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8440 Binder.getCallingUid(), -1, -1, "Task to back")) { 8441 return; 8442 } 8443 } 8444 final long origId = Binder.clearCallingIdentity(); 8445 try { 8446 stack.moveTaskToBackLocked(taskId, null); 8447 } finally { 8448 Binder.restoreCallingIdentity(origId); 8449 } 8450 } 8451 } 8452 } 8453 8454 /** 8455 * Moves an activity, and all of the other activities within the same task, to the bottom 8456 * of the history stack. The activity's order within the task is unchanged. 8457 * 8458 * @param token A reference to the activity we wish to move 8459 * @param nonRoot If false then this only works if the activity is the root 8460 * of a task; if true it will work for any activity in a task. 8461 * @return Returns true if the move completed, false if not. 8462 */ 8463 @Override 8464 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8465 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8466 synchronized(this) { 8467 final long origId = Binder.clearCallingIdentity(); 8468 try { 8469 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8470 if (taskId >= 0) { 8471 if ((mStackSupervisor.mLockTaskModeTask != null) 8472 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8473 mStackSupervisor.showLockTaskToast(); 8474 return false; 8475 } 8476 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8477 } 8478 } finally { 8479 Binder.restoreCallingIdentity(origId); 8480 } 8481 } 8482 return false; 8483 } 8484 8485 @Override 8486 public void moveTaskBackwards(int task) { 8487 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8488 "moveTaskBackwards()"); 8489 8490 synchronized(this) { 8491 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8492 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8493 return; 8494 } 8495 final long origId = Binder.clearCallingIdentity(); 8496 moveTaskBackwardsLocked(task); 8497 Binder.restoreCallingIdentity(origId); 8498 } 8499 } 8500 8501 private final void moveTaskBackwardsLocked(int task) { 8502 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8503 } 8504 8505 @Override 8506 public IBinder getHomeActivityToken() throws RemoteException { 8507 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8508 "getHomeActivityToken()"); 8509 synchronized (this) { 8510 return mStackSupervisor.getHomeActivityToken(); 8511 } 8512 } 8513 8514 @Override 8515 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8516 IActivityContainerCallback callback) throws RemoteException { 8517 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8518 "createActivityContainer()"); 8519 synchronized (this) { 8520 if (parentActivityToken == null) { 8521 throw new IllegalArgumentException("parent token must not be null"); 8522 } 8523 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8524 if (r == null) { 8525 return null; 8526 } 8527 if (callback == null) { 8528 throw new IllegalArgumentException("callback must not be null"); 8529 } 8530 return mStackSupervisor.createActivityContainer(r, callback); 8531 } 8532 } 8533 8534 @Override 8535 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8537 "deleteActivityContainer()"); 8538 synchronized (this) { 8539 mStackSupervisor.deleteActivityContainer(container); 8540 } 8541 } 8542 8543 @Override 8544 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8545 throws RemoteException { 8546 synchronized (this) { 8547 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8548 if (stack != null) { 8549 return stack.mActivityContainer; 8550 } 8551 return null; 8552 } 8553 } 8554 8555 @Override 8556 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8557 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8558 "moveTaskToStack()"); 8559 if (stackId == HOME_STACK_ID) { 8560 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8561 new RuntimeException("here").fillInStackTrace()); 8562 } 8563 synchronized (this) { 8564 long ident = Binder.clearCallingIdentity(); 8565 try { 8566 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8567 + stackId + " toTop=" + toTop); 8568 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8569 } finally { 8570 Binder.restoreCallingIdentity(ident); 8571 } 8572 } 8573 } 8574 8575 @Override 8576 public void resizeStack(int stackBoxId, Rect bounds) { 8577 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8578 "resizeStackBox()"); 8579 long ident = Binder.clearCallingIdentity(); 8580 try { 8581 mWindowManager.resizeStack(stackBoxId, bounds); 8582 } finally { 8583 Binder.restoreCallingIdentity(ident); 8584 } 8585 } 8586 8587 @Override 8588 public List<StackInfo> getAllStackInfos() { 8589 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8590 "getAllStackInfos()"); 8591 long ident = Binder.clearCallingIdentity(); 8592 try { 8593 synchronized (this) { 8594 return mStackSupervisor.getAllStackInfosLocked(); 8595 } 8596 } finally { 8597 Binder.restoreCallingIdentity(ident); 8598 } 8599 } 8600 8601 @Override 8602 public StackInfo getStackInfo(int stackId) { 8603 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8604 "getStackInfo()"); 8605 long ident = Binder.clearCallingIdentity(); 8606 try { 8607 synchronized (this) { 8608 return mStackSupervisor.getStackInfoLocked(stackId); 8609 } 8610 } finally { 8611 Binder.restoreCallingIdentity(ident); 8612 } 8613 } 8614 8615 @Override 8616 public boolean isInHomeStack(int taskId) { 8617 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8618 "getStackInfo()"); 8619 long ident = Binder.clearCallingIdentity(); 8620 try { 8621 synchronized (this) { 8622 TaskRecord tr = recentTaskForIdLocked(taskId); 8623 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8624 } 8625 } finally { 8626 Binder.restoreCallingIdentity(ident); 8627 } 8628 } 8629 8630 @Override 8631 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8632 synchronized(this) { 8633 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8634 } 8635 } 8636 8637 private boolean isLockTaskAuthorized(String pkg) { 8638 final DevicePolicyManager dpm = (DevicePolicyManager) 8639 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8640 try { 8641 int uid = mContext.getPackageManager().getPackageUid(pkg, 8642 Binder.getCallingUserHandle().getIdentifier()); 8643 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8644 } catch (NameNotFoundException e) { 8645 return false; 8646 } 8647 } 8648 8649 void startLockTaskMode(TaskRecord task) { 8650 final String pkg; 8651 synchronized (this) { 8652 pkg = task.intent.getComponent().getPackageName(); 8653 } 8654 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8655 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8656 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8657 StatusBarManagerInternal.class); 8658 if (statusBarManager != null) { 8659 statusBarManager.showScreenPinningRequest(); 8660 } 8661 return; 8662 } 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 synchronized (this) { 8666 // Since we lost lock on task, make sure it is still there. 8667 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8668 if (task != null) { 8669 if (!isSystemInitiated 8670 && ((mStackSupervisor.getFocusedStack() == null) 8671 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8672 throw new IllegalArgumentException("Invalid task, not in foreground"); 8673 } 8674 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8675 } 8676 } 8677 } finally { 8678 Binder.restoreCallingIdentity(ident); 8679 } 8680 } 8681 8682 @Override 8683 public void startLockTaskMode(int taskId) { 8684 final TaskRecord task; 8685 long ident = Binder.clearCallingIdentity(); 8686 try { 8687 synchronized (this) { 8688 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8689 } 8690 } finally { 8691 Binder.restoreCallingIdentity(ident); 8692 } 8693 if (task != null) { 8694 startLockTaskMode(task); 8695 } 8696 } 8697 8698 @Override 8699 public void startLockTaskMode(IBinder token) { 8700 final TaskRecord task; 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 synchronized (this) { 8704 final ActivityRecord r = ActivityRecord.forToken(token); 8705 if (r == null) { 8706 return; 8707 } 8708 task = r.task; 8709 } 8710 } finally { 8711 Binder.restoreCallingIdentity(ident); 8712 } 8713 if (task != null) { 8714 startLockTaskMode(task); 8715 } 8716 } 8717 8718 @Override 8719 public void startLockTaskModeOnCurrent() throws RemoteException { 8720 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8721 "startLockTaskModeOnCurrent"); 8722 long ident = Binder.clearCallingIdentity(); 8723 try { 8724 ActivityRecord r = null; 8725 synchronized (this) { 8726 r = mStackSupervisor.topRunningActivityLocked(); 8727 } 8728 startLockTaskMode(r.task); 8729 } finally { 8730 Binder.restoreCallingIdentity(ident); 8731 } 8732 } 8733 8734 @Override 8735 public void stopLockTaskMode() { 8736 // Verify that the user matches the package of the intent for the TaskRecord 8737 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8738 // and stopLockTaskMode. 8739 final int callingUid = Binder.getCallingUid(); 8740 if (callingUid != Process.SYSTEM_UID) { 8741 try { 8742 String pkg = 8743 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8744 int uid = mContext.getPackageManager().getPackageUid(pkg, 8745 Binder.getCallingUserHandle().getIdentifier()); 8746 if (uid != callingUid) { 8747 throw new SecurityException("Invalid uid, expected " + uid); 8748 } 8749 } catch (NameNotFoundException e) { 8750 Log.d(TAG, "stopLockTaskMode " + e); 8751 return; 8752 } 8753 } 8754 long ident = Binder.clearCallingIdentity(); 8755 try { 8756 Log.d(TAG, "stopLockTaskMode"); 8757 // Stop lock task 8758 synchronized (this) { 8759 mStackSupervisor.setLockTaskModeLocked(null, false); 8760 } 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 8766 @Override 8767 public void stopLockTaskModeOnCurrent() throws RemoteException { 8768 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8769 "stopLockTaskModeOnCurrent"); 8770 long ident = Binder.clearCallingIdentity(); 8771 try { 8772 stopLockTaskMode(); 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 } 8777 8778 @Override 8779 public boolean isInLockTaskMode() { 8780 synchronized (this) { 8781 return mStackSupervisor.isInLockTaskMode(); 8782 } 8783 } 8784 8785 // ========================================================= 8786 // CONTENT PROVIDERS 8787 // ========================================================= 8788 8789 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8790 List<ProviderInfo> providers = null; 8791 try { 8792 providers = AppGlobals.getPackageManager(). 8793 queryContentProviders(app.processName, app.uid, 8794 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8795 } catch (RemoteException ex) { 8796 } 8797 if (DEBUG_MU) 8798 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8799 int userId = app.userId; 8800 if (providers != null) { 8801 int N = providers.size(); 8802 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8803 for (int i=0; i<N; i++) { 8804 ProviderInfo cpi = 8805 (ProviderInfo)providers.get(i); 8806 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8807 cpi.name, cpi.flags); 8808 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8809 // This is a singleton provider, but a user besides the 8810 // default user is asking to initialize a process it runs 8811 // in... well, no, it doesn't actually run in this process, 8812 // it runs in the process of the default user. Get rid of it. 8813 providers.remove(i); 8814 N--; 8815 i--; 8816 continue; 8817 } 8818 8819 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8820 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8821 if (cpr == null) { 8822 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8823 mProviderMap.putProviderByClass(comp, cpr); 8824 } 8825 if (DEBUG_MU) 8826 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8827 app.pubProviders.put(cpi.name, cpr); 8828 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8829 // Don't add this if it is a platform component that is marked 8830 // to run in multiple processes, because this is actually 8831 // part of the framework so doesn't make sense to track as a 8832 // separate apk in the process. 8833 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8834 mProcessStats); 8835 } 8836 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8837 } 8838 } 8839 return providers; 8840 } 8841 8842 /** 8843 * Check if {@link ProcessRecord} has a possible chance at accessing the 8844 * given {@link ProviderInfo}. Final permission checking is always done 8845 * in {@link ContentProvider}. 8846 */ 8847 private final String checkContentProviderPermissionLocked( 8848 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8849 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8850 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8851 boolean checkedGrants = false; 8852 if (checkUser) { 8853 // Looking for cross-user grants before enforcing the typical cross-users permissions 8854 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8855 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8856 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8857 return null; 8858 } 8859 checkedGrants = true; 8860 } 8861 userId = handleIncomingUser(callingPid, callingUid, userId, 8862 false, ALLOW_NON_FULL, 8863 "checkContentProviderPermissionLocked " + cpi.authority, null); 8864 if (userId != tmpTargetUserId) { 8865 // When we actually went to determine the final targer user ID, this ended 8866 // up different than our initial check for the authority. This is because 8867 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8868 // SELF. So we need to re-check the grants again. 8869 checkedGrants = false; 8870 } 8871 } 8872 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8873 cpi.applicationInfo.uid, cpi.exported) 8874 == PackageManager.PERMISSION_GRANTED) { 8875 return null; 8876 } 8877 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8878 cpi.applicationInfo.uid, cpi.exported) 8879 == PackageManager.PERMISSION_GRANTED) { 8880 return null; 8881 } 8882 8883 PathPermission[] pps = cpi.pathPermissions; 8884 if (pps != null) { 8885 int i = pps.length; 8886 while (i > 0) { 8887 i--; 8888 PathPermission pp = pps[i]; 8889 String pprperm = pp.getReadPermission(); 8890 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8891 cpi.applicationInfo.uid, cpi.exported) 8892 == PackageManager.PERMISSION_GRANTED) { 8893 return null; 8894 } 8895 String ppwperm = pp.getWritePermission(); 8896 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8897 cpi.applicationInfo.uid, cpi.exported) 8898 == PackageManager.PERMISSION_GRANTED) { 8899 return null; 8900 } 8901 } 8902 } 8903 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8904 return null; 8905 } 8906 8907 String msg; 8908 if (!cpi.exported) { 8909 msg = "Permission Denial: opening provider " + cpi.name 8910 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8911 + ", uid=" + callingUid + ") that is not exported from uid " 8912 + cpi.applicationInfo.uid; 8913 } else { 8914 msg = "Permission Denial: opening provider " + cpi.name 8915 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8916 + ", uid=" + callingUid + ") requires " 8917 + cpi.readPermission + " or " + cpi.writePermission; 8918 } 8919 Slog.w(TAG, msg); 8920 return msg; 8921 } 8922 8923 /** 8924 * Returns if the ContentProvider has granted a uri to callingUid 8925 */ 8926 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8927 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8928 if (perms != null) { 8929 for (int i=perms.size()-1; i>=0; i--) { 8930 GrantUri grantUri = perms.keyAt(i); 8931 if (grantUri.sourceUserId == userId || !checkUser) { 8932 if (matchesProvider(grantUri.uri, cpi)) { 8933 return true; 8934 } 8935 } 8936 } 8937 } 8938 return false; 8939 } 8940 8941 /** 8942 * Returns true if the uri authority is one of the authorities specified in the provider. 8943 */ 8944 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8945 String uriAuth = uri.getAuthority(); 8946 String cpiAuth = cpi.authority; 8947 if (cpiAuth.indexOf(';') == -1) { 8948 return cpiAuth.equals(uriAuth); 8949 } 8950 String[] cpiAuths = cpiAuth.split(";"); 8951 int length = cpiAuths.length; 8952 for (int i = 0; i < length; i++) { 8953 if (cpiAuths[i].equals(uriAuth)) return true; 8954 } 8955 return false; 8956 } 8957 8958 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8959 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8960 if (r != null) { 8961 for (int i=0; i<r.conProviders.size(); i++) { 8962 ContentProviderConnection conn = r.conProviders.get(i); 8963 if (conn.provider == cpr) { 8964 if (DEBUG_PROVIDER) Slog.v(TAG, 8965 "Adding provider requested by " 8966 + r.processName + " from process " 8967 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8968 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8969 if (stable) { 8970 conn.stableCount++; 8971 conn.numStableIncs++; 8972 } else { 8973 conn.unstableCount++; 8974 conn.numUnstableIncs++; 8975 } 8976 return conn; 8977 } 8978 } 8979 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8980 if (stable) { 8981 conn.stableCount = 1; 8982 conn.numStableIncs = 1; 8983 } else { 8984 conn.unstableCount = 1; 8985 conn.numUnstableIncs = 1; 8986 } 8987 cpr.connections.add(conn); 8988 r.conProviders.add(conn); 8989 return conn; 8990 } 8991 cpr.addExternalProcessHandleLocked(externalProcessToken); 8992 return null; 8993 } 8994 8995 boolean decProviderCountLocked(ContentProviderConnection conn, 8996 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8997 if (conn != null) { 8998 cpr = conn.provider; 8999 if (DEBUG_PROVIDER) Slog.v(TAG, 9000 "Removing provider requested by " 9001 + conn.client.processName + " from process " 9002 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9003 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9004 if (stable) { 9005 conn.stableCount--; 9006 } else { 9007 conn.unstableCount--; 9008 } 9009 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9010 cpr.connections.remove(conn); 9011 conn.client.conProviders.remove(conn); 9012 return true; 9013 } 9014 return false; 9015 } 9016 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9017 return false; 9018 } 9019 9020 private void checkTime(long startTime, String where) { 9021 long now = SystemClock.elapsedRealtime(); 9022 if ((now-startTime) > 1000) { 9023 // If we are taking more than a second, log about it. 9024 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9025 } 9026 } 9027 9028 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9029 String name, IBinder token, boolean stable, int userId) { 9030 ContentProviderRecord cpr; 9031 ContentProviderConnection conn = null; 9032 ProviderInfo cpi = null; 9033 9034 synchronized(this) { 9035 long startTime = SystemClock.elapsedRealtime(); 9036 9037 ProcessRecord r = null; 9038 if (caller != null) { 9039 r = getRecordForAppLocked(caller); 9040 if (r == null) { 9041 throw new SecurityException( 9042 "Unable to find app for caller " + caller 9043 + " (pid=" + Binder.getCallingPid() 9044 + ") when getting content provider " + name); 9045 } 9046 } 9047 9048 boolean checkCrossUser = true; 9049 9050 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9051 9052 // First check if this content provider has been published... 9053 cpr = mProviderMap.getProviderByName(name, userId); 9054 // If that didn't work, check if it exists for user 0 and then 9055 // verify that it's a singleton provider before using it. 9056 if (cpr == null && userId != UserHandle.USER_OWNER) { 9057 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9058 if (cpr != null) { 9059 cpi = cpr.info; 9060 if (isSingleton(cpi.processName, cpi.applicationInfo, 9061 cpi.name, cpi.flags) 9062 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9063 userId = UserHandle.USER_OWNER; 9064 checkCrossUser = false; 9065 } else { 9066 cpr = null; 9067 cpi = null; 9068 } 9069 } 9070 } 9071 9072 boolean providerRunning = cpr != null; 9073 if (providerRunning) { 9074 cpi = cpr.info; 9075 String msg; 9076 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9077 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9078 != null) { 9079 throw new SecurityException(msg); 9080 } 9081 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9082 9083 if (r != null && cpr.canRunHere(r)) { 9084 // This provider has been published or is in the process 9085 // of being published... but it is also allowed to run 9086 // in the caller's process, so don't make a connection 9087 // and just let the caller instantiate its own instance. 9088 ContentProviderHolder holder = cpr.newHolder(null); 9089 // don't give caller the provider object, it needs 9090 // to make its own. 9091 holder.provider = null; 9092 return holder; 9093 } 9094 9095 final long origId = Binder.clearCallingIdentity(); 9096 9097 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9098 9099 // In this case the provider instance already exists, so we can 9100 // return it right away. 9101 conn = incProviderCountLocked(r, cpr, token, stable); 9102 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9103 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9104 // If this is a perceptible app accessing the provider, 9105 // make sure to count it as being accessed and thus 9106 // back up on the LRU list. This is good because 9107 // content providers are often expensive to start. 9108 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9109 updateLruProcessLocked(cpr.proc, false, null); 9110 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9111 } 9112 } 9113 9114 if (cpr.proc != null) { 9115 if (false) { 9116 if (cpr.name.flattenToShortString().equals( 9117 "com.android.providers.calendar/.CalendarProvider2")) { 9118 Slog.v(TAG, "****************** KILLING " 9119 + cpr.name.flattenToShortString()); 9120 Process.killProcess(cpr.proc.pid); 9121 } 9122 } 9123 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9124 boolean success = updateOomAdjLocked(cpr.proc); 9125 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9126 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9127 // NOTE: there is still a race here where a signal could be 9128 // pending on the process even though we managed to update its 9129 // adj level. Not sure what to do about this, but at least 9130 // the race is now smaller. 9131 if (!success) { 9132 // Uh oh... it looks like the provider's process 9133 // has been killed on us. We need to wait for a new 9134 // process to be started, and make sure its death 9135 // doesn't kill our process. 9136 Slog.i(TAG, 9137 "Existing provider " + cpr.name.flattenToShortString() 9138 + " is crashing; detaching " + r); 9139 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9140 checkTime(startTime, "getContentProviderImpl: before appDied"); 9141 appDiedLocked(cpr.proc); 9142 checkTime(startTime, "getContentProviderImpl: after appDied"); 9143 if (!lastRef) { 9144 // This wasn't the last ref our process had on 9145 // the provider... we have now been killed, bail. 9146 return null; 9147 } 9148 providerRunning = false; 9149 conn = null; 9150 } 9151 } 9152 9153 Binder.restoreCallingIdentity(origId); 9154 } 9155 9156 boolean singleton; 9157 if (!providerRunning) { 9158 try { 9159 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9160 cpi = AppGlobals.getPackageManager(). 9161 resolveContentProvider(name, 9162 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9163 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9164 } catch (RemoteException ex) { 9165 } 9166 if (cpi == null) { 9167 return null; 9168 } 9169 // If the provider is a singleton AND 9170 // (it's a call within the same user || the provider is a 9171 // privileged app) 9172 // Then allow connecting to the singleton provider 9173 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9174 cpi.name, cpi.flags) 9175 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9176 if (singleton) { 9177 userId = UserHandle.USER_OWNER; 9178 } 9179 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9180 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9181 9182 String msg; 9183 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9184 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9185 != null) { 9186 throw new SecurityException(msg); 9187 } 9188 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9189 9190 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9191 && !cpi.processName.equals("system")) { 9192 // If this content provider does not run in the system 9193 // process, and the system is not yet ready to run other 9194 // processes, then fail fast instead of hanging. 9195 throw new IllegalArgumentException( 9196 "Attempt to launch content provider before system ready"); 9197 } 9198 9199 // Make sure that the user who owns this provider is started. If not, 9200 // we don't want to allow it to run. 9201 if (mStartedUsers.get(userId) == null) { 9202 Slog.w(TAG, "Unable to launch app " 9203 + cpi.applicationInfo.packageName + "/" 9204 + cpi.applicationInfo.uid + " for provider " 9205 + name + ": user " + userId + " is stopped"); 9206 return null; 9207 } 9208 9209 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9210 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9211 cpr = mProviderMap.getProviderByClass(comp, userId); 9212 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9213 final boolean firstClass = cpr == null; 9214 if (firstClass) { 9215 final long ident = Binder.clearCallingIdentity(); 9216 try { 9217 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9218 ApplicationInfo ai = 9219 AppGlobals.getPackageManager(). 9220 getApplicationInfo( 9221 cpi.applicationInfo.packageName, 9222 STOCK_PM_FLAGS, userId); 9223 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9224 if (ai == null) { 9225 Slog.w(TAG, "No package info for content provider " 9226 + cpi.name); 9227 return null; 9228 } 9229 ai = getAppInfoForUser(ai, userId); 9230 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9231 } catch (RemoteException ex) { 9232 // pm is in same process, this will never happen. 9233 } finally { 9234 Binder.restoreCallingIdentity(ident); 9235 } 9236 } 9237 9238 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9239 9240 if (r != null && cpr.canRunHere(r)) { 9241 // If this is a multiprocess provider, then just return its 9242 // info and allow the caller to instantiate it. Only do 9243 // this if the provider is the same user as the caller's 9244 // process, or can run as root (so can be in any process). 9245 return cpr.newHolder(null); 9246 } 9247 9248 if (DEBUG_PROVIDER) { 9249 RuntimeException e = new RuntimeException("here"); 9250 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9251 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9252 } 9253 9254 // This is single process, and our app is now connecting to it. 9255 // See if we are already in the process of launching this 9256 // provider. 9257 final int N = mLaunchingProviders.size(); 9258 int i; 9259 for (i=0; i<N; i++) { 9260 if (mLaunchingProviders.get(i) == cpr) { 9261 break; 9262 } 9263 } 9264 9265 // If the provider is not already being launched, then get it 9266 // started. 9267 if (i >= N) { 9268 final long origId = Binder.clearCallingIdentity(); 9269 9270 try { 9271 // Content provider is now in use, its package can't be stopped. 9272 try { 9273 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9274 AppGlobals.getPackageManager().setPackageStoppedState( 9275 cpr.appInfo.packageName, false, userId); 9276 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9277 } catch (RemoteException e) { 9278 } catch (IllegalArgumentException e) { 9279 Slog.w(TAG, "Failed trying to unstop package " 9280 + cpr.appInfo.packageName + ": " + e); 9281 } 9282 9283 // Use existing process if already started 9284 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9285 ProcessRecord proc = getProcessRecordLocked( 9286 cpi.processName, cpr.appInfo.uid, false); 9287 if (proc != null && proc.thread != null) { 9288 if (DEBUG_PROVIDER) { 9289 Slog.d(TAG, "Installing in existing process " + proc); 9290 } 9291 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9292 proc.pubProviders.put(cpi.name, cpr); 9293 try { 9294 proc.thread.scheduleInstallProvider(cpi); 9295 } catch (RemoteException e) { 9296 } 9297 } else { 9298 checkTime(startTime, "getContentProviderImpl: before start process"); 9299 proc = startProcessLocked(cpi.processName, 9300 cpr.appInfo, false, 0, "content provider", 9301 new ComponentName(cpi.applicationInfo.packageName, 9302 cpi.name), false, false, false); 9303 checkTime(startTime, "getContentProviderImpl: after start process"); 9304 if (proc == null) { 9305 Slog.w(TAG, "Unable to launch app " 9306 + cpi.applicationInfo.packageName + "/" 9307 + cpi.applicationInfo.uid + " for provider " 9308 + name + ": process is bad"); 9309 return null; 9310 } 9311 } 9312 cpr.launchingApp = proc; 9313 mLaunchingProviders.add(cpr); 9314 } finally { 9315 Binder.restoreCallingIdentity(origId); 9316 } 9317 } 9318 9319 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9320 9321 // Make sure the provider is published (the same provider class 9322 // may be published under multiple names). 9323 if (firstClass) { 9324 mProviderMap.putProviderByClass(comp, cpr); 9325 } 9326 9327 mProviderMap.putProviderByName(name, cpr); 9328 conn = incProviderCountLocked(r, cpr, token, stable); 9329 if (conn != null) { 9330 conn.waiting = true; 9331 } 9332 } 9333 checkTime(startTime, "getContentProviderImpl: done!"); 9334 } 9335 9336 // Wait for the provider to be published... 9337 synchronized (cpr) { 9338 while (cpr.provider == null) { 9339 if (cpr.launchingApp == null) { 9340 Slog.w(TAG, "Unable to launch app " 9341 + cpi.applicationInfo.packageName + "/" 9342 + cpi.applicationInfo.uid + " for provider " 9343 + name + ": launching app became null"); 9344 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9345 UserHandle.getUserId(cpi.applicationInfo.uid), 9346 cpi.applicationInfo.packageName, 9347 cpi.applicationInfo.uid, name); 9348 return null; 9349 } 9350 try { 9351 if (DEBUG_MU) { 9352 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9353 + cpr.launchingApp); 9354 } 9355 if (conn != null) { 9356 conn.waiting = true; 9357 } 9358 cpr.wait(); 9359 } catch (InterruptedException ex) { 9360 } finally { 9361 if (conn != null) { 9362 conn.waiting = false; 9363 } 9364 } 9365 } 9366 } 9367 return cpr != null ? cpr.newHolder(conn) : null; 9368 } 9369 9370 @Override 9371 public final ContentProviderHolder getContentProvider( 9372 IApplicationThread caller, String name, int userId, boolean stable) { 9373 enforceNotIsolatedCaller("getContentProvider"); 9374 if (caller == null) { 9375 String msg = "null IApplicationThread when getting content provider " 9376 + name; 9377 Slog.w(TAG, msg); 9378 throw new SecurityException(msg); 9379 } 9380 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9381 // with cross-user grant. 9382 return getContentProviderImpl(caller, name, null, stable, userId); 9383 } 9384 9385 public ContentProviderHolder getContentProviderExternal( 9386 String name, int userId, IBinder token) { 9387 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9388 "Do not have permission in call getContentProviderExternal()"); 9389 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9390 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9391 return getContentProviderExternalUnchecked(name, token, userId); 9392 } 9393 9394 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9395 IBinder token, int userId) { 9396 return getContentProviderImpl(null, name, token, true, userId); 9397 } 9398 9399 /** 9400 * Drop a content provider from a ProcessRecord's bookkeeping 9401 */ 9402 public void removeContentProvider(IBinder connection, boolean stable) { 9403 enforceNotIsolatedCaller("removeContentProvider"); 9404 long ident = Binder.clearCallingIdentity(); 9405 try { 9406 synchronized (this) { 9407 ContentProviderConnection conn; 9408 try { 9409 conn = (ContentProviderConnection)connection; 9410 } catch (ClassCastException e) { 9411 String msg ="removeContentProvider: " + connection 9412 + " not a ContentProviderConnection"; 9413 Slog.w(TAG, msg); 9414 throw new IllegalArgumentException(msg); 9415 } 9416 if (conn == null) { 9417 throw new NullPointerException("connection is null"); 9418 } 9419 if (decProviderCountLocked(conn, null, null, stable)) { 9420 updateOomAdjLocked(); 9421 } 9422 } 9423 } finally { 9424 Binder.restoreCallingIdentity(ident); 9425 } 9426 } 9427 9428 public void removeContentProviderExternal(String name, IBinder token) { 9429 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9430 "Do not have permission in call removeContentProviderExternal()"); 9431 int userId = UserHandle.getCallingUserId(); 9432 long ident = Binder.clearCallingIdentity(); 9433 try { 9434 removeContentProviderExternalUnchecked(name, token, userId); 9435 } finally { 9436 Binder.restoreCallingIdentity(ident); 9437 } 9438 } 9439 9440 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9441 synchronized (this) { 9442 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9443 if(cpr == null) { 9444 //remove from mProvidersByClass 9445 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9446 return; 9447 } 9448 9449 //update content provider record entry info 9450 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9451 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9452 if (localCpr.hasExternalProcessHandles()) { 9453 if (localCpr.removeExternalProcessHandleLocked(token)) { 9454 updateOomAdjLocked(); 9455 } else { 9456 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9457 + " with no external reference for token: " 9458 + token + "."); 9459 } 9460 } else { 9461 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9462 + " with no external references."); 9463 } 9464 } 9465 } 9466 9467 public final void publishContentProviders(IApplicationThread caller, 9468 List<ContentProviderHolder> providers) { 9469 if (providers == null) { 9470 return; 9471 } 9472 9473 enforceNotIsolatedCaller("publishContentProviders"); 9474 synchronized (this) { 9475 final ProcessRecord r = getRecordForAppLocked(caller); 9476 if (DEBUG_MU) 9477 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9478 if (r == null) { 9479 throw new SecurityException( 9480 "Unable to find app for caller " + caller 9481 + " (pid=" + Binder.getCallingPid() 9482 + ") when publishing content providers"); 9483 } 9484 9485 final long origId = Binder.clearCallingIdentity(); 9486 9487 final int N = providers.size(); 9488 for (int i=0; i<N; i++) { 9489 ContentProviderHolder src = providers.get(i); 9490 if (src == null || src.info == null || src.provider == null) { 9491 continue; 9492 } 9493 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9494 if (DEBUG_MU) 9495 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9496 if (dst != null) { 9497 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9498 mProviderMap.putProviderByClass(comp, dst); 9499 String names[] = dst.info.authority.split(";"); 9500 for (int j = 0; j < names.length; j++) { 9501 mProviderMap.putProviderByName(names[j], dst); 9502 } 9503 9504 int NL = mLaunchingProviders.size(); 9505 int j; 9506 for (j=0; j<NL; j++) { 9507 if (mLaunchingProviders.get(j) == dst) { 9508 mLaunchingProviders.remove(j); 9509 j--; 9510 NL--; 9511 } 9512 } 9513 synchronized (dst) { 9514 dst.provider = src.provider; 9515 dst.proc = r; 9516 dst.notifyAll(); 9517 } 9518 updateOomAdjLocked(r); 9519 } 9520 } 9521 9522 Binder.restoreCallingIdentity(origId); 9523 } 9524 } 9525 9526 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9527 ContentProviderConnection conn; 9528 try { 9529 conn = (ContentProviderConnection)connection; 9530 } catch (ClassCastException e) { 9531 String msg ="refContentProvider: " + connection 9532 + " not a ContentProviderConnection"; 9533 Slog.w(TAG, msg); 9534 throw new IllegalArgumentException(msg); 9535 } 9536 if (conn == null) { 9537 throw new NullPointerException("connection is null"); 9538 } 9539 9540 synchronized (this) { 9541 if (stable > 0) { 9542 conn.numStableIncs += stable; 9543 } 9544 stable = conn.stableCount + stable; 9545 if (stable < 0) { 9546 throw new IllegalStateException("stableCount < 0: " + stable); 9547 } 9548 9549 if (unstable > 0) { 9550 conn.numUnstableIncs += unstable; 9551 } 9552 unstable = conn.unstableCount + unstable; 9553 if (unstable < 0) { 9554 throw new IllegalStateException("unstableCount < 0: " + unstable); 9555 } 9556 9557 if ((stable+unstable) <= 0) { 9558 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9559 + stable + " unstable=" + unstable); 9560 } 9561 conn.stableCount = stable; 9562 conn.unstableCount = unstable; 9563 return !conn.dead; 9564 } 9565 } 9566 9567 public void unstableProviderDied(IBinder connection) { 9568 ContentProviderConnection conn; 9569 try { 9570 conn = (ContentProviderConnection)connection; 9571 } catch (ClassCastException e) { 9572 String msg ="refContentProvider: " + connection 9573 + " not a ContentProviderConnection"; 9574 Slog.w(TAG, msg); 9575 throw new IllegalArgumentException(msg); 9576 } 9577 if (conn == null) { 9578 throw new NullPointerException("connection is null"); 9579 } 9580 9581 // Safely retrieve the content provider associated with the connection. 9582 IContentProvider provider; 9583 synchronized (this) { 9584 provider = conn.provider.provider; 9585 } 9586 9587 if (provider == null) { 9588 // Um, yeah, we're way ahead of you. 9589 return; 9590 } 9591 9592 // Make sure the caller is being honest with us. 9593 if (provider.asBinder().pingBinder()) { 9594 // Er, no, still looks good to us. 9595 synchronized (this) { 9596 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9597 + " says " + conn + " died, but we don't agree"); 9598 return; 9599 } 9600 } 9601 9602 // Well look at that! It's dead! 9603 synchronized (this) { 9604 if (conn.provider.provider != provider) { 9605 // But something changed... good enough. 9606 return; 9607 } 9608 9609 ProcessRecord proc = conn.provider.proc; 9610 if (proc == null || proc.thread == null) { 9611 // Seems like the process is already cleaned up. 9612 return; 9613 } 9614 9615 // As far as we're concerned, this is just like receiving a 9616 // death notification... just a bit prematurely. 9617 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9618 + ") early provider death"); 9619 final long ident = Binder.clearCallingIdentity(); 9620 try { 9621 appDiedLocked(proc); 9622 } finally { 9623 Binder.restoreCallingIdentity(ident); 9624 } 9625 } 9626 } 9627 9628 @Override 9629 public void appNotRespondingViaProvider(IBinder connection) { 9630 enforceCallingPermission( 9631 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9632 9633 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9634 if (conn == null) { 9635 Slog.w(TAG, "ContentProviderConnection is null"); 9636 return; 9637 } 9638 9639 final ProcessRecord host = conn.provider.proc; 9640 if (host == null) { 9641 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9642 return; 9643 } 9644 9645 final long token = Binder.clearCallingIdentity(); 9646 try { 9647 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9648 } finally { 9649 Binder.restoreCallingIdentity(token); 9650 } 9651 } 9652 9653 public final void installSystemProviders() { 9654 List<ProviderInfo> providers; 9655 synchronized (this) { 9656 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9657 providers = generateApplicationProvidersLocked(app); 9658 if (providers != null) { 9659 for (int i=providers.size()-1; i>=0; i--) { 9660 ProviderInfo pi = (ProviderInfo)providers.get(i); 9661 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9662 Slog.w(TAG, "Not installing system proc provider " + pi.name 9663 + ": not system .apk"); 9664 providers.remove(i); 9665 } 9666 } 9667 } 9668 } 9669 if (providers != null) { 9670 mSystemThread.installSystemProviders(providers); 9671 } 9672 9673 mCoreSettingsObserver = new CoreSettingsObserver(this); 9674 9675 //mUsageStatsService.monitorPackages(); 9676 } 9677 9678 /** 9679 * Allows apps to retrieve the MIME type of a URI. 9680 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9681 * users, then it does not need permission to access the ContentProvider. 9682 * Either, it needs cross-user uri grants. 9683 * 9684 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9685 * 9686 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9687 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9688 */ 9689 public String getProviderMimeType(Uri uri, int userId) { 9690 enforceNotIsolatedCaller("getProviderMimeType"); 9691 final String name = uri.getAuthority(); 9692 int callingUid = Binder.getCallingUid(); 9693 int callingPid = Binder.getCallingPid(); 9694 long ident = 0; 9695 boolean clearedIdentity = false; 9696 userId = unsafeConvertIncomingUser(userId); 9697 if (canClearIdentity(callingPid, callingUid, userId)) { 9698 clearedIdentity = true; 9699 ident = Binder.clearCallingIdentity(); 9700 } 9701 ContentProviderHolder holder = null; 9702 try { 9703 holder = getContentProviderExternalUnchecked(name, null, userId); 9704 if (holder != null) { 9705 return holder.provider.getType(uri); 9706 } 9707 } catch (RemoteException e) { 9708 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9709 return null; 9710 } finally { 9711 // We need to clear the identity to call removeContentProviderExternalUnchecked 9712 if (!clearedIdentity) { 9713 ident = Binder.clearCallingIdentity(); 9714 } 9715 try { 9716 if (holder != null) { 9717 removeContentProviderExternalUnchecked(name, null, userId); 9718 } 9719 } finally { 9720 Binder.restoreCallingIdentity(ident); 9721 } 9722 } 9723 9724 return null; 9725 } 9726 9727 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9728 if (UserHandle.getUserId(callingUid) == userId) { 9729 return true; 9730 } 9731 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9732 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9733 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9734 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9735 return true; 9736 } 9737 return false; 9738 } 9739 9740 // ========================================================= 9741 // GLOBAL MANAGEMENT 9742 // ========================================================= 9743 9744 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9745 boolean isolated, int isolatedUid) { 9746 String proc = customProcess != null ? customProcess : info.processName; 9747 BatteryStatsImpl.Uid.Proc ps = null; 9748 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9749 int uid = info.uid; 9750 if (isolated) { 9751 if (isolatedUid == 0) { 9752 int userId = UserHandle.getUserId(uid); 9753 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9754 while (true) { 9755 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9756 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9757 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9758 } 9759 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9760 mNextIsolatedProcessUid++; 9761 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9762 // No process for this uid, use it. 9763 break; 9764 } 9765 stepsLeft--; 9766 if (stepsLeft <= 0) { 9767 return null; 9768 } 9769 } 9770 } else { 9771 // Special case for startIsolatedProcess (internal only), where 9772 // the uid of the isolated process is specified by the caller. 9773 uid = isolatedUid; 9774 } 9775 } 9776 return new ProcessRecord(stats, info, proc, uid); 9777 } 9778 9779 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9780 String abiOverride) { 9781 ProcessRecord app; 9782 if (!isolated) { 9783 app = getProcessRecordLocked(info.processName, info.uid, true); 9784 } else { 9785 app = null; 9786 } 9787 9788 if (app == null) { 9789 app = newProcessRecordLocked(info, null, isolated, 0); 9790 mProcessNames.put(info.processName, app.uid, app); 9791 if (isolated) { 9792 mIsolatedProcesses.put(app.uid, app); 9793 } 9794 updateLruProcessLocked(app, false, null); 9795 updateOomAdjLocked(); 9796 } 9797 9798 // This package really, really can not be stopped. 9799 try { 9800 AppGlobals.getPackageManager().setPackageStoppedState( 9801 info.packageName, false, UserHandle.getUserId(app.uid)); 9802 } catch (RemoteException e) { 9803 } catch (IllegalArgumentException e) { 9804 Slog.w(TAG, "Failed trying to unstop package " 9805 + info.packageName + ": " + e); 9806 } 9807 9808 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9809 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9810 app.persistent = true; 9811 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9812 } 9813 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9814 mPersistentStartingProcesses.add(app); 9815 startProcessLocked(app, "added application", app.processName, abiOverride, 9816 null /* entryPoint */, null /* entryPointArgs */); 9817 } 9818 9819 return app; 9820 } 9821 9822 public void unhandledBack() { 9823 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9824 "unhandledBack()"); 9825 9826 synchronized(this) { 9827 final long origId = Binder.clearCallingIdentity(); 9828 try { 9829 getFocusedStack().unhandledBackLocked(); 9830 } finally { 9831 Binder.restoreCallingIdentity(origId); 9832 } 9833 } 9834 } 9835 9836 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9837 enforceNotIsolatedCaller("openContentUri"); 9838 final int userId = UserHandle.getCallingUserId(); 9839 String name = uri.getAuthority(); 9840 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9841 ParcelFileDescriptor pfd = null; 9842 if (cph != null) { 9843 // We record the binder invoker's uid in thread-local storage before 9844 // going to the content provider to open the file. Later, in the code 9845 // that handles all permissions checks, we look for this uid and use 9846 // that rather than the Activity Manager's own uid. The effect is that 9847 // we do the check against the caller's permissions even though it looks 9848 // to the content provider like the Activity Manager itself is making 9849 // the request. 9850 sCallerIdentity.set(new Identity( 9851 Binder.getCallingPid(), Binder.getCallingUid())); 9852 try { 9853 pfd = cph.provider.openFile(null, uri, "r", null); 9854 } catch (FileNotFoundException e) { 9855 // do nothing; pfd will be returned null 9856 } finally { 9857 // Ensure that whatever happens, we clean up the identity state 9858 sCallerIdentity.remove(); 9859 } 9860 9861 // We've got the fd now, so we're done with the provider. 9862 removeContentProviderExternalUnchecked(name, null, userId); 9863 } else { 9864 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9865 } 9866 return pfd; 9867 } 9868 9869 // Actually is sleeping or shutting down or whatever else in the future 9870 // is an inactive state. 9871 public boolean isSleepingOrShuttingDown() { 9872 return isSleeping() || mShuttingDown; 9873 } 9874 9875 public boolean isSleeping() { 9876 return mSleeping; 9877 } 9878 9879 void goingToSleep() { 9880 synchronized(this) { 9881 mWentToSleep = true; 9882 goToSleepIfNeededLocked(); 9883 } 9884 } 9885 9886 void finishRunningVoiceLocked() { 9887 if (mRunningVoice) { 9888 mRunningVoice = false; 9889 goToSleepIfNeededLocked(); 9890 } 9891 } 9892 9893 void goToSleepIfNeededLocked() { 9894 if (mWentToSleep && !mRunningVoice) { 9895 if (!mSleeping) { 9896 mSleeping = true; 9897 mStackSupervisor.goingToSleepLocked(); 9898 9899 // Initialize the wake times of all processes. 9900 checkExcessivePowerUsageLocked(false); 9901 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9902 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9903 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9904 } 9905 } 9906 } 9907 9908 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9909 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9910 // Never persist the home stack. 9911 return; 9912 } 9913 mTaskPersister.wakeup(task, flush); 9914 } 9915 9916 @Override 9917 public boolean shutdown(int timeout) { 9918 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9919 != PackageManager.PERMISSION_GRANTED) { 9920 throw new SecurityException("Requires permission " 9921 + android.Manifest.permission.SHUTDOWN); 9922 } 9923 9924 boolean timedout = false; 9925 9926 synchronized(this) { 9927 mShuttingDown = true; 9928 updateEventDispatchingLocked(); 9929 timedout = mStackSupervisor.shutdownLocked(timeout); 9930 } 9931 9932 mAppOpsService.shutdown(); 9933 if (mUsageStatsService != null) { 9934 mUsageStatsService.prepareShutdown(); 9935 } 9936 mBatteryStatsService.shutdown(); 9937 synchronized (this) { 9938 mProcessStats.shutdownLocked(); 9939 } 9940 notifyTaskPersisterLocked(null, true); 9941 9942 return timedout; 9943 } 9944 9945 public final void activitySlept(IBinder token) { 9946 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9947 9948 final long origId = Binder.clearCallingIdentity(); 9949 9950 synchronized (this) { 9951 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9952 if (r != null) { 9953 mStackSupervisor.activitySleptLocked(r); 9954 } 9955 } 9956 9957 Binder.restoreCallingIdentity(origId); 9958 } 9959 9960 void logLockScreen(String msg) { 9961 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9962 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9963 mWentToSleep + " mSleeping=" + mSleeping); 9964 } 9965 9966 private void comeOutOfSleepIfNeededLocked() { 9967 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9968 if (mSleeping) { 9969 mSleeping = false; 9970 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9971 } 9972 } 9973 } 9974 9975 void wakingUp() { 9976 synchronized(this) { 9977 mWentToSleep = false; 9978 comeOutOfSleepIfNeededLocked(); 9979 } 9980 } 9981 9982 void startRunningVoiceLocked() { 9983 if (!mRunningVoice) { 9984 mRunningVoice = true; 9985 comeOutOfSleepIfNeededLocked(); 9986 } 9987 } 9988 9989 private void updateEventDispatchingLocked() { 9990 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9991 } 9992 9993 public void setLockScreenShown(boolean shown) { 9994 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9995 != PackageManager.PERMISSION_GRANTED) { 9996 throw new SecurityException("Requires permission " 9997 + android.Manifest.permission.DEVICE_POWER); 9998 } 9999 10000 synchronized(this) { 10001 long ident = Binder.clearCallingIdentity(); 10002 try { 10003 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10004 mLockScreenShown = shown; 10005 comeOutOfSleepIfNeededLocked(); 10006 } finally { 10007 Binder.restoreCallingIdentity(ident); 10008 } 10009 } 10010 } 10011 10012 @Override 10013 public void stopAppSwitches() { 10014 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10015 != PackageManager.PERMISSION_GRANTED) { 10016 throw new SecurityException("Requires permission " 10017 + android.Manifest.permission.STOP_APP_SWITCHES); 10018 } 10019 10020 synchronized(this) { 10021 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10022 + APP_SWITCH_DELAY_TIME; 10023 mDidAppSwitch = false; 10024 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10025 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10026 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10027 } 10028 } 10029 10030 public void resumeAppSwitches() { 10031 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10032 != PackageManager.PERMISSION_GRANTED) { 10033 throw new SecurityException("Requires permission " 10034 + android.Manifest.permission.STOP_APP_SWITCHES); 10035 } 10036 10037 synchronized(this) { 10038 // Note that we don't execute any pending app switches... we will 10039 // let those wait until either the timeout, or the next start 10040 // activity request. 10041 mAppSwitchesAllowedTime = 0; 10042 } 10043 } 10044 10045 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10046 int callingPid, int callingUid, String name) { 10047 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10048 return true; 10049 } 10050 10051 int perm = checkComponentPermission( 10052 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10053 sourceUid, -1, true); 10054 if (perm == PackageManager.PERMISSION_GRANTED) { 10055 return true; 10056 } 10057 10058 // If the actual IPC caller is different from the logical source, then 10059 // also see if they are allowed to control app switches. 10060 if (callingUid != -1 && callingUid != sourceUid) { 10061 perm = checkComponentPermission( 10062 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10063 callingUid, -1, true); 10064 if (perm == PackageManager.PERMISSION_GRANTED) { 10065 return true; 10066 } 10067 } 10068 10069 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10070 return false; 10071 } 10072 10073 public void setDebugApp(String packageName, boolean waitForDebugger, 10074 boolean persistent) { 10075 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10076 "setDebugApp()"); 10077 10078 long ident = Binder.clearCallingIdentity(); 10079 try { 10080 // Note that this is not really thread safe if there are multiple 10081 // callers into it at the same time, but that's not a situation we 10082 // care about. 10083 if (persistent) { 10084 final ContentResolver resolver = mContext.getContentResolver(); 10085 Settings.Global.putString( 10086 resolver, Settings.Global.DEBUG_APP, 10087 packageName); 10088 Settings.Global.putInt( 10089 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10090 waitForDebugger ? 1 : 0); 10091 } 10092 10093 synchronized (this) { 10094 if (!persistent) { 10095 mOrigDebugApp = mDebugApp; 10096 mOrigWaitForDebugger = mWaitForDebugger; 10097 } 10098 mDebugApp = packageName; 10099 mWaitForDebugger = waitForDebugger; 10100 mDebugTransient = !persistent; 10101 if (packageName != null) { 10102 forceStopPackageLocked(packageName, -1, false, false, true, true, 10103 false, UserHandle.USER_ALL, "set debug app"); 10104 } 10105 } 10106 } finally { 10107 Binder.restoreCallingIdentity(ident); 10108 } 10109 } 10110 10111 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10112 synchronized (this) { 10113 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10114 if (!isDebuggable) { 10115 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10116 throw new SecurityException("Process not debuggable: " + app.packageName); 10117 } 10118 } 10119 10120 mOpenGlTraceApp = processName; 10121 } 10122 } 10123 10124 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10125 synchronized (this) { 10126 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10127 if (!isDebuggable) { 10128 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10129 throw new SecurityException("Process not debuggable: " + app.packageName); 10130 } 10131 } 10132 mProfileApp = processName; 10133 mProfileFile = profilerInfo.profileFile; 10134 if (mProfileFd != null) { 10135 try { 10136 mProfileFd.close(); 10137 } catch (IOException e) { 10138 } 10139 mProfileFd = null; 10140 } 10141 mProfileFd = profilerInfo.profileFd; 10142 mSamplingInterval = profilerInfo.samplingInterval; 10143 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10144 mProfileType = 0; 10145 } 10146 } 10147 10148 @Override 10149 public void setAlwaysFinish(boolean enabled) { 10150 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10151 "setAlwaysFinish()"); 10152 10153 Settings.Global.putInt( 10154 mContext.getContentResolver(), 10155 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10156 10157 synchronized (this) { 10158 mAlwaysFinishActivities = enabled; 10159 } 10160 } 10161 10162 @Override 10163 public void setActivityController(IActivityController controller) { 10164 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10165 "setActivityController()"); 10166 synchronized (this) { 10167 mController = controller; 10168 Watchdog.getInstance().setActivityController(controller); 10169 } 10170 } 10171 10172 @Override 10173 public void setUserIsMonkey(boolean userIsMonkey) { 10174 synchronized (this) { 10175 synchronized (mPidsSelfLocked) { 10176 final int callingPid = Binder.getCallingPid(); 10177 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10178 if (precessRecord == null) { 10179 throw new SecurityException("Unknown process: " + callingPid); 10180 } 10181 if (precessRecord.instrumentationUiAutomationConnection == null) { 10182 throw new SecurityException("Only an instrumentation process " 10183 + "with a UiAutomation can call setUserIsMonkey"); 10184 } 10185 } 10186 mUserIsMonkey = userIsMonkey; 10187 } 10188 } 10189 10190 @Override 10191 public boolean isUserAMonkey() { 10192 synchronized (this) { 10193 // If there is a controller also implies the user is a monkey. 10194 return (mUserIsMonkey || mController != null); 10195 } 10196 } 10197 10198 public void requestBugReport() { 10199 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10200 SystemProperties.set("ctl.start", "bugreport"); 10201 } 10202 10203 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10204 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10205 } 10206 10207 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10208 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10209 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10210 } 10211 return KEY_DISPATCHING_TIMEOUT; 10212 } 10213 10214 @Override 10215 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10216 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10217 != PackageManager.PERMISSION_GRANTED) { 10218 throw new SecurityException("Requires permission " 10219 + android.Manifest.permission.FILTER_EVENTS); 10220 } 10221 ProcessRecord proc; 10222 long timeout; 10223 synchronized (this) { 10224 synchronized (mPidsSelfLocked) { 10225 proc = mPidsSelfLocked.get(pid); 10226 } 10227 timeout = getInputDispatchingTimeoutLocked(proc); 10228 } 10229 10230 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10231 return -1; 10232 } 10233 10234 return timeout; 10235 } 10236 10237 /** 10238 * Handle input dispatching timeouts. 10239 * Returns whether input dispatching should be aborted or not. 10240 */ 10241 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10242 final ActivityRecord activity, final ActivityRecord parent, 10243 final boolean aboveSystem, String reason) { 10244 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10245 != PackageManager.PERMISSION_GRANTED) { 10246 throw new SecurityException("Requires permission " 10247 + android.Manifest.permission.FILTER_EVENTS); 10248 } 10249 10250 final String annotation; 10251 if (reason == null) { 10252 annotation = "Input dispatching timed out"; 10253 } else { 10254 annotation = "Input dispatching timed out (" + reason + ")"; 10255 } 10256 10257 if (proc != null) { 10258 synchronized (this) { 10259 if (proc.debugging) { 10260 return false; 10261 } 10262 10263 if (mDidDexOpt) { 10264 // Give more time since we were dexopting. 10265 mDidDexOpt = false; 10266 return false; 10267 } 10268 10269 if (proc.instrumentationClass != null) { 10270 Bundle info = new Bundle(); 10271 info.putString("shortMsg", "keyDispatchingTimedOut"); 10272 info.putString("longMsg", annotation); 10273 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10274 return true; 10275 } 10276 } 10277 mHandler.post(new Runnable() { 10278 @Override 10279 public void run() { 10280 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10281 } 10282 }); 10283 } 10284 10285 return true; 10286 } 10287 10288 public Bundle getAssistContextExtras(int requestType) { 10289 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10290 UserHandle.getCallingUserId()); 10291 if (pae == null) { 10292 return null; 10293 } 10294 synchronized (pae) { 10295 while (!pae.haveResult) { 10296 try { 10297 pae.wait(); 10298 } catch (InterruptedException e) { 10299 } 10300 } 10301 if (pae.result != null) { 10302 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10303 } 10304 } 10305 synchronized (this) { 10306 mPendingAssistExtras.remove(pae); 10307 mHandler.removeCallbacks(pae); 10308 } 10309 return pae.extras; 10310 } 10311 10312 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10313 int userHandle) { 10314 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10315 "getAssistContextExtras()"); 10316 PendingAssistExtras pae; 10317 Bundle extras = new Bundle(); 10318 synchronized (this) { 10319 ActivityRecord activity = getFocusedStack().mResumedActivity; 10320 if (activity == null) { 10321 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10322 return null; 10323 } 10324 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10325 if (activity.app == null || activity.app.thread == null) { 10326 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10327 return null; 10328 } 10329 if (activity.app.pid == Binder.getCallingPid()) { 10330 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10331 return null; 10332 } 10333 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10334 try { 10335 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10336 requestType); 10337 mPendingAssistExtras.add(pae); 10338 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10339 } catch (RemoteException e) { 10340 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10341 return null; 10342 } 10343 return pae; 10344 } 10345 } 10346 10347 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10348 PendingAssistExtras pae = (PendingAssistExtras)token; 10349 synchronized (pae) { 10350 pae.result = extras; 10351 pae.haveResult = true; 10352 pae.notifyAll(); 10353 if (pae.intent == null) { 10354 // Caller is just waiting for the result. 10355 return; 10356 } 10357 } 10358 10359 // We are now ready to launch the assist activity. 10360 synchronized (this) { 10361 boolean exists = mPendingAssistExtras.remove(pae); 10362 mHandler.removeCallbacks(pae); 10363 if (!exists) { 10364 // Timed out. 10365 return; 10366 } 10367 } 10368 pae.intent.replaceExtras(extras); 10369 if (pae.hint != null) { 10370 pae.intent.putExtra(pae.hint, true); 10371 } 10372 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10373 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10374 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10375 closeSystemDialogs("assist"); 10376 try { 10377 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10378 } catch (ActivityNotFoundException e) { 10379 Slog.w(TAG, "No activity to handle assist action.", e); 10380 } 10381 } 10382 10383 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10384 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10385 } 10386 10387 public void registerProcessObserver(IProcessObserver observer) { 10388 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10389 "registerProcessObserver()"); 10390 synchronized (this) { 10391 mProcessObservers.register(observer); 10392 } 10393 } 10394 10395 @Override 10396 public void unregisterProcessObserver(IProcessObserver observer) { 10397 synchronized (this) { 10398 mProcessObservers.unregister(observer); 10399 } 10400 } 10401 10402 @Override 10403 public boolean convertFromTranslucent(IBinder token) { 10404 final long origId = Binder.clearCallingIdentity(); 10405 try { 10406 synchronized (this) { 10407 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10408 if (r == null) { 10409 return false; 10410 } 10411 final boolean translucentChanged = r.changeWindowTranslucency(true); 10412 if (translucentChanged) { 10413 r.task.stack.releaseBackgroundResources(); 10414 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10415 } 10416 mWindowManager.setAppFullscreen(token, true); 10417 return translucentChanged; 10418 } 10419 } finally { 10420 Binder.restoreCallingIdentity(origId); 10421 } 10422 } 10423 10424 @Override 10425 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10426 final long origId = Binder.clearCallingIdentity(); 10427 try { 10428 synchronized (this) { 10429 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10430 if (r == null) { 10431 return false; 10432 } 10433 int index = r.task.mActivities.lastIndexOf(r); 10434 if (index > 0) { 10435 ActivityRecord under = r.task.mActivities.get(index - 1); 10436 under.returningOptions = options; 10437 } 10438 final boolean translucentChanged = r.changeWindowTranslucency(false); 10439 if (translucentChanged) { 10440 r.task.stack.convertToTranslucent(r); 10441 } 10442 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10443 mWindowManager.setAppFullscreen(token, false); 10444 return translucentChanged; 10445 } 10446 } finally { 10447 Binder.restoreCallingIdentity(origId); 10448 } 10449 } 10450 10451 @Override 10452 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10453 final long origId = Binder.clearCallingIdentity(); 10454 try { 10455 synchronized (this) { 10456 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10457 if (r != null) { 10458 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10459 } 10460 } 10461 return false; 10462 } finally { 10463 Binder.restoreCallingIdentity(origId); 10464 } 10465 } 10466 10467 @Override 10468 public boolean isBackgroundVisibleBehind(IBinder token) { 10469 final long origId = Binder.clearCallingIdentity(); 10470 try { 10471 synchronized (this) { 10472 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10473 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10474 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10475 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10476 return visible; 10477 } 10478 } finally { 10479 Binder.restoreCallingIdentity(origId); 10480 } 10481 } 10482 10483 @Override 10484 public ActivityOptions getActivityOptions(IBinder token) { 10485 final long origId = Binder.clearCallingIdentity(); 10486 try { 10487 synchronized (this) { 10488 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10489 if (r != null) { 10490 final ActivityOptions activityOptions = r.pendingOptions; 10491 r.pendingOptions = null; 10492 return activityOptions; 10493 } 10494 return null; 10495 } 10496 } finally { 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 } 10500 10501 @Override 10502 public void setImmersive(IBinder token, boolean immersive) { 10503 synchronized(this) { 10504 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10505 if (r == null) { 10506 throw new IllegalArgumentException(); 10507 } 10508 r.immersive = immersive; 10509 10510 // update associated state if we're frontmost 10511 if (r == mFocusedActivity) { 10512 if (DEBUG_IMMERSIVE) { 10513 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10514 } 10515 applyUpdateLockStateLocked(r); 10516 } 10517 } 10518 } 10519 10520 @Override 10521 public boolean isImmersive(IBinder token) { 10522 synchronized (this) { 10523 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10524 if (r == null) { 10525 throw new IllegalArgumentException(); 10526 } 10527 return r.immersive; 10528 } 10529 } 10530 10531 public boolean isTopActivityImmersive() { 10532 enforceNotIsolatedCaller("startActivity"); 10533 synchronized (this) { 10534 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10535 return (r != null) ? r.immersive : false; 10536 } 10537 } 10538 10539 @Override 10540 public boolean isTopOfTask(IBinder token) { 10541 synchronized (this) { 10542 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10543 if (r == null) { 10544 throw new IllegalArgumentException(); 10545 } 10546 return r.task.getTopActivity() == r; 10547 } 10548 } 10549 10550 public final void enterSafeMode() { 10551 synchronized(this) { 10552 // It only makes sense to do this before the system is ready 10553 // and started launching other packages. 10554 if (!mSystemReady) { 10555 try { 10556 AppGlobals.getPackageManager().enterSafeMode(); 10557 } catch (RemoteException e) { 10558 } 10559 } 10560 10561 mSafeMode = true; 10562 } 10563 } 10564 10565 public final void showSafeModeOverlay() { 10566 View v = LayoutInflater.from(mContext).inflate( 10567 com.android.internal.R.layout.safe_mode, null); 10568 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10569 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10570 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10571 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10572 lp.gravity = Gravity.BOTTOM | Gravity.START; 10573 lp.format = v.getBackground().getOpacity(); 10574 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10575 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10576 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10577 ((WindowManager)mContext.getSystemService( 10578 Context.WINDOW_SERVICE)).addView(v, lp); 10579 } 10580 10581 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10582 if (!(sender instanceof PendingIntentRecord)) { 10583 return; 10584 } 10585 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10586 synchronized (stats) { 10587 if (mBatteryStatsService.isOnBattery()) { 10588 mBatteryStatsService.enforceCallingPermission(); 10589 PendingIntentRecord rec = (PendingIntentRecord)sender; 10590 int MY_UID = Binder.getCallingUid(); 10591 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10592 BatteryStatsImpl.Uid.Pkg pkg = 10593 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10594 sourcePkg != null ? sourcePkg : rec.key.packageName); 10595 pkg.incWakeupsLocked(); 10596 } 10597 } 10598 } 10599 10600 public boolean killPids(int[] pids, String pReason, boolean secure) { 10601 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10602 throw new SecurityException("killPids only available to the system"); 10603 } 10604 String reason = (pReason == null) ? "Unknown" : pReason; 10605 // XXX Note: don't acquire main activity lock here, because the window 10606 // manager calls in with its locks held. 10607 10608 boolean killed = false; 10609 synchronized (mPidsSelfLocked) { 10610 int[] types = new int[pids.length]; 10611 int worstType = 0; 10612 for (int i=0; i<pids.length; i++) { 10613 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10614 if (proc != null) { 10615 int type = proc.setAdj; 10616 types[i] = type; 10617 if (type > worstType) { 10618 worstType = type; 10619 } 10620 } 10621 } 10622 10623 // If the worst oom_adj is somewhere in the cached proc LRU range, 10624 // then constrain it so we will kill all cached procs. 10625 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10626 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10627 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10628 } 10629 10630 // If this is not a secure call, don't let it kill processes that 10631 // are important. 10632 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10633 worstType = ProcessList.SERVICE_ADJ; 10634 } 10635 10636 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10637 for (int i=0; i<pids.length; i++) { 10638 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10639 if (proc == null) { 10640 continue; 10641 } 10642 int adj = proc.setAdj; 10643 if (adj >= worstType && !proc.killedByAm) { 10644 proc.kill(reason, true); 10645 killed = true; 10646 } 10647 } 10648 } 10649 return killed; 10650 } 10651 10652 @Override 10653 public void killUid(int uid, String reason) { 10654 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10655 throw new SecurityException("killUid only available to the system"); 10656 } 10657 synchronized (this) { 10658 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10659 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10660 reason != null ? reason : "kill uid"); 10661 } 10662 } 10663 10664 @Override 10665 public boolean killProcessesBelowForeground(String reason) { 10666 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10667 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10668 } 10669 10670 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10671 } 10672 10673 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10674 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10675 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10676 } 10677 10678 boolean killed = false; 10679 synchronized (mPidsSelfLocked) { 10680 final int size = mPidsSelfLocked.size(); 10681 for (int i = 0; i < size; i++) { 10682 final int pid = mPidsSelfLocked.keyAt(i); 10683 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10684 if (proc == null) continue; 10685 10686 final int adj = proc.setAdj; 10687 if (adj > belowAdj && !proc.killedByAm) { 10688 proc.kill(reason, true); 10689 killed = true; 10690 } 10691 } 10692 } 10693 return killed; 10694 } 10695 10696 @Override 10697 public void hang(final IBinder who, boolean allowRestart) { 10698 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10699 != PackageManager.PERMISSION_GRANTED) { 10700 throw new SecurityException("Requires permission " 10701 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10702 } 10703 10704 final IBinder.DeathRecipient death = new DeathRecipient() { 10705 @Override 10706 public void binderDied() { 10707 synchronized (this) { 10708 notifyAll(); 10709 } 10710 } 10711 }; 10712 10713 try { 10714 who.linkToDeath(death, 0); 10715 } catch (RemoteException e) { 10716 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10717 return; 10718 } 10719 10720 synchronized (this) { 10721 Watchdog.getInstance().setAllowRestart(allowRestart); 10722 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10723 synchronized (death) { 10724 while (who.isBinderAlive()) { 10725 try { 10726 death.wait(); 10727 } catch (InterruptedException e) { 10728 } 10729 } 10730 } 10731 Watchdog.getInstance().setAllowRestart(true); 10732 } 10733 } 10734 10735 @Override 10736 public void restart() { 10737 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10738 != PackageManager.PERMISSION_GRANTED) { 10739 throw new SecurityException("Requires permission " 10740 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10741 } 10742 10743 Log.i(TAG, "Sending shutdown broadcast..."); 10744 10745 BroadcastReceiver br = new BroadcastReceiver() { 10746 @Override public void onReceive(Context context, Intent intent) { 10747 // Now the broadcast is done, finish up the low-level shutdown. 10748 Log.i(TAG, "Shutting down activity manager..."); 10749 shutdown(10000); 10750 Log.i(TAG, "Shutdown complete, restarting!"); 10751 Process.killProcess(Process.myPid()); 10752 System.exit(10); 10753 } 10754 }; 10755 10756 // First send the high-level shut down broadcast. 10757 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10758 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10759 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10760 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10761 mContext.sendOrderedBroadcastAsUser(intent, 10762 UserHandle.ALL, null, br, mHandler, 0, null, null); 10763 */ 10764 br.onReceive(mContext, intent); 10765 } 10766 10767 private long getLowRamTimeSinceIdle(long now) { 10768 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10769 } 10770 10771 @Override 10772 public void performIdleMaintenance() { 10773 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10774 != PackageManager.PERMISSION_GRANTED) { 10775 throw new SecurityException("Requires permission " 10776 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10777 } 10778 10779 synchronized (this) { 10780 final long now = SystemClock.uptimeMillis(); 10781 final long timeSinceLastIdle = now - mLastIdleTime; 10782 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10783 mLastIdleTime = now; 10784 mLowRamTimeSinceLastIdle = 0; 10785 if (mLowRamStartTime != 0) { 10786 mLowRamStartTime = now; 10787 } 10788 10789 StringBuilder sb = new StringBuilder(128); 10790 sb.append("Idle maintenance over "); 10791 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10792 sb.append(" low RAM for "); 10793 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10794 Slog.i(TAG, sb.toString()); 10795 10796 // If at least 1/3 of our time since the last idle period has been spent 10797 // with RAM low, then we want to kill processes. 10798 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10799 10800 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10801 ProcessRecord proc = mLruProcesses.get(i); 10802 if (proc.notCachedSinceIdle) { 10803 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10804 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10805 if (doKilling && proc.initialIdlePss != 0 10806 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10807 proc.kill("idle maint (pss " + proc.lastPss 10808 + " from " + proc.initialIdlePss + ")", true); 10809 } 10810 } 10811 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10812 proc.notCachedSinceIdle = true; 10813 proc.initialIdlePss = 0; 10814 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10815 isSleeping(), now); 10816 } 10817 } 10818 10819 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10820 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10821 } 10822 } 10823 10824 private void retrieveSettings() { 10825 final ContentResolver resolver = mContext.getContentResolver(); 10826 String debugApp = Settings.Global.getString( 10827 resolver, Settings.Global.DEBUG_APP); 10828 boolean waitForDebugger = Settings.Global.getInt( 10829 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10830 boolean alwaysFinishActivities = Settings.Global.getInt( 10831 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10832 boolean forceRtl = Settings.Global.getInt( 10833 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10834 // Transfer any global setting for forcing RTL layout, into a System Property 10835 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10836 10837 Configuration configuration = new Configuration(); 10838 Settings.System.getConfiguration(resolver, configuration); 10839 if (forceRtl) { 10840 // This will take care of setting the correct layout direction flags 10841 configuration.setLayoutDirection(configuration.locale); 10842 } 10843 10844 synchronized (this) { 10845 mDebugApp = mOrigDebugApp = debugApp; 10846 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10847 mAlwaysFinishActivities = alwaysFinishActivities; 10848 // This happens before any activities are started, so we can 10849 // change mConfiguration in-place. 10850 updateConfigurationLocked(configuration, null, false, true); 10851 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10852 } 10853 } 10854 10855 /** Loads resources after the current configuration has been set. */ 10856 private void loadResourcesOnSystemReady() { 10857 final Resources res = mContext.getResources(); 10858 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10859 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10860 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10861 } 10862 10863 public boolean testIsSystemReady() { 10864 // no need to synchronize(this) just to read & return the value 10865 return mSystemReady; 10866 } 10867 10868 private static File getCalledPreBootReceiversFile() { 10869 File dataDir = Environment.getDataDirectory(); 10870 File systemDir = new File(dataDir, "system"); 10871 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10872 return fname; 10873 } 10874 10875 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10876 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10877 File file = getCalledPreBootReceiversFile(); 10878 FileInputStream fis = null; 10879 try { 10880 fis = new FileInputStream(file); 10881 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10882 int fvers = dis.readInt(); 10883 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10884 String vers = dis.readUTF(); 10885 String codename = dis.readUTF(); 10886 String build = dis.readUTF(); 10887 if (android.os.Build.VERSION.RELEASE.equals(vers) 10888 && android.os.Build.VERSION.CODENAME.equals(codename) 10889 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10890 int num = dis.readInt(); 10891 while (num > 0) { 10892 num--; 10893 String pkg = dis.readUTF(); 10894 String cls = dis.readUTF(); 10895 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10896 } 10897 } 10898 } 10899 } catch (FileNotFoundException e) { 10900 } catch (IOException e) { 10901 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10902 } finally { 10903 if (fis != null) { 10904 try { 10905 fis.close(); 10906 } catch (IOException e) { 10907 } 10908 } 10909 } 10910 return lastDoneReceivers; 10911 } 10912 10913 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10914 File file = getCalledPreBootReceiversFile(); 10915 FileOutputStream fos = null; 10916 DataOutputStream dos = null; 10917 try { 10918 fos = new FileOutputStream(file); 10919 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10920 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10921 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10922 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10923 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10924 dos.writeInt(list.size()); 10925 for (int i=0; i<list.size(); i++) { 10926 dos.writeUTF(list.get(i).getPackageName()); 10927 dos.writeUTF(list.get(i).getClassName()); 10928 } 10929 } catch (IOException e) { 10930 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10931 file.delete(); 10932 } finally { 10933 FileUtils.sync(fos); 10934 if (dos != null) { 10935 try { 10936 dos.close(); 10937 } catch (IOException e) { 10938 // TODO Auto-generated catch block 10939 e.printStackTrace(); 10940 } 10941 } 10942 } 10943 } 10944 10945 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10946 ArrayList<ComponentName> doneReceivers, int userId) { 10947 boolean waitingUpdate = false; 10948 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10949 List<ResolveInfo> ris = null; 10950 try { 10951 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10952 intent, null, 0, userId); 10953 } catch (RemoteException e) { 10954 } 10955 if (ris != null) { 10956 for (int i=ris.size()-1; i>=0; i--) { 10957 if ((ris.get(i).activityInfo.applicationInfo.flags 10958 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10959 ris.remove(i); 10960 } 10961 } 10962 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10963 10964 // For User 0, load the version number. When delivering to a new user, deliver 10965 // to all receivers. 10966 if (userId == UserHandle.USER_OWNER) { 10967 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10968 for (int i=0; i<ris.size(); i++) { 10969 ActivityInfo ai = ris.get(i).activityInfo; 10970 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10971 if (lastDoneReceivers.contains(comp)) { 10972 // We already did the pre boot receiver for this app with the current 10973 // platform version, so don't do it again... 10974 ris.remove(i); 10975 i--; 10976 // ...however, do keep it as one that has been done, so we don't 10977 // forget about it when rewriting the file of last done receivers. 10978 doneReceivers.add(comp); 10979 } 10980 } 10981 } 10982 10983 // If primary user, send broadcast to all available users, else just to userId 10984 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10985 : new int[] { userId }; 10986 for (int i = 0; i < ris.size(); i++) { 10987 ActivityInfo ai = ris.get(i).activityInfo; 10988 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10989 doneReceivers.add(comp); 10990 intent.setComponent(comp); 10991 for (int j=0; j<users.length; j++) { 10992 IIntentReceiver finisher = null; 10993 // On last receiver and user, set up a completion callback 10994 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10995 finisher = new IIntentReceiver.Stub() { 10996 public void performReceive(Intent intent, int resultCode, 10997 String data, Bundle extras, boolean ordered, 10998 boolean sticky, int sendingUser) { 10999 // The raw IIntentReceiver interface is called 11000 // with the AM lock held, so redispatch to 11001 // execute our code without the lock. 11002 mHandler.post(onFinishCallback); 11003 } 11004 }; 11005 } 11006 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11007 + " for user " + users[j]); 11008 broadcastIntentLocked(null, null, intent, null, finisher, 11009 0, null, null, null, AppOpsManager.OP_NONE, 11010 true, false, MY_PID, Process.SYSTEM_UID, 11011 users[j]); 11012 if (finisher != null) { 11013 waitingUpdate = true; 11014 } 11015 } 11016 } 11017 } 11018 11019 return waitingUpdate; 11020 } 11021 11022 public void systemReady(final Runnable goingCallback) { 11023 synchronized(this) { 11024 if (mSystemReady) { 11025 // If we're done calling all the receivers, run the next "boot phase" passed in 11026 // by the SystemServer 11027 if (goingCallback != null) { 11028 goingCallback.run(); 11029 } 11030 return; 11031 } 11032 11033 // Make sure we have the current profile info, since it is needed for 11034 // security checks. 11035 updateCurrentProfileIdsLocked(); 11036 11037 if (mRecentTasks == null) { 11038 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11039 if (!mRecentTasks.isEmpty()) { 11040 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11041 } 11042 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11043 mTaskPersister.startPersisting(); 11044 } 11045 11046 // Check to see if there are any update receivers to run. 11047 if (!mDidUpdate) { 11048 if (mWaitingUpdate) { 11049 return; 11050 } 11051 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11052 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11053 public void run() { 11054 synchronized (ActivityManagerService.this) { 11055 mDidUpdate = true; 11056 } 11057 writeLastDonePreBootReceivers(doneReceivers); 11058 showBootMessage(mContext.getText( 11059 R.string.android_upgrading_complete), 11060 false); 11061 systemReady(goingCallback); 11062 } 11063 }, doneReceivers, UserHandle.USER_OWNER); 11064 11065 if (mWaitingUpdate) { 11066 return; 11067 } 11068 mDidUpdate = true; 11069 } 11070 11071 mAppOpsService.systemReady(); 11072 mSystemReady = true; 11073 } 11074 11075 ArrayList<ProcessRecord> procsToKill = null; 11076 synchronized(mPidsSelfLocked) { 11077 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11078 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11079 if (!isAllowedWhileBooting(proc.info)){ 11080 if (procsToKill == null) { 11081 procsToKill = new ArrayList<ProcessRecord>(); 11082 } 11083 procsToKill.add(proc); 11084 } 11085 } 11086 } 11087 11088 synchronized(this) { 11089 if (procsToKill != null) { 11090 for (int i=procsToKill.size()-1; i>=0; i--) { 11091 ProcessRecord proc = procsToKill.get(i); 11092 Slog.i(TAG, "Removing system update proc: " + proc); 11093 removeProcessLocked(proc, true, false, "system update done"); 11094 } 11095 } 11096 11097 // Now that we have cleaned up any update processes, we 11098 // are ready to start launching real processes and know that 11099 // we won't trample on them any more. 11100 mProcessesReady = true; 11101 } 11102 11103 Slog.i(TAG, "System now ready"); 11104 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11105 SystemClock.uptimeMillis()); 11106 11107 synchronized(this) { 11108 // Make sure we have no pre-ready processes sitting around. 11109 11110 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11111 ResolveInfo ri = mContext.getPackageManager() 11112 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11113 STOCK_PM_FLAGS); 11114 CharSequence errorMsg = null; 11115 if (ri != null) { 11116 ActivityInfo ai = ri.activityInfo; 11117 ApplicationInfo app = ai.applicationInfo; 11118 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11119 mTopAction = Intent.ACTION_FACTORY_TEST; 11120 mTopData = null; 11121 mTopComponent = new ComponentName(app.packageName, 11122 ai.name); 11123 } else { 11124 errorMsg = mContext.getResources().getText( 11125 com.android.internal.R.string.factorytest_not_system); 11126 } 11127 } else { 11128 errorMsg = mContext.getResources().getText( 11129 com.android.internal.R.string.factorytest_no_action); 11130 } 11131 if (errorMsg != null) { 11132 mTopAction = null; 11133 mTopData = null; 11134 mTopComponent = null; 11135 Message msg = Message.obtain(); 11136 msg.what = SHOW_FACTORY_ERROR_MSG; 11137 msg.getData().putCharSequence("msg", errorMsg); 11138 mHandler.sendMessage(msg); 11139 } 11140 } 11141 } 11142 11143 retrieveSettings(); 11144 loadResourcesOnSystemReady(); 11145 11146 synchronized (this) { 11147 readGrantedUriPermissionsLocked(); 11148 } 11149 11150 if (goingCallback != null) goingCallback.run(); 11151 11152 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11153 Integer.toString(mCurrentUserId), mCurrentUserId); 11154 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11155 Integer.toString(mCurrentUserId), mCurrentUserId); 11156 mSystemServiceManager.startUser(mCurrentUserId); 11157 11158 synchronized (this) { 11159 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11160 try { 11161 List apps = AppGlobals.getPackageManager(). 11162 getPersistentApplications(STOCK_PM_FLAGS); 11163 if (apps != null) { 11164 int N = apps.size(); 11165 int i; 11166 for (i=0; i<N; i++) { 11167 ApplicationInfo info 11168 = (ApplicationInfo)apps.get(i); 11169 if (info != null && 11170 !info.packageName.equals("android")) { 11171 addAppLocked(info, false, null /* ABI override */); 11172 } 11173 } 11174 } 11175 } catch (RemoteException ex) { 11176 // pm is in same process, this will never happen. 11177 } 11178 } 11179 11180 // Start up initial activity. 11181 mBooting = true; 11182 startHomeActivityLocked(mCurrentUserId); 11183 11184 try { 11185 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11186 Message msg = Message.obtain(); 11187 msg.what = SHOW_UID_ERROR_MSG; 11188 mHandler.sendMessage(msg); 11189 } 11190 } catch (RemoteException e) { 11191 } 11192 11193 long ident = Binder.clearCallingIdentity(); 11194 try { 11195 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11196 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11197 | Intent.FLAG_RECEIVER_FOREGROUND); 11198 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11199 broadcastIntentLocked(null, null, intent, 11200 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11201 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11202 intent = new Intent(Intent.ACTION_USER_STARTING); 11203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11204 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11205 broadcastIntentLocked(null, null, intent, 11206 null, new IIntentReceiver.Stub() { 11207 @Override 11208 public void performReceive(Intent intent, int resultCode, String data, 11209 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11210 throws RemoteException { 11211 } 11212 }, 0, null, null, 11213 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11214 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11215 } catch (Throwable t) { 11216 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11217 } finally { 11218 Binder.restoreCallingIdentity(ident); 11219 } 11220 mStackSupervisor.resumeTopActivitiesLocked(); 11221 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11222 } 11223 } 11224 11225 private boolean makeAppCrashingLocked(ProcessRecord app, 11226 String shortMsg, String longMsg, String stackTrace) { 11227 app.crashing = true; 11228 app.crashingReport = generateProcessError(app, 11229 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11230 startAppProblemLocked(app); 11231 app.stopFreezingAllLocked(); 11232 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11233 } 11234 11235 private void makeAppNotRespondingLocked(ProcessRecord app, 11236 String activity, String shortMsg, String longMsg) { 11237 app.notResponding = true; 11238 app.notRespondingReport = generateProcessError(app, 11239 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11240 activity, shortMsg, longMsg, null); 11241 startAppProblemLocked(app); 11242 app.stopFreezingAllLocked(); 11243 } 11244 11245 /** 11246 * Generate a process error record, suitable for attachment to a ProcessRecord. 11247 * 11248 * @param app The ProcessRecord in which the error occurred. 11249 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11250 * ActivityManager.AppErrorStateInfo 11251 * @param activity The activity associated with the crash, if known. 11252 * @param shortMsg Short message describing the crash. 11253 * @param longMsg Long message describing the crash. 11254 * @param stackTrace Full crash stack trace, may be null. 11255 * 11256 * @return Returns a fully-formed AppErrorStateInfo record. 11257 */ 11258 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11259 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11260 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11261 11262 report.condition = condition; 11263 report.processName = app.processName; 11264 report.pid = app.pid; 11265 report.uid = app.info.uid; 11266 report.tag = activity; 11267 report.shortMsg = shortMsg; 11268 report.longMsg = longMsg; 11269 report.stackTrace = stackTrace; 11270 11271 return report; 11272 } 11273 11274 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11275 synchronized (this) { 11276 app.crashing = false; 11277 app.crashingReport = null; 11278 app.notResponding = false; 11279 app.notRespondingReport = null; 11280 if (app.anrDialog == fromDialog) { 11281 app.anrDialog = null; 11282 } 11283 if (app.waitDialog == fromDialog) { 11284 app.waitDialog = null; 11285 } 11286 if (app.pid > 0 && app.pid != MY_PID) { 11287 handleAppCrashLocked(app, null, null, null); 11288 app.kill("user request after error", true); 11289 } 11290 } 11291 } 11292 11293 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11294 String stackTrace) { 11295 long now = SystemClock.uptimeMillis(); 11296 11297 Long crashTime; 11298 if (!app.isolated) { 11299 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11300 } else { 11301 crashTime = null; 11302 } 11303 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11304 // This process loses! 11305 Slog.w(TAG, "Process " + app.info.processName 11306 + " has crashed too many times: killing!"); 11307 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11308 app.userId, app.info.processName, app.uid); 11309 mStackSupervisor.handleAppCrashLocked(app); 11310 if (!app.persistent) { 11311 // We don't want to start this process again until the user 11312 // explicitly does so... but for persistent process, we really 11313 // need to keep it running. If a persistent process is actually 11314 // repeatedly crashing, then badness for everyone. 11315 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11316 app.info.processName); 11317 if (!app.isolated) { 11318 // XXX We don't have a way to mark isolated processes 11319 // as bad, since they don't have a peristent identity. 11320 mBadProcesses.put(app.info.processName, app.uid, 11321 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11322 mProcessCrashTimes.remove(app.info.processName, app.uid); 11323 } 11324 app.bad = true; 11325 app.removed = true; 11326 // Don't let services in this process be restarted and potentially 11327 // annoy the user repeatedly. Unless it is persistent, since those 11328 // processes run critical code. 11329 removeProcessLocked(app, false, false, "crash"); 11330 mStackSupervisor.resumeTopActivitiesLocked(); 11331 return false; 11332 } 11333 mStackSupervisor.resumeTopActivitiesLocked(); 11334 } else { 11335 mStackSupervisor.finishTopRunningActivityLocked(app); 11336 } 11337 11338 // Bump up the crash count of any services currently running in the proc. 11339 for (int i=app.services.size()-1; i>=0; i--) { 11340 // Any services running in the application need to be placed 11341 // back in the pending list. 11342 ServiceRecord sr = app.services.valueAt(i); 11343 sr.crashCount++; 11344 } 11345 11346 // If the crashing process is what we consider to be the "home process" and it has been 11347 // replaced by a third-party app, clear the package preferred activities from packages 11348 // with a home activity running in the process to prevent a repeatedly crashing app 11349 // from blocking the user to manually clear the list. 11350 final ArrayList<ActivityRecord> activities = app.activities; 11351 if (app == mHomeProcess && activities.size() > 0 11352 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11353 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11354 final ActivityRecord r = activities.get(activityNdx); 11355 if (r.isHomeActivity()) { 11356 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11357 try { 11358 ActivityThread.getPackageManager() 11359 .clearPackagePreferredActivities(r.packageName); 11360 } catch (RemoteException c) { 11361 // pm is in same process, this will never happen. 11362 } 11363 } 11364 } 11365 } 11366 11367 if (!app.isolated) { 11368 // XXX Can't keep track of crash times for isolated processes, 11369 // because they don't have a perisistent identity. 11370 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11371 } 11372 11373 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11374 return true; 11375 } 11376 11377 void startAppProblemLocked(ProcessRecord app) { 11378 // If this app is not running under the current user, then we 11379 // can't give it a report button because that would require 11380 // launching the report UI under a different user. 11381 app.errorReportReceiver = null; 11382 11383 for (int userId : mCurrentProfileIds) { 11384 if (app.userId == userId) { 11385 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11386 mContext, app.info.packageName, app.info.flags); 11387 } 11388 } 11389 skipCurrentReceiverLocked(app); 11390 } 11391 11392 void skipCurrentReceiverLocked(ProcessRecord app) { 11393 for (BroadcastQueue queue : mBroadcastQueues) { 11394 queue.skipCurrentReceiverLocked(app); 11395 } 11396 } 11397 11398 /** 11399 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11400 * The application process will exit immediately after this call returns. 11401 * @param app object of the crashing app, null for the system server 11402 * @param crashInfo describing the exception 11403 */ 11404 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11405 ProcessRecord r = findAppProcess(app, "Crash"); 11406 final String processName = app == null ? "system_server" 11407 : (r == null ? "unknown" : r.processName); 11408 11409 handleApplicationCrashInner("crash", r, processName, crashInfo); 11410 } 11411 11412 /* Native crash reporting uses this inner version because it needs to be somewhat 11413 * decoupled from the AM-managed cleanup lifecycle 11414 */ 11415 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11416 ApplicationErrorReport.CrashInfo crashInfo) { 11417 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11418 UserHandle.getUserId(Binder.getCallingUid()), processName, 11419 r == null ? -1 : r.info.flags, 11420 crashInfo.exceptionClassName, 11421 crashInfo.exceptionMessage, 11422 crashInfo.throwFileName, 11423 crashInfo.throwLineNumber); 11424 11425 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11426 11427 crashApplication(r, crashInfo); 11428 } 11429 11430 public void handleApplicationStrictModeViolation( 11431 IBinder app, 11432 int violationMask, 11433 StrictMode.ViolationInfo info) { 11434 ProcessRecord r = findAppProcess(app, "StrictMode"); 11435 if (r == null) { 11436 return; 11437 } 11438 11439 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11440 Integer stackFingerprint = info.hashCode(); 11441 boolean logIt = true; 11442 synchronized (mAlreadyLoggedViolatedStacks) { 11443 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11444 logIt = false; 11445 // TODO: sub-sample into EventLog for these, with 11446 // the info.durationMillis? Then we'd get 11447 // the relative pain numbers, without logging all 11448 // the stack traces repeatedly. We'd want to do 11449 // likewise in the client code, which also does 11450 // dup suppression, before the Binder call. 11451 } else { 11452 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11453 mAlreadyLoggedViolatedStacks.clear(); 11454 } 11455 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11456 } 11457 } 11458 if (logIt) { 11459 logStrictModeViolationToDropBox(r, info); 11460 } 11461 } 11462 11463 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11464 AppErrorResult result = new AppErrorResult(); 11465 synchronized (this) { 11466 final long origId = Binder.clearCallingIdentity(); 11467 11468 Message msg = Message.obtain(); 11469 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11470 HashMap<String, Object> data = new HashMap<String, Object>(); 11471 data.put("result", result); 11472 data.put("app", r); 11473 data.put("violationMask", violationMask); 11474 data.put("info", info); 11475 msg.obj = data; 11476 mHandler.sendMessage(msg); 11477 11478 Binder.restoreCallingIdentity(origId); 11479 } 11480 int res = result.get(); 11481 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11482 } 11483 } 11484 11485 // Depending on the policy in effect, there could be a bunch of 11486 // these in quick succession so we try to batch these together to 11487 // minimize disk writes, number of dropbox entries, and maximize 11488 // compression, by having more fewer, larger records. 11489 private void logStrictModeViolationToDropBox( 11490 ProcessRecord process, 11491 StrictMode.ViolationInfo info) { 11492 if (info == null) { 11493 return; 11494 } 11495 final boolean isSystemApp = process == null || 11496 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11497 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11498 final String processName = process == null ? "unknown" : process.processName; 11499 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11500 final DropBoxManager dbox = (DropBoxManager) 11501 mContext.getSystemService(Context.DROPBOX_SERVICE); 11502 11503 // Exit early if the dropbox isn't configured to accept this report type. 11504 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11505 11506 boolean bufferWasEmpty; 11507 boolean needsFlush; 11508 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11509 synchronized (sb) { 11510 bufferWasEmpty = sb.length() == 0; 11511 appendDropBoxProcessHeaders(process, processName, sb); 11512 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11513 sb.append("System-App: ").append(isSystemApp).append("\n"); 11514 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11515 if (info.violationNumThisLoop != 0) { 11516 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11517 } 11518 if (info.numAnimationsRunning != 0) { 11519 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11520 } 11521 if (info.broadcastIntentAction != null) { 11522 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11523 } 11524 if (info.durationMillis != -1) { 11525 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11526 } 11527 if (info.numInstances != -1) { 11528 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11529 } 11530 if (info.tags != null) { 11531 for (String tag : info.tags) { 11532 sb.append("Span-Tag: ").append(tag).append("\n"); 11533 } 11534 } 11535 sb.append("\n"); 11536 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11537 sb.append(info.crashInfo.stackTrace); 11538 } 11539 sb.append("\n"); 11540 11541 // Only buffer up to ~64k. Various logging bits truncate 11542 // things at 128k. 11543 needsFlush = (sb.length() > 64 * 1024); 11544 } 11545 11546 // Flush immediately if the buffer's grown too large, or this 11547 // is a non-system app. Non-system apps are isolated with a 11548 // different tag & policy and not batched. 11549 // 11550 // Batching is useful during internal testing with 11551 // StrictMode settings turned up high. Without batching, 11552 // thousands of separate files could be created on boot. 11553 if (!isSystemApp || needsFlush) { 11554 new Thread("Error dump: " + dropboxTag) { 11555 @Override 11556 public void run() { 11557 String report; 11558 synchronized (sb) { 11559 report = sb.toString(); 11560 sb.delete(0, sb.length()); 11561 sb.trimToSize(); 11562 } 11563 if (report.length() != 0) { 11564 dbox.addText(dropboxTag, report); 11565 } 11566 } 11567 }.start(); 11568 return; 11569 } 11570 11571 // System app batching: 11572 if (!bufferWasEmpty) { 11573 // An existing dropbox-writing thread is outstanding, so 11574 // we don't need to start it up. The existing thread will 11575 // catch the buffer appends we just did. 11576 return; 11577 } 11578 11579 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11580 // (After this point, we shouldn't access AMS internal data structures.) 11581 new Thread("Error dump: " + dropboxTag) { 11582 @Override 11583 public void run() { 11584 // 5 second sleep to let stacks arrive and be batched together 11585 try { 11586 Thread.sleep(5000); // 5 seconds 11587 } catch (InterruptedException e) {} 11588 11589 String errorReport; 11590 synchronized (mStrictModeBuffer) { 11591 errorReport = mStrictModeBuffer.toString(); 11592 if (errorReport.length() == 0) { 11593 return; 11594 } 11595 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11596 mStrictModeBuffer.trimToSize(); 11597 } 11598 dbox.addText(dropboxTag, errorReport); 11599 } 11600 }.start(); 11601 } 11602 11603 /** 11604 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11605 * @param app object of the crashing app, null for the system server 11606 * @param tag reported by the caller 11607 * @param system whether this wtf is coming from the system 11608 * @param crashInfo describing the context of the error 11609 * @return true if the process should exit immediately (WTF is fatal) 11610 */ 11611 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11612 final ApplicationErrorReport.CrashInfo crashInfo) { 11613 final int callingUid = Binder.getCallingUid(); 11614 final int callingPid = Binder.getCallingPid(); 11615 11616 if (system) { 11617 // If this is coming from the system, we could very well have low-level 11618 // system locks held, so we want to do this all asynchronously. And we 11619 // never want this to become fatal, so there is that too. 11620 mHandler.post(new Runnable() { 11621 @Override public void run() { 11622 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11623 } 11624 }); 11625 return false; 11626 } 11627 11628 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11629 crashInfo); 11630 11631 if (r != null && r.pid != Process.myPid() && 11632 Settings.Global.getInt(mContext.getContentResolver(), 11633 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11634 crashApplication(r, crashInfo); 11635 return true; 11636 } else { 11637 return false; 11638 } 11639 } 11640 11641 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11642 final ApplicationErrorReport.CrashInfo crashInfo) { 11643 final ProcessRecord r = findAppProcess(app, "WTF"); 11644 final String processName = app == null ? "system_server" 11645 : (r == null ? "unknown" : r.processName); 11646 11647 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11648 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11649 11650 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11651 11652 return r; 11653 } 11654 11655 /** 11656 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11657 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11658 */ 11659 private ProcessRecord findAppProcess(IBinder app, String reason) { 11660 if (app == null) { 11661 return null; 11662 } 11663 11664 synchronized (this) { 11665 final int NP = mProcessNames.getMap().size(); 11666 for (int ip=0; ip<NP; ip++) { 11667 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11668 final int NA = apps.size(); 11669 for (int ia=0; ia<NA; ia++) { 11670 ProcessRecord p = apps.valueAt(ia); 11671 if (p.thread != null && p.thread.asBinder() == app) { 11672 return p; 11673 } 11674 } 11675 } 11676 11677 Slog.w(TAG, "Can't find mystery application for " + reason 11678 + " from pid=" + Binder.getCallingPid() 11679 + " uid=" + Binder.getCallingUid() + ": " + app); 11680 return null; 11681 } 11682 } 11683 11684 /** 11685 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11686 * to append various headers to the dropbox log text. 11687 */ 11688 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11689 StringBuilder sb) { 11690 // Watchdog thread ends up invoking this function (with 11691 // a null ProcessRecord) to add the stack file to dropbox. 11692 // Do not acquire a lock on this (am) in such cases, as it 11693 // could cause a potential deadlock, if and when watchdog 11694 // is invoked due to unavailability of lock on am and it 11695 // would prevent watchdog from killing system_server. 11696 if (process == null) { 11697 sb.append("Process: ").append(processName).append("\n"); 11698 return; 11699 } 11700 // Note: ProcessRecord 'process' is guarded by the service 11701 // instance. (notably process.pkgList, which could otherwise change 11702 // concurrently during execution of this method) 11703 synchronized (this) { 11704 sb.append("Process: ").append(processName).append("\n"); 11705 int flags = process.info.flags; 11706 IPackageManager pm = AppGlobals.getPackageManager(); 11707 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11708 for (int ip=0; ip<process.pkgList.size(); ip++) { 11709 String pkg = process.pkgList.keyAt(ip); 11710 sb.append("Package: ").append(pkg); 11711 try { 11712 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11713 if (pi != null) { 11714 sb.append(" v").append(pi.versionCode); 11715 if (pi.versionName != null) { 11716 sb.append(" (").append(pi.versionName).append(")"); 11717 } 11718 } 11719 } catch (RemoteException e) { 11720 Slog.e(TAG, "Error getting package info: " + pkg, e); 11721 } 11722 sb.append("\n"); 11723 } 11724 } 11725 } 11726 11727 private static String processClass(ProcessRecord process) { 11728 if (process == null || process.pid == MY_PID) { 11729 return "system_server"; 11730 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11731 return "system_app"; 11732 } else { 11733 return "data_app"; 11734 } 11735 } 11736 11737 /** 11738 * Write a description of an error (crash, WTF, ANR) to the drop box. 11739 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11740 * @param process which caused the error, null means the system server 11741 * @param activity which triggered the error, null if unknown 11742 * @param parent activity related to the error, null if unknown 11743 * @param subject line related to the error, null if absent 11744 * @param report in long form describing the error, null if absent 11745 * @param logFile to include in the report, null if none 11746 * @param crashInfo giving an application stack trace, null if absent 11747 */ 11748 public void addErrorToDropBox(String eventType, 11749 ProcessRecord process, String processName, ActivityRecord activity, 11750 ActivityRecord parent, String subject, 11751 final String report, final File logFile, 11752 final ApplicationErrorReport.CrashInfo crashInfo) { 11753 // NOTE -- this must never acquire the ActivityManagerService lock, 11754 // otherwise the watchdog may be prevented from resetting the system. 11755 11756 final String dropboxTag = processClass(process) + "_" + eventType; 11757 final DropBoxManager dbox = (DropBoxManager) 11758 mContext.getSystemService(Context.DROPBOX_SERVICE); 11759 11760 // Exit early if the dropbox isn't configured to accept this report type. 11761 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11762 11763 final StringBuilder sb = new StringBuilder(1024); 11764 appendDropBoxProcessHeaders(process, processName, sb); 11765 if (activity != null) { 11766 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11767 } 11768 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11769 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11770 } 11771 if (parent != null && parent != activity) { 11772 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11773 } 11774 if (subject != null) { 11775 sb.append("Subject: ").append(subject).append("\n"); 11776 } 11777 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11778 if (Debug.isDebuggerConnected()) { 11779 sb.append("Debugger: Connected\n"); 11780 } 11781 sb.append("\n"); 11782 11783 // Do the rest in a worker thread to avoid blocking the caller on I/O 11784 // (After this point, we shouldn't access AMS internal data structures.) 11785 Thread worker = new Thread("Error dump: " + dropboxTag) { 11786 @Override 11787 public void run() { 11788 if (report != null) { 11789 sb.append(report); 11790 } 11791 if (logFile != null) { 11792 try { 11793 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11794 "\n\n[[TRUNCATED]]")); 11795 } catch (IOException e) { 11796 Slog.e(TAG, "Error reading " + logFile, e); 11797 } 11798 } 11799 if (crashInfo != null && crashInfo.stackTrace != null) { 11800 sb.append(crashInfo.stackTrace); 11801 } 11802 11803 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11804 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11805 if (lines > 0) { 11806 sb.append("\n"); 11807 11808 // Merge several logcat streams, and take the last N lines 11809 InputStreamReader input = null; 11810 try { 11811 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11812 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11813 "-b", "crash", 11814 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11815 11816 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11817 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11818 input = new InputStreamReader(logcat.getInputStream()); 11819 11820 int num; 11821 char[] buf = new char[8192]; 11822 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11823 } catch (IOException e) { 11824 Slog.e(TAG, "Error running logcat", e); 11825 } finally { 11826 if (input != null) try { input.close(); } catch (IOException e) {} 11827 } 11828 } 11829 11830 dbox.addText(dropboxTag, sb.toString()); 11831 } 11832 }; 11833 11834 if (process == null) { 11835 // If process is null, we are being called from some internal code 11836 // and may be about to die -- run this synchronously. 11837 worker.run(); 11838 } else { 11839 worker.start(); 11840 } 11841 } 11842 11843 /** 11844 * Bring up the "unexpected error" dialog box for a crashing app. 11845 * Deal with edge cases (intercepts from instrumented applications, 11846 * ActivityController, error intent receivers, that sort of thing). 11847 * @param r the application crashing 11848 * @param crashInfo describing the failure 11849 */ 11850 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11851 long timeMillis = System.currentTimeMillis(); 11852 String shortMsg = crashInfo.exceptionClassName; 11853 String longMsg = crashInfo.exceptionMessage; 11854 String stackTrace = crashInfo.stackTrace; 11855 if (shortMsg != null && longMsg != null) { 11856 longMsg = shortMsg + ": " + longMsg; 11857 } else if (shortMsg != null) { 11858 longMsg = shortMsg; 11859 } 11860 11861 AppErrorResult result = new AppErrorResult(); 11862 synchronized (this) { 11863 if (mController != null) { 11864 try { 11865 String name = r != null ? r.processName : null; 11866 int pid = r != null ? r.pid : Binder.getCallingPid(); 11867 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11868 if (!mController.appCrashed(name, pid, 11869 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11870 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11871 && "Native crash".equals(crashInfo.exceptionClassName)) { 11872 Slog.w(TAG, "Skip killing native crashed app " + name 11873 + "(" + pid + ") during testing"); 11874 } else { 11875 Slog.w(TAG, "Force-killing crashed app " + name 11876 + " at watcher's request"); 11877 if (r != null) { 11878 r.kill("crash", true); 11879 } else { 11880 // Huh. 11881 Process.killProcess(pid); 11882 Process.killProcessGroup(uid, pid); 11883 } 11884 } 11885 return; 11886 } 11887 } catch (RemoteException e) { 11888 mController = null; 11889 Watchdog.getInstance().setActivityController(null); 11890 } 11891 } 11892 11893 final long origId = Binder.clearCallingIdentity(); 11894 11895 // If this process is running instrumentation, finish it. 11896 if (r != null && r.instrumentationClass != null) { 11897 Slog.w(TAG, "Error in app " + r.processName 11898 + " running instrumentation " + r.instrumentationClass + ":"); 11899 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11900 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11901 Bundle info = new Bundle(); 11902 info.putString("shortMsg", shortMsg); 11903 info.putString("longMsg", longMsg); 11904 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11905 Binder.restoreCallingIdentity(origId); 11906 return; 11907 } 11908 11909 // If we can't identify the process or it's already exceeded its crash quota, 11910 // quit right away without showing a crash dialog. 11911 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11912 Binder.restoreCallingIdentity(origId); 11913 return; 11914 } 11915 11916 Message msg = Message.obtain(); 11917 msg.what = SHOW_ERROR_MSG; 11918 HashMap data = new HashMap(); 11919 data.put("result", result); 11920 data.put("app", r); 11921 msg.obj = data; 11922 mHandler.sendMessage(msg); 11923 11924 Binder.restoreCallingIdentity(origId); 11925 } 11926 11927 int res = result.get(); 11928 11929 Intent appErrorIntent = null; 11930 synchronized (this) { 11931 if (r != null && !r.isolated) { 11932 // XXX Can't keep track of crash time for isolated processes, 11933 // since they don't have a persistent identity. 11934 mProcessCrashTimes.put(r.info.processName, r.uid, 11935 SystemClock.uptimeMillis()); 11936 } 11937 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11938 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11939 } 11940 } 11941 11942 if (appErrorIntent != null) { 11943 try { 11944 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11945 } catch (ActivityNotFoundException e) { 11946 Slog.w(TAG, "bug report receiver dissappeared", e); 11947 } 11948 } 11949 } 11950 11951 Intent createAppErrorIntentLocked(ProcessRecord r, 11952 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11953 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11954 if (report == null) { 11955 return null; 11956 } 11957 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11958 result.setComponent(r.errorReportReceiver); 11959 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11960 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11961 return result; 11962 } 11963 11964 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11965 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11966 if (r.errorReportReceiver == null) { 11967 return null; 11968 } 11969 11970 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11971 return null; 11972 } 11973 11974 ApplicationErrorReport report = new ApplicationErrorReport(); 11975 report.packageName = r.info.packageName; 11976 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11977 report.processName = r.processName; 11978 report.time = timeMillis; 11979 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11980 11981 if (r.crashing || r.forceCrashReport) { 11982 report.type = ApplicationErrorReport.TYPE_CRASH; 11983 report.crashInfo = crashInfo; 11984 } else if (r.notResponding) { 11985 report.type = ApplicationErrorReport.TYPE_ANR; 11986 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11987 11988 report.anrInfo.activity = r.notRespondingReport.tag; 11989 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11990 report.anrInfo.info = r.notRespondingReport.longMsg; 11991 } 11992 11993 return report; 11994 } 11995 11996 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11997 enforceNotIsolatedCaller("getProcessesInErrorState"); 11998 // assume our apps are happy - lazy create the list 11999 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12000 12001 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12002 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12003 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12004 12005 synchronized (this) { 12006 12007 // iterate across all processes 12008 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12009 ProcessRecord app = mLruProcesses.get(i); 12010 if (!allUsers && app.userId != userId) { 12011 continue; 12012 } 12013 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12014 // This one's in trouble, so we'll generate a report for it 12015 // crashes are higher priority (in case there's a crash *and* an anr) 12016 ActivityManager.ProcessErrorStateInfo report = null; 12017 if (app.crashing) { 12018 report = app.crashingReport; 12019 } else if (app.notResponding) { 12020 report = app.notRespondingReport; 12021 } 12022 12023 if (report != null) { 12024 if (errList == null) { 12025 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12026 } 12027 errList.add(report); 12028 } else { 12029 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12030 " crashing = " + app.crashing + 12031 " notResponding = " + app.notResponding); 12032 } 12033 } 12034 } 12035 } 12036 12037 return errList; 12038 } 12039 12040 static int procStateToImportance(int procState, int memAdj, 12041 ActivityManager.RunningAppProcessInfo currApp) { 12042 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12043 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12044 currApp.lru = memAdj; 12045 } else { 12046 currApp.lru = 0; 12047 } 12048 return imp; 12049 } 12050 12051 private void fillInProcMemInfo(ProcessRecord app, 12052 ActivityManager.RunningAppProcessInfo outInfo) { 12053 outInfo.pid = app.pid; 12054 outInfo.uid = app.info.uid; 12055 if (mHeavyWeightProcess == app) { 12056 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12057 } 12058 if (app.persistent) { 12059 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12060 } 12061 if (app.activities.size() > 0) { 12062 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12063 } 12064 outInfo.lastTrimLevel = app.trimMemoryLevel; 12065 int adj = app.curAdj; 12066 int procState = app.curProcState; 12067 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12068 outInfo.importanceReasonCode = app.adjTypeCode; 12069 outInfo.processState = app.curProcState; 12070 } 12071 12072 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12073 enforceNotIsolatedCaller("getRunningAppProcesses"); 12074 // Lazy instantiation of list 12075 List<ActivityManager.RunningAppProcessInfo> runList = null; 12076 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12077 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12078 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12079 synchronized (this) { 12080 // Iterate across all processes 12081 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12082 ProcessRecord app = mLruProcesses.get(i); 12083 if (!allUsers && app.userId != userId) { 12084 continue; 12085 } 12086 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12087 // Generate process state info for running application 12088 ActivityManager.RunningAppProcessInfo currApp = 12089 new ActivityManager.RunningAppProcessInfo(app.processName, 12090 app.pid, app.getPackageList()); 12091 fillInProcMemInfo(app, currApp); 12092 if (app.adjSource instanceof ProcessRecord) { 12093 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12094 currApp.importanceReasonImportance = 12095 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12096 app.adjSourceProcState); 12097 } else if (app.adjSource instanceof ActivityRecord) { 12098 ActivityRecord r = (ActivityRecord)app.adjSource; 12099 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12100 } 12101 if (app.adjTarget instanceof ComponentName) { 12102 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12103 } 12104 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12105 // + " lru=" + currApp.lru); 12106 if (runList == null) { 12107 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12108 } 12109 runList.add(currApp); 12110 } 12111 } 12112 } 12113 return runList; 12114 } 12115 12116 public List<ApplicationInfo> getRunningExternalApplications() { 12117 enforceNotIsolatedCaller("getRunningExternalApplications"); 12118 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12119 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12120 if (runningApps != null && runningApps.size() > 0) { 12121 Set<String> extList = new HashSet<String>(); 12122 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12123 if (app.pkgList != null) { 12124 for (String pkg : app.pkgList) { 12125 extList.add(pkg); 12126 } 12127 } 12128 } 12129 IPackageManager pm = AppGlobals.getPackageManager(); 12130 for (String pkg : extList) { 12131 try { 12132 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12133 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12134 retList.add(info); 12135 } 12136 } catch (RemoteException e) { 12137 } 12138 } 12139 } 12140 return retList; 12141 } 12142 12143 @Override 12144 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12145 enforceNotIsolatedCaller("getMyMemoryState"); 12146 synchronized (this) { 12147 ProcessRecord proc; 12148 synchronized (mPidsSelfLocked) { 12149 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12150 } 12151 fillInProcMemInfo(proc, outInfo); 12152 } 12153 } 12154 12155 @Override 12156 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12157 if (checkCallingPermission(android.Manifest.permission.DUMP) 12158 != PackageManager.PERMISSION_GRANTED) { 12159 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12160 + Binder.getCallingPid() 12161 + ", uid=" + Binder.getCallingUid() 12162 + " without permission " 12163 + android.Manifest.permission.DUMP); 12164 return; 12165 } 12166 12167 boolean dumpAll = false; 12168 boolean dumpClient = false; 12169 String dumpPackage = null; 12170 12171 int opti = 0; 12172 while (opti < args.length) { 12173 String opt = args[opti]; 12174 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12175 break; 12176 } 12177 opti++; 12178 if ("-a".equals(opt)) { 12179 dumpAll = true; 12180 } else if ("-c".equals(opt)) { 12181 dumpClient = true; 12182 } else if ("-h".equals(opt)) { 12183 pw.println("Activity manager dump options:"); 12184 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12185 pw.println(" cmd may be one of:"); 12186 pw.println(" a[ctivities]: activity stack state"); 12187 pw.println(" r[recents]: recent activities state"); 12188 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12189 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12190 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12191 pw.println(" o[om]: out of memory management"); 12192 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12193 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12194 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12195 pw.println(" service [COMP_SPEC]: service client-side state"); 12196 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12197 pw.println(" all: dump all activities"); 12198 pw.println(" top: dump the top activity"); 12199 pw.println(" write: write all pending state to storage"); 12200 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12201 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12202 pw.println(" a partial substring in a component name, a"); 12203 pw.println(" hex object identifier."); 12204 pw.println(" -a: include all available server state."); 12205 pw.println(" -c: include client state."); 12206 return; 12207 } else { 12208 pw.println("Unknown argument: " + opt + "; use -h for help"); 12209 } 12210 } 12211 12212 long origId = Binder.clearCallingIdentity(); 12213 boolean more = false; 12214 // Is the caller requesting to dump a particular piece of data? 12215 if (opti < args.length) { 12216 String cmd = args[opti]; 12217 opti++; 12218 if ("activities".equals(cmd) || "a".equals(cmd)) { 12219 synchronized (this) { 12220 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12221 } 12222 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12223 synchronized (this) { 12224 dumpRecentsLocked(fd, pw, args, opti, true, null); 12225 } 12226 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12227 String[] newArgs; 12228 String name; 12229 if (opti >= args.length) { 12230 name = null; 12231 newArgs = EMPTY_STRING_ARRAY; 12232 } else { 12233 name = args[opti]; 12234 opti++; 12235 newArgs = new String[args.length - opti]; 12236 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12237 args.length - opti); 12238 } 12239 synchronized (this) { 12240 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12241 } 12242 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12243 String[] newArgs; 12244 String name; 12245 if (opti >= args.length) { 12246 name = null; 12247 newArgs = EMPTY_STRING_ARRAY; 12248 } else { 12249 name = args[opti]; 12250 opti++; 12251 newArgs = new String[args.length - opti]; 12252 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12253 args.length - opti); 12254 } 12255 synchronized (this) { 12256 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12257 } 12258 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12259 String[] newArgs; 12260 String name; 12261 if (opti >= args.length) { 12262 name = null; 12263 newArgs = EMPTY_STRING_ARRAY; 12264 } else { 12265 name = args[opti]; 12266 opti++; 12267 newArgs = new String[args.length - opti]; 12268 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12269 args.length - opti); 12270 } 12271 synchronized (this) { 12272 dumpProcessesLocked(fd, pw, args, opti, true, name); 12273 } 12274 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12275 synchronized (this) { 12276 dumpOomLocked(fd, pw, args, opti, true); 12277 } 12278 } else if ("provider".equals(cmd)) { 12279 String[] newArgs; 12280 String name; 12281 if (opti >= args.length) { 12282 name = null; 12283 newArgs = EMPTY_STRING_ARRAY; 12284 } else { 12285 name = args[opti]; 12286 opti++; 12287 newArgs = new String[args.length - opti]; 12288 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12289 } 12290 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12291 pw.println("No providers match: " + name); 12292 pw.println("Use -h for help."); 12293 } 12294 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12295 synchronized (this) { 12296 dumpProvidersLocked(fd, pw, args, opti, true, null); 12297 } 12298 } else if ("service".equals(cmd)) { 12299 String[] newArgs; 12300 String name; 12301 if (opti >= args.length) { 12302 name = null; 12303 newArgs = EMPTY_STRING_ARRAY; 12304 } else { 12305 name = args[opti]; 12306 opti++; 12307 newArgs = new String[args.length - opti]; 12308 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12309 args.length - opti); 12310 } 12311 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12312 pw.println("No services match: " + name); 12313 pw.println("Use -h for help."); 12314 } 12315 } else if ("package".equals(cmd)) { 12316 String[] newArgs; 12317 if (opti >= args.length) { 12318 pw.println("package: no package name specified"); 12319 pw.println("Use -h for help."); 12320 } else { 12321 dumpPackage = args[opti]; 12322 opti++; 12323 newArgs = new String[args.length - opti]; 12324 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12325 args.length - opti); 12326 args = newArgs; 12327 opti = 0; 12328 more = true; 12329 } 12330 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12331 synchronized (this) { 12332 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12333 } 12334 } else if ("write".equals(cmd)) { 12335 mTaskPersister.flush(); 12336 pw.println("All tasks persisted."); 12337 return; 12338 } else { 12339 // Dumping a single activity? 12340 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12341 pw.println("Bad activity command, or no activities match: " + cmd); 12342 pw.println("Use -h for help."); 12343 } 12344 } 12345 if (!more) { 12346 Binder.restoreCallingIdentity(origId); 12347 return; 12348 } 12349 } 12350 12351 // No piece of data specified, dump everything. 12352 synchronized (this) { 12353 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12354 pw.println(); 12355 if (dumpAll) { 12356 pw.println("-------------------------------------------------------------------------------"); 12357 } 12358 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12359 pw.println(); 12360 if (dumpAll) { 12361 pw.println("-------------------------------------------------------------------------------"); 12362 } 12363 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12364 pw.println(); 12365 if (dumpAll) { 12366 pw.println("-------------------------------------------------------------------------------"); 12367 } 12368 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12369 pw.println(); 12370 if (dumpAll) { 12371 pw.println("-------------------------------------------------------------------------------"); 12372 } 12373 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12374 pw.println(); 12375 if (dumpAll) { 12376 pw.println("-------------------------------------------------------------------------------"); 12377 } 12378 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12379 pw.println(); 12380 if (dumpAll) { 12381 pw.println("-------------------------------------------------------------------------------"); 12382 } 12383 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12384 } 12385 Binder.restoreCallingIdentity(origId); 12386 } 12387 12388 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12389 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12390 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12391 12392 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12393 dumpPackage); 12394 boolean needSep = printedAnything; 12395 12396 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12397 dumpPackage, needSep, " mFocusedActivity: "); 12398 if (printed) { 12399 printedAnything = true; 12400 needSep = false; 12401 } 12402 12403 if (dumpPackage == null) { 12404 if (needSep) { 12405 pw.println(); 12406 } 12407 needSep = true; 12408 printedAnything = true; 12409 mStackSupervisor.dump(pw, " "); 12410 } 12411 12412 if (!printedAnything) { 12413 pw.println(" (nothing)"); 12414 } 12415 } 12416 12417 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12418 int opti, boolean dumpAll, String dumpPackage) { 12419 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12420 12421 boolean printedAnything = false; 12422 12423 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12424 boolean printedHeader = false; 12425 12426 final int N = mRecentTasks.size(); 12427 for (int i=0; i<N; i++) { 12428 TaskRecord tr = mRecentTasks.get(i); 12429 if (dumpPackage != null) { 12430 if (tr.realActivity == null || 12431 !dumpPackage.equals(tr.realActivity)) { 12432 continue; 12433 } 12434 } 12435 if (!printedHeader) { 12436 pw.println(" Recent tasks:"); 12437 printedHeader = true; 12438 printedAnything = true; 12439 } 12440 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12441 pw.println(tr); 12442 if (dumpAll) { 12443 mRecentTasks.get(i).dump(pw, " "); 12444 } 12445 } 12446 } 12447 12448 if (!printedAnything) { 12449 pw.println(" (nothing)"); 12450 } 12451 } 12452 12453 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12454 int opti, boolean dumpAll, String dumpPackage) { 12455 boolean needSep = false; 12456 boolean printedAnything = false; 12457 int numPers = 0; 12458 12459 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12460 12461 if (dumpAll) { 12462 final int NP = mProcessNames.getMap().size(); 12463 for (int ip=0; ip<NP; ip++) { 12464 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12465 final int NA = procs.size(); 12466 for (int ia=0; ia<NA; ia++) { 12467 ProcessRecord r = procs.valueAt(ia); 12468 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12469 continue; 12470 } 12471 if (!needSep) { 12472 pw.println(" All known processes:"); 12473 needSep = true; 12474 printedAnything = true; 12475 } 12476 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12477 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12478 pw.print(" "); pw.println(r); 12479 r.dump(pw, " "); 12480 if (r.persistent) { 12481 numPers++; 12482 } 12483 } 12484 } 12485 } 12486 12487 if (mIsolatedProcesses.size() > 0) { 12488 boolean printed = false; 12489 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12490 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12491 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12492 continue; 12493 } 12494 if (!printed) { 12495 if (needSep) { 12496 pw.println(); 12497 } 12498 pw.println(" Isolated process list (sorted by uid):"); 12499 printedAnything = true; 12500 printed = true; 12501 needSep = true; 12502 } 12503 pw.println(String.format("%sIsolated #%2d: %s", 12504 " ", i, r.toString())); 12505 } 12506 } 12507 12508 if (mLruProcesses.size() > 0) { 12509 if (needSep) { 12510 pw.println(); 12511 } 12512 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12513 pw.print(" total, non-act at "); 12514 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12515 pw.print(", non-svc at "); 12516 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12517 pw.println("):"); 12518 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12519 needSep = true; 12520 printedAnything = true; 12521 } 12522 12523 if (dumpAll || dumpPackage != null) { 12524 synchronized (mPidsSelfLocked) { 12525 boolean printed = false; 12526 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12527 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12528 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12529 continue; 12530 } 12531 if (!printed) { 12532 if (needSep) pw.println(); 12533 needSep = true; 12534 pw.println(" PID mappings:"); 12535 printed = true; 12536 printedAnything = true; 12537 } 12538 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12539 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12540 } 12541 } 12542 } 12543 12544 if (mForegroundProcesses.size() > 0) { 12545 synchronized (mPidsSelfLocked) { 12546 boolean printed = false; 12547 for (int i=0; i<mForegroundProcesses.size(); i++) { 12548 ProcessRecord r = mPidsSelfLocked.get( 12549 mForegroundProcesses.valueAt(i).pid); 12550 if (dumpPackage != null && (r == null 12551 || !r.pkgList.containsKey(dumpPackage))) { 12552 continue; 12553 } 12554 if (!printed) { 12555 if (needSep) pw.println(); 12556 needSep = true; 12557 pw.println(" Foreground Processes:"); 12558 printed = true; 12559 printedAnything = true; 12560 } 12561 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12562 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12563 } 12564 } 12565 } 12566 12567 if (mPersistentStartingProcesses.size() > 0) { 12568 if (needSep) pw.println(); 12569 needSep = true; 12570 printedAnything = true; 12571 pw.println(" Persisent processes that are starting:"); 12572 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12573 "Starting Norm", "Restarting PERS", dumpPackage); 12574 } 12575 12576 if (mRemovedProcesses.size() > 0) { 12577 if (needSep) pw.println(); 12578 needSep = true; 12579 printedAnything = true; 12580 pw.println(" Processes that are being removed:"); 12581 dumpProcessList(pw, this, mRemovedProcesses, " ", 12582 "Removed Norm", "Removed PERS", dumpPackage); 12583 } 12584 12585 if (mProcessesOnHold.size() > 0) { 12586 if (needSep) pw.println(); 12587 needSep = true; 12588 printedAnything = true; 12589 pw.println(" Processes that are on old until the system is ready:"); 12590 dumpProcessList(pw, this, mProcessesOnHold, " ", 12591 "OnHold Norm", "OnHold PERS", dumpPackage); 12592 } 12593 12594 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12595 12596 if (mProcessCrashTimes.getMap().size() > 0) { 12597 boolean printed = false; 12598 long now = SystemClock.uptimeMillis(); 12599 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12600 final int NP = pmap.size(); 12601 for (int ip=0; ip<NP; ip++) { 12602 String pname = pmap.keyAt(ip); 12603 SparseArray<Long> uids = pmap.valueAt(ip); 12604 final int N = uids.size(); 12605 for (int i=0; i<N; i++) { 12606 int puid = uids.keyAt(i); 12607 ProcessRecord r = mProcessNames.get(pname, puid); 12608 if (dumpPackage != null && (r == null 12609 || !r.pkgList.containsKey(dumpPackage))) { 12610 continue; 12611 } 12612 if (!printed) { 12613 if (needSep) pw.println(); 12614 needSep = true; 12615 pw.println(" Time since processes crashed:"); 12616 printed = true; 12617 printedAnything = true; 12618 } 12619 pw.print(" Process "); pw.print(pname); 12620 pw.print(" uid "); pw.print(puid); 12621 pw.print(": last crashed "); 12622 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12623 pw.println(" ago"); 12624 } 12625 } 12626 } 12627 12628 if (mBadProcesses.getMap().size() > 0) { 12629 boolean printed = false; 12630 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12631 final int NP = pmap.size(); 12632 for (int ip=0; ip<NP; ip++) { 12633 String pname = pmap.keyAt(ip); 12634 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12635 final int N = uids.size(); 12636 for (int i=0; i<N; i++) { 12637 int puid = uids.keyAt(i); 12638 ProcessRecord r = mProcessNames.get(pname, puid); 12639 if (dumpPackage != null && (r == null 12640 || !r.pkgList.containsKey(dumpPackage))) { 12641 continue; 12642 } 12643 if (!printed) { 12644 if (needSep) pw.println(); 12645 needSep = true; 12646 pw.println(" Bad processes:"); 12647 printedAnything = true; 12648 } 12649 BadProcessInfo info = uids.valueAt(i); 12650 pw.print(" Bad process "); pw.print(pname); 12651 pw.print(" uid "); pw.print(puid); 12652 pw.print(": crashed at time "); pw.println(info.time); 12653 if (info.shortMsg != null) { 12654 pw.print(" Short msg: "); pw.println(info.shortMsg); 12655 } 12656 if (info.longMsg != null) { 12657 pw.print(" Long msg: "); pw.println(info.longMsg); 12658 } 12659 if (info.stack != null) { 12660 pw.println(" Stack:"); 12661 int lastPos = 0; 12662 for (int pos=0; pos<info.stack.length(); pos++) { 12663 if (info.stack.charAt(pos) == '\n') { 12664 pw.print(" "); 12665 pw.write(info.stack, lastPos, pos-lastPos); 12666 pw.println(); 12667 lastPos = pos+1; 12668 } 12669 } 12670 if (lastPos < info.stack.length()) { 12671 pw.print(" "); 12672 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12673 pw.println(); 12674 } 12675 } 12676 } 12677 } 12678 } 12679 12680 if (dumpPackage == null) { 12681 pw.println(); 12682 needSep = false; 12683 pw.println(" mStartedUsers:"); 12684 for (int i=0; i<mStartedUsers.size(); i++) { 12685 UserStartedState uss = mStartedUsers.valueAt(i); 12686 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12687 pw.print(": "); uss.dump("", pw); 12688 } 12689 pw.print(" mStartedUserArray: ["); 12690 for (int i=0; i<mStartedUserArray.length; i++) { 12691 if (i > 0) pw.print(", "); 12692 pw.print(mStartedUserArray[i]); 12693 } 12694 pw.println("]"); 12695 pw.print(" mUserLru: ["); 12696 for (int i=0; i<mUserLru.size(); i++) { 12697 if (i > 0) pw.print(", "); 12698 pw.print(mUserLru.get(i)); 12699 } 12700 pw.println("]"); 12701 if (dumpAll) { 12702 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12703 } 12704 synchronized (mUserProfileGroupIdsSelfLocked) { 12705 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12706 pw.println(" mUserProfileGroupIds:"); 12707 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12708 pw.print(" User #"); 12709 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12710 pw.print(" -> profile #"); 12711 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12712 } 12713 } 12714 } 12715 } 12716 if (mHomeProcess != null && (dumpPackage == null 12717 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12718 if (needSep) { 12719 pw.println(); 12720 needSep = false; 12721 } 12722 pw.println(" mHomeProcess: " + mHomeProcess); 12723 } 12724 if (mPreviousProcess != null && (dumpPackage == null 12725 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12726 if (needSep) { 12727 pw.println(); 12728 needSep = false; 12729 } 12730 pw.println(" mPreviousProcess: " + mPreviousProcess); 12731 } 12732 if (dumpAll) { 12733 StringBuilder sb = new StringBuilder(128); 12734 sb.append(" mPreviousProcessVisibleTime: "); 12735 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12736 pw.println(sb); 12737 } 12738 if (mHeavyWeightProcess != null && (dumpPackage == null 12739 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12740 if (needSep) { 12741 pw.println(); 12742 needSep = false; 12743 } 12744 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12745 } 12746 if (dumpPackage == null) { 12747 pw.println(" mConfiguration: " + mConfiguration); 12748 } 12749 if (dumpAll) { 12750 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12751 if (mCompatModePackages.getPackages().size() > 0) { 12752 boolean printed = false; 12753 for (Map.Entry<String, Integer> entry 12754 : mCompatModePackages.getPackages().entrySet()) { 12755 String pkg = entry.getKey(); 12756 int mode = entry.getValue(); 12757 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12758 continue; 12759 } 12760 if (!printed) { 12761 pw.println(" mScreenCompatPackages:"); 12762 printed = true; 12763 } 12764 pw.print(" "); pw.print(pkg); pw.print(": "); 12765 pw.print(mode); pw.println(); 12766 } 12767 } 12768 } 12769 if (dumpPackage == null) { 12770 if (mSleeping || mWentToSleep || mLockScreenShown) { 12771 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12772 + " mLockScreenShown " + mLockScreenShown); 12773 } 12774 if (mShuttingDown || mRunningVoice) { 12775 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12776 } 12777 } 12778 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12779 || mOrigWaitForDebugger) { 12780 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12781 || dumpPackage.equals(mOrigDebugApp)) { 12782 if (needSep) { 12783 pw.println(); 12784 needSep = false; 12785 } 12786 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12787 + " mDebugTransient=" + mDebugTransient 12788 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12789 } 12790 } 12791 if (mOpenGlTraceApp != null) { 12792 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12793 if (needSep) { 12794 pw.println(); 12795 needSep = false; 12796 } 12797 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12798 } 12799 } 12800 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12801 || mProfileFd != null) { 12802 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12803 if (needSep) { 12804 pw.println(); 12805 needSep = false; 12806 } 12807 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12808 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12809 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12810 + mAutoStopProfiler); 12811 pw.println(" mProfileType=" + mProfileType); 12812 } 12813 } 12814 if (dumpPackage == null) { 12815 if (mAlwaysFinishActivities || mController != null) { 12816 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12817 + " mController=" + mController); 12818 } 12819 if (dumpAll) { 12820 pw.println(" Total persistent processes: " + numPers); 12821 pw.println(" mProcessesReady=" + mProcessesReady 12822 + " mSystemReady=" + mSystemReady 12823 + " mBooted=" + mBooted 12824 + " mFactoryTest=" + mFactoryTest); 12825 pw.println(" mBooting=" + mBooting 12826 + " mCallFinishBooting=" + mCallFinishBooting 12827 + " mBootAnimationComplete=" + mBootAnimationComplete); 12828 pw.print(" mLastPowerCheckRealtime="); 12829 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12830 pw.println(""); 12831 pw.print(" mLastPowerCheckUptime="); 12832 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12833 pw.println(""); 12834 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12835 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12836 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12837 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12838 + " (" + mLruProcesses.size() + " total)" 12839 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12840 + " mNumServiceProcs=" + mNumServiceProcs 12841 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12842 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12843 + " mLastMemoryLevel" + mLastMemoryLevel 12844 + " mLastNumProcesses" + mLastNumProcesses); 12845 long now = SystemClock.uptimeMillis(); 12846 pw.print(" mLastIdleTime="); 12847 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12848 pw.print(" mLowRamSinceLastIdle="); 12849 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12850 pw.println(); 12851 } 12852 } 12853 12854 if (!printedAnything) { 12855 pw.println(" (nothing)"); 12856 } 12857 } 12858 12859 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12860 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12861 if (mProcessesToGc.size() > 0) { 12862 boolean printed = false; 12863 long now = SystemClock.uptimeMillis(); 12864 for (int i=0; i<mProcessesToGc.size(); i++) { 12865 ProcessRecord proc = mProcessesToGc.get(i); 12866 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12867 continue; 12868 } 12869 if (!printed) { 12870 if (needSep) pw.println(); 12871 needSep = true; 12872 pw.println(" Processes that are waiting to GC:"); 12873 printed = true; 12874 } 12875 pw.print(" Process "); pw.println(proc); 12876 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12877 pw.print(", last gced="); 12878 pw.print(now-proc.lastRequestedGc); 12879 pw.print(" ms ago, last lowMem="); 12880 pw.print(now-proc.lastLowMemory); 12881 pw.println(" ms ago"); 12882 12883 } 12884 } 12885 return needSep; 12886 } 12887 12888 void printOomLevel(PrintWriter pw, String name, int adj) { 12889 pw.print(" "); 12890 if (adj >= 0) { 12891 pw.print(' '); 12892 if (adj < 10) pw.print(' '); 12893 } else { 12894 if (adj > -10) pw.print(' '); 12895 } 12896 pw.print(adj); 12897 pw.print(": "); 12898 pw.print(name); 12899 pw.print(" ("); 12900 pw.print(mProcessList.getMemLevel(adj)/1024); 12901 pw.println(" kB)"); 12902 } 12903 12904 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12905 int opti, boolean dumpAll) { 12906 boolean needSep = false; 12907 12908 if (mLruProcesses.size() > 0) { 12909 if (needSep) pw.println(); 12910 needSep = true; 12911 pw.println(" OOM levels:"); 12912 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12913 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12914 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12915 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12916 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12917 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12918 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12919 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12920 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12921 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12922 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12923 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12924 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12925 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12926 12927 if (needSep) pw.println(); 12928 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12929 pw.print(" total, non-act at "); 12930 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12931 pw.print(", non-svc at "); 12932 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12933 pw.println("):"); 12934 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12935 needSep = true; 12936 } 12937 12938 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12939 12940 pw.println(); 12941 pw.println(" mHomeProcess: " + mHomeProcess); 12942 pw.println(" mPreviousProcess: " + mPreviousProcess); 12943 if (mHeavyWeightProcess != null) { 12944 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12945 } 12946 12947 return true; 12948 } 12949 12950 /** 12951 * There are three ways to call this: 12952 * - no provider specified: dump all the providers 12953 * - a flattened component name that matched an existing provider was specified as the 12954 * first arg: dump that one provider 12955 * - the first arg isn't the flattened component name of an existing provider: 12956 * dump all providers whose component contains the first arg as a substring 12957 */ 12958 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12959 int opti, boolean dumpAll) { 12960 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12961 } 12962 12963 static class ItemMatcher { 12964 ArrayList<ComponentName> components; 12965 ArrayList<String> strings; 12966 ArrayList<Integer> objects; 12967 boolean all; 12968 12969 ItemMatcher() { 12970 all = true; 12971 } 12972 12973 void build(String name) { 12974 ComponentName componentName = ComponentName.unflattenFromString(name); 12975 if (componentName != null) { 12976 if (components == null) { 12977 components = new ArrayList<ComponentName>(); 12978 } 12979 components.add(componentName); 12980 all = false; 12981 } else { 12982 int objectId = 0; 12983 // Not a '/' separated full component name; maybe an object ID? 12984 try { 12985 objectId = Integer.parseInt(name, 16); 12986 if (objects == null) { 12987 objects = new ArrayList<Integer>(); 12988 } 12989 objects.add(objectId); 12990 all = false; 12991 } catch (RuntimeException e) { 12992 // Not an integer; just do string match. 12993 if (strings == null) { 12994 strings = new ArrayList<String>(); 12995 } 12996 strings.add(name); 12997 all = false; 12998 } 12999 } 13000 } 13001 13002 int build(String[] args, int opti) { 13003 for (; opti<args.length; opti++) { 13004 String name = args[opti]; 13005 if ("--".equals(name)) { 13006 return opti+1; 13007 } 13008 build(name); 13009 } 13010 return opti; 13011 } 13012 13013 boolean match(Object object, ComponentName comp) { 13014 if (all) { 13015 return true; 13016 } 13017 if (components != null) { 13018 for (int i=0; i<components.size(); i++) { 13019 if (components.get(i).equals(comp)) { 13020 return true; 13021 } 13022 } 13023 } 13024 if (objects != null) { 13025 for (int i=0; i<objects.size(); i++) { 13026 if (System.identityHashCode(object) == objects.get(i)) { 13027 return true; 13028 } 13029 } 13030 } 13031 if (strings != null) { 13032 String flat = comp.flattenToString(); 13033 for (int i=0; i<strings.size(); i++) { 13034 if (flat.contains(strings.get(i))) { 13035 return true; 13036 } 13037 } 13038 } 13039 return false; 13040 } 13041 } 13042 13043 /** 13044 * There are three things that cmd can be: 13045 * - a flattened component name that matches an existing activity 13046 * - the cmd arg isn't the flattened component name of an existing activity: 13047 * dump all activity whose component contains the cmd as a substring 13048 * - A hex number of the ActivityRecord object instance. 13049 */ 13050 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13051 int opti, boolean dumpAll) { 13052 ArrayList<ActivityRecord> activities; 13053 13054 synchronized (this) { 13055 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13056 } 13057 13058 if (activities.size() <= 0) { 13059 return false; 13060 } 13061 13062 String[] newArgs = new String[args.length - opti]; 13063 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13064 13065 TaskRecord lastTask = null; 13066 boolean needSep = false; 13067 for (int i=activities.size()-1; i>=0; i--) { 13068 ActivityRecord r = activities.get(i); 13069 if (needSep) { 13070 pw.println(); 13071 } 13072 needSep = true; 13073 synchronized (this) { 13074 if (lastTask != r.task) { 13075 lastTask = r.task; 13076 pw.print("TASK "); pw.print(lastTask.affinity); 13077 pw.print(" id="); pw.println(lastTask.taskId); 13078 if (dumpAll) { 13079 lastTask.dump(pw, " "); 13080 } 13081 } 13082 } 13083 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13084 } 13085 return true; 13086 } 13087 13088 /** 13089 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13090 * there is a thread associated with the activity. 13091 */ 13092 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13093 final ActivityRecord r, String[] args, boolean dumpAll) { 13094 String innerPrefix = prefix + " "; 13095 synchronized (this) { 13096 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13097 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13098 pw.print(" pid="); 13099 if (r.app != null) pw.println(r.app.pid); 13100 else pw.println("(not running)"); 13101 if (dumpAll) { 13102 r.dump(pw, innerPrefix); 13103 } 13104 } 13105 if (r.app != null && r.app.thread != null) { 13106 // flush anything that is already in the PrintWriter since the thread is going 13107 // to write to the file descriptor directly 13108 pw.flush(); 13109 try { 13110 TransferPipe tp = new TransferPipe(); 13111 try { 13112 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13113 r.appToken, innerPrefix, args); 13114 tp.go(fd); 13115 } finally { 13116 tp.kill(); 13117 } 13118 } catch (IOException e) { 13119 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13120 } catch (RemoteException e) { 13121 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13122 } 13123 } 13124 } 13125 13126 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13127 int opti, boolean dumpAll, String dumpPackage) { 13128 boolean needSep = false; 13129 boolean onlyHistory = false; 13130 boolean printedAnything = false; 13131 13132 if ("history".equals(dumpPackage)) { 13133 if (opti < args.length && "-s".equals(args[opti])) { 13134 dumpAll = false; 13135 } 13136 onlyHistory = true; 13137 dumpPackage = null; 13138 } 13139 13140 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13141 if (!onlyHistory && dumpAll) { 13142 if (mRegisteredReceivers.size() > 0) { 13143 boolean printed = false; 13144 Iterator it = mRegisteredReceivers.values().iterator(); 13145 while (it.hasNext()) { 13146 ReceiverList r = (ReceiverList)it.next(); 13147 if (dumpPackage != null && (r.app == null || 13148 !dumpPackage.equals(r.app.info.packageName))) { 13149 continue; 13150 } 13151 if (!printed) { 13152 pw.println(" Registered Receivers:"); 13153 needSep = true; 13154 printed = true; 13155 printedAnything = true; 13156 } 13157 pw.print(" * "); pw.println(r); 13158 r.dump(pw, " "); 13159 } 13160 } 13161 13162 if (mReceiverResolver.dump(pw, needSep ? 13163 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13164 " ", dumpPackage, false)) { 13165 needSep = true; 13166 printedAnything = true; 13167 } 13168 } 13169 13170 for (BroadcastQueue q : mBroadcastQueues) { 13171 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13172 printedAnything |= needSep; 13173 } 13174 13175 needSep = true; 13176 13177 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13178 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13179 if (needSep) { 13180 pw.println(); 13181 } 13182 needSep = true; 13183 printedAnything = true; 13184 pw.print(" Sticky broadcasts for user "); 13185 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13186 StringBuilder sb = new StringBuilder(128); 13187 for (Map.Entry<String, ArrayList<Intent>> ent 13188 : mStickyBroadcasts.valueAt(user).entrySet()) { 13189 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13190 if (dumpAll) { 13191 pw.println(":"); 13192 ArrayList<Intent> intents = ent.getValue(); 13193 final int N = intents.size(); 13194 for (int i=0; i<N; i++) { 13195 sb.setLength(0); 13196 sb.append(" Intent: "); 13197 intents.get(i).toShortString(sb, false, true, false, false); 13198 pw.println(sb.toString()); 13199 Bundle bundle = intents.get(i).getExtras(); 13200 if (bundle != null) { 13201 pw.print(" "); 13202 pw.println(bundle.toString()); 13203 } 13204 } 13205 } else { 13206 pw.println(""); 13207 } 13208 } 13209 } 13210 } 13211 13212 if (!onlyHistory && dumpAll) { 13213 pw.println(); 13214 for (BroadcastQueue queue : mBroadcastQueues) { 13215 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13216 + queue.mBroadcastsScheduled); 13217 } 13218 pw.println(" mHandler:"); 13219 mHandler.dump(new PrintWriterPrinter(pw), " "); 13220 needSep = true; 13221 printedAnything = true; 13222 } 13223 13224 if (!printedAnything) { 13225 pw.println(" (nothing)"); 13226 } 13227 } 13228 13229 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13230 int opti, boolean dumpAll, String dumpPackage) { 13231 boolean needSep; 13232 boolean printedAnything = false; 13233 13234 ItemMatcher matcher = new ItemMatcher(); 13235 matcher.build(args, opti); 13236 13237 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13238 13239 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13240 printedAnything |= needSep; 13241 13242 if (mLaunchingProviders.size() > 0) { 13243 boolean printed = false; 13244 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13245 ContentProviderRecord r = mLaunchingProviders.get(i); 13246 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13247 continue; 13248 } 13249 if (!printed) { 13250 if (needSep) pw.println(); 13251 needSep = true; 13252 pw.println(" Launching content providers:"); 13253 printed = true; 13254 printedAnything = true; 13255 } 13256 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13257 pw.println(r); 13258 } 13259 } 13260 13261 if (mGrantedUriPermissions.size() > 0) { 13262 boolean printed = false; 13263 int dumpUid = -2; 13264 if (dumpPackage != null) { 13265 try { 13266 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13267 } catch (NameNotFoundException e) { 13268 dumpUid = -1; 13269 } 13270 } 13271 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13272 int uid = mGrantedUriPermissions.keyAt(i); 13273 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13274 continue; 13275 } 13276 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13277 if (!printed) { 13278 if (needSep) pw.println(); 13279 needSep = true; 13280 pw.println(" Granted Uri Permissions:"); 13281 printed = true; 13282 printedAnything = true; 13283 } 13284 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13285 for (UriPermission perm : perms.values()) { 13286 pw.print(" "); pw.println(perm); 13287 if (dumpAll) { 13288 perm.dump(pw, " "); 13289 } 13290 } 13291 } 13292 } 13293 13294 if (!printedAnything) { 13295 pw.println(" (nothing)"); 13296 } 13297 } 13298 13299 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13300 int opti, boolean dumpAll, String dumpPackage) { 13301 boolean printed = false; 13302 13303 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13304 13305 if (mIntentSenderRecords.size() > 0) { 13306 Iterator<WeakReference<PendingIntentRecord>> it 13307 = mIntentSenderRecords.values().iterator(); 13308 while (it.hasNext()) { 13309 WeakReference<PendingIntentRecord> ref = it.next(); 13310 PendingIntentRecord rec = ref != null ? ref.get(): null; 13311 if (dumpPackage != null && (rec == null 13312 || !dumpPackage.equals(rec.key.packageName))) { 13313 continue; 13314 } 13315 printed = true; 13316 if (rec != null) { 13317 pw.print(" * "); pw.println(rec); 13318 if (dumpAll) { 13319 rec.dump(pw, " "); 13320 } 13321 } else { 13322 pw.print(" * "); pw.println(ref); 13323 } 13324 } 13325 } 13326 13327 if (!printed) { 13328 pw.println(" (nothing)"); 13329 } 13330 } 13331 13332 private static final int dumpProcessList(PrintWriter pw, 13333 ActivityManagerService service, List list, 13334 String prefix, String normalLabel, String persistentLabel, 13335 String dumpPackage) { 13336 int numPers = 0; 13337 final int N = list.size()-1; 13338 for (int i=N; i>=0; i--) { 13339 ProcessRecord r = (ProcessRecord)list.get(i); 13340 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13341 continue; 13342 } 13343 pw.println(String.format("%s%s #%2d: %s", 13344 prefix, (r.persistent ? persistentLabel : normalLabel), 13345 i, r.toString())); 13346 if (r.persistent) { 13347 numPers++; 13348 } 13349 } 13350 return numPers; 13351 } 13352 13353 private static final boolean dumpProcessOomList(PrintWriter pw, 13354 ActivityManagerService service, List<ProcessRecord> origList, 13355 String prefix, String normalLabel, String persistentLabel, 13356 boolean inclDetails, String dumpPackage) { 13357 13358 ArrayList<Pair<ProcessRecord, Integer>> list 13359 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13360 for (int i=0; i<origList.size(); i++) { 13361 ProcessRecord r = origList.get(i); 13362 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13363 continue; 13364 } 13365 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13366 } 13367 13368 if (list.size() <= 0) { 13369 return false; 13370 } 13371 13372 Comparator<Pair<ProcessRecord, Integer>> comparator 13373 = new Comparator<Pair<ProcessRecord, Integer>>() { 13374 @Override 13375 public int compare(Pair<ProcessRecord, Integer> object1, 13376 Pair<ProcessRecord, Integer> object2) { 13377 if (object1.first.setAdj != object2.first.setAdj) { 13378 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13379 } 13380 if (object1.second.intValue() != object2.second.intValue()) { 13381 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13382 } 13383 return 0; 13384 } 13385 }; 13386 13387 Collections.sort(list, comparator); 13388 13389 final long curRealtime = SystemClock.elapsedRealtime(); 13390 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13391 final long curUptime = SystemClock.uptimeMillis(); 13392 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13393 13394 for (int i=list.size()-1; i>=0; i--) { 13395 ProcessRecord r = list.get(i).first; 13396 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13397 char schedGroup; 13398 switch (r.setSchedGroup) { 13399 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13400 schedGroup = 'B'; 13401 break; 13402 case Process.THREAD_GROUP_DEFAULT: 13403 schedGroup = 'F'; 13404 break; 13405 default: 13406 schedGroup = '?'; 13407 break; 13408 } 13409 char foreground; 13410 if (r.foregroundActivities) { 13411 foreground = 'A'; 13412 } else if (r.foregroundServices) { 13413 foreground = 'S'; 13414 } else { 13415 foreground = ' '; 13416 } 13417 String procState = ProcessList.makeProcStateString(r.curProcState); 13418 pw.print(prefix); 13419 pw.print(r.persistent ? persistentLabel : normalLabel); 13420 pw.print(" #"); 13421 int num = (origList.size()-1)-list.get(i).second; 13422 if (num < 10) pw.print(' '); 13423 pw.print(num); 13424 pw.print(": "); 13425 pw.print(oomAdj); 13426 pw.print(' '); 13427 pw.print(schedGroup); 13428 pw.print('/'); 13429 pw.print(foreground); 13430 pw.print('/'); 13431 pw.print(procState); 13432 pw.print(" trm:"); 13433 if (r.trimMemoryLevel < 10) pw.print(' '); 13434 pw.print(r.trimMemoryLevel); 13435 pw.print(' '); 13436 pw.print(r.toShortString()); 13437 pw.print(" ("); 13438 pw.print(r.adjType); 13439 pw.println(')'); 13440 if (r.adjSource != null || r.adjTarget != null) { 13441 pw.print(prefix); 13442 pw.print(" "); 13443 if (r.adjTarget instanceof ComponentName) { 13444 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13445 } else if (r.adjTarget != null) { 13446 pw.print(r.adjTarget.toString()); 13447 } else { 13448 pw.print("{null}"); 13449 } 13450 pw.print("<="); 13451 if (r.adjSource instanceof ProcessRecord) { 13452 pw.print("Proc{"); 13453 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13454 pw.println("}"); 13455 } else if (r.adjSource != null) { 13456 pw.println(r.adjSource.toString()); 13457 } else { 13458 pw.println("{null}"); 13459 } 13460 } 13461 if (inclDetails) { 13462 pw.print(prefix); 13463 pw.print(" "); 13464 pw.print("oom: max="); pw.print(r.maxAdj); 13465 pw.print(" curRaw="); pw.print(r.curRawAdj); 13466 pw.print(" setRaw="); pw.print(r.setRawAdj); 13467 pw.print(" cur="); pw.print(r.curAdj); 13468 pw.print(" set="); pw.println(r.setAdj); 13469 pw.print(prefix); 13470 pw.print(" "); 13471 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13472 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13473 pw.print(" lastPss="); pw.print(r.lastPss); 13474 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13475 pw.print(prefix); 13476 pw.print(" "); 13477 pw.print("cached="); pw.print(r.cached); 13478 pw.print(" empty="); pw.print(r.empty); 13479 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13480 13481 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13482 if (r.lastWakeTime != 0) { 13483 long wtime; 13484 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13485 synchronized (stats) { 13486 wtime = stats.getProcessWakeTime(r.info.uid, 13487 r.pid, curRealtime); 13488 } 13489 long timeUsed = wtime - r.lastWakeTime; 13490 pw.print(prefix); 13491 pw.print(" "); 13492 pw.print("keep awake over "); 13493 TimeUtils.formatDuration(realtimeSince, pw); 13494 pw.print(" used "); 13495 TimeUtils.formatDuration(timeUsed, pw); 13496 pw.print(" ("); 13497 pw.print((timeUsed*100)/realtimeSince); 13498 pw.println("%)"); 13499 } 13500 if (r.lastCpuTime != 0) { 13501 long timeUsed = r.curCpuTime - r.lastCpuTime; 13502 pw.print(prefix); 13503 pw.print(" "); 13504 pw.print("run cpu over "); 13505 TimeUtils.formatDuration(uptimeSince, pw); 13506 pw.print(" used "); 13507 TimeUtils.formatDuration(timeUsed, pw); 13508 pw.print(" ("); 13509 pw.print((timeUsed*100)/uptimeSince); 13510 pw.println("%)"); 13511 } 13512 } 13513 } 13514 } 13515 return true; 13516 } 13517 13518 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13519 String[] args) { 13520 ArrayList<ProcessRecord> procs; 13521 synchronized (this) { 13522 if (args != null && args.length > start 13523 && args[start].charAt(0) != '-') { 13524 procs = new ArrayList<ProcessRecord>(); 13525 int pid = -1; 13526 try { 13527 pid = Integer.parseInt(args[start]); 13528 } catch (NumberFormatException e) { 13529 } 13530 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13531 ProcessRecord proc = mLruProcesses.get(i); 13532 if (proc.pid == pid) { 13533 procs.add(proc); 13534 } else if (allPkgs && proc.pkgList != null 13535 && proc.pkgList.containsKey(args[start])) { 13536 procs.add(proc); 13537 } else if (proc.processName.equals(args[start])) { 13538 procs.add(proc); 13539 } 13540 } 13541 if (procs.size() <= 0) { 13542 return null; 13543 } 13544 } else { 13545 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13546 } 13547 } 13548 return procs; 13549 } 13550 13551 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13552 PrintWriter pw, String[] args) { 13553 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13554 if (procs == null) { 13555 pw.println("No process found for: " + args[0]); 13556 return; 13557 } 13558 13559 long uptime = SystemClock.uptimeMillis(); 13560 long realtime = SystemClock.elapsedRealtime(); 13561 pw.println("Applications Graphics Acceleration Info:"); 13562 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13563 13564 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13565 ProcessRecord r = procs.get(i); 13566 if (r.thread != null) { 13567 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13568 pw.flush(); 13569 try { 13570 TransferPipe tp = new TransferPipe(); 13571 try { 13572 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13573 tp.go(fd); 13574 } finally { 13575 tp.kill(); 13576 } 13577 } catch (IOException e) { 13578 pw.println("Failure while dumping the app: " + r); 13579 pw.flush(); 13580 } catch (RemoteException e) { 13581 pw.println("Got a RemoteException while dumping the app " + r); 13582 pw.flush(); 13583 } 13584 } 13585 } 13586 } 13587 13588 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13589 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13590 if (procs == null) { 13591 pw.println("No process found for: " + args[0]); 13592 return; 13593 } 13594 13595 pw.println("Applications Database Info:"); 13596 13597 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13598 ProcessRecord r = procs.get(i); 13599 if (r.thread != null) { 13600 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13601 pw.flush(); 13602 try { 13603 TransferPipe tp = new TransferPipe(); 13604 try { 13605 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13606 tp.go(fd); 13607 } finally { 13608 tp.kill(); 13609 } 13610 } catch (IOException e) { 13611 pw.println("Failure while dumping the app: " + r); 13612 pw.flush(); 13613 } catch (RemoteException e) { 13614 pw.println("Got a RemoteException while dumping the app " + r); 13615 pw.flush(); 13616 } 13617 } 13618 } 13619 } 13620 13621 final static class MemItem { 13622 final boolean isProc; 13623 final String label; 13624 final String shortLabel; 13625 final long pss; 13626 final int id; 13627 final boolean hasActivities; 13628 ArrayList<MemItem> subitems; 13629 13630 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13631 boolean _hasActivities) { 13632 isProc = true; 13633 label = _label; 13634 shortLabel = _shortLabel; 13635 pss = _pss; 13636 id = _id; 13637 hasActivities = _hasActivities; 13638 } 13639 13640 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13641 isProc = false; 13642 label = _label; 13643 shortLabel = _shortLabel; 13644 pss = _pss; 13645 id = _id; 13646 hasActivities = false; 13647 } 13648 } 13649 13650 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13651 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13652 if (sort && !isCompact) { 13653 Collections.sort(items, new Comparator<MemItem>() { 13654 @Override 13655 public int compare(MemItem lhs, MemItem rhs) { 13656 if (lhs.pss < rhs.pss) { 13657 return 1; 13658 } else if (lhs.pss > rhs.pss) { 13659 return -1; 13660 } 13661 return 0; 13662 } 13663 }); 13664 } 13665 13666 for (int i=0; i<items.size(); i++) { 13667 MemItem mi = items.get(i); 13668 if (!isCompact) { 13669 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13670 } else if (mi.isProc) { 13671 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13672 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13673 pw.println(mi.hasActivities ? ",a" : ",e"); 13674 } else { 13675 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13676 pw.println(mi.pss); 13677 } 13678 if (mi.subitems != null) { 13679 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13680 true, isCompact); 13681 } 13682 } 13683 } 13684 13685 // These are in KB. 13686 static final long[] DUMP_MEM_BUCKETS = new long[] { 13687 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13688 120*1024, 160*1024, 200*1024, 13689 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13690 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13691 }; 13692 13693 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13694 boolean stackLike) { 13695 int start = label.lastIndexOf('.'); 13696 if (start >= 0) start++; 13697 else start = 0; 13698 int end = label.length(); 13699 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13700 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13701 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13702 out.append(bucket); 13703 out.append(stackLike ? "MB." : "MB "); 13704 out.append(label, start, end); 13705 return; 13706 } 13707 } 13708 out.append(memKB/1024); 13709 out.append(stackLike ? "MB." : "MB "); 13710 out.append(label, start, end); 13711 } 13712 13713 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13714 ProcessList.NATIVE_ADJ, 13715 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13716 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13717 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13718 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13719 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13720 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13721 }; 13722 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13723 "Native", 13724 "System", "Persistent", "Persistent Service", "Foreground", 13725 "Visible", "Perceptible", 13726 "Heavy Weight", "Backup", 13727 "A Services", "Home", 13728 "Previous", "B Services", "Cached" 13729 }; 13730 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13731 "native", 13732 "sys", "pers", "persvc", "fore", 13733 "vis", "percept", 13734 "heavy", "backup", 13735 "servicea", "home", 13736 "prev", "serviceb", "cached" 13737 }; 13738 13739 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13740 long realtime, boolean isCheckinRequest, boolean isCompact) { 13741 if (isCheckinRequest || isCompact) { 13742 // short checkin version 13743 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13744 } else { 13745 pw.println("Applications Memory Usage (kB):"); 13746 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13747 } 13748 } 13749 13750 private static final int KSM_SHARED = 0; 13751 private static final int KSM_SHARING = 1; 13752 private static final int KSM_UNSHARED = 2; 13753 private static final int KSM_VOLATILE = 3; 13754 13755 private final long[] getKsmInfo() { 13756 long[] longOut = new long[4]; 13757 final int[] SINGLE_LONG_FORMAT = new int[] { 13758 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13759 }; 13760 long[] longTmp = new long[1]; 13761 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13762 SINGLE_LONG_FORMAT, null, longTmp, null); 13763 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13764 longTmp[0] = 0; 13765 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13766 SINGLE_LONG_FORMAT, null, longTmp, null); 13767 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13768 longTmp[0] = 0; 13769 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13770 SINGLE_LONG_FORMAT, null, longTmp, null); 13771 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13772 longTmp[0] = 0; 13773 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13774 SINGLE_LONG_FORMAT, null, longTmp, null); 13775 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13776 return longOut; 13777 } 13778 13779 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13780 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13781 boolean dumpDetails = false; 13782 boolean dumpFullDetails = false; 13783 boolean dumpDalvik = false; 13784 boolean oomOnly = false; 13785 boolean isCompact = false; 13786 boolean localOnly = false; 13787 boolean packages = false; 13788 13789 int opti = 0; 13790 while (opti < args.length) { 13791 String opt = args[opti]; 13792 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13793 break; 13794 } 13795 opti++; 13796 if ("-a".equals(opt)) { 13797 dumpDetails = true; 13798 dumpFullDetails = true; 13799 dumpDalvik = true; 13800 } else if ("-d".equals(opt)) { 13801 dumpDalvik = true; 13802 } else if ("-c".equals(opt)) { 13803 isCompact = true; 13804 } else if ("--oom".equals(opt)) { 13805 oomOnly = true; 13806 } else if ("--local".equals(opt)) { 13807 localOnly = true; 13808 } else if ("--package".equals(opt)) { 13809 packages = true; 13810 } else if ("-h".equals(opt)) { 13811 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13812 pw.println(" -a: include all available information for each process."); 13813 pw.println(" -d: include dalvik details when dumping process details."); 13814 pw.println(" -c: dump in a compact machine-parseable representation."); 13815 pw.println(" --oom: only show processes organized by oom adj."); 13816 pw.println(" --local: only collect details locally, don't call process."); 13817 pw.println(" --package: interpret process arg as package, dumping all"); 13818 pw.println(" processes that have loaded that package."); 13819 pw.println("If [process] is specified it can be the name or "); 13820 pw.println("pid of a specific process to dump."); 13821 return; 13822 } else { 13823 pw.println("Unknown argument: " + opt + "; use -h for help"); 13824 } 13825 } 13826 13827 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13828 long uptime = SystemClock.uptimeMillis(); 13829 long realtime = SystemClock.elapsedRealtime(); 13830 final long[] tmpLong = new long[1]; 13831 13832 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13833 if (procs == null) { 13834 // No Java processes. Maybe they want to print a native process. 13835 if (args != null && args.length > opti 13836 && args[opti].charAt(0) != '-') { 13837 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13838 = new ArrayList<ProcessCpuTracker.Stats>(); 13839 updateCpuStatsNow(); 13840 int findPid = -1; 13841 try { 13842 findPid = Integer.parseInt(args[opti]); 13843 } catch (NumberFormatException e) { 13844 } 13845 synchronized (mProcessCpuTracker) { 13846 final int N = mProcessCpuTracker.countStats(); 13847 for (int i=0; i<N; i++) { 13848 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13849 if (st.pid == findPid || (st.baseName != null 13850 && st.baseName.equals(args[opti]))) { 13851 nativeProcs.add(st); 13852 } 13853 } 13854 } 13855 if (nativeProcs.size() > 0) { 13856 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13857 isCompact); 13858 Debug.MemoryInfo mi = null; 13859 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13860 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13861 final int pid = r.pid; 13862 if (!isCheckinRequest && dumpDetails) { 13863 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13864 } 13865 if (mi == null) { 13866 mi = new Debug.MemoryInfo(); 13867 } 13868 if (dumpDetails || (!brief && !oomOnly)) { 13869 Debug.getMemoryInfo(pid, mi); 13870 } else { 13871 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13872 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13873 } 13874 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13875 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13876 if (isCheckinRequest) { 13877 pw.println(); 13878 } 13879 } 13880 return; 13881 } 13882 } 13883 pw.println("No process found for: " + args[opti]); 13884 return; 13885 } 13886 13887 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13888 dumpDetails = true; 13889 } 13890 13891 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13892 13893 String[] innerArgs = new String[args.length-opti]; 13894 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13895 13896 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13897 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13898 long nativePss=0, dalvikPss=0, otherPss=0; 13899 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13900 13901 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13902 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13903 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13904 13905 long totalPss = 0; 13906 long cachedPss = 0; 13907 13908 Debug.MemoryInfo mi = null; 13909 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13910 final ProcessRecord r = procs.get(i); 13911 final IApplicationThread thread; 13912 final int pid; 13913 final int oomAdj; 13914 final boolean hasActivities; 13915 synchronized (this) { 13916 thread = r.thread; 13917 pid = r.pid; 13918 oomAdj = r.getSetAdjWithServices(); 13919 hasActivities = r.activities.size() > 0; 13920 } 13921 if (thread != null) { 13922 if (!isCheckinRequest && dumpDetails) { 13923 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13924 } 13925 if (mi == null) { 13926 mi = new Debug.MemoryInfo(); 13927 } 13928 if (dumpDetails || (!brief && !oomOnly)) { 13929 Debug.getMemoryInfo(pid, mi); 13930 } else { 13931 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13932 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13933 } 13934 if (dumpDetails) { 13935 if (localOnly) { 13936 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13937 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13938 if (isCheckinRequest) { 13939 pw.println(); 13940 } 13941 } else { 13942 try { 13943 pw.flush(); 13944 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13945 dumpDalvik, innerArgs); 13946 } catch (RemoteException e) { 13947 if (!isCheckinRequest) { 13948 pw.println("Got RemoteException!"); 13949 pw.flush(); 13950 } 13951 } 13952 } 13953 } 13954 13955 final long myTotalPss = mi.getTotalPss(); 13956 final long myTotalUss = mi.getTotalUss(); 13957 13958 synchronized (this) { 13959 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13960 // Record this for posterity if the process has been stable. 13961 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13962 } 13963 } 13964 13965 if (!isCheckinRequest && mi != null) { 13966 totalPss += myTotalPss; 13967 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13968 (hasActivities ? " / activities)" : ")"), 13969 r.processName, myTotalPss, pid, hasActivities); 13970 procMems.add(pssItem); 13971 procMemsMap.put(pid, pssItem); 13972 13973 nativePss += mi.nativePss; 13974 dalvikPss += mi.dalvikPss; 13975 otherPss += mi.otherPss; 13976 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13977 long mem = mi.getOtherPss(j); 13978 miscPss[j] += mem; 13979 otherPss -= mem; 13980 } 13981 13982 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13983 cachedPss += myTotalPss; 13984 } 13985 13986 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13987 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13988 || oomIndex == (oomPss.length-1)) { 13989 oomPss[oomIndex] += myTotalPss; 13990 if (oomProcs[oomIndex] == null) { 13991 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13992 } 13993 oomProcs[oomIndex].add(pssItem); 13994 break; 13995 } 13996 } 13997 } 13998 } 13999 } 14000 14001 long nativeProcTotalPss = 0; 14002 14003 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14004 // If we are showing aggregations, also look for native processes to 14005 // include so that our aggregations are more accurate. 14006 updateCpuStatsNow(); 14007 synchronized (mProcessCpuTracker) { 14008 final int N = mProcessCpuTracker.countStats(); 14009 for (int i=0; i<N; i++) { 14010 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14011 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14012 if (mi == null) { 14013 mi = new Debug.MemoryInfo(); 14014 } 14015 if (!brief && !oomOnly) { 14016 Debug.getMemoryInfo(st.pid, mi); 14017 } else { 14018 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14019 mi.nativePrivateDirty = (int)tmpLong[0]; 14020 } 14021 14022 final long myTotalPss = mi.getTotalPss(); 14023 totalPss += myTotalPss; 14024 nativeProcTotalPss += myTotalPss; 14025 14026 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14027 st.name, myTotalPss, st.pid, false); 14028 procMems.add(pssItem); 14029 14030 nativePss += mi.nativePss; 14031 dalvikPss += mi.dalvikPss; 14032 otherPss += mi.otherPss; 14033 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14034 long mem = mi.getOtherPss(j); 14035 miscPss[j] += mem; 14036 otherPss -= mem; 14037 } 14038 oomPss[0] += myTotalPss; 14039 if (oomProcs[0] == null) { 14040 oomProcs[0] = new ArrayList<MemItem>(); 14041 } 14042 oomProcs[0].add(pssItem); 14043 } 14044 } 14045 } 14046 14047 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14048 14049 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14050 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14051 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14052 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14053 String label = Debug.MemoryInfo.getOtherLabel(j); 14054 catMems.add(new MemItem(label, label, miscPss[j], j)); 14055 } 14056 14057 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14058 for (int j=0; j<oomPss.length; j++) { 14059 if (oomPss[j] != 0) { 14060 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14061 : DUMP_MEM_OOM_LABEL[j]; 14062 MemItem item = new MemItem(label, label, oomPss[j], 14063 DUMP_MEM_OOM_ADJ[j]); 14064 item.subitems = oomProcs[j]; 14065 oomMems.add(item); 14066 } 14067 } 14068 14069 if (!brief && !oomOnly && !isCompact) { 14070 pw.println(); 14071 pw.println("Total PSS by process:"); 14072 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14073 pw.println(); 14074 } 14075 if (!isCompact) { 14076 pw.println("Total PSS by OOM adjustment:"); 14077 } 14078 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14079 if (!brief && !oomOnly) { 14080 PrintWriter out = categoryPw != null ? categoryPw : pw; 14081 if (!isCompact) { 14082 out.println(); 14083 out.println("Total PSS by category:"); 14084 } 14085 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14086 } 14087 if (!isCompact) { 14088 pw.println(); 14089 } 14090 MemInfoReader memInfo = new MemInfoReader(); 14091 memInfo.readMemInfo(); 14092 if (nativeProcTotalPss > 0) { 14093 synchronized (this) { 14094 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14095 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14096 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14097 } 14098 } 14099 if (!brief) { 14100 if (!isCompact) { 14101 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14102 pw.print(" kB (status "); 14103 switch (mLastMemoryLevel) { 14104 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14105 pw.println("normal)"); 14106 break; 14107 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14108 pw.println("moderate)"); 14109 break; 14110 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14111 pw.println("low)"); 14112 break; 14113 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14114 pw.println("critical)"); 14115 break; 14116 default: 14117 pw.print(mLastMemoryLevel); 14118 pw.println(")"); 14119 break; 14120 } 14121 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14122 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14123 pw.print(cachedPss); pw.print(" cached pss + "); 14124 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14125 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14126 } else { 14127 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14128 pw.print(cachedPss + memInfo.getCachedSizeKb() 14129 + memInfo.getFreeSizeKb()); pw.print(","); 14130 pw.println(totalPss - cachedPss); 14131 } 14132 } 14133 if (!isCompact) { 14134 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14135 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14136 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14137 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14138 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14139 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14140 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14141 } 14142 if (!brief) { 14143 if (memInfo.getZramTotalSizeKb() != 0) { 14144 if (!isCompact) { 14145 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14146 pw.print(" kB physical used for "); 14147 pw.print(memInfo.getSwapTotalSizeKb() 14148 - memInfo.getSwapFreeSizeKb()); 14149 pw.print(" kB in swap ("); 14150 pw.print(memInfo.getSwapTotalSizeKb()); 14151 pw.println(" kB total swap)"); 14152 } else { 14153 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14154 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14155 pw.println(memInfo.getSwapFreeSizeKb()); 14156 } 14157 } 14158 final long[] ksm = getKsmInfo(); 14159 if (!isCompact) { 14160 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14161 || ksm[KSM_VOLATILE] != 0) { 14162 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14163 pw.print(" kB saved from shared "); 14164 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14165 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14166 pw.print(" kB unshared; "); 14167 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14168 } 14169 pw.print(" Tuning: "); 14170 pw.print(ActivityManager.staticGetMemoryClass()); 14171 pw.print(" (large "); 14172 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14173 pw.print("), oom "); 14174 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14175 pw.print(" kB"); 14176 pw.print(", restore limit "); 14177 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14178 pw.print(" kB"); 14179 if (ActivityManager.isLowRamDeviceStatic()) { 14180 pw.print(" (low-ram)"); 14181 } 14182 if (ActivityManager.isHighEndGfx()) { 14183 pw.print(" (high-end-gfx)"); 14184 } 14185 pw.println(); 14186 } else { 14187 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14188 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14189 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14190 pw.print("tuning,"); 14191 pw.print(ActivityManager.staticGetMemoryClass()); 14192 pw.print(','); 14193 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14194 pw.print(','); 14195 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14196 if (ActivityManager.isLowRamDeviceStatic()) { 14197 pw.print(",low-ram"); 14198 } 14199 if (ActivityManager.isHighEndGfx()) { 14200 pw.print(",high-end-gfx"); 14201 } 14202 pw.println(); 14203 } 14204 } 14205 } 14206 } 14207 14208 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14209 String name) { 14210 sb.append(" "); 14211 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14212 sb.append(' '); 14213 sb.append(ProcessList.makeProcStateString(procState)); 14214 sb.append(' '); 14215 ProcessList.appendRamKb(sb, pss); 14216 sb.append(" kB: "); 14217 sb.append(name); 14218 } 14219 14220 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14221 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14222 sb.append(" ("); 14223 sb.append(mi.pid); 14224 sb.append(") "); 14225 sb.append(mi.adjType); 14226 sb.append('\n'); 14227 if (mi.adjReason != null) { 14228 sb.append(" "); 14229 sb.append(mi.adjReason); 14230 sb.append('\n'); 14231 } 14232 } 14233 14234 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14235 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14236 for (int i=0, N=memInfos.size(); i<N; i++) { 14237 ProcessMemInfo mi = memInfos.get(i); 14238 infoMap.put(mi.pid, mi); 14239 } 14240 updateCpuStatsNow(); 14241 synchronized (mProcessCpuTracker) { 14242 final int N = mProcessCpuTracker.countStats(); 14243 for (int i=0; i<N; i++) { 14244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14245 if (st.vsize > 0) { 14246 long pss = Debug.getPss(st.pid, null); 14247 if (pss > 0) { 14248 if (infoMap.indexOfKey(st.pid) < 0) { 14249 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14250 ProcessList.NATIVE_ADJ, -1, "native", null); 14251 mi.pss = pss; 14252 memInfos.add(mi); 14253 } 14254 } 14255 } 14256 } 14257 } 14258 14259 long totalPss = 0; 14260 for (int i=0, N=memInfos.size(); i<N; i++) { 14261 ProcessMemInfo mi = memInfos.get(i); 14262 if (mi.pss == 0) { 14263 mi.pss = Debug.getPss(mi.pid, null); 14264 } 14265 totalPss += mi.pss; 14266 } 14267 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14268 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14269 if (lhs.oomAdj != rhs.oomAdj) { 14270 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14271 } 14272 if (lhs.pss != rhs.pss) { 14273 return lhs.pss < rhs.pss ? 1 : -1; 14274 } 14275 return 0; 14276 } 14277 }); 14278 14279 StringBuilder tag = new StringBuilder(128); 14280 StringBuilder stack = new StringBuilder(128); 14281 tag.append("Low on memory -- "); 14282 appendMemBucket(tag, totalPss, "total", false); 14283 appendMemBucket(stack, totalPss, "total", true); 14284 14285 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14286 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14287 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14288 14289 boolean firstLine = true; 14290 int lastOomAdj = Integer.MIN_VALUE; 14291 long extraNativeRam = 0; 14292 long cachedPss = 0; 14293 for (int i=0, N=memInfos.size(); i<N; i++) { 14294 ProcessMemInfo mi = memInfos.get(i); 14295 14296 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14297 cachedPss += mi.pss; 14298 } 14299 14300 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14301 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14302 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14303 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14304 if (lastOomAdj != mi.oomAdj) { 14305 lastOomAdj = mi.oomAdj; 14306 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14307 tag.append(" / "); 14308 } 14309 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14310 if (firstLine) { 14311 stack.append(":"); 14312 firstLine = false; 14313 } 14314 stack.append("\n\t at "); 14315 } else { 14316 stack.append("$"); 14317 } 14318 } else { 14319 tag.append(" "); 14320 stack.append("$"); 14321 } 14322 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14323 appendMemBucket(tag, mi.pss, mi.name, false); 14324 } 14325 appendMemBucket(stack, mi.pss, mi.name, true); 14326 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14327 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14328 stack.append("("); 14329 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14330 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14331 stack.append(DUMP_MEM_OOM_LABEL[k]); 14332 stack.append(":"); 14333 stack.append(DUMP_MEM_OOM_ADJ[k]); 14334 } 14335 } 14336 stack.append(")"); 14337 } 14338 } 14339 14340 appendMemInfo(fullNativeBuilder, mi); 14341 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14342 // The short form only has native processes that are >= 1MB. 14343 if (mi.pss >= 1000) { 14344 appendMemInfo(shortNativeBuilder, mi); 14345 } else { 14346 extraNativeRam += mi.pss; 14347 } 14348 } else { 14349 // Short form has all other details, but if we have collected RAM 14350 // from smaller native processes let's dump a summary of that. 14351 if (extraNativeRam > 0) { 14352 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14353 -1, extraNativeRam, "(Other native)"); 14354 shortNativeBuilder.append('\n'); 14355 extraNativeRam = 0; 14356 } 14357 appendMemInfo(fullJavaBuilder, mi); 14358 } 14359 } 14360 14361 fullJavaBuilder.append(" "); 14362 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14363 fullJavaBuilder.append(" kB: TOTAL\n"); 14364 14365 MemInfoReader memInfo = new MemInfoReader(); 14366 memInfo.readMemInfo(); 14367 final long[] infos = memInfo.getRawInfo(); 14368 14369 StringBuilder memInfoBuilder = new StringBuilder(1024); 14370 Debug.getMemInfo(infos); 14371 memInfoBuilder.append(" MemInfo: "); 14372 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14373 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14374 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14375 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14376 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14377 memInfoBuilder.append(" "); 14378 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14379 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14380 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14381 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14382 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14383 memInfoBuilder.append(" ZRAM: "); 14384 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14385 memInfoBuilder.append(" kB RAM, "); 14386 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14387 memInfoBuilder.append(" kB swap total, "); 14388 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14389 memInfoBuilder.append(" kB swap free\n"); 14390 } 14391 final long[] ksm = getKsmInfo(); 14392 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14393 || ksm[KSM_VOLATILE] != 0) { 14394 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14395 memInfoBuilder.append(" kB saved from shared "); 14396 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14397 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14398 memInfoBuilder.append(" kB unshared; "); 14399 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14400 } 14401 memInfoBuilder.append(" Free RAM: "); 14402 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14403 + memInfo.getFreeSizeKb()); 14404 memInfoBuilder.append(" kB\n"); 14405 memInfoBuilder.append(" Used RAM: "); 14406 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14407 memInfoBuilder.append(" kB\n"); 14408 memInfoBuilder.append(" Lost RAM: "); 14409 memInfoBuilder.append(memInfo.getTotalSizeKb() 14410 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14411 - memInfo.getKernelUsedSizeKb()); 14412 memInfoBuilder.append(" kB\n"); 14413 Slog.i(TAG, "Low on memory:"); 14414 Slog.i(TAG, shortNativeBuilder.toString()); 14415 Slog.i(TAG, fullJavaBuilder.toString()); 14416 Slog.i(TAG, memInfoBuilder.toString()); 14417 14418 StringBuilder dropBuilder = new StringBuilder(1024); 14419 /* 14420 StringWriter oomSw = new StringWriter(); 14421 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14422 StringWriter catSw = new StringWriter(); 14423 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14424 String[] emptyArgs = new String[] { }; 14425 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14426 oomPw.flush(); 14427 String oomString = oomSw.toString(); 14428 */ 14429 dropBuilder.append("Low on memory:"); 14430 dropBuilder.append(stack); 14431 dropBuilder.append('\n'); 14432 dropBuilder.append(fullNativeBuilder); 14433 dropBuilder.append(fullJavaBuilder); 14434 dropBuilder.append('\n'); 14435 dropBuilder.append(memInfoBuilder); 14436 dropBuilder.append('\n'); 14437 /* 14438 dropBuilder.append(oomString); 14439 dropBuilder.append('\n'); 14440 */ 14441 StringWriter catSw = new StringWriter(); 14442 synchronized (ActivityManagerService.this) { 14443 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14444 String[] emptyArgs = new String[] { }; 14445 catPw.println(); 14446 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14447 catPw.println(); 14448 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14449 false, false, null); 14450 catPw.println(); 14451 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14452 catPw.flush(); 14453 } 14454 dropBuilder.append(catSw.toString()); 14455 addErrorToDropBox("lowmem", null, "system_server", null, 14456 null, tag.toString(), dropBuilder.toString(), null, null); 14457 //Slog.i(TAG, "Sent to dropbox:"); 14458 //Slog.i(TAG, dropBuilder.toString()); 14459 synchronized (ActivityManagerService.this) { 14460 long now = SystemClock.uptimeMillis(); 14461 if (mLastMemUsageReportTime < now) { 14462 mLastMemUsageReportTime = now; 14463 } 14464 } 14465 } 14466 14467 /** 14468 * Searches array of arguments for the specified string 14469 * @param args array of argument strings 14470 * @param value value to search for 14471 * @return true if the value is contained in the array 14472 */ 14473 private static boolean scanArgs(String[] args, String value) { 14474 if (args != null) { 14475 for (String arg : args) { 14476 if (value.equals(arg)) { 14477 return true; 14478 } 14479 } 14480 } 14481 return false; 14482 } 14483 14484 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14485 ContentProviderRecord cpr, boolean always) { 14486 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14487 14488 if (!inLaunching || always) { 14489 synchronized (cpr) { 14490 cpr.launchingApp = null; 14491 cpr.notifyAll(); 14492 } 14493 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14494 String names[] = cpr.info.authority.split(";"); 14495 for (int j = 0; j < names.length; j++) { 14496 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14497 } 14498 } 14499 14500 for (int i=0; i<cpr.connections.size(); i++) { 14501 ContentProviderConnection conn = cpr.connections.get(i); 14502 if (conn.waiting) { 14503 // If this connection is waiting for the provider, then we don't 14504 // need to mess with its process unless we are always removing 14505 // or for some reason the provider is not currently launching. 14506 if (inLaunching && !always) { 14507 continue; 14508 } 14509 } 14510 ProcessRecord capp = conn.client; 14511 conn.dead = true; 14512 if (conn.stableCount > 0) { 14513 if (!capp.persistent && capp.thread != null 14514 && capp.pid != 0 14515 && capp.pid != MY_PID) { 14516 capp.kill("depends on provider " 14517 + cpr.name.flattenToShortString() 14518 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14519 } 14520 } else if (capp.thread != null && conn.provider.provider != null) { 14521 try { 14522 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14523 } catch (RemoteException e) { 14524 } 14525 // In the protocol here, we don't expect the client to correctly 14526 // clean up this connection, we'll just remove it. 14527 cpr.connections.remove(i); 14528 conn.client.conProviders.remove(conn); 14529 } 14530 } 14531 14532 if (inLaunching && always) { 14533 mLaunchingProviders.remove(cpr); 14534 } 14535 return inLaunching; 14536 } 14537 14538 /** 14539 * Main code for cleaning up a process when it has gone away. This is 14540 * called both as a result of the process dying, or directly when stopping 14541 * a process when running in single process mode. 14542 * 14543 * @return Returns true if the given process has been restarted, so the 14544 * app that was passed in must remain on the process lists. 14545 */ 14546 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14547 boolean restarting, boolean allowRestart, int index) { 14548 if (index >= 0) { 14549 removeLruProcessLocked(app); 14550 ProcessList.remove(app.pid); 14551 } 14552 14553 mProcessesToGc.remove(app); 14554 mPendingPssProcesses.remove(app); 14555 14556 // Dismiss any open dialogs. 14557 if (app.crashDialog != null && !app.forceCrashReport) { 14558 app.crashDialog.dismiss(); 14559 app.crashDialog = null; 14560 } 14561 if (app.anrDialog != null) { 14562 app.anrDialog.dismiss(); 14563 app.anrDialog = null; 14564 } 14565 if (app.waitDialog != null) { 14566 app.waitDialog.dismiss(); 14567 app.waitDialog = null; 14568 } 14569 14570 app.crashing = false; 14571 app.notResponding = false; 14572 14573 app.resetPackageList(mProcessStats); 14574 app.unlinkDeathRecipient(); 14575 app.makeInactive(mProcessStats); 14576 app.waitingToKill = null; 14577 app.forcingToForeground = null; 14578 updateProcessForegroundLocked(app, false, false); 14579 app.foregroundActivities = false; 14580 app.hasShownUi = false; 14581 app.treatLikeActivity = false; 14582 app.hasAboveClient = false; 14583 app.hasClientActivities = false; 14584 14585 mServices.killServicesLocked(app, allowRestart); 14586 14587 boolean restart = false; 14588 14589 // Remove published content providers. 14590 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14591 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14592 final boolean always = app.bad || !allowRestart; 14593 if (removeDyingProviderLocked(app, cpr, always) || always) { 14594 // We left the provider in the launching list, need to 14595 // restart it. 14596 restart = true; 14597 } 14598 14599 cpr.provider = null; 14600 cpr.proc = null; 14601 } 14602 app.pubProviders.clear(); 14603 14604 // Take care of any launching providers waiting for this process. 14605 if (checkAppInLaunchingProvidersLocked(app, false)) { 14606 restart = true; 14607 } 14608 14609 // Unregister from connected content providers. 14610 if (!app.conProviders.isEmpty()) { 14611 for (int i=0; i<app.conProviders.size(); i++) { 14612 ContentProviderConnection conn = app.conProviders.get(i); 14613 conn.provider.connections.remove(conn); 14614 } 14615 app.conProviders.clear(); 14616 } 14617 14618 // At this point there may be remaining entries in mLaunchingProviders 14619 // where we were the only one waiting, so they are no longer of use. 14620 // Look for these and clean up if found. 14621 // XXX Commented out for now. Trying to figure out a way to reproduce 14622 // the actual situation to identify what is actually going on. 14623 if (false) { 14624 for (int i=0; i<mLaunchingProviders.size(); i++) { 14625 ContentProviderRecord cpr = (ContentProviderRecord) 14626 mLaunchingProviders.get(i); 14627 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14628 synchronized (cpr) { 14629 cpr.launchingApp = null; 14630 cpr.notifyAll(); 14631 } 14632 } 14633 } 14634 } 14635 14636 skipCurrentReceiverLocked(app); 14637 14638 // Unregister any receivers. 14639 for (int i=app.receivers.size()-1; i>=0; i--) { 14640 removeReceiverLocked(app.receivers.valueAt(i)); 14641 } 14642 app.receivers.clear(); 14643 14644 // If the app is undergoing backup, tell the backup manager about it 14645 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14646 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14647 + mBackupTarget.appInfo + " died during backup"); 14648 try { 14649 IBackupManager bm = IBackupManager.Stub.asInterface( 14650 ServiceManager.getService(Context.BACKUP_SERVICE)); 14651 bm.agentDisconnected(app.info.packageName); 14652 } catch (RemoteException e) { 14653 // can't happen; backup manager is local 14654 } 14655 } 14656 14657 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14658 ProcessChangeItem item = mPendingProcessChanges.get(i); 14659 if (item.pid == app.pid) { 14660 mPendingProcessChanges.remove(i); 14661 mAvailProcessChanges.add(item); 14662 } 14663 } 14664 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14665 14666 // If the caller is restarting this app, then leave it in its 14667 // current lists and let the caller take care of it. 14668 if (restarting) { 14669 return false; 14670 } 14671 14672 if (!app.persistent || app.isolated) { 14673 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14674 "Removing non-persistent process during cleanup: " + app); 14675 mProcessNames.remove(app.processName, app.uid); 14676 mIsolatedProcesses.remove(app.uid); 14677 if (mHeavyWeightProcess == app) { 14678 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14679 mHeavyWeightProcess.userId, 0)); 14680 mHeavyWeightProcess = null; 14681 } 14682 } else if (!app.removed) { 14683 // This app is persistent, so we need to keep its record around. 14684 // If it is not already on the pending app list, add it there 14685 // and start a new process for it. 14686 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14687 mPersistentStartingProcesses.add(app); 14688 restart = true; 14689 } 14690 } 14691 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14692 "Clean-up removing on hold: " + app); 14693 mProcessesOnHold.remove(app); 14694 14695 if (app == mHomeProcess) { 14696 mHomeProcess = null; 14697 } 14698 if (app == mPreviousProcess) { 14699 mPreviousProcess = null; 14700 } 14701 14702 if (restart && !app.isolated) { 14703 // We have components that still need to be running in the 14704 // process, so re-launch it. 14705 if (index < 0) { 14706 ProcessList.remove(app.pid); 14707 } 14708 mProcessNames.put(app.processName, app.uid, app); 14709 startProcessLocked(app, "restart", app.processName); 14710 return true; 14711 } else if (app.pid > 0 && app.pid != MY_PID) { 14712 // Goodbye! 14713 boolean removed; 14714 synchronized (mPidsSelfLocked) { 14715 mPidsSelfLocked.remove(app.pid); 14716 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14717 } 14718 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14719 if (app.isolated) { 14720 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14721 } 14722 app.setPid(0); 14723 } 14724 return false; 14725 } 14726 14727 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14728 // Look through the content providers we are waiting to have launched, 14729 // and if any run in this process then either schedule a restart of 14730 // the process or kill the client waiting for it if this process has 14731 // gone bad. 14732 int NL = mLaunchingProviders.size(); 14733 boolean restart = false; 14734 for (int i=0; i<NL; i++) { 14735 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14736 if (cpr.launchingApp == app) { 14737 if (!alwaysBad && !app.bad) { 14738 restart = true; 14739 } else { 14740 removeDyingProviderLocked(app, cpr, true); 14741 // cpr should have been removed from mLaunchingProviders 14742 NL = mLaunchingProviders.size(); 14743 i--; 14744 } 14745 } 14746 } 14747 return restart; 14748 } 14749 14750 // ========================================================= 14751 // SERVICES 14752 // ========================================================= 14753 14754 @Override 14755 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14756 int flags) { 14757 enforceNotIsolatedCaller("getServices"); 14758 synchronized (this) { 14759 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14760 } 14761 } 14762 14763 @Override 14764 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14765 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14766 synchronized (this) { 14767 return mServices.getRunningServiceControlPanelLocked(name); 14768 } 14769 } 14770 14771 @Override 14772 public ComponentName startService(IApplicationThread caller, Intent service, 14773 String resolvedType, int userId) { 14774 enforceNotIsolatedCaller("startService"); 14775 // Refuse possible leaked file descriptors 14776 if (service != null && service.hasFileDescriptors() == true) { 14777 throw new IllegalArgumentException("File descriptors passed in Intent"); 14778 } 14779 14780 if (DEBUG_SERVICE) 14781 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14782 synchronized(this) { 14783 final int callingPid = Binder.getCallingPid(); 14784 final int callingUid = Binder.getCallingUid(); 14785 final long origId = Binder.clearCallingIdentity(); 14786 ComponentName res = mServices.startServiceLocked(caller, service, 14787 resolvedType, callingPid, callingUid, userId); 14788 Binder.restoreCallingIdentity(origId); 14789 return res; 14790 } 14791 } 14792 14793 ComponentName startServiceInPackage(int uid, 14794 Intent service, String resolvedType, int userId) { 14795 synchronized(this) { 14796 if (DEBUG_SERVICE) 14797 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14798 final long origId = Binder.clearCallingIdentity(); 14799 ComponentName res = mServices.startServiceLocked(null, service, 14800 resolvedType, -1, uid, userId); 14801 Binder.restoreCallingIdentity(origId); 14802 return res; 14803 } 14804 } 14805 14806 @Override 14807 public int stopService(IApplicationThread caller, Intent service, 14808 String resolvedType, int userId) { 14809 enforceNotIsolatedCaller("stopService"); 14810 // Refuse possible leaked file descriptors 14811 if (service != null && service.hasFileDescriptors() == true) { 14812 throw new IllegalArgumentException("File descriptors passed in Intent"); 14813 } 14814 14815 synchronized(this) { 14816 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14817 } 14818 } 14819 14820 @Override 14821 public IBinder peekService(Intent service, String resolvedType) { 14822 enforceNotIsolatedCaller("peekService"); 14823 // Refuse possible leaked file descriptors 14824 if (service != null && service.hasFileDescriptors() == true) { 14825 throw new IllegalArgumentException("File descriptors passed in Intent"); 14826 } 14827 synchronized(this) { 14828 return mServices.peekServiceLocked(service, resolvedType); 14829 } 14830 } 14831 14832 @Override 14833 public boolean stopServiceToken(ComponentName className, IBinder token, 14834 int startId) { 14835 synchronized(this) { 14836 return mServices.stopServiceTokenLocked(className, token, startId); 14837 } 14838 } 14839 14840 @Override 14841 public void setServiceForeground(ComponentName className, IBinder token, 14842 int id, Notification notification, boolean removeNotification) { 14843 synchronized(this) { 14844 mServices.setServiceForegroundLocked(className, token, id, notification, 14845 removeNotification); 14846 } 14847 } 14848 14849 @Override 14850 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14851 boolean requireFull, String name, String callerPackage) { 14852 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14853 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14854 } 14855 14856 int unsafeConvertIncomingUser(int userId) { 14857 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14858 ? mCurrentUserId : userId; 14859 } 14860 14861 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14862 int allowMode, String name, String callerPackage) { 14863 final int callingUserId = UserHandle.getUserId(callingUid); 14864 if (callingUserId == userId) { 14865 return userId; 14866 } 14867 14868 // Note that we may be accessing mCurrentUserId outside of a lock... 14869 // shouldn't be a big deal, if this is being called outside 14870 // of a locked context there is intrinsically a race with 14871 // the value the caller will receive and someone else changing it. 14872 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14873 // we will switch to the calling user if access to the current user fails. 14874 int targetUserId = unsafeConvertIncomingUser(userId); 14875 14876 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14877 final boolean allow; 14878 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14879 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14880 // If the caller has this permission, they always pass go. And collect $200. 14881 allow = true; 14882 } else if (allowMode == ALLOW_FULL_ONLY) { 14883 // We require full access, sucks to be you. 14884 allow = false; 14885 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14886 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14887 // If the caller does not have either permission, they are always doomed. 14888 allow = false; 14889 } else if (allowMode == ALLOW_NON_FULL) { 14890 // We are blanket allowing non-full access, you lucky caller! 14891 allow = true; 14892 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14893 // We may or may not allow this depending on whether the two users are 14894 // in the same profile. 14895 synchronized (mUserProfileGroupIdsSelfLocked) { 14896 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14897 UserInfo.NO_PROFILE_GROUP_ID); 14898 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14899 UserInfo.NO_PROFILE_GROUP_ID); 14900 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14901 && callingProfile == targetProfile; 14902 } 14903 } else { 14904 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14905 } 14906 if (!allow) { 14907 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14908 // In this case, they would like to just execute as their 14909 // owner user instead of failing. 14910 targetUserId = callingUserId; 14911 } else { 14912 StringBuilder builder = new StringBuilder(128); 14913 builder.append("Permission Denial: "); 14914 builder.append(name); 14915 if (callerPackage != null) { 14916 builder.append(" from "); 14917 builder.append(callerPackage); 14918 } 14919 builder.append(" asks to run as user "); 14920 builder.append(userId); 14921 builder.append(" but is calling from user "); 14922 builder.append(UserHandle.getUserId(callingUid)); 14923 builder.append("; this requires "); 14924 builder.append(INTERACT_ACROSS_USERS_FULL); 14925 if (allowMode != ALLOW_FULL_ONLY) { 14926 builder.append(" or "); 14927 builder.append(INTERACT_ACROSS_USERS); 14928 } 14929 String msg = builder.toString(); 14930 Slog.w(TAG, msg); 14931 throw new SecurityException(msg); 14932 } 14933 } 14934 } 14935 if (!allowAll && targetUserId < 0) { 14936 throw new IllegalArgumentException( 14937 "Call does not support special user #" + targetUserId); 14938 } 14939 // Check shell permission 14940 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14941 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14942 targetUserId)) { 14943 throw new SecurityException("Shell does not have permission to access user " 14944 + targetUserId + "\n " + Debug.getCallers(3)); 14945 } 14946 } 14947 return targetUserId; 14948 } 14949 14950 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14951 String className, int flags) { 14952 boolean result = false; 14953 // For apps that don't have pre-defined UIDs, check for permission 14954 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14955 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14956 if (ActivityManager.checkUidPermission( 14957 INTERACT_ACROSS_USERS, 14958 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14959 ComponentName comp = new ComponentName(aInfo.packageName, className); 14960 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14961 + " requests FLAG_SINGLE_USER, but app does not hold " 14962 + INTERACT_ACROSS_USERS; 14963 Slog.w(TAG, msg); 14964 throw new SecurityException(msg); 14965 } 14966 // Permission passed 14967 result = true; 14968 } 14969 } else if ("system".equals(componentProcessName)) { 14970 result = true; 14971 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14972 // Phone app and persistent apps are allowed to export singleuser providers. 14973 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14974 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14975 } 14976 if (DEBUG_MU) { 14977 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14978 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14979 } 14980 return result; 14981 } 14982 14983 /** 14984 * Checks to see if the caller is in the same app as the singleton 14985 * component, or the component is in a special app. It allows special apps 14986 * to export singleton components but prevents exporting singleton 14987 * components for regular apps. 14988 */ 14989 boolean isValidSingletonCall(int callingUid, int componentUid) { 14990 int componentAppId = UserHandle.getAppId(componentUid); 14991 return UserHandle.isSameApp(callingUid, componentUid) 14992 || componentAppId == Process.SYSTEM_UID 14993 || componentAppId == Process.PHONE_UID 14994 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14995 == PackageManager.PERMISSION_GRANTED; 14996 } 14997 14998 public int bindService(IApplicationThread caller, IBinder token, 14999 Intent service, String resolvedType, 15000 IServiceConnection connection, int flags, int userId) { 15001 enforceNotIsolatedCaller("bindService"); 15002 15003 // Refuse possible leaked file descriptors 15004 if (service != null && service.hasFileDescriptors() == true) { 15005 throw new IllegalArgumentException("File descriptors passed in Intent"); 15006 } 15007 15008 synchronized(this) { 15009 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15010 connection, flags, userId); 15011 } 15012 } 15013 15014 public boolean unbindService(IServiceConnection connection) { 15015 synchronized (this) { 15016 return mServices.unbindServiceLocked(connection); 15017 } 15018 } 15019 15020 public void publishService(IBinder token, Intent intent, IBinder service) { 15021 // Refuse possible leaked file descriptors 15022 if (intent != null && intent.hasFileDescriptors() == true) { 15023 throw new IllegalArgumentException("File descriptors passed in Intent"); 15024 } 15025 15026 synchronized(this) { 15027 if (!(token instanceof ServiceRecord)) { 15028 throw new IllegalArgumentException("Invalid service token"); 15029 } 15030 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15031 } 15032 } 15033 15034 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15035 // Refuse possible leaked file descriptors 15036 if (intent != null && intent.hasFileDescriptors() == true) { 15037 throw new IllegalArgumentException("File descriptors passed in Intent"); 15038 } 15039 15040 synchronized(this) { 15041 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15042 } 15043 } 15044 15045 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15046 synchronized(this) { 15047 if (!(token instanceof ServiceRecord)) { 15048 throw new IllegalArgumentException("Invalid service token"); 15049 } 15050 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15051 } 15052 } 15053 15054 // ========================================================= 15055 // BACKUP AND RESTORE 15056 // ========================================================= 15057 15058 // Cause the target app to be launched if necessary and its backup agent 15059 // instantiated. The backup agent will invoke backupAgentCreated() on the 15060 // activity manager to announce its creation. 15061 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15062 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15063 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15064 15065 synchronized(this) { 15066 // !!! TODO: currently no check here that we're already bound 15067 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15068 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15069 synchronized (stats) { 15070 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15071 } 15072 15073 // Backup agent is now in use, its package can't be stopped. 15074 try { 15075 AppGlobals.getPackageManager().setPackageStoppedState( 15076 app.packageName, false, UserHandle.getUserId(app.uid)); 15077 } catch (RemoteException e) { 15078 } catch (IllegalArgumentException e) { 15079 Slog.w(TAG, "Failed trying to unstop package " 15080 + app.packageName + ": " + e); 15081 } 15082 15083 BackupRecord r = new BackupRecord(ss, app, backupMode); 15084 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15085 ? new ComponentName(app.packageName, app.backupAgentName) 15086 : new ComponentName("android", "FullBackupAgent"); 15087 // startProcessLocked() returns existing proc's record if it's already running 15088 ProcessRecord proc = startProcessLocked(app.processName, app, 15089 false, 0, "backup", hostingName, false, false, false); 15090 if (proc == null) { 15091 Slog.e(TAG, "Unable to start backup agent process " + r); 15092 return false; 15093 } 15094 15095 r.app = proc; 15096 mBackupTarget = r; 15097 mBackupAppName = app.packageName; 15098 15099 // Try not to kill the process during backup 15100 updateOomAdjLocked(proc); 15101 15102 // If the process is already attached, schedule the creation of the backup agent now. 15103 // If it is not yet live, this will be done when it attaches to the framework. 15104 if (proc.thread != null) { 15105 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15106 try { 15107 proc.thread.scheduleCreateBackupAgent(app, 15108 compatibilityInfoForPackageLocked(app), backupMode); 15109 } catch (RemoteException e) { 15110 // Will time out on the backup manager side 15111 } 15112 } else { 15113 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15114 } 15115 // Invariants: at this point, the target app process exists and the application 15116 // is either already running or in the process of coming up. mBackupTarget and 15117 // mBackupAppName describe the app, so that when it binds back to the AM we 15118 // know that it's scheduled for a backup-agent operation. 15119 } 15120 15121 return true; 15122 } 15123 15124 @Override 15125 public void clearPendingBackup() { 15126 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15127 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15128 15129 synchronized (this) { 15130 mBackupTarget = null; 15131 mBackupAppName = null; 15132 } 15133 } 15134 15135 // A backup agent has just come up 15136 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15137 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15138 + " = " + agent); 15139 15140 synchronized(this) { 15141 if (!agentPackageName.equals(mBackupAppName)) { 15142 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15143 return; 15144 } 15145 } 15146 15147 long oldIdent = Binder.clearCallingIdentity(); 15148 try { 15149 IBackupManager bm = IBackupManager.Stub.asInterface( 15150 ServiceManager.getService(Context.BACKUP_SERVICE)); 15151 bm.agentConnected(agentPackageName, agent); 15152 } catch (RemoteException e) { 15153 // can't happen; the backup manager service is local 15154 } catch (Exception e) { 15155 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15156 e.printStackTrace(); 15157 } finally { 15158 Binder.restoreCallingIdentity(oldIdent); 15159 } 15160 } 15161 15162 // done with this agent 15163 public void unbindBackupAgent(ApplicationInfo appInfo) { 15164 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15165 if (appInfo == null) { 15166 Slog.w(TAG, "unbind backup agent for null app"); 15167 return; 15168 } 15169 15170 synchronized(this) { 15171 try { 15172 if (mBackupAppName == null) { 15173 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15174 return; 15175 } 15176 15177 if (!mBackupAppName.equals(appInfo.packageName)) { 15178 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15179 return; 15180 } 15181 15182 // Not backing this app up any more; reset its OOM adjustment 15183 final ProcessRecord proc = mBackupTarget.app; 15184 updateOomAdjLocked(proc); 15185 15186 // If the app crashed during backup, 'thread' will be null here 15187 if (proc.thread != null) { 15188 try { 15189 proc.thread.scheduleDestroyBackupAgent(appInfo, 15190 compatibilityInfoForPackageLocked(appInfo)); 15191 } catch (Exception e) { 15192 Slog.e(TAG, "Exception when unbinding backup agent:"); 15193 e.printStackTrace(); 15194 } 15195 } 15196 } finally { 15197 mBackupTarget = null; 15198 mBackupAppName = null; 15199 } 15200 } 15201 } 15202 // ========================================================= 15203 // BROADCASTS 15204 // ========================================================= 15205 15206 private final List getStickiesLocked(String action, IntentFilter filter, 15207 List cur, int userId) { 15208 final ContentResolver resolver = mContext.getContentResolver(); 15209 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15210 if (stickies == null) { 15211 return cur; 15212 } 15213 final ArrayList<Intent> list = stickies.get(action); 15214 if (list == null) { 15215 return cur; 15216 } 15217 int N = list.size(); 15218 for (int i=0; i<N; i++) { 15219 Intent intent = list.get(i); 15220 if (filter.match(resolver, intent, true, TAG) >= 0) { 15221 if (cur == null) { 15222 cur = new ArrayList<Intent>(); 15223 } 15224 cur.add(intent); 15225 } 15226 } 15227 return cur; 15228 } 15229 15230 boolean isPendingBroadcastProcessLocked(int pid) { 15231 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15232 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15233 } 15234 15235 void skipPendingBroadcastLocked(int pid) { 15236 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15237 for (BroadcastQueue queue : mBroadcastQueues) { 15238 queue.skipPendingBroadcastLocked(pid); 15239 } 15240 } 15241 15242 // The app just attached; send any pending broadcasts that it should receive 15243 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15244 boolean didSomething = false; 15245 for (BroadcastQueue queue : mBroadcastQueues) { 15246 didSomething |= queue.sendPendingBroadcastsLocked(app); 15247 } 15248 return didSomething; 15249 } 15250 15251 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15252 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15253 enforceNotIsolatedCaller("registerReceiver"); 15254 int callingUid; 15255 int callingPid; 15256 synchronized(this) { 15257 ProcessRecord callerApp = null; 15258 if (caller != null) { 15259 callerApp = getRecordForAppLocked(caller); 15260 if (callerApp == null) { 15261 throw new SecurityException( 15262 "Unable to find app for caller " + caller 15263 + " (pid=" + Binder.getCallingPid() 15264 + ") when registering receiver " + receiver); 15265 } 15266 if (callerApp.info.uid != Process.SYSTEM_UID && 15267 !callerApp.pkgList.containsKey(callerPackage) && 15268 !"android".equals(callerPackage)) { 15269 throw new SecurityException("Given caller package " + callerPackage 15270 + " is not running in process " + callerApp); 15271 } 15272 callingUid = callerApp.info.uid; 15273 callingPid = callerApp.pid; 15274 } else { 15275 callerPackage = null; 15276 callingUid = Binder.getCallingUid(); 15277 callingPid = Binder.getCallingPid(); 15278 } 15279 15280 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15281 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15282 15283 List allSticky = null; 15284 15285 // Look for any matching sticky broadcasts... 15286 Iterator actions = filter.actionsIterator(); 15287 if (actions != null) { 15288 while (actions.hasNext()) { 15289 String action = (String)actions.next(); 15290 allSticky = getStickiesLocked(action, filter, allSticky, 15291 UserHandle.USER_ALL); 15292 allSticky = getStickiesLocked(action, filter, allSticky, 15293 UserHandle.getUserId(callingUid)); 15294 } 15295 } else { 15296 allSticky = getStickiesLocked(null, filter, allSticky, 15297 UserHandle.USER_ALL); 15298 allSticky = getStickiesLocked(null, filter, allSticky, 15299 UserHandle.getUserId(callingUid)); 15300 } 15301 15302 // The first sticky in the list is returned directly back to 15303 // the client. 15304 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15305 15306 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15307 + ": " + sticky); 15308 15309 if (receiver == null) { 15310 return sticky; 15311 } 15312 15313 ReceiverList rl 15314 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15315 if (rl == null) { 15316 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15317 userId, receiver); 15318 if (rl.app != null) { 15319 rl.app.receivers.add(rl); 15320 } else { 15321 try { 15322 receiver.asBinder().linkToDeath(rl, 0); 15323 } catch (RemoteException e) { 15324 return sticky; 15325 } 15326 rl.linkedToDeath = true; 15327 } 15328 mRegisteredReceivers.put(receiver.asBinder(), rl); 15329 } else if (rl.uid != callingUid) { 15330 throw new IllegalArgumentException( 15331 "Receiver requested to register for uid " + callingUid 15332 + " was previously registered for uid " + rl.uid); 15333 } else if (rl.pid != callingPid) { 15334 throw new IllegalArgumentException( 15335 "Receiver requested to register for pid " + callingPid 15336 + " was previously registered for pid " + rl.pid); 15337 } else if (rl.userId != userId) { 15338 throw new IllegalArgumentException( 15339 "Receiver requested to register for user " + userId 15340 + " was previously registered for user " + rl.userId); 15341 } 15342 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15343 permission, callingUid, userId); 15344 rl.add(bf); 15345 if (!bf.debugCheck()) { 15346 Slog.w(TAG, "==> For Dynamic broadast"); 15347 } 15348 mReceiverResolver.addFilter(bf); 15349 15350 // Enqueue broadcasts for all existing stickies that match 15351 // this filter. 15352 if (allSticky != null) { 15353 ArrayList receivers = new ArrayList(); 15354 receivers.add(bf); 15355 15356 int N = allSticky.size(); 15357 for (int i=0; i<N; i++) { 15358 Intent intent = (Intent)allSticky.get(i); 15359 BroadcastQueue queue = broadcastQueueForIntent(intent); 15360 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15361 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15362 null, null, false, true, true, -1); 15363 queue.enqueueParallelBroadcastLocked(r); 15364 queue.scheduleBroadcastsLocked(); 15365 } 15366 } 15367 15368 return sticky; 15369 } 15370 } 15371 15372 public void unregisterReceiver(IIntentReceiver receiver) { 15373 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15374 15375 final long origId = Binder.clearCallingIdentity(); 15376 try { 15377 boolean doTrim = false; 15378 15379 synchronized(this) { 15380 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15381 if (rl != null) { 15382 if (rl.curBroadcast != null) { 15383 BroadcastRecord r = rl.curBroadcast; 15384 final boolean doNext = finishReceiverLocked( 15385 receiver.asBinder(), r.resultCode, r.resultData, 15386 r.resultExtras, r.resultAbort); 15387 if (doNext) { 15388 doTrim = true; 15389 r.queue.processNextBroadcast(false); 15390 } 15391 } 15392 15393 if (rl.app != null) { 15394 rl.app.receivers.remove(rl); 15395 } 15396 removeReceiverLocked(rl); 15397 if (rl.linkedToDeath) { 15398 rl.linkedToDeath = false; 15399 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15400 } 15401 } 15402 } 15403 15404 // If we actually concluded any broadcasts, we might now be able 15405 // to trim the recipients' apps from our working set 15406 if (doTrim) { 15407 trimApplications(); 15408 return; 15409 } 15410 15411 } finally { 15412 Binder.restoreCallingIdentity(origId); 15413 } 15414 } 15415 15416 void removeReceiverLocked(ReceiverList rl) { 15417 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15418 int N = rl.size(); 15419 for (int i=0; i<N; i++) { 15420 mReceiverResolver.removeFilter(rl.get(i)); 15421 } 15422 } 15423 15424 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15425 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15426 ProcessRecord r = mLruProcesses.get(i); 15427 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15428 try { 15429 r.thread.dispatchPackageBroadcast(cmd, packages); 15430 } catch (RemoteException ex) { 15431 } 15432 } 15433 } 15434 } 15435 15436 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15437 int callingUid, int[] users) { 15438 List<ResolveInfo> receivers = null; 15439 try { 15440 HashSet<ComponentName> singleUserReceivers = null; 15441 boolean scannedFirstReceivers = false; 15442 for (int user : users) { 15443 // Skip users that have Shell restrictions 15444 if (callingUid == Process.SHELL_UID 15445 && getUserManagerLocked().hasUserRestriction( 15446 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15447 continue; 15448 } 15449 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15450 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15451 if (user != 0 && newReceivers != null) { 15452 // If this is not the primary user, we need to check for 15453 // any receivers that should be filtered out. 15454 for (int i=0; i<newReceivers.size(); i++) { 15455 ResolveInfo ri = newReceivers.get(i); 15456 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15457 newReceivers.remove(i); 15458 i--; 15459 } 15460 } 15461 } 15462 if (newReceivers != null && newReceivers.size() == 0) { 15463 newReceivers = null; 15464 } 15465 if (receivers == null) { 15466 receivers = newReceivers; 15467 } else if (newReceivers != null) { 15468 // We need to concatenate the additional receivers 15469 // found with what we have do far. This would be easy, 15470 // but we also need to de-dup any receivers that are 15471 // singleUser. 15472 if (!scannedFirstReceivers) { 15473 // Collect any single user receivers we had already retrieved. 15474 scannedFirstReceivers = true; 15475 for (int i=0; i<receivers.size(); i++) { 15476 ResolveInfo ri = receivers.get(i); 15477 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15478 ComponentName cn = new ComponentName( 15479 ri.activityInfo.packageName, ri.activityInfo.name); 15480 if (singleUserReceivers == null) { 15481 singleUserReceivers = new HashSet<ComponentName>(); 15482 } 15483 singleUserReceivers.add(cn); 15484 } 15485 } 15486 } 15487 // Add the new results to the existing results, tracking 15488 // and de-dupping single user receivers. 15489 for (int i=0; i<newReceivers.size(); i++) { 15490 ResolveInfo ri = newReceivers.get(i); 15491 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15492 ComponentName cn = new ComponentName( 15493 ri.activityInfo.packageName, ri.activityInfo.name); 15494 if (singleUserReceivers == null) { 15495 singleUserReceivers = new HashSet<ComponentName>(); 15496 } 15497 if (!singleUserReceivers.contains(cn)) { 15498 singleUserReceivers.add(cn); 15499 receivers.add(ri); 15500 } 15501 } else { 15502 receivers.add(ri); 15503 } 15504 } 15505 } 15506 } 15507 } catch (RemoteException ex) { 15508 // pm is in same process, this will never happen. 15509 } 15510 return receivers; 15511 } 15512 15513 private final int broadcastIntentLocked(ProcessRecord callerApp, 15514 String callerPackage, Intent intent, String resolvedType, 15515 IIntentReceiver resultTo, int resultCode, String resultData, 15516 Bundle map, String requiredPermission, int appOp, 15517 boolean ordered, boolean sticky, int callingPid, int callingUid, 15518 int userId) { 15519 intent = new Intent(intent); 15520 15521 // By default broadcasts do not go to stopped apps. 15522 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15523 15524 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15525 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15526 + " ordered=" + ordered + " userid=" + userId); 15527 if ((resultTo != null) && !ordered) { 15528 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15529 } 15530 15531 userId = handleIncomingUser(callingPid, callingUid, userId, 15532 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15533 15534 // Make sure that the user who is receiving this broadcast is started. 15535 // If not, we will just skip it. 15536 15537 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15538 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15539 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15540 Slog.w(TAG, "Skipping broadcast of " + intent 15541 + ": user " + userId + " is stopped"); 15542 return ActivityManager.BROADCAST_SUCCESS; 15543 } 15544 } 15545 15546 /* 15547 * Prevent non-system code (defined here to be non-persistent 15548 * processes) from sending protected broadcasts. 15549 */ 15550 int callingAppId = UserHandle.getAppId(callingUid); 15551 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15552 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15553 || callingAppId == Process.NFC_UID || callingUid == 0) { 15554 // Always okay. 15555 } else if (callerApp == null || !callerApp.persistent) { 15556 try { 15557 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15558 intent.getAction())) { 15559 String msg = "Permission Denial: not allowed to send broadcast " 15560 + intent.getAction() + " from pid=" 15561 + callingPid + ", uid=" + callingUid; 15562 Slog.w(TAG, msg); 15563 throw new SecurityException(msg); 15564 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15565 // Special case for compatibility: we don't want apps to send this, 15566 // but historically it has not been protected and apps may be using it 15567 // to poke their own app widget. So, instead of making it protected, 15568 // just limit it to the caller. 15569 if (callerApp == null) { 15570 String msg = "Permission Denial: not allowed to send broadcast " 15571 + intent.getAction() + " from unknown caller."; 15572 Slog.w(TAG, msg); 15573 throw new SecurityException(msg); 15574 } else if (intent.getComponent() != null) { 15575 // They are good enough to send to an explicit component... verify 15576 // it is being sent to the calling app. 15577 if (!intent.getComponent().getPackageName().equals( 15578 callerApp.info.packageName)) { 15579 String msg = "Permission Denial: not allowed to send broadcast " 15580 + intent.getAction() + " to " 15581 + intent.getComponent().getPackageName() + " from " 15582 + callerApp.info.packageName; 15583 Slog.w(TAG, msg); 15584 throw new SecurityException(msg); 15585 } 15586 } else { 15587 // Limit broadcast to their own package. 15588 intent.setPackage(callerApp.info.packageName); 15589 } 15590 } 15591 } catch (RemoteException e) { 15592 Slog.w(TAG, "Remote exception", e); 15593 return ActivityManager.BROADCAST_SUCCESS; 15594 } 15595 } 15596 15597 // Handle special intents: if this broadcast is from the package 15598 // manager about a package being removed, we need to remove all of 15599 // its activities from the history stack. 15600 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15601 intent.getAction()); 15602 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15603 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15604 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15605 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15606 || uidRemoved) { 15607 if (checkComponentPermission( 15608 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15609 callingPid, callingUid, -1, true) 15610 == PackageManager.PERMISSION_GRANTED) { 15611 if (uidRemoved) { 15612 final Bundle intentExtras = intent.getExtras(); 15613 final int uid = intentExtras != null 15614 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15615 if (uid >= 0) { 15616 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15617 synchronized (bs) { 15618 bs.removeUidStatsLocked(uid); 15619 } 15620 mAppOpsService.uidRemoved(uid); 15621 } 15622 } else { 15623 // If resources are unavailable just force stop all 15624 // those packages and flush the attribute cache as well. 15625 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15626 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15627 if (list != null && (list.length > 0)) { 15628 for (String pkg : list) { 15629 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15630 "storage unmount"); 15631 } 15632 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15633 sendPackageBroadcastLocked( 15634 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15635 } 15636 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15637 intent.getAction())) { 15638 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15639 } else { 15640 Uri data = intent.getData(); 15641 String ssp; 15642 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15643 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15644 intent.getAction()); 15645 boolean fullUninstall = removed && 15646 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15647 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15648 forceStopPackageLocked(ssp, UserHandle.getAppId( 15649 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15650 false, fullUninstall, userId, 15651 removed ? "pkg removed" : "pkg changed"); 15652 } 15653 if (removed) { 15654 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15655 new String[] {ssp}, userId); 15656 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15657 mAppOpsService.packageRemoved( 15658 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15659 15660 // Remove all permissions granted from/to this package 15661 removeUriPermissionsForPackageLocked(ssp, userId, true); 15662 } 15663 } 15664 } 15665 } 15666 } 15667 } else { 15668 String msg = "Permission Denial: " + intent.getAction() 15669 + " broadcast from " + callerPackage + " (pid=" + callingPid 15670 + ", uid=" + callingUid + ")" 15671 + " requires " 15672 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15673 Slog.w(TAG, msg); 15674 throw new SecurityException(msg); 15675 } 15676 15677 // Special case for adding a package: by default turn on compatibility 15678 // mode. 15679 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15680 Uri data = intent.getData(); 15681 String ssp; 15682 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15683 mCompatModePackages.handlePackageAddedLocked(ssp, 15684 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15685 } 15686 } 15687 15688 /* 15689 * If this is the time zone changed action, queue up a message that will reset the timezone 15690 * of all currently running processes. This message will get queued up before the broadcast 15691 * happens. 15692 */ 15693 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15694 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15695 } 15696 15697 /* 15698 * If the user set the time, let all running processes know. 15699 */ 15700 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15701 final int is24Hour = intent.getBooleanExtra( 15702 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15703 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15705 synchronized (stats) { 15706 stats.noteCurrentTimeChangedLocked(); 15707 } 15708 } 15709 15710 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15711 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15712 } 15713 15714 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15715 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15716 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15717 } 15718 15719 // Add to the sticky list if requested. 15720 if (sticky) { 15721 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15722 callingPid, callingUid) 15723 != PackageManager.PERMISSION_GRANTED) { 15724 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15725 + callingPid + ", uid=" + callingUid 15726 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15727 Slog.w(TAG, msg); 15728 throw new SecurityException(msg); 15729 } 15730 if (requiredPermission != null) { 15731 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15732 + " and enforce permission " + requiredPermission); 15733 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15734 } 15735 if (intent.getComponent() != null) { 15736 throw new SecurityException( 15737 "Sticky broadcasts can't target a specific component"); 15738 } 15739 // We use userId directly here, since the "all" target is maintained 15740 // as a separate set of sticky broadcasts. 15741 if (userId != UserHandle.USER_ALL) { 15742 // But first, if this is not a broadcast to all users, then 15743 // make sure it doesn't conflict with an existing broadcast to 15744 // all users. 15745 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15746 UserHandle.USER_ALL); 15747 if (stickies != null) { 15748 ArrayList<Intent> list = stickies.get(intent.getAction()); 15749 if (list != null) { 15750 int N = list.size(); 15751 int i; 15752 for (i=0; i<N; i++) { 15753 if (intent.filterEquals(list.get(i))) { 15754 throw new IllegalArgumentException( 15755 "Sticky broadcast " + intent + " for user " 15756 + userId + " conflicts with existing global broadcast"); 15757 } 15758 } 15759 } 15760 } 15761 } 15762 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15763 if (stickies == null) { 15764 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15765 mStickyBroadcasts.put(userId, stickies); 15766 } 15767 ArrayList<Intent> list = stickies.get(intent.getAction()); 15768 if (list == null) { 15769 list = new ArrayList<Intent>(); 15770 stickies.put(intent.getAction(), list); 15771 } 15772 int N = list.size(); 15773 int i; 15774 for (i=0; i<N; i++) { 15775 if (intent.filterEquals(list.get(i))) { 15776 // This sticky already exists, replace it. 15777 list.set(i, new Intent(intent)); 15778 break; 15779 } 15780 } 15781 if (i >= N) { 15782 list.add(new Intent(intent)); 15783 } 15784 } 15785 15786 int[] users; 15787 if (userId == UserHandle.USER_ALL) { 15788 // Caller wants broadcast to go to all started users. 15789 users = mStartedUserArray; 15790 } else { 15791 // Caller wants broadcast to go to one specific user. 15792 users = new int[] {userId}; 15793 } 15794 15795 // Figure out who all will receive this broadcast. 15796 List receivers = null; 15797 List<BroadcastFilter> registeredReceivers = null; 15798 // Need to resolve the intent to interested receivers... 15799 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15800 == 0) { 15801 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15802 } 15803 if (intent.getComponent() == null) { 15804 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15805 // Query one target user at a time, excluding shell-restricted users 15806 UserManagerService ums = getUserManagerLocked(); 15807 for (int i = 0; i < users.length; i++) { 15808 if (ums.hasUserRestriction( 15809 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15810 continue; 15811 } 15812 List<BroadcastFilter> registeredReceiversForUser = 15813 mReceiverResolver.queryIntent(intent, 15814 resolvedType, false, users[i]); 15815 if (registeredReceivers == null) { 15816 registeredReceivers = registeredReceiversForUser; 15817 } else if (registeredReceiversForUser != null) { 15818 registeredReceivers.addAll(registeredReceiversForUser); 15819 } 15820 } 15821 } else { 15822 registeredReceivers = mReceiverResolver.queryIntent(intent, 15823 resolvedType, false, userId); 15824 } 15825 } 15826 15827 final boolean replacePending = 15828 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15829 15830 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15831 + " replacePending=" + replacePending); 15832 15833 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15834 if (!ordered && NR > 0) { 15835 // If we are not serializing this broadcast, then send the 15836 // registered receivers separately so they don't wait for the 15837 // components to be launched. 15838 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15839 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15840 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15841 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15842 ordered, sticky, false, userId); 15843 if (DEBUG_BROADCAST) Slog.v( 15844 TAG, "Enqueueing parallel broadcast " + r); 15845 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15846 if (!replaced) { 15847 queue.enqueueParallelBroadcastLocked(r); 15848 queue.scheduleBroadcastsLocked(); 15849 } 15850 registeredReceivers = null; 15851 NR = 0; 15852 } 15853 15854 // Merge into one list. 15855 int ir = 0; 15856 if (receivers != null) { 15857 // A special case for PACKAGE_ADDED: do not allow the package 15858 // being added to see this broadcast. This prevents them from 15859 // using this as a back door to get run as soon as they are 15860 // installed. Maybe in the future we want to have a special install 15861 // broadcast or such for apps, but we'd like to deliberately make 15862 // this decision. 15863 String skipPackages[] = null; 15864 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15865 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15866 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15867 Uri data = intent.getData(); 15868 if (data != null) { 15869 String pkgName = data.getSchemeSpecificPart(); 15870 if (pkgName != null) { 15871 skipPackages = new String[] { pkgName }; 15872 } 15873 } 15874 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15875 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15876 } 15877 if (skipPackages != null && (skipPackages.length > 0)) { 15878 for (String skipPackage : skipPackages) { 15879 if (skipPackage != null) { 15880 int NT = receivers.size(); 15881 for (int it=0; it<NT; it++) { 15882 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15883 if (curt.activityInfo.packageName.equals(skipPackage)) { 15884 receivers.remove(it); 15885 it--; 15886 NT--; 15887 } 15888 } 15889 } 15890 } 15891 } 15892 15893 int NT = receivers != null ? receivers.size() : 0; 15894 int it = 0; 15895 ResolveInfo curt = null; 15896 BroadcastFilter curr = null; 15897 while (it < NT && ir < NR) { 15898 if (curt == null) { 15899 curt = (ResolveInfo)receivers.get(it); 15900 } 15901 if (curr == null) { 15902 curr = registeredReceivers.get(ir); 15903 } 15904 if (curr.getPriority() >= curt.priority) { 15905 // Insert this broadcast record into the final list. 15906 receivers.add(it, curr); 15907 ir++; 15908 curr = null; 15909 it++; 15910 NT++; 15911 } else { 15912 // Skip to the next ResolveInfo in the final list. 15913 it++; 15914 curt = null; 15915 } 15916 } 15917 } 15918 while (ir < NR) { 15919 if (receivers == null) { 15920 receivers = new ArrayList(); 15921 } 15922 receivers.add(registeredReceivers.get(ir)); 15923 ir++; 15924 } 15925 15926 if ((receivers != null && receivers.size() > 0) 15927 || resultTo != null) { 15928 BroadcastQueue queue = broadcastQueueForIntent(intent); 15929 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15930 callerPackage, callingPid, callingUid, resolvedType, 15931 requiredPermission, appOp, receivers, resultTo, resultCode, 15932 resultData, map, ordered, sticky, false, userId); 15933 if (DEBUG_BROADCAST) Slog.v( 15934 TAG, "Enqueueing ordered broadcast " + r 15935 + ": prev had " + queue.mOrderedBroadcasts.size()); 15936 if (DEBUG_BROADCAST) { 15937 int seq = r.intent.getIntExtra("seq", -1); 15938 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15939 } 15940 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15941 if (!replaced) { 15942 queue.enqueueOrderedBroadcastLocked(r); 15943 queue.scheduleBroadcastsLocked(); 15944 } 15945 } 15946 15947 return ActivityManager.BROADCAST_SUCCESS; 15948 } 15949 15950 final Intent verifyBroadcastLocked(Intent intent) { 15951 // Refuse possible leaked file descriptors 15952 if (intent != null && intent.hasFileDescriptors() == true) { 15953 throw new IllegalArgumentException("File descriptors passed in Intent"); 15954 } 15955 15956 int flags = intent.getFlags(); 15957 15958 if (!mProcessesReady) { 15959 // if the caller really truly claims to know what they're doing, go 15960 // ahead and allow the broadcast without launching any receivers 15961 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15962 intent = new Intent(intent); 15963 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15964 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15965 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15966 + " before boot completion"); 15967 throw new IllegalStateException("Cannot broadcast before boot completed"); 15968 } 15969 } 15970 15971 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15972 throw new IllegalArgumentException( 15973 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15974 } 15975 15976 return intent; 15977 } 15978 15979 public final int broadcastIntent(IApplicationThread caller, 15980 Intent intent, String resolvedType, IIntentReceiver resultTo, 15981 int resultCode, String resultData, Bundle map, 15982 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15983 enforceNotIsolatedCaller("broadcastIntent"); 15984 synchronized(this) { 15985 intent = verifyBroadcastLocked(intent); 15986 15987 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15988 final int callingPid = Binder.getCallingPid(); 15989 final int callingUid = Binder.getCallingUid(); 15990 final long origId = Binder.clearCallingIdentity(); 15991 int res = broadcastIntentLocked(callerApp, 15992 callerApp != null ? callerApp.info.packageName : null, 15993 intent, resolvedType, resultTo, 15994 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15995 callingPid, callingUid, userId); 15996 Binder.restoreCallingIdentity(origId); 15997 return res; 15998 } 15999 } 16000 16001 int broadcastIntentInPackage(String packageName, int uid, 16002 Intent intent, String resolvedType, IIntentReceiver resultTo, 16003 int resultCode, String resultData, Bundle map, 16004 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16005 synchronized(this) { 16006 intent = verifyBroadcastLocked(intent); 16007 16008 final long origId = Binder.clearCallingIdentity(); 16009 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16010 resultTo, resultCode, resultData, map, requiredPermission, 16011 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16012 Binder.restoreCallingIdentity(origId); 16013 return res; 16014 } 16015 } 16016 16017 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16018 // Refuse possible leaked file descriptors 16019 if (intent != null && intent.hasFileDescriptors() == true) { 16020 throw new IllegalArgumentException("File descriptors passed in Intent"); 16021 } 16022 16023 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16024 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16025 16026 synchronized(this) { 16027 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16028 != PackageManager.PERMISSION_GRANTED) { 16029 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16030 + Binder.getCallingPid() 16031 + ", uid=" + Binder.getCallingUid() 16032 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16033 Slog.w(TAG, msg); 16034 throw new SecurityException(msg); 16035 } 16036 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16037 if (stickies != null) { 16038 ArrayList<Intent> list = stickies.get(intent.getAction()); 16039 if (list != null) { 16040 int N = list.size(); 16041 int i; 16042 for (i=0; i<N; i++) { 16043 if (intent.filterEquals(list.get(i))) { 16044 list.remove(i); 16045 break; 16046 } 16047 } 16048 if (list.size() <= 0) { 16049 stickies.remove(intent.getAction()); 16050 } 16051 } 16052 if (stickies.size() <= 0) { 16053 mStickyBroadcasts.remove(userId); 16054 } 16055 } 16056 } 16057 } 16058 16059 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16060 String resultData, Bundle resultExtras, boolean resultAbort) { 16061 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16062 if (r == null) { 16063 Slog.w(TAG, "finishReceiver called but not found on queue"); 16064 return false; 16065 } 16066 16067 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16068 } 16069 16070 void backgroundServicesFinishedLocked(int userId) { 16071 for (BroadcastQueue queue : mBroadcastQueues) { 16072 queue.backgroundServicesFinishedLocked(userId); 16073 } 16074 } 16075 16076 public void finishReceiver(IBinder who, int resultCode, String resultData, 16077 Bundle resultExtras, boolean resultAbort) { 16078 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16079 16080 // Refuse possible leaked file descriptors 16081 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16082 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16083 } 16084 16085 final long origId = Binder.clearCallingIdentity(); 16086 try { 16087 boolean doNext = false; 16088 BroadcastRecord r; 16089 16090 synchronized(this) { 16091 r = broadcastRecordForReceiverLocked(who); 16092 if (r != null) { 16093 doNext = r.queue.finishReceiverLocked(r, resultCode, 16094 resultData, resultExtras, resultAbort, true); 16095 } 16096 } 16097 16098 if (doNext) { 16099 r.queue.processNextBroadcast(false); 16100 } 16101 trimApplications(); 16102 } finally { 16103 Binder.restoreCallingIdentity(origId); 16104 } 16105 } 16106 16107 // ========================================================= 16108 // INSTRUMENTATION 16109 // ========================================================= 16110 16111 public boolean startInstrumentation(ComponentName className, 16112 String profileFile, int flags, Bundle arguments, 16113 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16114 int userId, String abiOverride) { 16115 enforceNotIsolatedCaller("startInstrumentation"); 16116 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16117 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16118 // Refuse possible leaked file descriptors 16119 if (arguments != null && arguments.hasFileDescriptors()) { 16120 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16121 } 16122 16123 synchronized(this) { 16124 InstrumentationInfo ii = null; 16125 ApplicationInfo ai = null; 16126 try { 16127 ii = mContext.getPackageManager().getInstrumentationInfo( 16128 className, STOCK_PM_FLAGS); 16129 ai = AppGlobals.getPackageManager().getApplicationInfo( 16130 ii.targetPackage, STOCK_PM_FLAGS, userId); 16131 } catch (PackageManager.NameNotFoundException e) { 16132 } catch (RemoteException e) { 16133 } 16134 if (ii == null) { 16135 reportStartInstrumentationFailure(watcher, className, 16136 "Unable to find instrumentation info for: " + className); 16137 return false; 16138 } 16139 if (ai == null) { 16140 reportStartInstrumentationFailure(watcher, className, 16141 "Unable to find instrumentation target package: " + ii.targetPackage); 16142 return false; 16143 } 16144 16145 int match = mContext.getPackageManager().checkSignatures( 16146 ii.targetPackage, ii.packageName); 16147 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16148 String msg = "Permission Denial: starting instrumentation " 16149 + className + " from pid=" 16150 + Binder.getCallingPid() 16151 + ", uid=" + Binder.getCallingPid() 16152 + " not allowed because package " + ii.packageName 16153 + " does not have a signature matching the target " 16154 + ii.targetPackage; 16155 reportStartInstrumentationFailure(watcher, className, msg); 16156 throw new SecurityException(msg); 16157 } 16158 16159 final long origId = Binder.clearCallingIdentity(); 16160 // Instrumentation can kill and relaunch even persistent processes 16161 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16162 "start instr"); 16163 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16164 app.instrumentationClass = className; 16165 app.instrumentationInfo = ai; 16166 app.instrumentationProfileFile = profileFile; 16167 app.instrumentationArguments = arguments; 16168 app.instrumentationWatcher = watcher; 16169 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16170 app.instrumentationResultClass = className; 16171 Binder.restoreCallingIdentity(origId); 16172 } 16173 16174 return true; 16175 } 16176 16177 /** 16178 * Report errors that occur while attempting to start Instrumentation. Always writes the 16179 * error to the logs, but if somebody is watching, send the report there too. This enables 16180 * the "am" command to report errors with more information. 16181 * 16182 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16183 * @param cn The component name of the instrumentation. 16184 * @param report The error report. 16185 */ 16186 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16187 ComponentName cn, String report) { 16188 Slog.w(TAG, report); 16189 try { 16190 if (watcher != null) { 16191 Bundle results = new Bundle(); 16192 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16193 results.putString("Error", report); 16194 watcher.instrumentationStatus(cn, -1, results); 16195 } 16196 } catch (RemoteException e) { 16197 Slog.w(TAG, e); 16198 } 16199 } 16200 16201 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16202 if (app.instrumentationWatcher != null) { 16203 try { 16204 // NOTE: IInstrumentationWatcher *must* be oneway here 16205 app.instrumentationWatcher.instrumentationFinished( 16206 app.instrumentationClass, 16207 resultCode, 16208 results); 16209 } catch (RemoteException e) { 16210 } 16211 } 16212 if (app.instrumentationUiAutomationConnection != null) { 16213 try { 16214 app.instrumentationUiAutomationConnection.shutdown(); 16215 } catch (RemoteException re) { 16216 /* ignore */ 16217 } 16218 // Only a UiAutomation can set this flag and now that 16219 // it is finished we make sure it is reset to its default. 16220 mUserIsMonkey = false; 16221 } 16222 app.instrumentationWatcher = null; 16223 app.instrumentationUiAutomationConnection = null; 16224 app.instrumentationClass = null; 16225 app.instrumentationInfo = null; 16226 app.instrumentationProfileFile = null; 16227 app.instrumentationArguments = null; 16228 16229 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16230 "finished inst"); 16231 } 16232 16233 public void finishInstrumentation(IApplicationThread target, 16234 int resultCode, Bundle results) { 16235 int userId = UserHandle.getCallingUserId(); 16236 // Refuse possible leaked file descriptors 16237 if (results != null && results.hasFileDescriptors()) { 16238 throw new IllegalArgumentException("File descriptors passed in Intent"); 16239 } 16240 16241 synchronized(this) { 16242 ProcessRecord app = getRecordForAppLocked(target); 16243 if (app == null) { 16244 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16245 return; 16246 } 16247 final long origId = Binder.clearCallingIdentity(); 16248 finishInstrumentationLocked(app, resultCode, results); 16249 Binder.restoreCallingIdentity(origId); 16250 } 16251 } 16252 16253 // ========================================================= 16254 // CONFIGURATION 16255 // ========================================================= 16256 16257 public ConfigurationInfo getDeviceConfigurationInfo() { 16258 ConfigurationInfo config = new ConfigurationInfo(); 16259 synchronized (this) { 16260 config.reqTouchScreen = mConfiguration.touchscreen; 16261 config.reqKeyboardType = mConfiguration.keyboard; 16262 config.reqNavigation = mConfiguration.navigation; 16263 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16264 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16265 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16266 } 16267 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16268 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16269 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16270 } 16271 config.reqGlEsVersion = GL_ES_VERSION; 16272 } 16273 return config; 16274 } 16275 16276 ActivityStack getFocusedStack() { 16277 return mStackSupervisor.getFocusedStack(); 16278 } 16279 16280 public Configuration getConfiguration() { 16281 Configuration ci; 16282 synchronized(this) { 16283 ci = new Configuration(mConfiguration); 16284 } 16285 return ci; 16286 } 16287 16288 public void updatePersistentConfiguration(Configuration values) { 16289 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16290 "updateConfiguration()"); 16291 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16292 "updateConfiguration()"); 16293 if (values == null) { 16294 throw new NullPointerException("Configuration must not be null"); 16295 } 16296 16297 synchronized(this) { 16298 final long origId = Binder.clearCallingIdentity(); 16299 updateConfigurationLocked(values, null, true, false); 16300 Binder.restoreCallingIdentity(origId); 16301 } 16302 } 16303 16304 public void updateConfiguration(Configuration values) { 16305 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16306 "updateConfiguration()"); 16307 16308 synchronized(this) { 16309 if (values == null && mWindowManager != null) { 16310 // sentinel: fetch the current configuration from the window manager 16311 values = mWindowManager.computeNewConfiguration(); 16312 } 16313 16314 if (mWindowManager != null) { 16315 mProcessList.applyDisplaySize(mWindowManager); 16316 } 16317 16318 final long origId = Binder.clearCallingIdentity(); 16319 if (values != null) { 16320 Settings.System.clearConfiguration(values); 16321 } 16322 updateConfigurationLocked(values, null, false, false); 16323 Binder.restoreCallingIdentity(origId); 16324 } 16325 } 16326 16327 /** 16328 * Do either or both things: (1) change the current configuration, and (2) 16329 * make sure the given activity is running with the (now) current 16330 * configuration. Returns true if the activity has been left running, or 16331 * false if <var>starting</var> is being destroyed to match the new 16332 * configuration. 16333 * @param persistent TODO 16334 */ 16335 boolean updateConfigurationLocked(Configuration values, 16336 ActivityRecord starting, boolean persistent, boolean initLocale) { 16337 int changes = 0; 16338 16339 if (values != null) { 16340 Configuration newConfig = new Configuration(mConfiguration); 16341 changes = newConfig.updateFrom(values); 16342 if (changes != 0) { 16343 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16344 Slog.i(TAG, "Updating configuration to: " + values); 16345 } 16346 16347 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16348 16349 if (values.locale != null && !initLocale) { 16350 saveLocaleLocked(values.locale, 16351 !values.locale.equals(mConfiguration.locale), 16352 values.userSetLocale); 16353 } 16354 16355 mConfigurationSeq++; 16356 if (mConfigurationSeq <= 0) { 16357 mConfigurationSeq = 1; 16358 } 16359 newConfig.seq = mConfigurationSeq; 16360 mConfiguration = newConfig; 16361 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16362 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16363 //mUsageStatsService.noteStartConfig(newConfig); 16364 16365 final Configuration configCopy = new Configuration(mConfiguration); 16366 16367 // TODO: If our config changes, should we auto dismiss any currently 16368 // showing dialogs? 16369 mShowDialogs = shouldShowDialogs(newConfig); 16370 16371 AttributeCache ac = AttributeCache.instance(); 16372 if (ac != null) { 16373 ac.updateConfiguration(configCopy); 16374 } 16375 16376 // Make sure all resources in our process are updated 16377 // right now, so that anyone who is going to retrieve 16378 // resource values after we return will be sure to get 16379 // the new ones. This is especially important during 16380 // boot, where the first config change needs to guarantee 16381 // all resources have that config before following boot 16382 // code is executed. 16383 mSystemThread.applyConfigurationToResources(configCopy); 16384 16385 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16386 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16387 msg.obj = new Configuration(configCopy); 16388 mHandler.sendMessage(msg); 16389 } 16390 16391 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16392 ProcessRecord app = mLruProcesses.get(i); 16393 try { 16394 if (app.thread != null) { 16395 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16396 + app.processName + " new config " + mConfiguration); 16397 app.thread.scheduleConfigurationChanged(configCopy); 16398 } 16399 } catch (Exception e) { 16400 } 16401 } 16402 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16404 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16405 | Intent.FLAG_RECEIVER_FOREGROUND); 16406 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16407 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16408 Process.SYSTEM_UID, UserHandle.USER_ALL); 16409 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16410 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16411 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16412 broadcastIntentLocked(null, null, intent, 16413 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16414 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16415 } 16416 } 16417 } 16418 16419 boolean kept = true; 16420 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16421 // mainStack is null during startup. 16422 if (mainStack != null) { 16423 if (changes != 0 && starting == null) { 16424 // If the configuration changed, and the caller is not already 16425 // in the process of starting an activity, then find the top 16426 // activity to check if its configuration needs to change. 16427 starting = mainStack.topRunningActivityLocked(null); 16428 } 16429 16430 if (starting != null) { 16431 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16432 // And we need to make sure at this point that all other activities 16433 // are made visible with the correct configuration. 16434 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16435 } 16436 } 16437 16438 if (values != null && mWindowManager != null) { 16439 mWindowManager.setNewConfiguration(mConfiguration); 16440 } 16441 16442 return kept; 16443 } 16444 16445 /** 16446 * Decide based on the configuration whether we should shouw the ANR, 16447 * crash, etc dialogs. The idea is that if there is no affordnace to 16448 * press the on-screen buttons, we shouldn't show the dialog. 16449 * 16450 * A thought: SystemUI might also want to get told about this, the Power 16451 * dialog / global actions also might want different behaviors. 16452 */ 16453 private static final boolean shouldShowDialogs(Configuration config) { 16454 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16455 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16456 } 16457 16458 /** 16459 * Save the locale. You must be inside a synchronized (this) block. 16460 */ 16461 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16462 if(isDiff) { 16463 SystemProperties.set("user.language", l.getLanguage()); 16464 SystemProperties.set("user.region", l.getCountry()); 16465 } 16466 16467 if(isPersist) { 16468 SystemProperties.set("persist.sys.language", l.getLanguage()); 16469 SystemProperties.set("persist.sys.country", l.getCountry()); 16470 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16471 16472 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16473 } 16474 } 16475 16476 @Override 16477 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16478 synchronized (this) { 16479 ActivityRecord srec = ActivityRecord.forToken(token); 16480 if (srec.task != null && srec.task.stack != null) { 16481 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16482 } 16483 } 16484 return false; 16485 } 16486 16487 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16488 Intent resultData) { 16489 16490 synchronized (this) { 16491 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16492 if (stack != null) { 16493 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16494 } 16495 return false; 16496 } 16497 } 16498 16499 public int getLaunchedFromUid(IBinder activityToken) { 16500 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16501 if (srec == null) { 16502 return -1; 16503 } 16504 return srec.launchedFromUid; 16505 } 16506 16507 public String getLaunchedFromPackage(IBinder activityToken) { 16508 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16509 if (srec == null) { 16510 return null; 16511 } 16512 return srec.launchedFromPackage; 16513 } 16514 16515 // ========================================================= 16516 // LIFETIME MANAGEMENT 16517 // ========================================================= 16518 16519 // Returns which broadcast queue the app is the current [or imminent] receiver 16520 // on, or 'null' if the app is not an active broadcast recipient. 16521 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16522 BroadcastRecord r = app.curReceiver; 16523 if (r != null) { 16524 return r.queue; 16525 } 16526 16527 // It's not the current receiver, but it might be starting up to become one 16528 synchronized (this) { 16529 for (BroadcastQueue queue : mBroadcastQueues) { 16530 r = queue.mPendingBroadcast; 16531 if (r != null && r.curApp == app) { 16532 // found it; report which queue it's in 16533 return queue; 16534 } 16535 } 16536 } 16537 16538 return null; 16539 } 16540 16541 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16542 boolean doingAll, long now) { 16543 if (mAdjSeq == app.adjSeq) { 16544 // This adjustment has already been computed. 16545 return app.curRawAdj; 16546 } 16547 16548 if (app.thread == null) { 16549 app.adjSeq = mAdjSeq; 16550 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16551 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16552 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16553 } 16554 16555 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16556 app.adjSource = null; 16557 app.adjTarget = null; 16558 app.empty = false; 16559 app.cached = false; 16560 16561 final int activitiesSize = app.activities.size(); 16562 16563 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16564 // The max adjustment doesn't allow this app to be anything 16565 // below foreground, so it is not worth doing work for it. 16566 app.adjType = "fixed"; 16567 app.adjSeq = mAdjSeq; 16568 app.curRawAdj = app.maxAdj; 16569 app.foregroundActivities = false; 16570 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16571 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16572 // System processes can do UI, and when they do we want to have 16573 // them trim their memory after the user leaves the UI. To 16574 // facilitate this, here we need to determine whether or not it 16575 // is currently showing UI. 16576 app.systemNoUi = true; 16577 if (app == TOP_APP) { 16578 app.systemNoUi = false; 16579 } else if (activitiesSize > 0) { 16580 for (int j = 0; j < activitiesSize; j++) { 16581 final ActivityRecord r = app.activities.get(j); 16582 if (r.visible) { 16583 app.systemNoUi = false; 16584 } 16585 } 16586 } 16587 if (!app.systemNoUi) { 16588 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16589 } 16590 return (app.curAdj=app.maxAdj); 16591 } 16592 16593 app.systemNoUi = false; 16594 16595 // Determine the importance of the process, starting with most 16596 // important to least, and assign an appropriate OOM adjustment. 16597 int adj; 16598 int schedGroup; 16599 int procState; 16600 boolean foregroundActivities = false; 16601 BroadcastQueue queue; 16602 if (app == TOP_APP) { 16603 // The last app on the list is the foreground app. 16604 adj = ProcessList.FOREGROUND_APP_ADJ; 16605 schedGroup = Process.THREAD_GROUP_DEFAULT; 16606 app.adjType = "top-activity"; 16607 foregroundActivities = true; 16608 procState = ActivityManager.PROCESS_STATE_TOP; 16609 } else if (app.instrumentationClass != null) { 16610 // Don't want to kill running instrumentation. 16611 adj = ProcessList.FOREGROUND_APP_ADJ; 16612 schedGroup = Process.THREAD_GROUP_DEFAULT; 16613 app.adjType = "instrumentation"; 16614 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16615 } else if ((queue = isReceivingBroadcast(app)) != null) { 16616 // An app that is currently receiving a broadcast also 16617 // counts as being in the foreground for OOM killer purposes. 16618 // It's placed in a sched group based on the nature of the 16619 // broadcast as reflected by which queue it's active in. 16620 adj = ProcessList.FOREGROUND_APP_ADJ; 16621 schedGroup = (queue == mFgBroadcastQueue) 16622 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16623 app.adjType = "broadcast"; 16624 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16625 } else if (app.executingServices.size() > 0) { 16626 // An app that is currently executing a service callback also 16627 // counts as being in the foreground. 16628 adj = ProcessList.FOREGROUND_APP_ADJ; 16629 schedGroup = app.execServicesFg ? 16630 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16631 app.adjType = "exec-service"; 16632 procState = ActivityManager.PROCESS_STATE_SERVICE; 16633 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16634 } else { 16635 // As far as we know the process is empty. We may change our mind later. 16636 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16637 // At this point we don't actually know the adjustment. Use the cached adj 16638 // value that the caller wants us to. 16639 adj = cachedAdj; 16640 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16641 app.cached = true; 16642 app.empty = true; 16643 app.adjType = "cch-empty"; 16644 } 16645 16646 // Examine all activities if not already foreground. 16647 if (!foregroundActivities && activitiesSize > 0) { 16648 for (int j = 0; j < activitiesSize; j++) { 16649 final ActivityRecord r = app.activities.get(j); 16650 if (r.app != app) { 16651 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16652 + app + "?!?"); 16653 continue; 16654 } 16655 if (r.visible) { 16656 // App has a visible activity; only upgrade adjustment. 16657 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16658 adj = ProcessList.VISIBLE_APP_ADJ; 16659 app.adjType = "visible"; 16660 } 16661 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16662 procState = ActivityManager.PROCESS_STATE_TOP; 16663 } 16664 schedGroup = Process.THREAD_GROUP_DEFAULT; 16665 app.cached = false; 16666 app.empty = false; 16667 foregroundActivities = true; 16668 break; 16669 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16670 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16671 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16672 app.adjType = "pausing"; 16673 } 16674 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16675 procState = ActivityManager.PROCESS_STATE_TOP; 16676 } 16677 schedGroup = Process.THREAD_GROUP_DEFAULT; 16678 app.cached = false; 16679 app.empty = false; 16680 foregroundActivities = true; 16681 } else if (r.state == ActivityState.STOPPING) { 16682 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16683 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16684 app.adjType = "stopping"; 16685 } 16686 // For the process state, we will at this point consider the 16687 // process to be cached. It will be cached either as an activity 16688 // or empty depending on whether the activity is finishing. We do 16689 // this so that we can treat the process as cached for purposes of 16690 // memory trimming (determing current memory level, trim command to 16691 // send to process) since there can be an arbitrary number of stopping 16692 // processes and they should soon all go into the cached state. 16693 if (!r.finishing) { 16694 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16695 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16696 } 16697 } 16698 app.cached = false; 16699 app.empty = false; 16700 foregroundActivities = true; 16701 } else { 16702 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16703 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16704 app.adjType = "cch-act"; 16705 } 16706 } 16707 } 16708 } 16709 16710 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16711 if (app.foregroundServices) { 16712 // The user is aware of this app, so make it visible. 16713 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16714 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16715 app.cached = false; 16716 app.adjType = "fg-service"; 16717 schedGroup = Process.THREAD_GROUP_DEFAULT; 16718 } else if (app.forcingToForeground != null) { 16719 // The user is aware of this app, so make it visible. 16720 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16721 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16722 app.cached = false; 16723 app.adjType = "force-fg"; 16724 app.adjSource = app.forcingToForeground; 16725 schedGroup = Process.THREAD_GROUP_DEFAULT; 16726 } 16727 } 16728 16729 if (app == mHeavyWeightProcess) { 16730 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16731 // We don't want to kill the current heavy-weight process. 16732 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16733 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16734 app.cached = false; 16735 app.adjType = "heavy"; 16736 } 16737 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16738 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16739 } 16740 } 16741 16742 if (app == mHomeProcess) { 16743 if (adj > ProcessList.HOME_APP_ADJ) { 16744 // This process is hosting what we currently consider to be the 16745 // home app, so we don't want to let it go into the background. 16746 adj = ProcessList.HOME_APP_ADJ; 16747 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16748 app.cached = false; 16749 app.adjType = "home"; 16750 } 16751 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16752 procState = ActivityManager.PROCESS_STATE_HOME; 16753 } 16754 } 16755 16756 if (app == mPreviousProcess && app.activities.size() > 0) { 16757 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16758 // This was the previous process that showed UI to the user. 16759 // We want to try to keep it around more aggressively, to give 16760 // a good experience around switching between two apps. 16761 adj = ProcessList.PREVIOUS_APP_ADJ; 16762 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16763 app.cached = false; 16764 app.adjType = "previous"; 16765 } 16766 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16767 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16768 } 16769 } 16770 16771 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16772 + " reason=" + app.adjType); 16773 16774 // By default, we use the computed adjustment. It may be changed if 16775 // there are applications dependent on our services or providers, but 16776 // this gives us a baseline and makes sure we don't get into an 16777 // infinite recursion. 16778 app.adjSeq = mAdjSeq; 16779 app.curRawAdj = adj; 16780 app.hasStartedServices = false; 16781 16782 if (mBackupTarget != null && app == mBackupTarget.app) { 16783 // If possible we want to avoid killing apps while they're being backed up 16784 if (adj > ProcessList.BACKUP_APP_ADJ) { 16785 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16786 adj = ProcessList.BACKUP_APP_ADJ; 16787 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16788 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16789 } 16790 app.adjType = "backup"; 16791 app.cached = false; 16792 } 16793 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16794 procState = ActivityManager.PROCESS_STATE_BACKUP; 16795 } 16796 } 16797 16798 boolean mayBeTop = false; 16799 16800 for (int is = app.services.size()-1; 16801 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16802 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16803 || procState > ActivityManager.PROCESS_STATE_TOP); 16804 is--) { 16805 ServiceRecord s = app.services.valueAt(is); 16806 if (s.startRequested) { 16807 app.hasStartedServices = true; 16808 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16809 procState = ActivityManager.PROCESS_STATE_SERVICE; 16810 } 16811 if (app.hasShownUi && app != mHomeProcess) { 16812 // If this process has shown some UI, let it immediately 16813 // go to the LRU list because it may be pretty heavy with 16814 // UI stuff. We'll tag it with a label just to help 16815 // debug and understand what is going on. 16816 if (adj > ProcessList.SERVICE_ADJ) { 16817 app.adjType = "cch-started-ui-services"; 16818 } 16819 } else { 16820 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16821 // This service has seen some activity within 16822 // recent memory, so we will keep its process ahead 16823 // of the background processes. 16824 if (adj > ProcessList.SERVICE_ADJ) { 16825 adj = ProcessList.SERVICE_ADJ; 16826 app.adjType = "started-services"; 16827 app.cached = false; 16828 } 16829 } 16830 // If we have let the service slide into the background 16831 // state, still have some text describing what it is doing 16832 // even though the service no longer has an impact. 16833 if (adj > ProcessList.SERVICE_ADJ) { 16834 app.adjType = "cch-started-services"; 16835 } 16836 } 16837 } 16838 for (int conni = s.connections.size()-1; 16839 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16840 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16841 || procState > ActivityManager.PROCESS_STATE_TOP); 16842 conni--) { 16843 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16844 for (int i = 0; 16845 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16846 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16847 || procState > ActivityManager.PROCESS_STATE_TOP); 16848 i++) { 16849 // XXX should compute this based on the max of 16850 // all connected clients. 16851 ConnectionRecord cr = clist.get(i); 16852 if (cr.binding.client == app) { 16853 // Binding to ourself is not interesting. 16854 continue; 16855 } 16856 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16857 ProcessRecord client = cr.binding.client; 16858 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16859 TOP_APP, doingAll, now); 16860 int clientProcState = client.curProcState; 16861 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16862 // If the other app is cached for any reason, for purposes here 16863 // we are going to consider it empty. The specific cached state 16864 // doesn't propagate except under certain conditions. 16865 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16866 } 16867 String adjType = null; 16868 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16869 // Not doing bind OOM management, so treat 16870 // this guy more like a started service. 16871 if (app.hasShownUi && app != mHomeProcess) { 16872 // If this process has shown some UI, let it immediately 16873 // go to the LRU list because it may be pretty heavy with 16874 // UI stuff. We'll tag it with a label just to help 16875 // debug and understand what is going on. 16876 if (adj > clientAdj) { 16877 adjType = "cch-bound-ui-services"; 16878 } 16879 app.cached = false; 16880 clientAdj = adj; 16881 clientProcState = procState; 16882 } else { 16883 if (now >= (s.lastActivity 16884 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16885 // This service has not seen activity within 16886 // recent memory, so allow it to drop to the 16887 // LRU list if there is no other reason to keep 16888 // it around. We'll also tag it with a label just 16889 // to help debug and undertand what is going on. 16890 if (adj > clientAdj) { 16891 adjType = "cch-bound-services"; 16892 } 16893 clientAdj = adj; 16894 } 16895 } 16896 } 16897 if (adj > clientAdj) { 16898 // If this process has recently shown UI, and 16899 // the process that is binding to it is less 16900 // important than being visible, then we don't 16901 // care about the binding as much as we care 16902 // about letting this process get into the LRU 16903 // list to be killed and restarted if needed for 16904 // memory. 16905 if (app.hasShownUi && app != mHomeProcess 16906 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16907 adjType = "cch-bound-ui-services"; 16908 } else { 16909 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16910 |Context.BIND_IMPORTANT)) != 0) { 16911 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16912 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16913 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16914 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16915 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16916 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16917 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16918 adj = clientAdj; 16919 } else { 16920 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16921 adj = ProcessList.VISIBLE_APP_ADJ; 16922 } 16923 } 16924 if (!client.cached) { 16925 app.cached = false; 16926 } 16927 adjType = "service"; 16928 } 16929 } 16930 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16931 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16932 schedGroup = Process.THREAD_GROUP_DEFAULT; 16933 } 16934 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16935 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16936 // Special handling of clients who are in the top state. 16937 // We *may* want to consider this process to be in the 16938 // top state as well, but only if there is not another 16939 // reason for it to be running. Being on the top is a 16940 // special state, meaning you are specifically running 16941 // for the current top app. If the process is already 16942 // running in the background for some other reason, it 16943 // is more important to continue considering it to be 16944 // in the background state. 16945 mayBeTop = true; 16946 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16947 } else { 16948 // Special handling for above-top states (persistent 16949 // processes). These should not bring the current process 16950 // into the top state, since they are not on top. Instead 16951 // give them the best state after that. 16952 clientProcState = 16953 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16954 } 16955 } 16956 } else { 16957 if (clientProcState < 16958 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16959 clientProcState = 16960 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16961 } 16962 } 16963 if (procState > clientProcState) { 16964 procState = clientProcState; 16965 } 16966 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16967 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16968 app.pendingUiClean = true; 16969 } 16970 if (adjType != null) { 16971 app.adjType = adjType; 16972 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16973 .REASON_SERVICE_IN_USE; 16974 app.adjSource = cr.binding.client; 16975 app.adjSourceProcState = clientProcState; 16976 app.adjTarget = s.name; 16977 } 16978 } 16979 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16980 app.treatLikeActivity = true; 16981 } 16982 final ActivityRecord a = cr.activity; 16983 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16984 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16985 (a.visible || a.state == ActivityState.RESUMED 16986 || a.state == ActivityState.PAUSING)) { 16987 adj = ProcessList.FOREGROUND_APP_ADJ; 16988 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16989 schedGroup = Process.THREAD_GROUP_DEFAULT; 16990 } 16991 app.cached = false; 16992 app.adjType = "service"; 16993 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16994 .REASON_SERVICE_IN_USE; 16995 app.adjSource = a; 16996 app.adjSourceProcState = procState; 16997 app.adjTarget = s.name; 16998 } 16999 } 17000 } 17001 } 17002 } 17003 17004 for (int provi = app.pubProviders.size()-1; 17005 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17006 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17007 || procState > ActivityManager.PROCESS_STATE_TOP); 17008 provi--) { 17009 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17010 for (int i = cpr.connections.size()-1; 17011 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17012 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17013 || procState > ActivityManager.PROCESS_STATE_TOP); 17014 i--) { 17015 ContentProviderConnection conn = cpr.connections.get(i); 17016 ProcessRecord client = conn.client; 17017 if (client == app) { 17018 // Being our own client is not interesting. 17019 continue; 17020 } 17021 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17022 int clientProcState = client.curProcState; 17023 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17024 // If the other app is cached for any reason, for purposes here 17025 // we are going to consider it empty. 17026 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17027 } 17028 if (adj > clientAdj) { 17029 if (app.hasShownUi && app != mHomeProcess 17030 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17031 app.adjType = "cch-ui-provider"; 17032 } else { 17033 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17034 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17035 app.adjType = "provider"; 17036 } 17037 app.cached &= client.cached; 17038 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17039 .REASON_PROVIDER_IN_USE; 17040 app.adjSource = client; 17041 app.adjSourceProcState = clientProcState; 17042 app.adjTarget = cpr.name; 17043 } 17044 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17045 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17046 // Special handling of clients who are in the top state. 17047 // We *may* want to consider this process to be in the 17048 // top state as well, but only if there is not another 17049 // reason for it to be running. Being on the top is a 17050 // special state, meaning you are specifically running 17051 // for the current top app. If the process is already 17052 // running in the background for some other reason, it 17053 // is more important to continue considering it to be 17054 // in the background state. 17055 mayBeTop = true; 17056 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17057 } else { 17058 // Special handling for above-top states (persistent 17059 // processes). These should not bring the current process 17060 // into the top state, since they are not on top. Instead 17061 // give them the best state after that. 17062 clientProcState = 17063 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17064 } 17065 } 17066 if (procState > clientProcState) { 17067 procState = clientProcState; 17068 } 17069 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17070 schedGroup = Process.THREAD_GROUP_DEFAULT; 17071 } 17072 } 17073 // If the provider has external (non-framework) process 17074 // dependencies, ensure that its adjustment is at least 17075 // FOREGROUND_APP_ADJ. 17076 if (cpr.hasExternalProcessHandles()) { 17077 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17078 adj = ProcessList.FOREGROUND_APP_ADJ; 17079 schedGroup = Process.THREAD_GROUP_DEFAULT; 17080 app.cached = false; 17081 app.adjType = "provider"; 17082 app.adjTarget = cpr.name; 17083 } 17084 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17085 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17086 } 17087 } 17088 } 17089 17090 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17091 // A client of one of our services or providers is in the top state. We 17092 // *may* want to be in the top state, but not if we are already running in 17093 // the background for some other reason. For the decision here, we are going 17094 // to pick out a few specific states that we want to remain in when a client 17095 // is top (states that tend to be longer-term) and otherwise allow it to go 17096 // to the top state. 17097 switch (procState) { 17098 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17099 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17100 case ActivityManager.PROCESS_STATE_SERVICE: 17101 // These all are longer-term states, so pull them up to the top 17102 // of the background states, but not all the way to the top state. 17103 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17104 break; 17105 default: 17106 // Otherwise, top is a better choice, so take it. 17107 procState = ActivityManager.PROCESS_STATE_TOP; 17108 break; 17109 } 17110 } 17111 17112 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17113 if (app.hasClientActivities) { 17114 // This is a cached process, but with client activities. Mark it so. 17115 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17116 app.adjType = "cch-client-act"; 17117 } else if (app.treatLikeActivity) { 17118 // This is a cached process, but somebody wants us to treat it like it has 17119 // an activity, okay! 17120 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17121 app.adjType = "cch-as-act"; 17122 } 17123 } 17124 17125 if (adj == ProcessList.SERVICE_ADJ) { 17126 if (doingAll) { 17127 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17128 mNewNumServiceProcs++; 17129 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17130 if (!app.serviceb) { 17131 // This service isn't far enough down on the LRU list to 17132 // normally be a B service, but if we are low on RAM and it 17133 // is large we want to force it down since we would prefer to 17134 // keep launcher over it. 17135 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17136 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17137 app.serviceHighRam = true; 17138 app.serviceb = true; 17139 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17140 } else { 17141 mNewNumAServiceProcs++; 17142 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17143 } 17144 } else { 17145 app.serviceHighRam = false; 17146 } 17147 } 17148 if (app.serviceb) { 17149 adj = ProcessList.SERVICE_B_ADJ; 17150 } 17151 } 17152 17153 app.curRawAdj = adj; 17154 17155 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17156 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17157 if (adj > app.maxAdj) { 17158 adj = app.maxAdj; 17159 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17160 schedGroup = Process.THREAD_GROUP_DEFAULT; 17161 } 17162 } 17163 17164 // Do final modification to adj. Everything we do between here and applying 17165 // the final setAdj must be done in this function, because we will also use 17166 // it when computing the final cached adj later. Note that we don't need to 17167 // worry about this for max adj above, since max adj will always be used to 17168 // keep it out of the cached vaues. 17169 app.curAdj = app.modifyRawOomAdj(adj); 17170 app.curSchedGroup = schedGroup; 17171 app.curProcState = procState; 17172 app.foregroundActivities = foregroundActivities; 17173 17174 return app.curRawAdj; 17175 } 17176 17177 /** 17178 * Schedule PSS collection of a process. 17179 */ 17180 void requestPssLocked(ProcessRecord proc, int procState) { 17181 if (mPendingPssProcesses.contains(proc)) { 17182 return; 17183 } 17184 if (mPendingPssProcesses.size() == 0) { 17185 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17186 } 17187 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17188 proc.pssProcState = procState; 17189 mPendingPssProcesses.add(proc); 17190 } 17191 17192 /** 17193 * Schedule PSS collection of all processes. 17194 */ 17195 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17196 if (!always) { 17197 if (now < (mLastFullPssTime + 17198 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17199 return; 17200 } 17201 } 17202 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17203 mLastFullPssTime = now; 17204 mFullPssPending = true; 17205 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17206 mPendingPssProcesses.clear(); 17207 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17208 ProcessRecord app = mLruProcesses.get(i); 17209 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17210 app.pssProcState = app.setProcState; 17211 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17212 isSleeping(), now); 17213 mPendingPssProcesses.add(app); 17214 } 17215 } 17216 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17217 } 17218 17219 /** 17220 * Ask a given process to GC right now. 17221 */ 17222 final void performAppGcLocked(ProcessRecord app) { 17223 try { 17224 app.lastRequestedGc = SystemClock.uptimeMillis(); 17225 if (app.thread != null) { 17226 if (app.reportLowMemory) { 17227 app.reportLowMemory = false; 17228 app.thread.scheduleLowMemory(); 17229 } else { 17230 app.thread.processInBackground(); 17231 } 17232 } 17233 } catch (Exception e) { 17234 // whatever. 17235 } 17236 } 17237 17238 /** 17239 * Returns true if things are idle enough to perform GCs. 17240 */ 17241 private final boolean canGcNowLocked() { 17242 boolean processingBroadcasts = false; 17243 for (BroadcastQueue q : mBroadcastQueues) { 17244 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17245 processingBroadcasts = true; 17246 } 17247 } 17248 return !processingBroadcasts 17249 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17250 } 17251 17252 /** 17253 * Perform GCs on all processes that are waiting for it, but only 17254 * if things are idle. 17255 */ 17256 final void performAppGcsLocked() { 17257 final int N = mProcessesToGc.size(); 17258 if (N <= 0) { 17259 return; 17260 } 17261 if (canGcNowLocked()) { 17262 while (mProcessesToGc.size() > 0) { 17263 ProcessRecord proc = mProcessesToGc.remove(0); 17264 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17265 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17266 <= SystemClock.uptimeMillis()) { 17267 // To avoid spamming the system, we will GC processes one 17268 // at a time, waiting a few seconds between each. 17269 performAppGcLocked(proc); 17270 scheduleAppGcsLocked(); 17271 return; 17272 } else { 17273 // It hasn't been long enough since we last GCed this 17274 // process... put it in the list to wait for its time. 17275 addProcessToGcListLocked(proc); 17276 break; 17277 } 17278 } 17279 } 17280 17281 scheduleAppGcsLocked(); 17282 } 17283 } 17284 17285 /** 17286 * If all looks good, perform GCs on all processes waiting for them. 17287 */ 17288 final void performAppGcsIfAppropriateLocked() { 17289 if (canGcNowLocked()) { 17290 performAppGcsLocked(); 17291 return; 17292 } 17293 // Still not idle, wait some more. 17294 scheduleAppGcsLocked(); 17295 } 17296 17297 /** 17298 * Schedule the execution of all pending app GCs. 17299 */ 17300 final void scheduleAppGcsLocked() { 17301 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17302 17303 if (mProcessesToGc.size() > 0) { 17304 // Schedule a GC for the time to the next process. 17305 ProcessRecord proc = mProcessesToGc.get(0); 17306 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17307 17308 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17309 long now = SystemClock.uptimeMillis(); 17310 if (when < (now+GC_TIMEOUT)) { 17311 when = now + GC_TIMEOUT; 17312 } 17313 mHandler.sendMessageAtTime(msg, when); 17314 } 17315 } 17316 17317 /** 17318 * Add a process to the array of processes waiting to be GCed. Keeps the 17319 * list in sorted order by the last GC time. The process can't already be 17320 * on the list. 17321 */ 17322 final void addProcessToGcListLocked(ProcessRecord proc) { 17323 boolean added = false; 17324 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17325 if (mProcessesToGc.get(i).lastRequestedGc < 17326 proc.lastRequestedGc) { 17327 added = true; 17328 mProcessesToGc.add(i+1, proc); 17329 break; 17330 } 17331 } 17332 if (!added) { 17333 mProcessesToGc.add(0, proc); 17334 } 17335 } 17336 17337 /** 17338 * Set up to ask a process to GC itself. This will either do it 17339 * immediately, or put it on the list of processes to gc the next 17340 * time things are idle. 17341 */ 17342 final void scheduleAppGcLocked(ProcessRecord app) { 17343 long now = SystemClock.uptimeMillis(); 17344 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17345 return; 17346 } 17347 if (!mProcessesToGc.contains(app)) { 17348 addProcessToGcListLocked(app); 17349 scheduleAppGcsLocked(); 17350 } 17351 } 17352 17353 final void checkExcessivePowerUsageLocked(boolean doKills) { 17354 updateCpuStatsNow(); 17355 17356 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17357 boolean doWakeKills = doKills; 17358 boolean doCpuKills = doKills; 17359 if (mLastPowerCheckRealtime == 0) { 17360 doWakeKills = false; 17361 } 17362 if (mLastPowerCheckUptime == 0) { 17363 doCpuKills = false; 17364 } 17365 if (stats.isScreenOn()) { 17366 doWakeKills = false; 17367 } 17368 final long curRealtime = SystemClock.elapsedRealtime(); 17369 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17370 final long curUptime = SystemClock.uptimeMillis(); 17371 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17372 mLastPowerCheckRealtime = curRealtime; 17373 mLastPowerCheckUptime = curUptime; 17374 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17375 doWakeKills = false; 17376 } 17377 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17378 doCpuKills = false; 17379 } 17380 int i = mLruProcesses.size(); 17381 while (i > 0) { 17382 i--; 17383 ProcessRecord app = mLruProcesses.get(i); 17384 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17385 long wtime; 17386 synchronized (stats) { 17387 wtime = stats.getProcessWakeTime(app.info.uid, 17388 app.pid, curRealtime); 17389 } 17390 long wtimeUsed = wtime - app.lastWakeTime; 17391 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17392 if (DEBUG_POWER) { 17393 StringBuilder sb = new StringBuilder(128); 17394 sb.append("Wake for "); 17395 app.toShortString(sb); 17396 sb.append(": over "); 17397 TimeUtils.formatDuration(realtimeSince, sb); 17398 sb.append(" used "); 17399 TimeUtils.formatDuration(wtimeUsed, sb); 17400 sb.append(" ("); 17401 sb.append((wtimeUsed*100)/realtimeSince); 17402 sb.append("%)"); 17403 Slog.i(TAG, sb.toString()); 17404 sb.setLength(0); 17405 sb.append("CPU for "); 17406 app.toShortString(sb); 17407 sb.append(": over "); 17408 TimeUtils.formatDuration(uptimeSince, sb); 17409 sb.append(" used "); 17410 TimeUtils.formatDuration(cputimeUsed, sb); 17411 sb.append(" ("); 17412 sb.append((cputimeUsed*100)/uptimeSince); 17413 sb.append("%)"); 17414 Slog.i(TAG, sb.toString()); 17415 } 17416 // If a process has held a wake lock for more 17417 // than 50% of the time during this period, 17418 // that sounds bad. Kill! 17419 if (doWakeKills && realtimeSince > 0 17420 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17421 synchronized (stats) { 17422 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17423 realtimeSince, wtimeUsed); 17424 } 17425 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17426 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17427 } else if (doCpuKills && uptimeSince > 0 17428 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17429 synchronized (stats) { 17430 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17431 uptimeSince, cputimeUsed); 17432 } 17433 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17434 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17435 } else { 17436 app.lastWakeTime = wtime; 17437 app.lastCpuTime = app.curCpuTime; 17438 } 17439 } 17440 } 17441 } 17442 17443 private final boolean applyOomAdjLocked(ProcessRecord app, 17444 ProcessRecord TOP_APP, boolean doingAll, long now) { 17445 boolean success = true; 17446 17447 if (app.curRawAdj != app.setRawAdj) { 17448 app.setRawAdj = app.curRawAdj; 17449 } 17450 17451 int changes = 0; 17452 17453 if (app.curAdj != app.setAdj) { 17454 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17455 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17456 TAG, "Set " + app.pid + " " + app.processName + 17457 " adj " + app.curAdj + ": " + app.adjType); 17458 app.setAdj = app.curAdj; 17459 } 17460 17461 if (app.setSchedGroup != app.curSchedGroup) { 17462 app.setSchedGroup = app.curSchedGroup; 17463 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17464 "Setting process group of " + app.processName 17465 + " to " + app.curSchedGroup); 17466 if (app.waitingToKill != null && 17467 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17468 app.kill(app.waitingToKill, true); 17469 success = false; 17470 } else { 17471 if (true) { 17472 long oldId = Binder.clearCallingIdentity(); 17473 try { 17474 Process.setProcessGroup(app.pid, app.curSchedGroup); 17475 } catch (Exception e) { 17476 Slog.w(TAG, "Failed setting process group of " + app.pid 17477 + " to " + app.curSchedGroup); 17478 e.printStackTrace(); 17479 } finally { 17480 Binder.restoreCallingIdentity(oldId); 17481 } 17482 } else { 17483 if (app.thread != null) { 17484 try { 17485 app.thread.setSchedulingGroup(app.curSchedGroup); 17486 } catch (RemoteException e) { 17487 } 17488 } 17489 } 17490 Process.setSwappiness(app.pid, 17491 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17492 } 17493 } 17494 if (app.repForegroundActivities != app.foregroundActivities) { 17495 app.repForegroundActivities = app.foregroundActivities; 17496 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17497 } 17498 if (app.repProcState != app.curProcState) { 17499 app.repProcState = app.curProcState; 17500 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17501 if (app.thread != null) { 17502 try { 17503 if (false) { 17504 //RuntimeException h = new RuntimeException("here"); 17505 Slog.i(TAG, "Sending new process state " + app.repProcState 17506 + " to " + app /*, h*/); 17507 } 17508 app.thread.setProcessState(app.repProcState); 17509 } catch (RemoteException e) { 17510 } 17511 } 17512 } 17513 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17514 app.setProcState)) { 17515 app.lastStateTime = now; 17516 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17517 isSleeping(), now); 17518 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17519 + ProcessList.makeProcStateString(app.setProcState) + " to " 17520 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17521 + (app.nextPssTime-now) + ": " + app); 17522 } else { 17523 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17524 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17525 requestPssLocked(app, app.setProcState); 17526 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17527 isSleeping(), now); 17528 } else if (false && DEBUG_PSS) { 17529 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17530 } 17531 } 17532 if (app.setProcState != app.curProcState) { 17533 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17534 "Proc state change of " + app.processName 17535 + " to " + app.curProcState); 17536 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17537 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17538 if (setImportant && !curImportant) { 17539 // This app is no longer something we consider important enough to allow to 17540 // use arbitrary amounts of battery power. Note 17541 // its current wake lock time to later know to kill it if 17542 // it is not behaving well. 17543 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17544 synchronized (stats) { 17545 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17546 app.pid, SystemClock.elapsedRealtime()); 17547 } 17548 app.lastCpuTime = app.curCpuTime; 17549 17550 } 17551 app.setProcState = app.curProcState; 17552 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17553 app.notCachedSinceIdle = false; 17554 } 17555 if (!doingAll) { 17556 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17557 } else { 17558 app.procStateChanged = true; 17559 } 17560 } 17561 17562 if (changes != 0) { 17563 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17564 int i = mPendingProcessChanges.size()-1; 17565 ProcessChangeItem item = null; 17566 while (i >= 0) { 17567 item = mPendingProcessChanges.get(i); 17568 if (item.pid == app.pid) { 17569 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17570 break; 17571 } 17572 i--; 17573 } 17574 if (i < 0) { 17575 // No existing item in pending changes; need a new one. 17576 final int NA = mAvailProcessChanges.size(); 17577 if (NA > 0) { 17578 item = mAvailProcessChanges.remove(NA-1); 17579 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17580 } else { 17581 item = new ProcessChangeItem(); 17582 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17583 } 17584 item.changes = 0; 17585 item.pid = app.pid; 17586 item.uid = app.info.uid; 17587 if (mPendingProcessChanges.size() == 0) { 17588 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17589 "*** Enqueueing dispatch processes changed!"); 17590 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17591 } 17592 mPendingProcessChanges.add(item); 17593 } 17594 item.changes |= changes; 17595 item.processState = app.repProcState; 17596 item.foregroundActivities = app.repForegroundActivities; 17597 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17598 + Integer.toHexString(System.identityHashCode(item)) 17599 + " " + app.toShortString() + ": changes=" + item.changes 17600 + " procState=" + item.processState 17601 + " foreground=" + item.foregroundActivities 17602 + " type=" + app.adjType + " source=" + app.adjSource 17603 + " target=" + app.adjTarget); 17604 } 17605 17606 return success; 17607 } 17608 17609 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17610 if (proc.thread != null) { 17611 if (proc.baseProcessTracker != null) { 17612 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17613 } 17614 if (proc.repProcState >= 0) { 17615 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17616 proc.repProcState); 17617 } 17618 } 17619 } 17620 17621 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17622 ProcessRecord TOP_APP, boolean doingAll, long now) { 17623 if (app.thread == null) { 17624 return false; 17625 } 17626 17627 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17628 17629 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17630 } 17631 17632 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17633 boolean oomAdj) { 17634 if (isForeground != proc.foregroundServices) { 17635 proc.foregroundServices = isForeground; 17636 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17637 proc.info.uid); 17638 if (isForeground) { 17639 if (curProcs == null) { 17640 curProcs = new ArrayList<ProcessRecord>(); 17641 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17642 } 17643 if (!curProcs.contains(proc)) { 17644 curProcs.add(proc); 17645 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17646 proc.info.packageName, proc.info.uid); 17647 } 17648 } else { 17649 if (curProcs != null) { 17650 if (curProcs.remove(proc)) { 17651 mBatteryStatsService.noteEvent( 17652 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17653 proc.info.packageName, proc.info.uid); 17654 if (curProcs.size() <= 0) { 17655 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17656 } 17657 } 17658 } 17659 } 17660 if (oomAdj) { 17661 updateOomAdjLocked(); 17662 } 17663 } 17664 } 17665 17666 private final ActivityRecord resumedAppLocked() { 17667 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17668 String pkg; 17669 int uid; 17670 if (act != null) { 17671 pkg = act.packageName; 17672 uid = act.info.applicationInfo.uid; 17673 } else { 17674 pkg = null; 17675 uid = -1; 17676 } 17677 // Has the UID or resumed package name changed? 17678 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17679 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17680 if (mCurResumedPackage != null) { 17681 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17682 mCurResumedPackage, mCurResumedUid); 17683 } 17684 mCurResumedPackage = pkg; 17685 mCurResumedUid = uid; 17686 if (mCurResumedPackage != null) { 17687 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17688 mCurResumedPackage, mCurResumedUid); 17689 } 17690 } 17691 return act; 17692 } 17693 17694 final boolean updateOomAdjLocked(ProcessRecord app) { 17695 final ActivityRecord TOP_ACT = resumedAppLocked(); 17696 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17697 final boolean wasCached = app.cached; 17698 17699 mAdjSeq++; 17700 17701 // This is the desired cached adjusment we want to tell it to use. 17702 // If our app is currently cached, we know it, and that is it. Otherwise, 17703 // we don't know it yet, and it needs to now be cached we will then 17704 // need to do a complete oom adj. 17705 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17706 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17707 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17708 SystemClock.uptimeMillis()); 17709 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17710 // Changed to/from cached state, so apps after it in the LRU 17711 // list may also be changed. 17712 updateOomAdjLocked(); 17713 } 17714 return success; 17715 } 17716 17717 final void updateOomAdjLocked() { 17718 final ActivityRecord TOP_ACT = resumedAppLocked(); 17719 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17720 final long now = SystemClock.uptimeMillis(); 17721 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17722 final int N = mLruProcesses.size(); 17723 17724 if (false) { 17725 RuntimeException e = new RuntimeException(); 17726 e.fillInStackTrace(); 17727 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17728 } 17729 17730 mAdjSeq++; 17731 mNewNumServiceProcs = 0; 17732 mNewNumAServiceProcs = 0; 17733 17734 final int emptyProcessLimit; 17735 final int cachedProcessLimit; 17736 if (mProcessLimit <= 0) { 17737 emptyProcessLimit = cachedProcessLimit = 0; 17738 } else if (mProcessLimit == 1) { 17739 emptyProcessLimit = 1; 17740 cachedProcessLimit = 0; 17741 } else { 17742 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17743 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17744 } 17745 17746 // Let's determine how many processes we have running vs. 17747 // how many slots we have for background processes; we may want 17748 // to put multiple processes in a slot of there are enough of 17749 // them. 17750 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17751 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17752 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17753 if (numEmptyProcs > cachedProcessLimit) { 17754 // If there are more empty processes than our limit on cached 17755 // processes, then use the cached process limit for the factor. 17756 // This ensures that the really old empty processes get pushed 17757 // down to the bottom, so if we are running low on memory we will 17758 // have a better chance at keeping around more cached processes 17759 // instead of a gazillion empty processes. 17760 numEmptyProcs = cachedProcessLimit; 17761 } 17762 int emptyFactor = numEmptyProcs/numSlots; 17763 if (emptyFactor < 1) emptyFactor = 1; 17764 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17765 if (cachedFactor < 1) cachedFactor = 1; 17766 int stepCached = 0; 17767 int stepEmpty = 0; 17768 int numCached = 0; 17769 int numEmpty = 0; 17770 int numTrimming = 0; 17771 17772 mNumNonCachedProcs = 0; 17773 mNumCachedHiddenProcs = 0; 17774 17775 // First update the OOM adjustment for each of the 17776 // application processes based on their current state. 17777 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17778 int nextCachedAdj = curCachedAdj+1; 17779 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17780 int nextEmptyAdj = curEmptyAdj+2; 17781 for (int i=N-1; i>=0; i--) { 17782 ProcessRecord app = mLruProcesses.get(i); 17783 if (!app.killedByAm && app.thread != null) { 17784 app.procStateChanged = false; 17785 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17786 17787 // If we haven't yet assigned the final cached adj 17788 // to the process, do that now. 17789 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17790 switch (app.curProcState) { 17791 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17792 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17793 // This process is a cached process holding activities... 17794 // assign it the next cached value for that type, and then 17795 // step that cached level. 17796 app.curRawAdj = curCachedAdj; 17797 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17798 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17799 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17800 + ")"); 17801 if (curCachedAdj != nextCachedAdj) { 17802 stepCached++; 17803 if (stepCached >= cachedFactor) { 17804 stepCached = 0; 17805 curCachedAdj = nextCachedAdj; 17806 nextCachedAdj += 2; 17807 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17808 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17809 } 17810 } 17811 } 17812 break; 17813 default: 17814 // For everything else, assign next empty cached process 17815 // level and bump that up. Note that this means that 17816 // long-running services that have dropped down to the 17817 // cached level will be treated as empty (since their process 17818 // state is still as a service), which is what we want. 17819 app.curRawAdj = curEmptyAdj; 17820 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17821 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17822 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17823 + ")"); 17824 if (curEmptyAdj != nextEmptyAdj) { 17825 stepEmpty++; 17826 if (stepEmpty >= emptyFactor) { 17827 stepEmpty = 0; 17828 curEmptyAdj = nextEmptyAdj; 17829 nextEmptyAdj += 2; 17830 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17831 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17832 } 17833 } 17834 } 17835 break; 17836 } 17837 } 17838 17839 applyOomAdjLocked(app, TOP_APP, true, now); 17840 17841 // Count the number of process types. 17842 switch (app.curProcState) { 17843 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17844 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17845 mNumCachedHiddenProcs++; 17846 numCached++; 17847 if (numCached > cachedProcessLimit) { 17848 app.kill("cached #" + numCached, true); 17849 } 17850 break; 17851 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17852 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17853 && app.lastActivityTime < oldTime) { 17854 app.kill("empty for " 17855 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17856 / 1000) + "s", true); 17857 } else { 17858 numEmpty++; 17859 if (numEmpty > emptyProcessLimit) { 17860 app.kill("empty #" + numEmpty, true); 17861 } 17862 } 17863 break; 17864 default: 17865 mNumNonCachedProcs++; 17866 break; 17867 } 17868 17869 if (app.isolated && app.services.size() <= 0) { 17870 // If this is an isolated process, and there are no 17871 // services running in it, then the process is no longer 17872 // needed. We agressively kill these because we can by 17873 // definition not re-use the same process again, and it is 17874 // good to avoid having whatever code was running in them 17875 // left sitting around after no longer needed. 17876 app.kill("isolated not needed", true); 17877 } 17878 17879 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17880 && !app.killedByAm) { 17881 numTrimming++; 17882 } 17883 } 17884 } 17885 17886 mNumServiceProcs = mNewNumServiceProcs; 17887 17888 // Now determine the memory trimming level of background processes. 17889 // Unfortunately we need to start at the back of the list to do this 17890 // properly. We only do this if the number of background apps we 17891 // are managing to keep around is less than half the maximum we desire; 17892 // if we are keeping a good number around, we'll let them use whatever 17893 // memory they want. 17894 final int numCachedAndEmpty = numCached + numEmpty; 17895 int memFactor; 17896 if (numCached <= ProcessList.TRIM_CACHED_APPS 17897 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17898 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17899 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17900 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17901 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17902 } else { 17903 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17904 } 17905 } else { 17906 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17907 } 17908 // We always allow the memory level to go up (better). We only allow it to go 17909 // down if we are in a state where that is allowed, *and* the total number of processes 17910 // has gone down since last time. 17911 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17912 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17913 + " last=" + mLastNumProcesses); 17914 if (memFactor > mLastMemoryLevel) { 17915 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17916 memFactor = mLastMemoryLevel; 17917 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17918 } 17919 } 17920 mLastMemoryLevel = memFactor; 17921 mLastNumProcesses = mLruProcesses.size(); 17922 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17923 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17924 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17925 if (mLowRamStartTime == 0) { 17926 mLowRamStartTime = now; 17927 } 17928 int step = 0; 17929 int fgTrimLevel; 17930 switch (memFactor) { 17931 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17932 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17933 break; 17934 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17935 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17936 break; 17937 default: 17938 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17939 break; 17940 } 17941 int factor = numTrimming/3; 17942 int minFactor = 2; 17943 if (mHomeProcess != null) minFactor++; 17944 if (mPreviousProcess != null) minFactor++; 17945 if (factor < minFactor) factor = minFactor; 17946 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17947 for (int i=N-1; i>=0; i--) { 17948 ProcessRecord app = mLruProcesses.get(i); 17949 if (allChanged || app.procStateChanged) { 17950 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17951 app.procStateChanged = false; 17952 } 17953 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17954 && !app.killedByAm) { 17955 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17956 try { 17957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17958 "Trimming memory of " + app.processName 17959 + " to " + curLevel); 17960 app.thread.scheduleTrimMemory(curLevel); 17961 } catch (RemoteException e) { 17962 } 17963 if (false) { 17964 // For now we won't do this; our memory trimming seems 17965 // to be good enough at this point that destroying 17966 // activities causes more harm than good. 17967 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17968 && app != mHomeProcess && app != mPreviousProcess) { 17969 // Need to do this on its own message because the stack may not 17970 // be in a consistent state at this point. 17971 // For these apps we will also finish their activities 17972 // to help them free memory. 17973 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17974 } 17975 } 17976 } 17977 app.trimMemoryLevel = curLevel; 17978 step++; 17979 if (step >= factor) { 17980 step = 0; 17981 switch (curLevel) { 17982 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17983 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17984 break; 17985 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17986 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17987 break; 17988 } 17989 } 17990 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17991 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17992 && app.thread != null) { 17993 try { 17994 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17995 "Trimming memory of heavy-weight " + app.processName 17996 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17997 app.thread.scheduleTrimMemory( 17998 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17999 } catch (RemoteException e) { 18000 } 18001 } 18002 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18003 } else { 18004 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18005 || app.systemNoUi) && app.pendingUiClean) { 18006 // If this application is now in the background and it 18007 // had done UI, then give it the special trim level to 18008 // have it free UI resources. 18009 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18010 if (app.trimMemoryLevel < level && app.thread != null) { 18011 try { 18012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18013 "Trimming memory of bg-ui " + app.processName 18014 + " to " + level); 18015 app.thread.scheduleTrimMemory(level); 18016 } catch (RemoteException e) { 18017 } 18018 } 18019 app.pendingUiClean = false; 18020 } 18021 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18022 try { 18023 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18024 "Trimming memory of fg " + app.processName 18025 + " to " + fgTrimLevel); 18026 app.thread.scheduleTrimMemory(fgTrimLevel); 18027 } catch (RemoteException e) { 18028 } 18029 } 18030 app.trimMemoryLevel = fgTrimLevel; 18031 } 18032 } 18033 } else { 18034 if (mLowRamStartTime != 0) { 18035 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18036 mLowRamStartTime = 0; 18037 } 18038 for (int i=N-1; i>=0; i--) { 18039 ProcessRecord app = mLruProcesses.get(i); 18040 if (allChanged || app.procStateChanged) { 18041 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18042 app.procStateChanged = false; 18043 } 18044 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18045 || app.systemNoUi) && app.pendingUiClean) { 18046 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18047 && app.thread != null) { 18048 try { 18049 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18050 "Trimming memory of ui hidden " + app.processName 18051 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18052 app.thread.scheduleTrimMemory( 18053 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18054 } catch (RemoteException e) { 18055 } 18056 } 18057 app.pendingUiClean = false; 18058 } 18059 app.trimMemoryLevel = 0; 18060 } 18061 } 18062 18063 if (mAlwaysFinishActivities) { 18064 // Need to do this on its own message because the stack may not 18065 // be in a consistent state at this point. 18066 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18067 } 18068 18069 if (allChanged) { 18070 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18071 } 18072 18073 if (mProcessStats.shouldWriteNowLocked(now)) { 18074 mHandler.post(new Runnable() { 18075 @Override public void run() { 18076 synchronized (ActivityManagerService.this) { 18077 mProcessStats.writeStateAsyncLocked(); 18078 } 18079 } 18080 }); 18081 } 18082 18083 if (DEBUG_OOM_ADJ) { 18084 if (false) { 18085 RuntimeException here = new RuntimeException("here"); 18086 here.fillInStackTrace(); 18087 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18088 } else { 18089 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18090 } 18091 } 18092 } 18093 18094 final void trimApplications() { 18095 synchronized (this) { 18096 int i; 18097 18098 // First remove any unused application processes whose package 18099 // has been removed. 18100 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18101 final ProcessRecord app = mRemovedProcesses.get(i); 18102 if (app.activities.size() == 0 18103 && app.curReceiver == null && app.services.size() == 0) { 18104 Slog.i( 18105 TAG, "Exiting empty application process " 18106 + app.processName + " (" 18107 + (app.thread != null ? app.thread.asBinder() : null) 18108 + ")\n"); 18109 if (app.pid > 0 && app.pid != MY_PID) { 18110 app.kill("empty", false); 18111 } else { 18112 try { 18113 app.thread.scheduleExit(); 18114 } catch (Exception e) { 18115 // Ignore exceptions. 18116 } 18117 } 18118 cleanUpApplicationRecordLocked(app, false, true, -1); 18119 mRemovedProcesses.remove(i); 18120 18121 if (app.persistent) { 18122 addAppLocked(app.info, false, null /* ABI override */); 18123 } 18124 } 18125 } 18126 18127 // Now update the oom adj for all processes. 18128 updateOomAdjLocked(); 18129 } 18130 } 18131 18132 /** This method sends the specified signal to each of the persistent apps */ 18133 public void signalPersistentProcesses(int sig) throws RemoteException { 18134 if (sig != Process.SIGNAL_USR1) { 18135 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18136 } 18137 18138 synchronized (this) { 18139 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18140 != PackageManager.PERMISSION_GRANTED) { 18141 throw new SecurityException("Requires permission " 18142 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18143 } 18144 18145 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18146 ProcessRecord r = mLruProcesses.get(i); 18147 if (r.thread != null && r.persistent) { 18148 Process.sendSignal(r.pid, sig); 18149 } 18150 } 18151 } 18152 } 18153 18154 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18155 if (proc == null || proc == mProfileProc) { 18156 proc = mProfileProc; 18157 profileType = mProfileType; 18158 clearProfilerLocked(); 18159 } 18160 if (proc == null) { 18161 return; 18162 } 18163 try { 18164 proc.thread.profilerControl(false, null, profileType); 18165 } catch (RemoteException e) { 18166 throw new IllegalStateException("Process disappeared"); 18167 } 18168 } 18169 18170 private void clearProfilerLocked() { 18171 if (mProfileFd != null) { 18172 try { 18173 mProfileFd.close(); 18174 } catch (IOException e) { 18175 } 18176 } 18177 mProfileApp = null; 18178 mProfileProc = null; 18179 mProfileFile = null; 18180 mProfileType = 0; 18181 mAutoStopProfiler = false; 18182 mSamplingInterval = 0; 18183 } 18184 18185 public boolean profileControl(String process, int userId, boolean start, 18186 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18187 18188 try { 18189 synchronized (this) { 18190 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18191 // its own permission. 18192 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18193 != PackageManager.PERMISSION_GRANTED) { 18194 throw new SecurityException("Requires permission " 18195 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18196 } 18197 18198 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18199 throw new IllegalArgumentException("null profile info or fd"); 18200 } 18201 18202 ProcessRecord proc = null; 18203 if (process != null) { 18204 proc = findProcessLocked(process, userId, "profileControl"); 18205 } 18206 18207 if (start && (proc == null || proc.thread == null)) { 18208 throw new IllegalArgumentException("Unknown process: " + process); 18209 } 18210 18211 if (start) { 18212 stopProfilerLocked(null, 0); 18213 setProfileApp(proc.info, proc.processName, profilerInfo); 18214 mProfileProc = proc; 18215 mProfileType = profileType; 18216 ParcelFileDescriptor fd = profilerInfo.profileFd; 18217 try { 18218 fd = fd.dup(); 18219 } catch (IOException e) { 18220 fd = null; 18221 } 18222 profilerInfo.profileFd = fd; 18223 proc.thread.profilerControl(start, profilerInfo, profileType); 18224 fd = null; 18225 mProfileFd = null; 18226 } else { 18227 stopProfilerLocked(proc, profileType); 18228 if (profilerInfo != null && profilerInfo.profileFd != null) { 18229 try { 18230 profilerInfo.profileFd.close(); 18231 } catch (IOException e) { 18232 } 18233 } 18234 } 18235 18236 return true; 18237 } 18238 } catch (RemoteException e) { 18239 throw new IllegalStateException("Process disappeared"); 18240 } finally { 18241 if (profilerInfo != null && profilerInfo.profileFd != null) { 18242 try { 18243 profilerInfo.profileFd.close(); 18244 } catch (IOException e) { 18245 } 18246 } 18247 } 18248 } 18249 18250 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18251 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18252 userId, true, ALLOW_FULL_ONLY, callName, null); 18253 ProcessRecord proc = null; 18254 try { 18255 int pid = Integer.parseInt(process); 18256 synchronized (mPidsSelfLocked) { 18257 proc = mPidsSelfLocked.get(pid); 18258 } 18259 } catch (NumberFormatException e) { 18260 } 18261 18262 if (proc == null) { 18263 ArrayMap<String, SparseArray<ProcessRecord>> all 18264 = mProcessNames.getMap(); 18265 SparseArray<ProcessRecord> procs = all.get(process); 18266 if (procs != null && procs.size() > 0) { 18267 proc = procs.valueAt(0); 18268 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18269 for (int i=1; i<procs.size(); i++) { 18270 ProcessRecord thisProc = procs.valueAt(i); 18271 if (thisProc.userId == userId) { 18272 proc = thisProc; 18273 break; 18274 } 18275 } 18276 } 18277 } 18278 } 18279 18280 return proc; 18281 } 18282 18283 public boolean dumpHeap(String process, int userId, boolean managed, 18284 String path, ParcelFileDescriptor fd) throws RemoteException { 18285 18286 try { 18287 synchronized (this) { 18288 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18289 // its own permission (same as profileControl). 18290 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18291 != PackageManager.PERMISSION_GRANTED) { 18292 throw new SecurityException("Requires permission " 18293 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18294 } 18295 18296 if (fd == null) { 18297 throw new IllegalArgumentException("null fd"); 18298 } 18299 18300 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18301 if (proc == null || proc.thread == null) { 18302 throw new IllegalArgumentException("Unknown process: " + process); 18303 } 18304 18305 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18306 if (!isDebuggable) { 18307 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18308 throw new SecurityException("Process not debuggable: " + proc); 18309 } 18310 } 18311 18312 proc.thread.dumpHeap(managed, path, fd); 18313 fd = null; 18314 return true; 18315 } 18316 } catch (RemoteException e) { 18317 throw new IllegalStateException("Process disappeared"); 18318 } finally { 18319 if (fd != null) { 18320 try { 18321 fd.close(); 18322 } catch (IOException e) { 18323 } 18324 } 18325 } 18326 } 18327 18328 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18329 public void monitor() { 18330 synchronized (this) { } 18331 } 18332 18333 void onCoreSettingsChange(Bundle settings) { 18334 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18335 ProcessRecord processRecord = mLruProcesses.get(i); 18336 try { 18337 if (processRecord.thread != null) { 18338 processRecord.thread.setCoreSettings(settings); 18339 } 18340 } catch (RemoteException re) { 18341 /* ignore */ 18342 } 18343 } 18344 } 18345 18346 // Multi-user methods 18347 18348 /** 18349 * Start user, if its not already running, but don't bring it to foreground. 18350 */ 18351 @Override 18352 public boolean startUserInBackground(final int userId) { 18353 return startUser(userId, /* foreground */ false); 18354 } 18355 18356 /** 18357 * Start user, if its not already running, and bring it to foreground. 18358 */ 18359 boolean startUserInForeground(final int userId, Dialog dlg) { 18360 boolean result = startUser(userId, /* foreground */ true); 18361 dlg.dismiss(); 18362 return result; 18363 } 18364 18365 /** 18366 * Refreshes the list of users related to the current user when either a 18367 * user switch happens or when a new related user is started in the 18368 * background. 18369 */ 18370 private void updateCurrentProfileIdsLocked() { 18371 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18372 mCurrentUserId, false /* enabledOnly */); 18373 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18374 for (int i = 0; i < currentProfileIds.length; i++) { 18375 currentProfileIds[i] = profiles.get(i).id; 18376 } 18377 mCurrentProfileIds = currentProfileIds; 18378 18379 synchronized (mUserProfileGroupIdsSelfLocked) { 18380 mUserProfileGroupIdsSelfLocked.clear(); 18381 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18382 for (int i = 0; i < users.size(); i++) { 18383 UserInfo user = users.get(i); 18384 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18385 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18386 } 18387 } 18388 } 18389 } 18390 18391 private Set getProfileIdsLocked(int userId) { 18392 Set userIds = new HashSet<Integer>(); 18393 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18394 userId, false /* enabledOnly */); 18395 for (UserInfo user : profiles) { 18396 userIds.add(Integer.valueOf(user.id)); 18397 } 18398 return userIds; 18399 } 18400 18401 @Override 18402 public boolean switchUser(final int userId) { 18403 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18404 String userName; 18405 synchronized (this) { 18406 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18407 if (userInfo == null) { 18408 Slog.w(TAG, "No user info for user #" + userId); 18409 return false; 18410 } 18411 if (userInfo.isManagedProfile()) { 18412 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18413 return false; 18414 } 18415 userName = userInfo.name; 18416 mTargetUserId = userId; 18417 } 18418 mHandler.removeMessages(START_USER_SWITCH_MSG); 18419 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18420 return true; 18421 } 18422 18423 private void showUserSwitchDialog(int userId, String userName) { 18424 // The dialog will show and then initiate the user switch by calling startUserInForeground 18425 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18426 true /* above system */); 18427 d.show(); 18428 } 18429 18430 private boolean startUser(final int userId, final boolean foreground) { 18431 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18432 != PackageManager.PERMISSION_GRANTED) { 18433 String msg = "Permission Denial: switchUser() from pid=" 18434 + Binder.getCallingPid() 18435 + ", uid=" + Binder.getCallingUid() 18436 + " requires " + INTERACT_ACROSS_USERS_FULL; 18437 Slog.w(TAG, msg); 18438 throw new SecurityException(msg); 18439 } 18440 18441 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18442 18443 final long ident = Binder.clearCallingIdentity(); 18444 try { 18445 synchronized (this) { 18446 final int oldUserId = mCurrentUserId; 18447 if (oldUserId == userId) { 18448 return true; 18449 } 18450 18451 mStackSupervisor.setLockTaskModeLocked(null, false); 18452 18453 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18454 if (userInfo == null) { 18455 Slog.w(TAG, "No user info for user #" + userId); 18456 return false; 18457 } 18458 if (foreground && userInfo.isManagedProfile()) { 18459 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18460 return false; 18461 } 18462 18463 if (foreground) { 18464 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18465 R.anim.screen_user_enter); 18466 } 18467 18468 boolean needStart = false; 18469 18470 // If the user we are switching to is not currently started, then 18471 // we need to start it now. 18472 if (mStartedUsers.get(userId) == null) { 18473 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18474 updateStartedUserArrayLocked(); 18475 needStart = true; 18476 } 18477 18478 final Integer userIdInt = Integer.valueOf(userId); 18479 mUserLru.remove(userIdInt); 18480 mUserLru.add(userIdInt); 18481 18482 if (foreground) { 18483 mCurrentUserId = userId; 18484 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18485 updateCurrentProfileIdsLocked(); 18486 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18487 // Once the internal notion of the active user has switched, we lock the device 18488 // with the option to show the user switcher on the keyguard. 18489 mWindowManager.lockNow(null); 18490 } else { 18491 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18492 updateCurrentProfileIdsLocked(); 18493 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18494 mUserLru.remove(currentUserIdInt); 18495 mUserLru.add(currentUserIdInt); 18496 } 18497 18498 final UserStartedState uss = mStartedUsers.get(userId); 18499 18500 // Make sure user is in the started state. If it is currently 18501 // stopping, we need to knock that off. 18502 if (uss.mState == UserStartedState.STATE_STOPPING) { 18503 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18504 // so we can just fairly silently bring the user back from 18505 // the almost-dead. 18506 uss.mState = UserStartedState.STATE_RUNNING; 18507 updateStartedUserArrayLocked(); 18508 needStart = true; 18509 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18510 // This means ACTION_SHUTDOWN has been sent, so we will 18511 // need to treat this as a new boot of the user. 18512 uss.mState = UserStartedState.STATE_BOOTING; 18513 updateStartedUserArrayLocked(); 18514 needStart = true; 18515 } 18516 18517 if (uss.mState == UserStartedState.STATE_BOOTING) { 18518 // Booting up a new user, need to tell system services about it. 18519 // Note that this is on the same handler as scheduling of broadcasts, 18520 // which is important because it needs to go first. 18521 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18522 } 18523 18524 if (foreground) { 18525 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18526 oldUserId)); 18527 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18528 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18529 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18530 oldUserId, userId, uss)); 18531 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18532 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18533 } 18534 18535 if (needStart) { 18536 // Send USER_STARTED broadcast 18537 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18538 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18539 | Intent.FLAG_RECEIVER_FOREGROUND); 18540 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18541 broadcastIntentLocked(null, null, intent, 18542 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18543 false, false, MY_PID, Process.SYSTEM_UID, userId); 18544 } 18545 18546 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18547 if (userId != UserHandle.USER_OWNER) { 18548 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18549 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18550 broadcastIntentLocked(null, null, intent, null, 18551 new IIntentReceiver.Stub() { 18552 public void performReceive(Intent intent, int resultCode, 18553 String data, Bundle extras, boolean ordered, 18554 boolean sticky, int sendingUser) { 18555 onUserInitialized(uss, foreground, oldUserId, userId); 18556 } 18557 }, 0, null, null, null, AppOpsManager.OP_NONE, 18558 true, false, MY_PID, Process.SYSTEM_UID, 18559 userId); 18560 uss.initializing = true; 18561 } else { 18562 getUserManagerLocked().makeInitialized(userInfo.id); 18563 } 18564 } 18565 18566 if (foreground) { 18567 if (!uss.initializing) { 18568 moveUserToForeground(uss, oldUserId, userId); 18569 } 18570 } else { 18571 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18572 } 18573 18574 if (needStart) { 18575 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18576 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18577 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18578 broadcastIntentLocked(null, null, intent, 18579 null, new IIntentReceiver.Stub() { 18580 @Override 18581 public void performReceive(Intent intent, int resultCode, String data, 18582 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18583 throws RemoteException { 18584 } 18585 }, 0, null, null, 18586 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18587 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18588 } 18589 } 18590 } finally { 18591 Binder.restoreCallingIdentity(ident); 18592 } 18593 18594 return true; 18595 } 18596 18597 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18598 long ident = Binder.clearCallingIdentity(); 18599 try { 18600 Intent intent; 18601 if (oldUserId >= 0) { 18602 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18603 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18604 int count = profiles.size(); 18605 for (int i = 0; i < count; i++) { 18606 int profileUserId = profiles.get(i).id; 18607 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18608 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18609 | Intent.FLAG_RECEIVER_FOREGROUND); 18610 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18611 broadcastIntentLocked(null, null, intent, 18612 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18613 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18614 } 18615 } 18616 if (newUserId >= 0) { 18617 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18618 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18619 int count = profiles.size(); 18620 for (int i = 0; i < count; i++) { 18621 int profileUserId = profiles.get(i).id; 18622 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18623 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18624 | Intent.FLAG_RECEIVER_FOREGROUND); 18625 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18626 broadcastIntentLocked(null, null, intent, 18627 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18628 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18629 } 18630 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18631 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18632 | Intent.FLAG_RECEIVER_FOREGROUND); 18633 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18634 broadcastIntentLocked(null, null, intent, 18635 null, null, 0, null, null, 18636 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18637 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18638 } 18639 } finally { 18640 Binder.restoreCallingIdentity(ident); 18641 } 18642 } 18643 18644 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18645 final int newUserId) { 18646 final int N = mUserSwitchObservers.beginBroadcast(); 18647 if (N > 0) { 18648 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18649 int mCount = 0; 18650 @Override 18651 public void sendResult(Bundle data) throws RemoteException { 18652 synchronized (ActivityManagerService.this) { 18653 if (mCurUserSwitchCallback == this) { 18654 mCount++; 18655 if (mCount == N) { 18656 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18657 } 18658 } 18659 } 18660 } 18661 }; 18662 synchronized (this) { 18663 uss.switching = true; 18664 mCurUserSwitchCallback = callback; 18665 } 18666 for (int i=0; i<N; i++) { 18667 try { 18668 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18669 newUserId, callback); 18670 } catch (RemoteException e) { 18671 } 18672 } 18673 } else { 18674 synchronized (this) { 18675 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18676 } 18677 } 18678 mUserSwitchObservers.finishBroadcast(); 18679 } 18680 18681 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18682 synchronized (this) { 18683 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18684 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18685 } 18686 } 18687 18688 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18689 mCurUserSwitchCallback = null; 18690 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18691 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18692 oldUserId, newUserId, uss)); 18693 } 18694 18695 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18696 synchronized (this) { 18697 if (foreground) { 18698 moveUserToForeground(uss, oldUserId, newUserId); 18699 } 18700 } 18701 18702 completeSwitchAndInitalize(uss, newUserId, true, false); 18703 } 18704 18705 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18706 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18707 if (homeInFront) { 18708 startHomeActivityLocked(newUserId); 18709 } else { 18710 mStackSupervisor.resumeTopActivitiesLocked(); 18711 } 18712 EventLogTags.writeAmSwitchUser(newUserId); 18713 getUserManagerLocked().userForeground(newUserId); 18714 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18715 } 18716 18717 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18718 completeSwitchAndInitalize(uss, newUserId, false, true); 18719 } 18720 18721 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18722 boolean clearInitializing, boolean clearSwitching) { 18723 boolean unfrozen = false; 18724 synchronized (this) { 18725 if (clearInitializing) { 18726 uss.initializing = false; 18727 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18728 } 18729 if (clearSwitching) { 18730 uss.switching = false; 18731 } 18732 if (!uss.switching && !uss.initializing) { 18733 mWindowManager.stopFreezingScreen(); 18734 unfrozen = true; 18735 } 18736 } 18737 if (unfrozen) { 18738 final int N = mUserSwitchObservers.beginBroadcast(); 18739 for (int i=0; i<N; i++) { 18740 try { 18741 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18742 } catch (RemoteException e) { 18743 } 18744 } 18745 mUserSwitchObservers.finishBroadcast(); 18746 } 18747 } 18748 18749 void scheduleStartProfilesLocked() { 18750 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18751 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18752 DateUtils.SECOND_IN_MILLIS); 18753 } 18754 } 18755 18756 void startProfilesLocked() { 18757 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18758 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18759 mCurrentUserId, false /* enabledOnly */); 18760 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18761 for (UserInfo user : profiles) { 18762 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18763 && user.id != mCurrentUserId) { 18764 toStart.add(user); 18765 } 18766 } 18767 final int n = toStart.size(); 18768 int i = 0; 18769 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18770 startUserInBackground(toStart.get(i).id); 18771 } 18772 if (i < n) { 18773 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18774 } 18775 } 18776 18777 void finishUserBoot(UserStartedState uss) { 18778 synchronized (this) { 18779 if (uss.mState == UserStartedState.STATE_BOOTING 18780 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18781 uss.mState = UserStartedState.STATE_RUNNING; 18782 final int userId = uss.mHandle.getIdentifier(); 18783 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18784 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18785 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18786 broadcastIntentLocked(null, null, intent, 18787 null, null, 0, null, null, 18788 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18789 true, false, MY_PID, Process.SYSTEM_UID, userId); 18790 } 18791 } 18792 } 18793 18794 void finishUserSwitch(UserStartedState uss) { 18795 synchronized (this) { 18796 finishUserBoot(uss); 18797 18798 startProfilesLocked(); 18799 18800 int num = mUserLru.size(); 18801 int i = 0; 18802 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18803 Integer oldUserId = mUserLru.get(i); 18804 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18805 if (oldUss == null) { 18806 // Shouldn't happen, but be sane if it does. 18807 mUserLru.remove(i); 18808 num--; 18809 continue; 18810 } 18811 if (oldUss.mState == UserStartedState.STATE_STOPPING 18812 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18813 // This user is already stopping, doesn't count. 18814 num--; 18815 i++; 18816 continue; 18817 } 18818 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18819 // Owner and current can't be stopped, but count as running. 18820 i++; 18821 continue; 18822 } 18823 // This is a user to be stopped. 18824 stopUserLocked(oldUserId, null); 18825 num--; 18826 i++; 18827 } 18828 } 18829 } 18830 18831 @Override 18832 public int stopUser(final int userId, final IStopUserCallback callback) { 18833 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18834 != PackageManager.PERMISSION_GRANTED) { 18835 String msg = "Permission Denial: switchUser() from pid=" 18836 + Binder.getCallingPid() 18837 + ", uid=" + Binder.getCallingUid() 18838 + " requires " + INTERACT_ACROSS_USERS_FULL; 18839 Slog.w(TAG, msg); 18840 throw new SecurityException(msg); 18841 } 18842 if (userId <= 0) { 18843 throw new IllegalArgumentException("Can't stop primary user " + userId); 18844 } 18845 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18846 synchronized (this) { 18847 return stopUserLocked(userId, callback); 18848 } 18849 } 18850 18851 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18852 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18853 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18854 return ActivityManager.USER_OP_IS_CURRENT; 18855 } 18856 18857 final UserStartedState uss = mStartedUsers.get(userId); 18858 if (uss == null) { 18859 // User is not started, nothing to do... but we do need to 18860 // callback if requested. 18861 if (callback != null) { 18862 mHandler.post(new Runnable() { 18863 @Override 18864 public void run() { 18865 try { 18866 callback.userStopped(userId); 18867 } catch (RemoteException e) { 18868 } 18869 } 18870 }); 18871 } 18872 return ActivityManager.USER_OP_SUCCESS; 18873 } 18874 18875 if (callback != null) { 18876 uss.mStopCallbacks.add(callback); 18877 } 18878 18879 if (uss.mState != UserStartedState.STATE_STOPPING 18880 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18881 uss.mState = UserStartedState.STATE_STOPPING; 18882 updateStartedUserArrayLocked(); 18883 18884 long ident = Binder.clearCallingIdentity(); 18885 try { 18886 // We are going to broadcast ACTION_USER_STOPPING and then 18887 // once that is done send a final ACTION_SHUTDOWN and then 18888 // stop the user. 18889 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18890 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18891 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18892 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18893 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18894 // This is the result receiver for the final shutdown broadcast. 18895 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18896 @Override 18897 public void performReceive(Intent intent, int resultCode, String data, 18898 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18899 finishUserStop(uss); 18900 } 18901 }; 18902 // This is the result receiver for the initial stopping broadcast. 18903 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18904 @Override 18905 public void performReceive(Intent intent, int resultCode, String data, 18906 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18907 // On to the next. 18908 synchronized (ActivityManagerService.this) { 18909 if (uss.mState != UserStartedState.STATE_STOPPING) { 18910 // Whoops, we are being started back up. Abort, abort! 18911 return; 18912 } 18913 uss.mState = UserStartedState.STATE_SHUTDOWN; 18914 } 18915 mBatteryStatsService.noteEvent( 18916 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18917 Integer.toString(userId), userId); 18918 mSystemServiceManager.stopUser(userId); 18919 broadcastIntentLocked(null, null, shutdownIntent, 18920 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18921 true, false, MY_PID, Process.SYSTEM_UID, userId); 18922 } 18923 }; 18924 // Kick things off. 18925 broadcastIntentLocked(null, null, stoppingIntent, 18926 null, stoppingReceiver, 0, null, null, 18927 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18928 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18929 } finally { 18930 Binder.restoreCallingIdentity(ident); 18931 } 18932 } 18933 18934 return ActivityManager.USER_OP_SUCCESS; 18935 } 18936 18937 void finishUserStop(UserStartedState uss) { 18938 final int userId = uss.mHandle.getIdentifier(); 18939 boolean stopped; 18940 ArrayList<IStopUserCallback> callbacks; 18941 synchronized (this) { 18942 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18943 if (mStartedUsers.get(userId) != uss) { 18944 stopped = false; 18945 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18946 stopped = false; 18947 } else { 18948 stopped = true; 18949 // User can no longer run. 18950 mStartedUsers.remove(userId); 18951 mUserLru.remove(Integer.valueOf(userId)); 18952 updateStartedUserArrayLocked(); 18953 18954 // Clean up all state and processes associated with the user. 18955 // Kill all the processes for the user. 18956 forceStopUserLocked(userId, "finish user"); 18957 } 18958 18959 // Explicitly remove the old information in mRecentTasks. 18960 removeRecentTasksForUserLocked(userId); 18961 } 18962 18963 for (int i=0; i<callbacks.size(); i++) { 18964 try { 18965 if (stopped) callbacks.get(i).userStopped(userId); 18966 else callbacks.get(i).userStopAborted(userId); 18967 } catch (RemoteException e) { 18968 } 18969 } 18970 18971 if (stopped) { 18972 mSystemServiceManager.cleanupUser(userId); 18973 synchronized (this) { 18974 mStackSupervisor.removeUserLocked(userId); 18975 } 18976 } 18977 } 18978 18979 @Override 18980 public UserInfo getCurrentUser() { 18981 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18982 != PackageManager.PERMISSION_GRANTED) && ( 18983 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18984 != PackageManager.PERMISSION_GRANTED)) { 18985 String msg = "Permission Denial: getCurrentUser() from pid=" 18986 + Binder.getCallingPid() 18987 + ", uid=" + Binder.getCallingUid() 18988 + " requires " + INTERACT_ACROSS_USERS; 18989 Slog.w(TAG, msg); 18990 throw new SecurityException(msg); 18991 } 18992 synchronized (this) { 18993 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18994 return getUserManagerLocked().getUserInfo(userId); 18995 } 18996 } 18997 18998 int getCurrentUserIdLocked() { 18999 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19000 } 19001 19002 @Override 19003 public boolean isUserRunning(int userId, boolean orStopped) { 19004 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19005 != PackageManager.PERMISSION_GRANTED) { 19006 String msg = "Permission Denial: isUserRunning() from pid=" 19007 + Binder.getCallingPid() 19008 + ", uid=" + Binder.getCallingUid() 19009 + " requires " + INTERACT_ACROSS_USERS; 19010 Slog.w(TAG, msg); 19011 throw new SecurityException(msg); 19012 } 19013 synchronized (this) { 19014 return isUserRunningLocked(userId, orStopped); 19015 } 19016 } 19017 19018 boolean isUserRunningLocked(int userId, boolean orStopped) { 19019 UserStartedState state = mStartedUsers.get(userId); 19020 if (state == null) { 19021 return false; 19022 } 19023 if (orStopped) { 19024 return true; 19025 } 19026 return state.mState != UserStartedState.STATE_STOPPING 19027 && state.mState != UserStartedState.STATE_SHUTDOWN; 19028 } 19029 19030 @Override 19031 public int[] getRunningUserIds() { 19032 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19033 != PackageManager.PERMISSION_GRANTED) { 19034 String msg = "Permission Denial: isUserRunning() from pid=" 19035 + Binder.getCallingPid() 19036 + ", uid=" + Binder.getCallingUid() 19037 + " requires " + INTERACT_ACROSS_USERS; 19038 Slog.w(TAG, msg); 19039 throw new SecurityException(msg); 19040 } 19041 synchronized (this) { 19042 return mStartedUserArray; 19043 } 19044 } 19045 19046 private void updateStartedUserArrayLocked() { 19047 int num = 0; 19048 for (int i=0; i<mStartedUsers.size(); i++) { 19049 UserStartedState uss = mStartedUsers.valueAt(i); 19050 // This list does not include stopping users. 19051 if (uss.mState != UserStartedState.STATE_STOPPING 19052 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19053 num++; 19054 } 19055 } 19056 mStartedUserArray = new int[num]; 19057 num = 0; 19058 for (int i=0; i<mStartedUsers.size(); i++) { 19059 UserStartedState uss = mStartedUsers.valueAt(i); 19060 if (uss.mState != UserStartedState.STATE_STOPPING 19061 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19062 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19063 num++; 19064 } 19065 } 19066 } 19067 19068 @Override 19069 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19070 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19071 != PackageManager.PERMISSION_GRANTED) { 19072 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19073 + Binder.getCallingPid() 19074 + ", uid=" + Binder.getCallingUid() 19075 + " requires " + INTERACT_ACROSS_USERS_FULL; 19076 Slog.w(TAG, msg); 19077 throw new SecurityException(msg); 19078 } 19079 19080 mUserSwitchObservers.register(observer); 19081 } 19082 19083 @Override 19084 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19085 mUserSwitchObservers.unregister(observer); 19086 } 19087 19088 private boolean userExists(int userId) { 19089 if (userId == 0) { 19090 return true; 19091 } 19092 UserManagerService ums = getUserManagerLocked(); 19093 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19094 } 19095 19096 int[] getUsersLocked() { 19097 UserManagerService ums = getUserManagerLocked(); 19098 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19099 } 19100 19101 UserManagerService getUserManagerLocked() { 19102 if (mUserManager == null) { 19103 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19104 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19105 } 19106 return mUserManager; 19107 } 19108 19109 private int applyUserId(int uid, int userId) { 19110 return UserHandle.getUid(userId, uid); 19111 } 19112 19113 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19114 if (info == null) return null; 19115 ApplicationInfo newInfo = new ApplicationInfo(info); 19116 newInfo.uid = applyUserId(info.uid, userId); 19117 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19118 + info.packageName; 19119 return newInfo; 19120 } 19121 19122 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19123 if (aInfo == null 19124 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19125 return aInfo; 19126 } 19127 19128 ActivityInfo info = new ActivityInfo(aInfo); 19129 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19130 return info; 19131 } 19132 19133 private final class LocalService extends ActivityManagerInternal { 19134 @Override 19135 public void goingToSleep() { 19136 ActivityManagerService.this.goingToSleep(); 19137 } 19138 19139 @Override 19140 public void wakingUp() { 19141 ActivityManagerService.this.wakingUp(); 19142 } 19143 19144 @Override 19145 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19146 String processName, String abiOverride, int uid, Runnable crashHandler) { 19147 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19148 processName, abiOverride, uid, crashHandler); 19149 } 19150 } 19151 19152 /** 19153 * An implementation of IAppTask, that allows an app to manage its own tasks via 19154 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19155 * only the process that calls getAppTasks() can call the AppTask methods. 19156 */ 19157 class AppTaskImpl extends IAppTask.Stub { 19158 private int mTaskId; 19159 private int mCallingUid; 19160 19161 public AppTaskImpl(int taskId, int callingUid) { 19162 mTaskId = taskId; 19163 mCallingUid = callingUid; 19164 } 19165 19166 private void checkCaller() { 19167 if (mCallingUid != Binder.getCallingUid()) { 19168 throw new SecurityException("Caller " + mCallingUid 19169 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19170 } 19171 } 19172 19173 @Override 19174 public void finishAndRemoveTask() { 19175 checkCaller(); 19176 19177 synchronized (ActivityManagerService.this) { 19178 long origId = Binder.clearCallingIdentity(); 19179 try { 19180 if (!removeTaskByIdLocked(mTaskId, false)) { 19181 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19182 } 19183 } finally { 19184 Binder.restoreCallingIdentity(origId); 19185 } 19186 } 19187 } 19188 19189 @Override 19190 public ActivityManager.RecentTaskInfo getTaskInfo() { 19191 checkCaller(); 19192 19193 synchronized (ActivityManagerService.this) { 19194 long origId = Binder.clearCallingIdentity(); 19195 try { 19196 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19197 if (tr == null) { 19198 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19199 } 19200 return createRecentTaskInfoFromTaskRecord(tr); 19201 } finally { 19202 Binder.restoreCallingIdentity(origId); 19203 } 19204 } 19205 } 19206 19207 @Override 19208 public void moveToFront() { 19209 checkCaller(); 19210 19211 final TaskRecord tr; 19212 synchronized (ActivityManagerService.this) { 19213 tr = recentTaskForIdLocked(mTaskId); 19214 if (tr == null) { 19215 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19216 } 19217 if (tr.getRootActivity() != null) { 19218 moveTaskToFrontLocked(tr.taskId, 0, null); 19219 return; 19220 } 19221 } 19222 19223 startActivityFromRecentsInner(tr.taskId, null); 19224 } 19225 19226 @Override 19227 public int startActivity(IBinder whoThread, String callingPackage, 19228 Intent intent, String resolvedType, Bundle options) { 19229 checkCaller(); 19230 19231 int callingUser = UserHandle.getCallingUserId(); 19232 TaskRecord tr; 19233 IApplicationThread appThread; 19234 synchronized (ActivityManagerService.this) { 19235 tr = recentTaskForIdLocked(mTaskId); 19236 if (tr == null) { 19237 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19238 } 19239 appThread = ApplicationThreadNative.asInterface(whoThread); 19240 if (appThread == null) { 19241 throw new IllegalArgumentException("Bad app thread " + appThread); 19242 } 19243 } 19244 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19245 resolvedType, null, null, null, null, 0, 0, null, null, 19246 null, options, callingUser, null, tr); 19247 } 19248 19249 @Override 19250 public void setExcludeFromRecents(boolean exclude) { 19251 checkCaller(); 19252 19253 synchronized (ActivityManagerService.this) { 19254 long origId = Binder.clearCallingIdentity(); 19255 try { 19256 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19257 if (tr == null) { 19258 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19259 } 19260 Intent intent = tr.getBaseIntent(); 19261 if (exclude) { 19262 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19263 } else { 19264 intent.setFlags(intent.getFlags() 19265 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19266 } 19267 } finally { 19268 Binder.restoreCallingIdentity(origId); 19269 } 19270 } 19271 } 19272 } 19273} 19274