ActivityManagerService.java revision bb742462781a73bb25516067c8fe6311c1c8a93e
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.content.pm.PackageManager.PERMISSION_GRANTED; 22import static com.android.internal.util.XmlUtils.readBooleanAttribute; 23import static com.android.internal.util.XmlUtils.readIntAttribute; 24import static com.android.internal.util.XmlUtils.readLongAttribute; 25import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 26import static com.android.internal.util.XmlUtils.writeIntAttribute; 27import static com.android.internal.util.XmlUtils.writeLongAttribute; 28import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 29import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 30import static org.xmlpull.v1.XmlPullParser.START_TAG; 31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 32 33import android.Manifest; 34import android.app.AppOpsManager; 35import android.app.IActivityContainer; 36import android.app.IActivityContainerCallback; 37import android.app.IAppTask; 38import android.app.admin.DevicePolicyManager; 39import android.appwidget.AppWidgetManager; 40import android.graphics.Rect; 41import android.os.BatteryStats; 42import android.os.PersistableBundle; 43import android.service.voice.IVoiceInteractionSession; 44import android.util.ArrayMap; 45import android.util.ArraySet; 46 47import android.util.SparseIntArray; 48import com.android.internal.R; 49import com.android.internal.annotations.GuardedBy; 50import com.android.internal.app.IAppOpsService; 51import com.android.internal.app.IVoiceInteractor; 52import com.android.internal.app.ProcessMap; 53import com.android.internal.app.ProcessStats; 54import com.android.internal.content.PackageMonitor; 55import com.android.internal.os.BackgroundThread; 56import com.android.internal.os.BatteryStatsImpl; 57import com.android.internal.os.ProcessCpuTracker; 58import com.android.internal.os.TransferPipe; 59import com.android.internal.os.Zygote; 60import com.android.internal.util.FastPrintWriter; 61import com.android.internal.util.FastXmlSerializer; 62import com.android.internal.util.MemInfoReader; 63import com.android.internal.util.Preconditions; 64import com.android.server.AppOpsService; 65import com.android.server.AttributeCache; 66import com.android.server.IntentResolver; 67import com.android.server.LocalServices; 68import com.android.server.ServiceThread; 69import com.android.server.SystemService; 70import com.android.server.SystemServiceManager; 71import com.android.server.Watchdog; 72import com.android.server.am.ActivityStack.ActivityState; 73import com.android.server.firewall.IntentFirewall; 74import com.android.server.pm.UserManagerService; 75import com.android.server.wm.AppTransition; 76import com.android.server.wm.WindowManagerService; 77import com.google.android.collect.Lists; 78import com.google.android.collect.Maps; 79 80import libcore.io.IoUtils; 81 82import org.xmlpull.v1.XmlPullParser; 83import org.xmlpull.v1.XmlPullParserException; 84import org.xmlpull.v1.XmlSerializer; 85 86import android.app.Activity; 87import android.app.ActivityManager; 88import android.app.ActivityManager.RunningTaskInfo; 89import android.app.ActivityManager.StackInfo; 90import android.app.ActivityManagerInternal; 91import android.app.ActivityManagerNative; 92import android.app.ActivityOptions; 93import android.app.ActivityThread; 94import android.app.AlertDialog; 95import android.app.AppGlobals; 96import android.app.ApplicationErrorReport; 97import android.app.Dialog; 98import android.app.IActivityController; 99import android.app.IApplicationThread; 100import android.app.IInstrumentationWatcher; 101import android.app.INotificationManager; 102import android.app.IProcessObserver; 103import android.app.IServiceConnection; 104import android.app.IStopUserCallback; 105import android.app.IUiAutomationConnection; 106import android.app.IUserSwitchObserver; 107import android.app.Instrumentation; 108import android.app.Notification; 109import android.app.NotificationManager; 110import android.app.PendingIntent; 111import android.app.backup.IBackupManager; 112import android.content.ActivityNotFoundException; 113import android.content.BroadcastReceiver; 114import android.content.ClipData; 115import android.content.ComponentCallbacks2; 116import android.content.ComponentName; 117import android.content.ContentProvider; 118import android.content.ContentResolver; 119import android.content.Context; 120import android.content.DialogInterface; 121import android.content.IContentProvider; 122import android.content.IIntentReceiver; 123import android.content.IIntentSender; 124import android.content.Intent; 125import android.content.IntentFilter; 126import android.content.IntentSender; 127import android.content.pm.ActivityInfo; 128import android.content.pm.ApplicationInfo; 129import android.content.pm.ConfigurationInfo; 130import android.content.pm.IPackageDataObserver; 131import android.content.pm.IPackageManager; 132import android.content.pm.InstrumentationInfo; 133import android.content.pm.PackageInfo; 134import android.content.pm.PackageManager; 135import android.content.pm.ParceledListSlice; 136import android.content.pm.UserInfo; 137import android.content.pm.PackageManager.NameNotFoundException; 138import android.content.pm.PathPermission; 139import android.content.pm.ProviderInfo; 140import android.content.pm.ResolveInfo; 141import android.content.pm.ServiceInfo; 142import android.content.res.CompatibilityInfo; 143import android.content.res.Configuration; 144import android.net.Proxy; 145import android.net.ProxyInfo; 146import android.net.Uri; 147import android.os.Binder; 148import android.os.Build; 149import android.os.Bundle; 150import android.os.Debug; 151import android.os.DropBoxManager; 152import android.os.Environment; 153import android.os.FactoryTest; 154import android.os.FileObserver; 155import android.os.FileUtils; 156import android.os.Handler; 157import android.os.IBinder; 158import android.os.IPermissionController; 159import android.os.IRemoteCallback; 160import android.os.IUserManager; 161import android.os.Looper; 162import android.os.Message; 163import android.os.Parcel; 164import android.os.ParcelFileDescriptor; 165import android.os.Process; 166import android.os.RemoteCallbackList; 167import android.os.RemoteException; 168import android.os.SELinux; 169import android.os.ServiceManager; 170import android.os.StrictMode; 171import android.os.SystemClock; 172import android.os.SystemProperties; 173import android.os.UpdateLock; 174import android.os.UserHandle; 175import android.provider.Settings; 176import android.text.format.DateUtils; 177import android.text.format.Time; 178import android.util.AtomicFile; 179import android.util.EventLog; 180import android.util.Log; 181import android.util.Pair; 182import android.util.PrintWriterPrinter; 183import android.util.Slog; 184import android.util.SparseArray; 185import android.util.TimeUtils; 186import android.util.Xml; 187import android.view.Gravity; 188import android.view.LayoutInflater; 189import android.view.View; 190import android.view.WindowManager; 191 192import java.io.BufferedInputStream; 193import java.io.BufferedOutputStream; 194import java.io.DataInputStream; 195import java.io.DataOutputStream; 196import java.io.File; 197import java.io.FileDescriptor; 198import java.io.FileInputStream; 199import java.io.FileNotFoundException; 200import java.io.FileOutputStream; 201import java.io.IOException; 202import java.io.InputStreamReader; 203import java.io.PrintWriter; 204import java.io.StringWriter; 205import java.lang.ref.WeakReference; 206import java.util.ArrayList; 207import java.util.Arrays; 208import java.util.Collections; 209import java.util.Comparator; 210import java.util.HashMap; 211import java.util.HashSet; 212import java.util.Iterator; 213import java.util.List; 214import java.util.Locale; 215import java.util.Map; 216import java.util.Set; 217import java.util.concurrent.atomic.AtomicBoolean; 218import java.util.concurrent.atomic.AtomicLong; 219 220public final class ActivityManagerService extends ActivityManagerNative 221 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 222 private static final String USER_DATA_DIR = "/data/user/"; 223 static final String TAG = "ActivityManager"; 224 static final String TAG_MU = "ActivityManagerServiceMU"; 225 static final boolean DEBUG = false; 226 static final boolean localLOGV = DEBUG; 227 static final boolean DEBUG_BACKUP = localLOGV || false; 228 static final boolean DEBUG_BROADCAST = localLOGV || false; 229 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 230 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 231 static final boolean DEBUG_CLEANUP = localLOGV || false; 232 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 233 static final boolean DEBUG_FOCUS = false; 234 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 235 static final boolean DEBUG_MU = localLOGV || false; 236 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 237 static final boolean DEBUG_LRU = localLOGV || false; 238 static final boolean DEBUG_PAUSE = localLOGV || false; 239 static final boolean DEBUG_POWER = localLOGV || false; 240 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 241 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 242 static final boolean DEBUG_PROCESSES = localLOGV || false; 243 static final boolean DEBUG_PROVIDER = localLOGV || false; 244 static final boolean DEBUG_RESULTS = localLOGV || false; 245 static final boolean DEBUG_SERVICE = localLOGV || false; 246 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 247 static final boolean DEBUG_STACK = localLOGV || false; 248 static final boolean DEBUG_SWITCH = localLOGV || false; 249 static final boolean DEBUG_TASKS = localLOGV || false; 250 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 251 static final boolean DEBUG_TRANSITION = localLOGV || false; 252 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 253 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 254 static final boolean DEBUG_VISBILITY = localLOGV || false; 255 static final boolean DEBUG_PSS = localLOGV || false; 256 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 257 static final boolean VALIDATE_TOKENS = false; 258 static final boolean SHOW_ACTIVITY_START_TIME = true; 259 260 // Control over CPU and battery monitoring. 261 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 262 static final boolean MONITOR_CPU_USAGE = true; 263 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 264 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 265 static final boolean MONITOR_THREAD_CPU_USAGE = false; 266 267 // The flags that are set for all calls we make to the package manager. 268 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 269 270 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 271 272 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 273 274 // Maximum number of recent tasks that we can remember. 275 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 276 277 // Maximum number recent bitmaps to keep in memory. 278 static final int MAX_RECENT_BITMAPS = 5; 279 280 // Amount of time after a call to stopAppSwitches() during which we will 281 // prevent further untrusted switches from happening. 282 static final long APP_SWITCH_DELAY_TIME = 5*1000; 283 284 // How long we wait for a launched process to attach to the activity manager 285 // before we decide it's never going to come up for real. 286 static final int PROC_START_TIMEOUT = 10*1000; 287 288 // How long we wait for a launched process to attach to the activity manager 289 // before we decide it's never going to come up for real, when the process was 290 // started with a wrapper for instrumentation (such as Valgrind) because it 291 // could take much longer than usual. 292 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 293 294 // How long to wait after going idle before forcing apps to GC. 295 static final int GC_TIMEOUT = 5*1000; 296 297 // The minimum amount of time between successive GC requests for a process. 298 static final int GC_MIN_INTERVAL = 60*1000; 299 300 // The minimum amount of time between successive PSS requests for a process. 301 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 302 303 // The minimum amount of time between successive PSS requests for a process 304 // when the request is due to the memory state being lowered. 305 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 306 307 // The rate at which we check for apps using excessive power -- 15 mins. 308 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 309 310 // The minimum sample duration we will allow before deciding we have 311 // enough data on wake locks to start killing things. 312 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 313 314 // The minimum sample duration we will allow before deciding we have 315 // enough data on CPU usage to start killing things. 316 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 317 318 // How long we allow a receiver to run before giving up on it. 319 static final int BROADCAST_FG_TIMEOUT = 10*1000; 320 static final int BROADCAST_BG_TIMEOUT = 60*1000; 321 322 // How long we wait until we timeout on key dispatching. 323 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 324 325 // How long we wait until we timeout on key dispatching during instrumentation. 326 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 327 328 // Amount of time we wait for observers to handle a user switch before 329 // giving up on them and unfreezing the screen. 330 static final int USER_SWITCH_TIMEOUT = 2*1000; 331 332 // Maximum number of users we allow to be running at a time. 333 static final int MAX_RUNNING_USERS = 3; 334 335 // How long to wait in getAssistContextExtras for the activity and foreground services 336 // to respond with the result. 337 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 338 339 // Maximum number of persisted Uri grants a package is allowed 340 static final int MAX_PERSISTED_URI_GRANTS = 128; 341 342 static final int MY_PID = Process.myPid(); 343 344 static final String[] EMPTY_STRING_ARRAY = new String[0]; 345 346 // How many bytes to write into the dropbox log before truncating 347 static final int DROPBOX_MAX_SIZE = 256 * 1024; 348 349 // Access modes for handleIncomingUser. 350 static final int ALLOW_NON_FULL = 0; 351 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 352 static final int ALLOW_FULL_ONLY = 2; 353 354 /** All system services */ 355 SystemServiceManager mSystemServiceManager; 356 357 /** Run all ActivityStacks through this */ 358 ActivityStackSupervisor mStackSupervisor; 359 360 public IntentFirewall mIntentFirewall; 361 362 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 363 // default actuion automatically. Important for devices without direct input 364 // devices. 365 private boolean mShowDialogs = true; 366 367 /** 368 * Description of a request to start a new activity, which has been held 369 * due to app switches being disabled. 370 */ 371 static class PendingActivityLaunch { 372 final ActivityRecord r; 373 final ActivityRecord sourceRecord; 374 final int startFlags; 375 final ActivityStack stack; 376 377 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 378 int _startFlags, ActivityStack _stack) { 379 r = _r; 380 sourceRecord = _sourceRecord; 381 startFlags = _startFlags; 382 stack = _stack; 383 } 384 } 385 386 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 387 = new ArrayList<PendingActivityLaunch>(); 388 389 BroadcastQueue mFgBroadcastQueue; 390 BroadcastQueue mBgBroadcastQueue; 391 // Convenient for easy iteration over the queues. Foreground is first 392 // so that dispatch of foreground broadcasts gets precedence. 393 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 394 395 BroadcastQueue broadcastQueueForIntent(Intent intent) { 396 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 397 if (DEBUG_BACKGROUND_BROADCAST) { 398 Slog.i(TAG, "Broadcast intent " + intent + " on " 399 + (isFg ? "foreground" : "background") 400 + " queue"); 401 } 402 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 403 } 404 405 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 406 for (BroadcastQueue queue : mBroadcastQueues) { 407 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 408 if (r != null) { 409 return r; 410 } 411 } 412 return null; 413 } 414 415 /** 416 * Activity we have told the window manager to have key focus. 417 */ 418 ActivityRecord mFocusedActivity = null; 419 420 /** 421 * List of intents that were used to start the most recent tasks. 422 */ 423 ArrayList<TaskRecord> mRecentTasks; 424 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 425 426 public class PendingAssistExtras extends Binder implements Runnable { 427 public final ActivityRecord activity; 428 public boolean haveResult = false; 429 public Bundle result = null; 430 public PendingAssistExtras(ActivityRecord _activity) { 431 activity = _activity; 432 } 433 @Override 434 public void run() { 435 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 436 synchronized (this) { 437 haveResult = true; 438 notifyAll(); 439 } 440 } 441 } 442 443 final ArrayList<PendingAssistExtras> mPendingAssistExtras 444 = new ArrayList<PendingAssistExtras>(); 445 446 /** 447 * Process management. 448 */ 449 final ProcessList mProcessList = new ProcessList(); 450 451 /** 452 * All of the applications we currently have running organized by name. 453 * The keys are strings of the application package name (as 454 * returned by the package manager), and the keys are ApplicationRecord 455 * objects. 456 */ 457 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 458 459 /** 460 * Tracking long-term execution of processes to look for abuse and other 461 * bad app behavior. 462 */ 463 final ProcessStatsService mProcessStats; 464 465 /** 466 * The currently running isolated processes. 467 */ 468 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 469 470 /** 471 * Counter for assigning isolated process uids, to avoid frequently reusing the 472 * same ones. 473 */ 474 int mNextIsolatedProcessUid = 0; 475 476 /** 477 * The currently running heavy-weight process, if any. 478 */ 479 ProcessRecord mHeavyWeightProcess = null; 480 481 /** 482 * The last time that various processes have crashed. 483 */ 484 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 485 486 /** 487 * Information about a process that is currently marked as bad. 488 */ 489 static final class BadProcessInfo { 490 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 491 this.time = time; 492 this.shortMsg = shortMsg; 493 this.longMsg = longMsg; 494 this.stack = stack; 495 } 496 497 final long time; 498 final String shortMsg; 499 final String longMsg; 500 final String stack; 501 } 502 503 /** 504 * Set of applications that we consider to be bad, and will reject 505 * incoming broadcasts from (which the user has no control over). 506 * Processes are added to this set when they have crashed twice within 507 * a minimum amount of time; they are removed from it when they are 508 * later restarted (hopefully due to some user action). The value is the 509 * time it was added to the list. 510 */ 511 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 512 513 /** 514 * All of the processes we currently have running organized by pid. 515 * The keys are the pid running the application. 516 * 517 * <p>NOTE: This object is protected by its own lock, NOT the global 518 * activity manager lock! 519 */ 520 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 521 522 /** 523 * All of the processes that have been forced to be foreground. The key 524 * is the pid of the caller who requested it (we hold a death 525 * link on it). 526 */ 527 abstract class ForegroundToken implements IBinder.DeathRecipient { 528 int pid; 529 IBinder token; 530 } 531 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 532 533 /** 534 * List of records for processes that someone had tried to start before the 535 * system was ready. We don't start them at that point, but ensure they 536 * are started by the time booting is complete. 537 */ 538 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 539 540 /** 541 * List of persistent applications that are in the process 542 * of being started. 543 */ 544 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Processes that are being forcibly torn down. 548 */ 549 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * List of running applications, sorted by recent usage. 553 * The first entry in the list is the least recently used. 554 */ 555 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * Where in mLruProcesses that the processes hosting activities start. 559 */ 560 int mLruProcessActivityStart = 0; 561 562 /** 563 * Where in mLruProcesses that the processes hosting services start. 564 * This is after (lower index) than mLruProcessesActivityStart. 565 */ 566 int mLruProcessServiceStart = 0; 567 568 /** 569 * List of processes that should gc as soon as things are idle. 570 */ 571 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 572 573 /** 574 * Processes we want to collect PSS data from. 575 */ 576 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Last time we requested PSS data of all processes. 580 */ 581 long mLastFullPssTime = SystemClock.uptimeMillis(); 582 583 /** 584 * If set, the next time we collect PSS data we should do a full collection 585 * with data from native processes and the kernel. 586 */ 587 boolean mFullPssPending = false; 588 589 /** 590 * This is the process holding what we currently consider to be 591 * the "home" activity. 592 */ 593 ProcessRecord mHomeProcess; 594 595 /** 596 * This is the process holding the activity the user last visited that 597 * is in a different process from the one they are currently in. 598 */ 599 ProcessRecord mPreviousProcess; 600 601 /** 602 * The time at which the previous process was last visible. 603 */ 604 long mPreviousProcessVisibleTime; 605 606 /** 607 * Which uses have been started, so are allowed to run code. 608 */ 609 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 610 611 /** 612 * LRU list of history of current users. Most recently current is at the end. 613 */ 614 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 615 616 /** 617 * Constant array of the users that are currently started. 618 */ 619 int[] mStartedUserArray = new int[] { 0 }; 620 621 /** 622 * Registered observers of the user switching mechanics. 623 */ 624 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 625 = new RemoteCallbackList<IUserSwitchObserver>(); 626 627 /** 628 * Currently active user switch. 629 */ 630 Object mCurUserSwitchCallback; 631 632 /** 633 * Packages that the user has asked to have run in screen size 634 * compatibility mode instead of filling the screen. 635 */ 636 final CompatModePackages mCompatModePackages; 637 638 /** 639 * Set of IntentSenderRecord objects that are currently active. 640 */ 641 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 642 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 643 644 /** 645 * Fingerprints (hashCode()) of stack traces that we've 646 * already logged DropBox entries for. Guarded by itself. If 647 * something (rogue user app) forces this over 648 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 649 */ 650 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 651 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 652 653 /** 654 * Strict Mode background batched logging state. 655 * 656 * The string buffer is guarded by itself, and its lock is also 657 * used to determine if another batched write is already 658 * in-flight. 659 */ 660 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 661 662 /** 663 * Keeps track of all IIntentReceivers that have been registered for 664 * broadcasts. Hash keys are the receiver IBinder, hash value is 665 * a ReceiverList. 666 */ 667 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 668 new HashMap<IBinder, ReceiverList>(); 669 670 /** 671 * Resolver for broadcast intents to registered receivers. 672 * Holds BroadcastFilter (subclass of IntentFilter). 673 */ 674 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 675 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 676 @Override 677 protected boolean allowFilterResult( 678 BroadcastFilter filter, List<BroadcastFilter> dest) { 679 IBinder target = filter.receiverList.receiver.asBinder(); 680 for (int i=dest.size()-1; i>=0; i--) { 681 if (dest.get(i).receiverList.receiver.asBinder() == target) { 682 return false; 683 } 684 } 685 return true; 686 } 687 688 @Override 689 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 690 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 691 || userId == filter.owningUserId) { 692 return super.newResult(filter, match, userId); 693 } 694 return null; 695 } 696 697 @Override 698 protected BroadcastFilter[] newArray(int size) { 699 return new BroadcastFilter[size]; 700 } 701 702 @Override 703 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 704 return packageName.equals(filter.packageName); 705 } 706 }; 707 708 /** 709 * State of all active sticky broadcasts per user. Keys are the action of the 710 * sticky Intent, values are an ArrayList of all broadcasted intents with 711 * that action (which should usually be one). The SparseArray is keyed 712 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 713 * for stickies that are sent to all users. 714 */ 715 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 716 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 717 718 final ActiveServices mServices; 719 720 /** 721 * Backup/restore process management 722 */ 723 String mBackupAppName = null; 724 BackupRecord mBackupTarget = null; 725 726 final ProviderMap mProviderMap; 727 728 /** 729 * List of content providers who have clients waiting for them. The 730 * application is currently being launched and the provider will be 731 * removed from this list once it is published. 732 */ 733 final ArrayList<ContentProviderRecord> mLaunchingProviders 734 = new ArrayList<ContentProviderRecord>(); 735 736 /** 737 * File storing persisted {@link #mGrantedUriPermissions}. 738 */ 739 private final AtomicFile mGrantFile; 740 741 /** XML constants used in {@link #mGrantFile} */ 742 private static final String TAG_URI_GRANTS = "uri-grants"; 743 private static final String TAG_URI_GRANT = "uri-grant"; 744 private static final String ATTR_USER_HANDLE = "userHandle"; 745 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 746 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 747 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 748 private static final String ATTR_TARGET_PKG = "targetPkg"; 749 private static final String ATTR_URI = "uri"; 750 private static final String ATTR_MODE_FLAGS = "modeFlags"; 751 private static final String ATTR_CREATED_TIME = "createdTime"; 752 private static final String ATTR_PREFIX = "prefix"; 753 754 /** 755 * Global set of specific {@link Uri} permissions that have been granted. 756 * This optimized lookup structure maps from {@link UriPermission#targetUid} 757 * to {@link UriPermission#uri} to {@link UriPermission}. 758 */ 759 @GuardedBy("this") 760 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 761 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 762 763 public static class GrantUri { 764 public final int sourceUserId; 765 public final Uri uri; 766 public boolean prefix; 767 768 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 769 this.sourceUserId = sourceUserId; 770 this.uri = uri; 771 this.prefix = prefix; 772 } 773 774 @Override 775 public int hashCode() { 776 return toString().hashCode(); 777 } 778 779 @Override 780 public boolean equals(Object o) { 781 if (o instanceof GrantUri) { 782 GrantUri other = (GrantUri) o; 783 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 784 && prefix == other.prefix; 785 } 786 return false; 787 } 788 789 @Override 790 public String toString() { 791 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 792 if (prefix) result += " [prefix]"; 793 return result; 794 } 795 796 public String toSafeString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 803 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 804 ContentProvider.getUriWithoutUserId(uri), false); 805 } 806 } 807 808 CoreSettingsObserver mCoreSettingsObserver; 809 810 /** 811 * Thread-local storage used to carry caller permissions over through 812 * indirect content-provider access. 813 */ 814 private class Identity { 815 public int pid; 816 public int uid; 817 818 Identity(int _pid, int _uid) { 819 pid = _pid; 820 uid = _uid; 821 } 822 } 823 824 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 825 826 /** 827 * All information we have collected about the runtime performance of 828 * any user id that can impact battery performance. 829 */ 830 final BatteryStatsService mBatteryStatsService; 831 832 /** 833 * Information about component usage 834 */ 835 final UsageStatsService mUsageStatsService; 836 837 /** 838 * Information about and control over application operations 839 */ 840 final AppOpsService mAppOpsService; 841 842 /** 843 * Save recent tasks information across reboots. 844 */ 845 final TaskPersister mTaskPersister; 846 847 /** 848 * Current configuration information. HistoryRecord objects are given 849 * a reference to this object to indicate which configuration they are 850 * currently running in, so this object must be kept immutable. 851 */ 852 Configuration mConfiguration = new Configuration(); 853 854 /** 855 * Current sequencing integer of the configuration, for skipping old 856 * configurations. 857 */ 858 int mConfigurationSeq = 0; 859 860 /** 861 * Hardware-reported OpenGLES version. 862 */ 863 final int GL_ES_VERSION; 864 865 /** 866 * List of initialization arguments to pass to all processes when binding applications to them. 867 * For example, references to the commonly used services. 868 */ 869 HashMap<String, IBinder> mAppBindArgs; 870 871 /** 872 * Temporary to avoid allocations. Protected by main lock. 873 */ 874 final StringBuilder mStringBuilder = new StringBuilder(256); 875 876 /** 877 * Used to control how we initialize the service. 878 */ 879 ComponentName mTopComponent; 880 String mTopAction = Intent.ACTION_MAIN; 881 String mTopData; 882 boolean mProcessesReady = false; 883 boolean mSystemReady = false; 884 boolean mBooting = false; 885 boolean mWaitingUpdate = false; 886 boolean mDidUpdate = false; 887 boolean mOnBattery = false; 888 boolean mLaunchWarningShown = false; 889 890 Context mContext; 891 892 int mFactoryTest; 893 894 boolean mCheckedForSetup; 895 896 /** 897 * The time at which we will allow normal application switches again, 898 * after a call to {@link #stopAppSwitches()}. 899 */ 900 long mAppSwitchesAllowedTime; 901 902 /** 903 * This is set to true after the first switch after mAppSwitchesAllowedTime 904 * is set; any switches after that will clear the time. 905 */ 906 boolean mDidAppSwitch; 907 908 /** 909 * Last time (in realtime) at which we checked for power usage. 910 */ 911 long mLastPowerCheckRealtime; 912 913 /** 914 * Last time (in uptime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckUptime; 917 918 /** 919 * Set while we are wanting to sleep, to prevent any 920 * activities from being started/resumed. 921 */ 922 private boolean mSleeping = false; 923 924 /** 925 * Set while we are running a voice interaction. This overrides 926 * sleeping while it is active. 927 */ 928 private boolean mRunningVoice = false; 929 930 /** 931 * State of external calls telling us if the device is asleep. 932 */ 933 private boolean mWentToSleep = false; 934 935 /** 936 * State of external call telling us if the lock screen is shown. 937 */ 938 private boolean mLockScreenShown = false; 939 940 /** 941 * Set if we are shutting down the system, similar to sleeping. 942 */ 943 boolean mShuttingDown = false; 944 945 /** 946 * Current sequence id for oom_adj computation traversal. 947 */ 948 int mAdjSeq = 0; 949 950 /** 951 * Current sequence id for process LRU updating. 952 */ 953 int mLruSeq = 0; 954 955 /** 956 * Keep track of the non-cached/empty process we last found, to help 957 * determine how to distribute cached/empty processes next time. 958 */ 959 int mNumNonCachedProcs = 0; 960 961 /** 962 * Keep track of the number of cached hidden procs, to balance oom adj 963 * distribution between those and empty procs. 964 */ 965 int mNumCachedHiddenProcs = 0; 966 967 /** 968 * Keep track of the number of service processes we last found, to 969 * determine on the next iteration which should be B services. 970 */ 971 int mNumServiceProcs = 0; 972 int mNewNumAServiceProcs = 0; 973 int mNewNumServiceProcs = 0; 974 975 /** 976 * Allow the current computed overall memory level of the system to go down? 977 * This is set to false when we are killing processes for reasons other than 978 * memory management, so that the now smaller process list will not be taken as 979 * an indication that memory is tighter. 980 */ 981 boolean mAllowLowerMemLevel = false; 982 983 /** 984 * The last computed memory level, for holding when we are in a state that 985 * processes are going away for other reasons. 986 */ 987 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 988 989 /** 990 * The last total number of process we have, to determine if changes actually look 991 * like a shrinking number of process due to lower RAM. 992 */ 993 int mLastNumProcesses; 994 995 /** 996 * The uptime of the last time we performed idle maintenance. 997 */ 998 long mLastIdleTime = SystemClock.uptimeMillis(); 999 1000 /** 1001 * Total time spent with RAM that has been added in the past since the last idle time. 1002 */ 1003 long mLowRamTimeSinceLastIdle = 0; 1004 1005 /** 1006 * If RAM is currently low, when that horrible situation started. 1007 */ 1008 long mLowRamStartTime = 0; 1009 1010 /** 1011 * For reporting to battery stats the current top application. 1012 */ 1013 private String mCurResumedPackage = null; 1014 private int mCurResumedUid = -1; 1015 1016 /** 1017 * For reporting to battery stats the apps currently running foreground 1018 * service. The ProcessMap is package/uid tuples; each of these contain 1019 * an array of the currently foreground processes. 1020 */ 1021 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1022 = new ProcessMap<ArrayList<ProcessRecord>>(); 1023 1024 /** 1025 * This is set if we had to do a delayed dexopt of an app before launching 1026 * it, to increase the ANR timeouts in that case. 1027 */ 1028 boolean mDidDexOpt; 1029 1030 /** 1031 * Set if the systemServer made a call to enterSafeMode. 1032 */ 1033 boolean mSafeMode; 1034 1035 String mDebugApp = null; 1036 boolean mWaitForDebugger = false; 1037 boolean mDebugTransient = false; 1038 String mOrigDebugApp = null; 1039 boolean mOrigWaitForDebugger = false; 1040 boolean mAlwaysFinishActivities = false; 1041 IActivityController mController = null; 1042 String mProfileApp = null; 1043 ProcessRecord mProfileProc = null; 1044 String mProfileFile; 1045 ParcelFileDescriptor mProfileFd; 1046 int mProfileType = 0; 1047 boolean mAutoStopProfiler = false; 1048 String mOpenGlTraceApp = null; 1049 1050 static class ProcessChangeItem { 1051 static final int CHANGE_ACTIVITIES = 1<<0; 1052 static final int CHANGE_PROCESS_STATE = 1<<1; 1053 int changes; 1054 int uid; 1055 int pid; 1056 int processState; 1057 boolean foregroundActivities; 1058 } 1059 1060 final RemoteCallbackList<IProcessObserver> mProcessObservers 1061 = new RemoteCallbackList<IProcessObserver>(); 1062 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1063 1064 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1065 = new ArrayList<ProcessChangeItem>(); 1066 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1067 = new ArrayList<ProcessChangeItem>(); 1068 1069 /** 1070 * Runtime CPU use collection thread. This object's lock is used to 1071 * protect all related state. 1072 */ 1073 final Thread mProcessCpuThread; 1074 1075 /** 1076 * Used to collect process stats when showing not responding dialog. 1077 * Protected by mProcessCpuThread. 1078 */ 1079 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1080 MONITOR_THREAD_CPU_USAGE); 1081 final AtomicLong mLastCpuTime = new AtomicLong(0); 1082 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1083 1084 long mLastWriteTime = 0; 1085 1086 /** 1087 * Used to retain an update lock when the foreground activity is in 1088 * immersive mode. 1089 */ 1090 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1091 1092 /** 1093 * Set to true after the system has finished booting. 1094 */ 1095 boolean mBooted = false; 1096 1097 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1098 int mProcessLimitOverride = -1; 1099 1100 WindowManagerService mWindowManager; 1101 1102 final ActivityThread mSystemThread; 1103 1104 int mCurrentUserId = 0; 1105 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1106 1107 /** 1108 * Mapping from each known user ID to the profile group ID it is associated with. 1109 */ 1110 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1111 1112 private UserManagerService mUserManager; 1113 1114 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1115 final ProcessRecord mApp; 1116 final int mPid; 1117 final IApplicationThread mAppThread; 1118 1119 AppDeathRecipient(ProcessRecord app, int pid, 1120 IApplicationThread thread) { 1121 if (localLOGV) Slog.v( 1122 TAG, "New death recipient " + this 1123 + " for thread " + thread.asBinder()); 1124 mApp = app; 1125 mPid = pid; 1126 mAppThread = thread; 1127 } 1128 1129 @Override 1130 public void binderDied() { 1131 if (localLOGV) Slog.v( 1132 TAG, "Death received in " + this 1133 + " for thread " + mAppThread.asBinder()); 1134 synchronized(ActivityManagerService.this) { 1135 appDiedLocked(mApp, mPid, mAppThread); 1136 } 1137 } 1138 } 1139 1140 static final int SHOW_ERROR_MSG = 1; 1141 static final int SHOW_NOT_RESPONDING_MSG = 2; 1142 static final int SHOW_FACTORY_ERROR_MSG = 3; 1143 static final int UPDATE_CONFIGURATION_MSG = 4; 1144 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1145 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1146 static final int SERVICE_TIMEOUT_MSG = 12; 1147 static final int UPDATE_TIME_ZONE = 13; 1148 static final int SHOW_UID_ERROR_MSG = 14; 1149 static final int IM_FEELING_LUCKY_MSG = 15; 1150 static final int PROC_START_TIMEOUT_MSG = 20; 1151 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1152 static final int KILL_APPLICATION_MSG = 22; 1153 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1154 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1155 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1156 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1157 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1158 static final int CLEAR_DNS_CACHE_MSG = 28; 1159 static final int UPDATE_HTTP_PROXY_MSG = 29; 1160 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1161 static final int DISPATCH_PROCESSES_CHANGED = 31; 1162 static final int DISPATCH_PROCESS_DIED = 32; 1163 static final int REPORT_MEM_USAGE_MSG = 33; 1164 static final int REPORT_USER_SWITCH_MSG = 34; 1165 static final int CONTINUE_USER_SWITCH_MSG = 35; 1166 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1167 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1168 static final int PERSIST_URI_GRANTS_MSG = 38; 1169 static final int REQUEST_ALL_PSS_MSG = 39; 1170 static final int START_PROFILES_MSG = 40; 1171 static final int UPDATE_TIME = 41; 1172 static final int SYSTEM_USER_START_MSG = 42; 1173 static final int SYSTEM_USER_CURRENT_MSG = 43; 1174 1175 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1176 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1177 static final int FIRST_COMPAT_MODE_MSG = 300; 1178 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1179 1180 AlertDialog mUidAlert; 1181 CompatModeDialog mCompatModeDialog; 1182 long mLastMemUsageReportTime = 0; 1183 1184 private LockToAppRequestDialog mLockToAppRequest; 1185 1186 /** 1187 * Flag whether the current user is a "monkey", i.e. whether 1188 * the UI is driven by a UI automation tool. 1189 */ 1190 private boolean mUserIsMonkey; 1191 1192 /** Flag whether the device has a recents UI */ 1193 final boolean mHasRecents; 1194 1195 final ServiceThread mHandlerThread; 1196 final MainHandler mHandler; 1197 1198 final class MainHandler extends Handler { 1199 public MainHandler(Looper looper) { 1200 super(looper, null, true); 1201 } 1202 1203 @Override 1204 public void handleMessage(Message msg) { 1205 switch (msg.what) { 1206 case SHOW_ERROR_MSG: { 1207 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1208 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1209 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1210 synchronized (ActivityManagerService.this) { 1211 ProcessRecord proc = (ProcessRecord)data.get("app"); 1212 AppErrorResult res = (AppErrorResult) data.get("result"); 1213 if (proc != null && proc.crashDialog != null) { 1214 Slog.e(TAG, "App already has crash dialog: " + proc); 1215 if (res != null) { 1216 res.set(0); 1217 } 1218 return; 1219 } 1220 if (!showBackground && UserHandle.getAppId(proc.uid) 1221 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1222 && proc.pid != MY_PID) { 1223 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1224 if (res != null) { 1225 res.set(0); 1226 } 1227 return; 1228 } 1229 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1230 Dialog d = new AppErrorDialog(mContext, 1231 ActivityManagerService.this, res, proc); 1232 d.show(); 1233 proc.crashDialog = d; 1234 } else { 1235 // The device is asleep, so just pretend that the user 1236 // saw a crash dialog and hit "force quit". 1237 if (res != null) { 1238 res.set(0); 1239 } 1240 } 1241 } 1242 1243 ensureBootCompleted(); 1244 } break; 1245 case SHOW_NOT_RESPONDING_MSG: { 1246 synchronized (ActivityManagerService.this) { 1247 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 if (proc != null && proc.anrDialog != null) { 1250 Slog.e(TAG, "App already has anr dialog: " + proc); 1251 return; 1252 } 1253 1254 Intent intent = new Intent("android.intent.action.ANR"); 1255 if (!mProcessesReady) { 1256 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1257 | Intent.FLAG_RECEIVER_FOREGROUND); 1258 } 1259 broadcastIntentLocked(null, null, intent, 1260 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1261 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1262 1263 if (mShowDialogs) { 1264 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1265 mContext, proc, (ActivityRecord)data.get("activity"), 1266 msg.arg1 != 0); 1267 d.show(); 1268 proc.anrDialog = d; 1269 } else { 1270 // Just kill the app if there is no dialog to be shown. 1271 killAppAtUsersRequest(proc, null); 1272 } 1273 } 1274 1275 ensureBootCompleted(); 1276 } break; 1277 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1278 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1279 synchronized (ActivityManagerService.this) { 1280 ProcessRecord proc = (ProcessRecord) data.get("app"); 1281 if (proc == null) { 1282 Slog.e(TAG, "App not found when showing strict mode dialog."); 1283 break; 1284 } 1285 if (proc.crashDialog != null) { 1286 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1287 return; 1288 } 1289 AppErrorResult res = (AppErrorResult) data.get("result"); 1290 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1291 Dialog d = new StrictModeViolationDialog(mContext, 1292 ActivityManagerService.this, res, proc); 1293 d.show(); 1294 proc.crashDialog = d; 1295 } else { 1296 // The device is asleep, so just pretend that the user 1297 // saw a crash dialog and hit "force quit". 1298 res.set(0); 1299 } 1300 } 1301 ensureBootCompleted(); 1302 } break; 1303 case SHOW_FACTORY_ERROR_MSG: { 1304 Dialog d = new FactoryErrorDialog( 1305 mContext, msg.getData().getCharSequence("msg")); 1306 d.show(); 1307 ensureBootCompleted(); 1308 } break; 1309 case UPDATE_CONFIGURATION_MSG: { 1310 final ContentResolver resolver = mContext.getContentResolver(); 1311 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1312 } break; 1313 case GC_BACKGROUND_PROCESSES_MSG: { 1314 synchronized (ActivityManagerService.this) { 1315 performAppGcsIfAppropriateLocked(); 1316 } 1317 } break; 1318 case WAIT_FOR_DEBUGGER_MSG: { 1319 synchronized (ActivityManagerService.this) { 1320 ProcessRecord app = (ProcessRecord)msg.obj; 1321 if (msg.arg1 != 0) { 1322 if (!app.waitedForDebugger) { 1323 Dialog d = new AppWaitingForDebuggerDialog( 1324 ActivityManagerService.this, 1325 mContext, app); 1326 app.waitDialog = d; 1327 app.waitedForDebugger = true; 1328 d.show(); 1329 } 1330 } else { 1331 if (app.waitDialog != null) { 1332 app.waitDialog.dismiss(); 1333 app.waitDialog = null; 1334 } 1335 } 1336 } 1337 } break; 1338 case SERVICE_TIMEOUT_MSG: { 1339 if (mDidDexOpt) { 1340 mDidDexOpt = false; 1341 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1342 nmsg.obj = msg.obj; 1343 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1344 return; 1345 } 1346 mServices.serviceTimeout((ProcessRecord)msg.obj); 1347 } break; 1348 case UPDATE_TIME_ZONE: { 1349 synchronized (ActivityManagerService.this) { 1350 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1351 ProcessRecord r = mLruProcesses.get(i); 1352 if (r.thread != null) { 1353 try { 1354 r.thread.updateTimeZone(); 1355 } catch (RemoteException ex) { 1356 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1357 } 1358 } 1359 } 1360 } 1361 } break; 1362 case CLEAR_DNS_CACHE_MSG: { 1363 synchronized (ActivityManagerService.this) { 1364 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1365 ProcessRecord r = mLruProcesses.get(i); 1366 if (r.thread != null) { 1367 try { 1368 r.thread.clearDnsCache(); 1369 } catch (RemoteException ex) { 1370 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1371 } 1372 } 1373 } 1374 } 1375 } break; 1376 case UPDATE_HTTP_PROXY_MSG: { 1377 ProxyInfo proxy = (ProxyInfo)msg.obj; 1378 String host = ""; 1379 String port = ""; 1380 String exclList = ""; 1381 Uri pacFileUrl = Uri.EMPTY; 1382 if (proxy != null) { 1383 host = proxy.getHost(); 1384 port = Integer.toString(proxy.getPort()); 1385 exclList = proxy.getExclusionListAsString(); 1386 pacFileUrl = proxy.getPacFileUrl(); 1387 } 1388 synchronized (ActivityManagerService.this) { 1389 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1390 ProcessRecord r = mLruProcesses.get(i); 1391 if (r.thread != null) { 1392 try { 1393 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1394 } catch (RemoteException ex) { 1395 Slog.w(TAG, "Failed to update http proxy for: " + 1396 r.info.processName); 1397 } 1398 } 1399 } 1400 } 1401 } break; 1402 case SHOW_UID_ERROR_MSG: { 1403 String title = "System UIDs Inconsistent"; 1404 String text = "UIDs on the system are inconsistent, you need to wipe your" 1405 + " data partition or your device will be unstable."; 1406 Log.e(TAG, title + ": " + text); 1407 if (mShowDialogs) { 1408 // XXX This is a temporary dialog, no need to localize. 1409 AlertDialog d = new BaseErrorDialog(mContext); 1410 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1411 d.setCancelable(false); 1412 d.setTitle(title); 1413 d.setMessage(text); 1414 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1415 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1416 mUidAlert = d; 1417 d.show(); 1418 } 1419 } break; 1420 case IM_FEELING_LUCKY_MSG: { 1421 if (mUidAlert != null) { 1422 mUidAlert.dismiss(); 1423 mUidAlert = null; 1424 } 1425 } break; 1426 case PROC_START_TIMEOUT_MSG: { 1427 if (mDidDexOpt) { 1428 mDidDexOpt = false; 1429 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1430 nmsg.obj = msg.obj; 1431 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1432 return; 1433 } 1434 ProcessRecord app = (ProcessRecord)msg.obj; 1435 synchronized (ActivityManagerService.this) { 1436 processStartTimedOutLocked(app); 1437 } 1438 } break; 1439 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1440 synchronized (ActivityManagerService.this) { 1441 doPendingActivityLaunchesLocked(true); 1442 } 1443 } break; 1444 case KILL_APPLICATION_MSG: { 1445 synchronized (ActivityManagerService.this) { 1446 int appid = msg.arg1; 1447 boolean restart = (msg.arg2 == 1); 1448 Bundle bundle = (Bundle)msg.obj; 1449 String pkg = bundle.getString("pkg"); 1450 String reason = bundle.getString("reason"); 1451 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1452 false, UserHandle.USER_ALL, reason); 1453 } 1454 } break; 1455 case FINALIZE_PENDING_INTENT_MSG: { 1456 ((PendingIntentRecord)msg.obj).completeFinalize(); 1457 } break; 1458 case POST_HEAVY_NOTIFICATION_MSG: { 1459 INotificationManager inm = NotificationManager.getService(); 1460 if (inm == null) { 1461 return; 1462 } 1463 1464 ActivityRecord root = (ActivityRecord)msg.obj; 1465 ProcessRecord process = root.app; 1466 if (process == null) { 1467 return; 1468 } 1469 1470 try { 1471 Context context = mContext.createPackageContext(process.info.packageName, 0); 1472 String text = mContext.getString(R.string.heavy_weight_notification, 1473 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1474 Notification notification = new Notification(); 1475 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1476 notification.when = 0; 1477 notification.flags = Notification.FLAG_ONGOING_EVENT; 1478 notification.tickerText = text; 1479 notification.defaults = 0; // please be quiet 1480 notification.sound = null; 1481 notification.vibrate = null; 1482 notification.setLatestEventInfo(context, text, 1483 mContext.getText(R.string.heavy_weight_notification_detail), 1484 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1485 PendingIntent.FLAG_CANCEL_CURRENT, null, 1486 new UserHandle(root.userId))); 1487 1488 try { 1489 int[] outId = new int[1]; 1490 inm.enqueueNotificationWithTag("android", "android", null, 1491 R.string.heavy_weight_notification, 1492 notification, outId, root.userId); 1493 } catch (RuntimeException e) { 1494 Slog.w(ActivityManagerService.TAG, 1495 "Error showing notification for heavy-weight app", e); 1496 } catch (RemoteException e) { 1497 } 1498 } catch (NameNotFoundException e) { 1499 Slog.w(TAG, "Unable to create context for heavy notification", e); 1500 } 1501 } break; 1502 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1503 INotificationManager inm = NotificationManager.getService(); 1504 if (inm == null) { 1505 return; 1506 } 1507 try { 1508 inm.cancelNotificationWithTag("android", null, 1509 R.string.heavy_weight_notification, msg.arg1); 1510 } catch (RuntimeException e) { 1511 Slog.w(ActivityManagerService.TAG, 1512 "Error canceling notification for service", e); 1513 } catch (RemoteException e) { 1514 } 1515 } break; 1516 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1517 synchronized (ActivityManagerService.this) { 1518 checkExcessivePowerUsageLocked(true); 1519 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1520 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1521 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1522 } 1523 } break; 1524 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1525 synchronized (ActivityManagerService.this) { 1526 ActivityRecord ar = (ActivityRecord)msg.obj; 1527 if (mCompatModeDialog != null) { 1528 if (mCompatModeDialog.mAppInfo.packageName.equals( 1529 ar.info.applicationInfo.packageName)) { 1530 return; 1531 } 1532 mCompatModeDialog.dismiss(); 1533 mCompatModeDialog = null; 1534 } 1535 if (ar != null && false) { 1536 if (mCompatModePackages.getPackageAskCompatModeLocked( 1537 ar.packageName)) { 1538 int mode = mCompatModePackages.computeCompatModeLocked( 1539 ar.info.applicationInfo); 1540 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1541 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1542 mCompatModeDialog = new CompatModeDialog( 1543 ActivityManagerService.this, mContext, 1544 ar.info.applicationInfo); 1545 mCompatModeDialog.show(); 1546 } 1547 } 1548 } 1549 } 1550 break; 1551 } 1552 case DISPATCH_PROCESSES_CHANGED: { 1553 dispatchProcessesChanged(); 1554 break; 1555 } 1556 case DISPATCH_PROCESS_DIED: { 1557 final int pid = msg.arg1; 1558 final int uid = msg.arg2; 1559 dispatchProcessDied(pid, uid); 1560 break; 1561 } 1562 case REPORT_MEM_USAGE_MSG: { 1563 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1564 Thread thread = new Thread() { 1565 @Override public void run() { 1566 final SparseArray<ProcessMemInfo> infoMap 1567 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1568 for (int i=0, N=memInfos.size(); i<N; i++) { 1569 ProcessMemInfo mi = memInfos.get(i); 1570 infoMap.put(mi.pid, mi); 1571 } 1572 updateCpuStatsNow(); 1573 synchronized (mProcessCpuThread) { 1574 final int N = mProcessCpuTracker.countStats(); 1575 for (int i=0; i<N; i++) { 1576 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1577 if (st.vsize > 0) { 1578 long pss = Debug.getPss(st.pid, null); 1579 if (pss > 0) { 1580 if (infoMap.indexOfKey(st.pid) < 0) { 1581 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1582 ProcessList.NATIVE_ADJ, -1, "native", null); 1583 mi.pss = pss; 1584 memInfos.add(mi); 1585 } 1586 } 1587 } 1588 } 1589 } 1590 1591 long totalPss = 0; 1592 for (int i=0, N=memInfos.size(); i<N; i++) { 1593 ProcessMemInfo mi = memInfos.get(i); 1594 if (mi.pss == 0) { 1595 mi.pss = Debug.getPss(mi.pid, null); 1596 } 1597 totalPss += mi.pss; 1598 } 1599 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1600 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1601 if (lhs.oomAdj != rhs.oomAdj) { 1602 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1603 } 1604 if (lhs.pss != rhs.pss) { 1605 return lhs.pss < rhs.pss ? 1 : -1; 1606 } 1607 return 0; 1608 } 1609 }); 1610 1611 StringBuilder tag = new StringBuilder(128); 1612 StringBuilder stack = new StringBuilder(128); 1613 tag.append("Low on memory -- "); 1614 appendMemBucket(tag, totalPss, "total", false); 1615 appendMemBucket(stack, totalPss, "total", true); 1616 1617 StringBuilder logBuilder = new StringBuilder(1024); 1618 logBuilder.append("Low on memory:\n"); 1619 1620 boolean firstLine = true; 1621 int lastOomAdj = Integer.MIN_VALUE; 1622 for (int i=0, N=memInfos.size(); i<N; i++) { 1623 ProcessMemInfo mi = memInfos.get(i); 1624 1625 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1626 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1627 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1628 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1629 if (lastOomAdj != mi.oomAdj) { 1630 lastOomAdj = mi.oomAdj; 1631 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1632 tag.append(" / "); 1633 } 1634 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1635 if (firstLine) { 1636 stack.append(":"); 1637 firstLine = false; 1638 } 1639 stack.append("\n\t at "); 1640 } else { 1641 stack.append("$"); 1642 } 1643 } else { 1644 tag.append(" "); 1645 stack.append("$"); 1646 } 1647 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1648 appendMemBucket(tag, mi.pss, mi.name, false); 1649 } 1650 appendMemBucket(stack, mi.pss, mi.name, true); 1651 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1652 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1653 stack.append("("); 1654 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1655 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1656 stack.append(DUMP_MEM_OOM_LABEL[k]); 1657 stack.append(":"); 1658 stack.append(DUMP_MEM_OOM_ADJ[k]); 1659 } 1660 } 1661 stack.append(")"); 1662 } 1663 } 1664 1665 logBuilder.append(" "); 1666 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1667 logBuilder.append(' '); 1668 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1669 logBuilder.append(' '); 1670 ProcessList.appendRamKb(logBuilder, mi.pss); 1671 logBuilder.append(" kB: "); 1672 logBuilder.append(mi.name); 1673 logBuilder.append(" ("); 1674 logBuilder.append(mi.pid); 1675 logBuilder.append(") "); 1676 logBuilder.append(mi.adjType); 1677 logBuilder.append('\n'); 1678 if (mi.adjReason != null) { 1679 logBuilder.append(" "); 1680 logBuilder.append(mi.adjReason); 1681 logBuilder.append('\n'); 1682 } 1683 } 1684 1685 logBuilder.append(" "); 1686 ProcessList.appendRamKb(logBuilder, totalPss); 1687 logBuilder.append(" kB: TOTAL\n"); 1688 1689 long[] infos = new long[Debug.MEMINFO_COUNT]; 1690 Debug.getMemInfo(infos); 1691 logBuilder.append(" MemInfo: "); 1692 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1693 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1694 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1695 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1696 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1697 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1698 logBuilder.append(" ZRAM: "); 1699 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1700 logBuilder.append(" kB RAM, "); 1701 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1702 logBuilder.append(" kB swap total, "); 1703 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1704 logBuilder.append(" kB swap free\n"); 1705 } 1706 Slog.i(TAG, logBuilder.toString()); 1707 1708 StringBuilder dropBuilder = new StringBuilder(1024); 1709 /* 1710 StringWriter oomSw = new StringWriter(); 1711 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1712 StringWriter catSw = new StringWriter(); 1713 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1714 String[] emptyArgs = new String[] { }; 1715 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1716 oomPw.flush(); 1717 String oomString = oomSw.toString(); 1718 */ 1719 dropBuilder.append(stack); 1720 dropBuilder.append('\n'); 1721 dropBuilder.append('\n'); 1722 dropBuilder.append(logBuilder); 1723 dropBuilder.append('\n'); 1724 /* 1725 dropBuilder.append(oomString); 1726 dropBuilder.append('\n'); 1727 */ 1728 StringWriter catSw = new StringWriter(); 1729 synchronized (ActivityManagerService.this) { 1730 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1731 String[] emptyArgs = new String[] { }; 1732 catPw.println(); 1733 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1734 catPw.println(); 1735 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1736 false, false, null); 1737 catPw.println(); 1738 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1739 catPw.flush(); 1740 } 1741 dropBuilder.append(catSw.toString()); 1742 addErrorToDropBox("lowmem", null, "system_server", null, 1743 null, tag.toString(), dropBuilder.toString(), null, null); 1744 //Slog.i(TAG, "Sent to dropbox:"); 1745 //Slog.i(TAG, dropBuilder.toString()); 1746 synchronized (ActivityManagerService.this) { 1747 long now = SystemClock.uptimeMillis(); 1748 if (mLastMemUsageReportTime < now) { 1749 mLastMemUsageReportTime = now; 1750 } 1751 } 1752 } 1753 }; 1754 thread.start(); 1755 break; 1756 } 1757 case REPORT_USER_SWITCH_MSG: { 1758 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1759 break; 1760 } 1761 case CONTINUE_USER_SWITCH_MSG: { 1762 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1763 break; 1764 } 1765 case USER_SWITCH_TIMEOUT_MSG: { 1766 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1767 break; 1768 } 1769 case IMMERSIVE_MODE_LOCK_MSG: { 1770 final boolean nextState = (msg.arg1 != 0); 1771 if (mUpdateLock.isHeld() != nextState) { 1772 if (DEBUG_IMMERSIVE) { 1773 final ActivityRecord r = (ActivityRecord) msg.obj; 1774 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1775 } 1776 if (nextState) { 1777 mUpdateLock.acquire(); 1778 } else { 1779 mUpdateLock.release(); 1780 } 1781 } 1782 break; 1783 } 1784 case PERSIST_URI_GRANTS_MSG: { 1785 writeGrantedUriPermissions(); 1786 break; 1787 } 1788 case REQUEST_ALL_PSS_MSG: { 1789 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1790 break; 1791 } 1792 case START_PROFILES_MSG: { 1793 synchronized (ActivityManagerService.this) { 1794 startProfilesLocked(); 1795 } 1796 break; 1797 } 1798 case UPDATE_TIME: { 1799 synchronized (ActivityManagerService.this) { 1800 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1801 ProcessRecord r = mLruProcesses.get(i); 1802 if (r.thread != null) { 1803 try { 1804 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1805 } catch (RemoteException ex) { 1806 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1807 } 1808 } 1809 } 1810 } 1811 break; 1812 } 1813 case SYSTEM_USER_START_MSG: { 1814 mSystemServiceManager.startUser(msg.arg1); 1815 break; 1816 } 1817 case SYSTEM_USER_CURRENT_MSG: { 1818 mSystemServiceManager.switchUser(msg.arg1); 1819 break; 1820 } 1821 } 1822 } 1823 }; 1824 1825 static final int COLLECT_PSS_BG_MSG = 1; 1826 1827 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1828 @Override 1829 public void handleMessage(Message msg) { 1830 switch (msg.what) { 1831 case COLLECT_PSS_BG_MSG: { 1832 long start = SystemClock.uptimeMillis(); 1833 MemInfoReader memInfo = null; 1834 synchronized (ActivityManagerService.this) { 1835 if (mFullPssPending) { 1836 mFullPssPending = false; 1837 memInfo = new MemInfoReader(); 1838 } 1839 } 1840 if (memInfo != null) { 1841 updateCpuStatsNow(); 1842 long nativeTotalPss = 0; 1843 synchronized (mProcessCpuThread) { 1844 final int N = mProcessCpuTracker.countStats(); 1845 for (int j=0; j<N; j++) { 1846 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1847 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1848 // This is definitely an application process; skip it. 1849 continue; 1850 } 1851 synchronized (mPidsSelfLocked) { 1852 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1853 // This is one of our own processes; skip it. 1854 continue; 1855 } 1856 } 1857 nativeTotalPss += Debug.getPss(st.pid, null); 1858 } 1859 } 1860 memInfo.readMemInfo(); 1861 synchronized (this) { 1862 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1863 + (SystemClock.uptimeMillis()-start) + "ms"); 1864 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1865 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1866 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1867 +memInfo.getSlabSizeKb(), 1868 nativeTotalPss); 1869 } 1870 } 1871 1872 int i=0, num=0; 1873 long[] tmp = new long[1]; 1874 do { 1875 ProcessRecord proc; 1876 int procState; 1877 int pid; 1878 synchronized (ActivityManagerService.this) { 1879 if (i >= mPendingPssProcesses.size()) { 1880 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1881 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1882 mPendingPssProcesses.clear(); 1883 return; 1884 } 1885 proc = mPendingPssProcesses.get(i); 1886 procState = proc.pssProcState; 1887 if (proc.thread != null && procState == proc.setProcState) { 1888 pid = proc.pid; 1889 } else { 1890 proc = null; 1891 pid = 0; 1892 } 1893 i++; 1894 } 1895 if (proc != null) { 1896 long pss = Debug.getPss(pid, tmp); 1897 synchronized (ActivityManagerService.this) { 1898 if (proc.thread != null && proc.setProcState == procState 1899 && proc.pid == pid) { 1900 num++; 1901 proc.lastPssTime = SystemClock.uptimeMillis(); 1902 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1903 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1904 + ": " + pss + " lastPss=" + proc.lastPss 1905 + " state=" + ProcessList.makeProcStateString(procState)); 1906 if (proc.initialIdlePss == 0) { 1907 proc.initialIdlePss = pss; 1908 } 1909 proc.lastPss = pss; 1910 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1911 proc.lastCachedPss = pss; 1912 } 1913 } 1914 } 1915 } 1916 } while (true); 1917 } 1918 } 1919 } 1920 }; 1921 1922 /** 1923 * Monitor for package changes and update our internal state. 1924 */ 1925 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1926 @Override 1927 public void onPackageRemoved(String packageName, int uid) { 1928 // Remove all tasks with activities in the specified package from the list of recent tasks 1929 synchronized (ActivityManagerService.this) { 1930 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1931 TaskRecord tr = mRecentTasks.get(i); 1932 ComponentName cn = tr.intent.getComponent(); 1933 if (cn != null && cn.getPackageName().equals(packageName)) { 1934 // If the package name matches, remove the task and kill the process 1935 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1936 } 1937 } 1938 } 1939 } 1940 1941 @Override 1942 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1943 onPackageModified(packageName); 1944 return true; 1945 } 1946 1947 @Override 1948 public void onPackageModified(String packageName) { 1949 final PackageManager pm = mContext.getPackageManager(); 1950 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1951 new ArrayList<Pair<Intent, Integer>>(); 1952 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1953 // Copy the list of recent tasks so that we don't hold onto the lock on 1954 // ActivityManagerService for long periods while checking if components exist. 1955 synchronized (ActivityManagerService.this) { 1956 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1957 TaskRecord tr = mRecentTasks.get(i); 1958 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1959 } 1960 } 1961 // Check the recent tasks and filter out all tasks with components that no longer exist. 1962 Intent tmpI = new Intent(); 1963 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1964 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1965 ComponentName cn = p.first.getComponent(); 1966 if (cn != null && cn.getPackageName().equals(packageName)) { 1967 try { 1968 // Add the task to the list to remove if the component no longer exists 1969 tmpI.setComponent(cn); 1970 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1971 tasksToRemove.add(p.second); 1972 } 1973 } catch (Exception e) {} 1974 } 1975 } 1976 // Prune all the tasks with removed components from the list of recent tasks 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1979 // Remove the task but don't kill the process (since other components in that 1980 // package may still be running and in the background) 1981 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1982 } 1983 } 1984 } 1985 1986 @Override 1987 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1988 // Force stop the specified packages 1989 if (packages != null) { 1990 for (String pkg : packages) { 1991 synchronized (ActivityManagerService.this) { 1992 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1993 "finished booting")) { 1994 return true; 1995 } 1996 } 1997 } 1998 } 1999 return false; 2000 } 2001 }; 2002 2003 public void setSystemProcess() { 2004 try { 2005 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2006 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2007 ServiceManager.addService("meminfo", new MemBinder(this)); 2008 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2009 ServiceManager.addService("dbinfo", new DbBinder(this)); 2010 if (MONITOR_CPU_USAGE) { 2011 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2012 } 2013 ServiceManager.addService("permission", new PermissionController(this)); 2014 2015 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2016 "android", STOCK_PM_FLAGS); 2017 mSystemThread.installSystemApplicationInfo(info); 2018 2019 synchronized (this) { 2020 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2021 app.persistent = true; 2022 app.pid = MY_PID; 2023 app.maxAdj = ProcessList.SYSTEM_ADJ; 2024 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2025 mProcessNames.put(app.processName, app.uid, app); 2026 synchronized (mPidsSelfLocked) { 2027 mPidsSelfLocked.put(app.pid, app); 2028 } 2029 updateLruProcessLocked(app, false, null); 2030 updateOomAdjLocked(); 2031 } 2032 } catch (PackageManager.NameNotFoundException e) { 2033 throw new RuntimeException( 2034 "Unable to find android system package", e); 2035 } 2036 } 2037 2038 public void setWindowManager(WindowManagerService wm) { 2039 mWindowManager = wm; 2040 mStackSupervisor.setWindowManager(wm); 2041 } 2042 2043 public void startObservingNativeCrashes() { 2044 final NativeCrashListener ncl = new NativeCrashListener(this); 2045 ncl.start(); 2046 } 2047 2048 public IAppOpsService getAppOpsService() { 2049 return mAppOpsService; 2050 } 2051 2052 static class MemBinder extends Binder { 2053 ActivityManagerService mActivityManagerService; 2054 MemBinder(ActivityManagerService activityManagerService) { 2055 mActivityManagerService = activityManagerService; 2056 } 2057 2058 @Override 2059 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2060 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2061 != PackageManager.PERMISSION_GRANTED) { 2062 pw.println("Permission Denial: can't dump meminfo from from pid=" 2063 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2064 + " without permission " + android.Manifest.permission.DUMP); 2065 return; 2066 } 2067 2068 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2069 } 2070 } 2071 2072 static class GraphicsBinder extends Binder { 2073 ActivityManagerService mActivityManagerService; 2074 GraphicsBinder(ActivityManagerService activityManagerService) { 2075 mActivityManagerService = activityManagerService; 2076 } 2077 2078 @Override 2079 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2080 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2081 != PackageManager.PERMISSION_GRANTED) { 2082 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2083 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2084 + " without permission " + android.Manifest.permission.DUMP); 2085 return; 2086 } 2087 2088 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2089 } 2090 } 2091 2092 static class DbBinder extends Binder { 2093 ActivityManagerService mActivityManagerService; 2094 DbBinder(ActivityManagerService activityManagerService) { 2095 mActivityManagerService = activityManagerService; 2096 } 2097 2098 @Override 2099 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2100 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2101 != PackageManager.PERMISSION_GRANTED) { 2102 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2103 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2104 + " without permission " + android.Manifest.permission.DUMP); 2105 return; 2106 } 2107 2108 mActivityManagerService.dumpDbInfo(fd, pw, args); 2109 } 2110 } 2111 2112 static class CpuBinder extends Binder { 2113 ActivityManagerService mActivityManagerService; 2114 CpuBinder(ActivityManagerService activityManagerService) { 2115 mActivityManagerService = activityManagerService; 2116 } 2117 2118 @Override 2119 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2120 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2121 != PackageManager.PERMISSION_GRANTED) { 2122 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2123 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2124 + " without permission " + android.Manifest.permission.DUMP); 2125 return; 2126 } 2127 2128 synchronized (mActivityManagerService.mProcessCpuThread) { 2129 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2130 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2131 SystemClock.uptimeMillis())); 2132 } 2133 } 2134 } 2135 2136 public static final class Lifecycle extends SystemService { 2137 private final ActivityManagerService mService; 2138 2139 public Lifecycle(Context context) { 2140 super(context); 2141 mService = new ActivityManagerService(context); 2142 } 2143 2144 @Override 2145 public void onStart() { 2146 mService.start(); 2147 } 2148 2149 public ActivityManagerService getService() { 2150 return mService; 2151 } 2152 } 2153 2154 // Note: This method is invoked on the main thread but may need to attach various 2155 // handlers to other threads. So take care to be explicit about the looper. 2156 public ActivityManagerService(Context systemContext) { 2157 mContext = systemContext; 2158 mFactoryTest = FactoryTest.getMode(); 2159 mSystemThread = ActivityThread.currentActivityThread(); 2160 2161 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2162 2163 mHandlerThread = new ServiceThread(TAG, 2164 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2165 mHandlerThread.start(); 2166 mHandler = new MainHandler(mHandlerThread.getLooper()); 2167 2168 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2169 "foreground", BROADCAST_FG_TIMEOUT, false); 2170 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2171 "background", BROADCAST_BG_TIMEOUT, true); 2172 mBroadcastQueues[0] = mFgBroadcastQueue; 2173 mBroadcastQueues[1] = mBgBroadcastQueue; 2174 2175 mServices = new ActiveServices(this); 2176 mProviderMap = new ProviderMap(this); 2177 2178 // TODO: Move creation of battery stats service outside of activity manager service. 2179 File dataDir = Environment.getDataDirectory(); 2180 File systemDir = new File(dataDir, "system"); 2181 systemDir.mkdirs(); 2182 mBatteryStatsService = new BatteryStatsService(new File( 2183 systemDir, "batterystats.bin").toString(), mHandler); 2184 mBatteryStatsService.getActiveStatistics().readLocked(); 2185 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2186 mOnBattery = DEBUG_POWER ? true 2187 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2188 mBatteryStatsService.getActiveStatistics().setCallback(this); 2189 2190 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2191 2192 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2193 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2194 2195 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2196 2197 // User 0 is the first and only user that runs at boot. 2198 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2199 mUserLru.add(Integer.valueOf(0)); 2200 updateStartedUserArrayLocked(); 2201 2202 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2203 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2204 2205 mConfiguration.setToDefaults(); 2206 mConfiguration.setLocale(Locale.getDefault()); 2207 2208 mConfigurationSeq = mConfiguration.seq = 1; 2209 mProcessCpuTracker.init(); 2210 2211 mHasRecents = mContext.getResources().getBoolean( 2212 com.android.internal.R.bool.config_hasRecents); 2213 2214 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2215 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2216 mStackSupervisor = new ActivityStackSupervisor(this); 2217 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2218 2219 mProcessCpuThread = new Thread("CpuTracker") { 2220 @Override 2221 public void run() { 2222 while (true) { 2223 try { 2224 try { 2225 synchronized(this) { 2226 final long now = SystemClock.uptimeMillis(); 2227 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2228 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2229 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2230 // + ", write delay=" + nextWriteDelay); 2231 if (nextWriteDelay < nextCpuDelay) { 2232 nextCpuDelay = nextWriteDelay; 2233 } 2234 if (nextCpuDelay > 0) { 2235 mProcessCpuMutexFree.set(true); 2236 this.wait(nextCpuDelay); 2237 } 2238 } 2239 } catch (InterruptedException e) { 2240 } 2241 updateCpuStatsNow(); 2242 } catch (Exception e) { 2243 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2244 } 2245 } 2246 } 2247 }; 2248 2249 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2250 2251 Watchdog.getInstance().addMonitor(this); 2252 Watchdog.getInstance().addThread(mHandler); 2253 } 2254 2255 public void setSystemServiceManager(SystemServiceManager mgr) { 2256 mSystemServiceManager = mgr; 2257 } 2258 2259 private void start() { 2260 Process.removeAllProcessGroups(); 2261 mProcessCpuThread.start(); 2262 2263 mBatteryStatsService.publish(mContext); 2264 mUsageStatsService.publish(mContext); 2265 mAppOpsService.publish(mContext); 2266 Slog.d("AppOps", "AppOpsService published"); 2267 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2268 } 2269 2270 public void initPowerManagement() { 2271 mStackSupervisor.initPowerManagement(); 2272 mBatteryStatsService.initPowerManagement(); 2273 } 2274 2275 @Override 2276 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2277 throws RemoteException { 2278 if (code == SYSPROPS_TRANSACTION) { 2279 // We need to tell all apps about the system property change. 2280 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2281 synchronized(this) { 2282 final int NP = mProcessNames.getMap().size(); 2283 for (int ip=0; ip<NP; ip++) { 2284 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2285 final int NA = apps.size(); 2286 for (int ia=0; ia<NA; ia++) { 2287 ProcessRecord app = apps.valueAt(ia); 2288 if (app.thread != null) { 2289 procs.add(app.thread.asBinder()); 2290 } 2291 } 2292 } 2293 } 2294 2295 int N = procs.size(); 2296 for (int i=0; i<N; i++) { 2297 Parcel data2 = Parcel.obtain(); 2298 try { 2299 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2300 } catch (RemoteException e) { 2301 } 2302 data2.recycle(); 2303 } 2304 } 2305 try { 2306 return super.onTransact(code, data, reply, flags); 2307 } catch (RuntimeException e) { 2308 // The activity manager only throws security exceptions, so let's 2309 // log all others. 2310 if (!(e instanceof SecurityException)) { 2311 Slog.wtf(TAG, "Activity Manager Crash", e); 2312 } 2313 throw e; 2314 } 2315 } 2316 2317 void updateCpuStats() { 2318 final long now = SystemClock.uptimeMillis(); 2319 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2320 return; 2321 } 2322 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2323 synchronized (mProcessCpuThread) { 2324 mProcessCpuThread.notify(); 2325 } 2326 } 2327 } 2328 2329 void updateCpuStatsNow() { 2330 synchronized (mProcessCpuThread) { 2331 mProcessCpuMutexFree.set(false); 2332 final long now = SystemClock.uptimeMillis(); 2333 boolean haveNewCpuStats = false; 2334 2335 if (MONITOR_CPU_USAGE && 2336 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2337 mLastCpuTime.set(now); 2338 haveNewCpuStats = true; 2339 mProcessCpuTracker.update(); 2340 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2341 //Slog.i(TAG, "Total CPU usage: " 2342 // + mProcessCpu.getTotalCpuPercent() + "%"); 2343 2344 // Slog the cpu usage if the property is set. 2345 if ("true".equals(SystemProperties.get("events.cpu"))) { 2346 int user = mProcessCpuTracker.getLastUserTime(); 2347 int system = mProcessCpuTracker.getLastSystemTime(); 2348 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2349 int irq = mProcessCpuTracker.getLastIrqTime(); 2350 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2351 int idle = mProcessCpuTracker.getLastIdleTime(); 2352 2353 int total = user + system + iowait + irq + softIrq + idle; 2354 if (total == 0) total = 1; 2355 2356 EventLog.writeEvent(EventLogTags.CPU, 2357 ((user+system+iowait+irq+softIrq) * 100) / total, 2358 (user * 100) / total, 2359 (system * 100) / total, 2360 (iowait * 100) / total, 2361 (irq * 100) / total, 2362 (softIrq * 100) / total); 2363 } 2364 } 2365 2366 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2367 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2368 synchronized(bstats) { 2369 synchronized(mPidsSelfLocked) { 2370 if (haveNewCpuStats) { 2371 if (mOnBattery) { 2372 int perc = bstats.startAddingCpuLocked(); 2373 int totalUTime = 0; 2374 int totalSTime = 0; 2375 final int N = mProcessCpuTracker.countStats(); 2376 for (int i=0; i<N; i++) { 2377 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2378 if (!st.working) { 2379 continue; 2380 } 2381 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2382 int otherUTime = (st.rel_utime*perc)/100; 2383 int otherSTime = (st.rel_stime*perc)/100; 2384 totalUTime += otherUTime; 2385 totalSTime += otherSTime; 2386 if (pr != null) { 2387 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2388 if (ps == null || !ps.isActive()) { 2389 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2390 pr.info.uid, pr.processName); 2391 } 2392 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2393 st.rel_stime-otherSTime); 2394 ps.addSpeedStepTimes(cpuSpeedTimes); 2395 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2396 } else { 2397 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2398 if (ps == null || !ps.isActive()) { 2399 st.batteryStats = ps = bstats.getProcessStatsLocked( 2400 bstats.mapUid(st.uid), st.name); 2401 } 2402 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2403 st.rel_stime-otherSTime); 2404 ps.addSpeedStepTimes(cpuSpeedTimes); 2405 } 2406 } 2407 bstats.finishAddingCpuLocked(perc, totalUTime, 2408 totalSTime, cpuSpeedTimes); 2409 } 2410 } 2411 } 2412 2413 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2414 mLastWriteTime = now; 2415 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2416 } 2417 } 2418 } 2419 } 2420 2421 @Override 2422 public void batteryNeedsCpuUpdate() { 2423 updateCpuStatsNow(); 2424 } 2425 2426 @Override 2427 public void batteryPowerChanged(boolean onBattery) { 2428 // When plugging in, update the CPU stats first before changing 2429 // the plug state. 2430 updateCpuStatsNow(); 2431 synchronized (this) { 2432 synchronized(mPidsSelfLocked) { 2433 mOnBattery = DEBUG_POWER ? true : onBattery; 2434 } 2435 } 2436 } 2437 2438 /** 2439 * Initialize the application bind args. These are passed to each 2440 * process when the bindApplication() IPC is sent to the process. They're 2441 * lazily setup to make sure the services are running when they're asked for. 2442 */ 2443 private HashMap<String, IBinder> getCommonServicesLocked() { 2444 if (mAppBindArgs == null) { 2445 mAppBindArgs = new HashMap<String, IBinder>(); 2446 2447 // Setup the application init args 2448 mAppBindArgs.put("package", ServiceManager.getService("package")); 2449 mAppBindArgs.put("window", ServiceManager.getService("window")); 2450 mAppBindArgs.put(Context.ALARM_SERVICE, 2451 ServiceManager.getService(Context.ALARM_SERVICE)); 2452 } 2453 return mAppBindArgs; 2454 } 2455 2456 final void setFocusedActivityLocked(ActivityRecord r) { 2457 if (mFocusedActivity != r) { 2458 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2459 mFocusedActivity = r; 2460 if (r.task != null && r.task.voiceInteractor != null) { 2461 startRunningVoiceLocked(); 2462 } else { 2463 finishRunningVoiceLocked(); 2464 } 2465 mStackSupervisor.setFocusedStack(r); 2466 if (r != null) { 2467 mWindowManager.setFocusedApp(r.appToken, true); 2468 } 2469 applyUpdateLockStateLocked(r); 2470 } 2471 } 2472 2473 final void clearFocusedActivity(ActivityRecord r) { 2474 if (mFocusedActivity == r) { 2475 mFocusedActivity = null; 2476 } 2477 } 2478 2479 @Override 2480 public void setFocusedStack(int stackId) { 2481 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2482 synchronized (ActivityManagerService.this) { 2483 ActivityStack stack = mStackSupervisor.getStack(stackId); 2484 if (stack != null) { 2485 ActivityRecord r = stack.topRunningActivityLocked(null); 2486 if (r != null) { 2487 setFocusedActivityLocked(r); 2488 } 2489 } 2490 } 2491 } 2492 2493 @Override 2494 public void notifyActivityDrawn(IBinder token) { 2495 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2496 synchronized (this) { 2497 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2498 if (r != null) { 2499 r.task.stack.notifyActivityDrawnLocked(r); 2500 } 2501 } 2502 } 2503 2504 final void applyUpdateLockStateLocked(ActivityRecord r) { 2505 // Modifications to the UpdateLock state are done on our handler, outside 2506 // the activity manager's locks. The new state is determined based on the 2507 // state *now* of the relevant activity record. The object is passed to 2508 // the handler solely for logging detail, not to be consulted/modified. 2509 final boolean nextState = r != null && r.immersive; 2510 mHandler.sendMessage( 2511 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2512 } 2513 2514 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2515 Message msg = Message.obtain(); 2516 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2517 msg.obj = r.task.askedCompatMode ? null : r; 2518 mHandler.sendMessage(msg); 2519 } 2520 2521 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2522 String what, Object obj, ProcessRecord srcApp) { 2523 app.lastActivityTime = now; 2524 2525 if (app.activities.size() > 0) { 2526 // Don't want to touch dependent processes that are hosting activities. 2527 return index; 2528 } 2529 2530 int lrui = mLruProcesses.lastIndexOf(app); 2531 if (lrui < 0) { 2532 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2533 + what + " " + obj + " from " + srcApp); 2534 return index; 2535 } 2536 2537 if (lrui >= index) { 2538 // Don't want to cause this to move dependent processes *back* in the 2539 // list as if they were less frequently used. 2540 return index; 2541 } 2542 2543 if (lrui >= mLruProcessActivityStart) { 2544 // Don't want to touch dependent processes that are hosting activities. 2545 return index; 2546 } 2547 2548 mLruProcesses.remove(lrui); 2549 if (index > 0) { 2550 index--; 2551 } 2552 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2553 + " in LRU list: " + app); 2554 mLruProcesses.add(index, app); 2555 return index; 2556 } 2557 2558 final void removeLruProcessLocked(ProcessRecord app) { 2559 int lrui = mLruProcesses.lastIndexOf(app); 2560 if (lrui >= 0) { 2561 if (lrui <= mLruProcessActivityStart) { 2562 mLruProcessActivityStart--; 2563 } 2564 if (lrui <= mLruProcessServiceStart) { 2565 mLruProcessServiceStart--; 2566 } 2567 mLruProcesses.remove(lrui); 2568 } 2569 } 2570 2571 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2572 ProcessRecord client) { 2573 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2574 || app.treatLikeActivity; 2575 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2576 if (!activityChange && hasActivity) { 2577 // The process has activities, so we are only allowing activity-based adjustments 2578 // to move it. It should be kept in the front of the list with other 2579 // processes that have activities, and we don't want those to change their 2580 // order except due to activity operations. 2581 return; 2582 } 2583 2584 mLruSeq++; 2585 final long now = SystemClock.uptimeMillis(); 2586 app.lastActivityTime = now; 2587 2588 // First a quick reject: if the app is already at the position we will 2589 // put it, then there is nothing to do. 2590 if (hasActivity) { 2591 final int N = mLruProcesses.size(); 2592 if (N > 0 && mLruProcesses.get(N-1) == app) { 2593 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2594 return; 2595 } 2596 } else { 2597 if (mLruProcessServiceStart > 0 2598 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2599 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2600 return; 2601 } 2602 } 2603 2604 int lrui = mLruProcesses.lastIndexOf(app); 2605 2606 if (app.persistent && lrui >= 0) { 2607 // We don't care about the position of persistent processes, as long as 2608 // they are in the list. 2609 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2610 return; 2611 } 2612 2613 /* In progress: compute new position first, so we can avoid doing work 2614 if the process is not actually going to move. Not yet working. 2615 int addIndex; 2616 int nextIndex; 2617 boolean inActivity = false, inService = false; 2618 if (hasActivity) { 2619 // Process has activities, put it at the very tipsy-top. 2620 addIndex = mLruProcesses.size(); 2621 nextIndex = mLruProcessServiceStart; 2622 inActivity = true; 2623 } else if (hasService) { 2624 // Process has services, put it at the top of the service list. 2625 addIndex = mLruProcessActivityStart; 2626 nextIndex = mLruProcessServiceStart; 2627 inActivity = true; 2628 inService = true; 2629 } else { 2630 // Process not otherwise of interest, it goes to the top of the non-service area. 2631 addIndex = mLruProcessServiceStart; 2632 if (client != null) { 2633 int clientIndex = mLruProcesses.lastIndexOf(client); 2634 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2635 + app); 2636 if (clientIndex >= 0 && addIndex > clientIndex) { 2637 addIndex = clientIndex; 2638 } 2639 } 2640 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2641 } 2642 2643 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2644 + mLruProcessActivityStart + "): " + app); 2645 */ 2646 2647 if (lrui >= 0) { 2648 if (lrui < mLruProcessActivityStart) { 2649 mLruProcessActivityStart--; 2650 } 2651 if (lrui < mLruProcessServiceStart) { 2652 mLruProcessServiceStart--; 2653 } 2654 /* 2655 if (addIndex > lrui) { 2656 addIndex--; 2657 } 2658 if (nextIndex > lrui) { 2659 nextIndex--; 2660 } 2661 */ 2662 mLruProcesses.remove(lrui); 2663 } 2664 2665 /* 2666 mLruProcesses.add(addIndex, app); 2667 if (inActivity) { 2668 mLruProcessActivityStart++; 2669 } 2670 if (inService) { 2671 mLruProcessActivityStart++; 2672 } 2673 */ 2674 2675 int nextIndex; 2676 if (hasActivity) { 2677 final int N = mLruProcesses.size(); 2678 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2679 // Process doesn't have activities, but has clients with 2680 // activities... move it up, but one below the top (the top 2681 // should always have a real activity). 2682 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2683 mLruProcesses.add(N-1, app); 2684 // To keep it from spamming the LRU list (by making a bunch of clients), 2685 // we will push down any other entries owned by the app. 2686 final int uid = app.info.uid; 2687 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2688 ProcessRecord subProc = mLruProcesses.get(i); 2689 if (subProc.info.uid == uid) { 2690 // We want to push this one down the list. If the process after 2691 // it is for the same uid, however, don't do so, because we don't 2692 // want them internally to be re-ordered. 2693 if (mLruProcesses.get(i-1).info.uid != uid) { 2694 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2695 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2696 ProcessRecord tmp = mLruProcesses.get(i); 2697 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2698 mLruProcesses.set(i-1, tmp); 2699 i--; 2700 } 2701 } else { 2702 // A gap, we can stop here. 2703 break; 2704 } 2705 } 2706 } else { 2707 // Process has activities, put it at the very tipsy-top. 2708 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2709 mLruProcesses.add(app); 2710 } 2711 nextIndex = mLruProcessServiceStart; 2712 } else if (hasService) { 2713 // Process has services, put it at the top of the service list. 2714 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2715 mLruProcesses.add(mLruProcessActivityStart, app); 2716 nextIndex = mLruProcessServiceStart; 2717 mLruProcessActivityStart++; 2718 } else { 2719 // Process not otherwise of interest, it goes to the top of the non-service area. 2720 int index = mLruProcessServiceStart; 2721 if (client != null) { 2722 // If there is a client, don't allow the process to be moved up higher 2723 // in the list than that client. 2724 int clientIndex = mLruProcesses.lastIndexOf(client); 2725 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2726 + " when updating " + app); 2727 if (clientIndex <= lrui) { 2728 // Don't allow the client index restriction to push it down farther in the 2729 // list than it already is. 2730 clientIndex = lrui; 2731 } 2732 if (clientIndex >= 0 && index > clientIndex) { 2733 index = clientIndex; 2734 } 2735 } 2736 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2737 mLruProcesses.add(index, app); 2738 nextIndex = index-1; 2739 mLruProcessActivityStart++; 2740 mLruProcessServiceStart++; 2741 } 2742 2743 // If the app is currently using a content provider or service, 2744 // bump those processes as well. 2745 for (int j=app.connections.size()-1; j>=0; j--) { 2746 ConnectionRecord cr = app.connections.valueAt(j); 2747 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2748 && cr.binding.service.app != null 2749 && cr.binding.service.app.lruSeq != mLruSeq 2750 && !cr.binding.service.app.persistent) { 2751 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2752 "service connection", cr, app); 2753 } 2754 } 2755 for (int j=app.conProviders.size()-1; j>=0; j--) { 2756 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2757 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2758 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2759 "provider reference", cpr, app); 2760 } 2761 } 2762 } 2763 2764 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2765 if (uid == Process.SYSTEM_UID) { 2766 // The system gets to run in any process. If there are multiple 2767 // processes with the same uid, just pick the first (this 2768 // should never happen). 2769 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2770 if (procs == null) return null; 2771 final int N = procs.size(); 2772 for (int i = 0; i < N; i++) { 2773 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2774 } 2775 } 2776 ProcessRecord proc = mProcessNames.get(processName, uid); 2777 if (false && proc != null && !keepIfLarge 2778 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2779 && proc.lastCachedPss >= 4000) { 2780 // Turn this condition on to cause killing to happen regularly, for testing. 2781 if (proc.baseProcessTracker != null) { 2782 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2783 } 2784 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2785 + "k from cached"); 2786 } else if (proc != null && !keepIfLarge 2787 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2788 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2789 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2790 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2791 if (proc.baseProcessTracker != null) { 2792 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2793 } 2794 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2795 + "k from cached"); 2796 } 2797 } 2798 return proc; 2799 } 2800 2801 void ensurePackageDexOpt(String packageName) { 2802 IPackageManager pm = AppGlobals.getPackageManager(); 2803 try { 2804 if (pm.performDexOpt(packageName)) { 2805 mDidDexOpt = true; 2806 } 2807 } catch (RemoteException e) { 2808 } 2809 } 2810 2811 boolean isNextTransitionForward() { 2812 int transit = mWindowManager.getPendingAppTransition(); 2813 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2814 || transit == AppTransition.TRANSIT_TASK_OPEN 2815 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2816 } 2817 2818 final ProcessRecord startProcessLocked(String processName, 2819 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2820 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2821 boolean isolated, boolean keepIfLarge) { 2822 ProcessRecord app; 2823 if (!isolated) { 2824 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2825 } else { 2826 // If this is an isolated process, it can't re-use an existing process. 2827 app = null; 2828 } 2829 // We don't have to do anything more if: 2830 // (1) There is an existing application record; and 2831 // (2) The caller doesn't think it is dead, OR there is no thread 2832 // object attached to it so we know it couldn't have crashed; and 2833 // (3) There is a pid assigned to it, so it is either starting or 2834 // already running. 2835 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2836 + " app=" + app + " knownToBeDead=" + knownToBeDead 2837 + " thread=" + (app != null ? app.thread : null) 2838 + " pid=" + (app != null ? app.pid : -1)); 2839 if (app != null && app.pid > 0) { 2840 if (!knownToBeDead || app.thread == null) { 2841 // We already have the app running, or are waiting for it to 2842 // come up (we have a pid but not yet its thread), so keep it. 2843 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2844 // If this is a new package in the process, add the package to the list 2845 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2846 return app; 2847 } 2848 2849 // An application record is attached to a previous process, 2850 // clean it up now. 2851 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2852 Process.killProcessGroup(app.info.uid, app.pid); 2853 handleAppDiedLocked(app, true, true); 2854 } 2855 2856 String hostingNameStr = hostingName != null 2857 ? hostingName.flattenToShortString() : null; 2858 2859 if (!isolated) { 2860 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2861 // If we are in the background, then check to see if this process 2862 // is bad. If so, we will just silently fail. 2863 if (mBadProcesses.get(info.processName, info.uid) != null) { 2864 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2865 + "/" + info.processName); 2866 return null; 2867 } 2868 } else { 2869 // When the user is explicitly starting a process, then clear its 2870 // crash count so that we won't make it bad until they see at 2871 // least one crash dialog again, and make the process good again 2872 // if it had been bad. 2873 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2874 + "/" + info.processName); 2875 mProcessCrashTimes.remove(info.processName, info.uid); 2876 if (mBadProcesses.get(info.processName, info.uid) != null) { 2877 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2878 UserHandle.getUserId(info.uid), info.uid, 2879 info.processName); 2880 mBadProcesses.remove(info.processName, info.uid); 2881 if (app != null) { 2882 app.bad = false; 2883 } 2884 } 2885 } 2886 } 2887 2888 if (app == null) { 2889 app = newProcessRecordLocked(info, processName, isolated); 2890 if (app == null) { 2891 Slog.w(TAG, "Failed making new process record for " 2892 + processName + "/" + info.uid + " isolated=" + isolated); 2893 return null; 2894 } 2895 mProcessNames.put(processName, app.uid, app); 2896 if (isolated) { 2897 mIsolatedProcesses.put(app.uid, app); 2898 } 2899 } else { 2900 // If this is a new package in the process, add the package to the list 2901 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2902 } 2903 2904 // If the system is not ready yet, then hold off on starting this 2905 // process until it is. 2906 if (!mProcessesReady 2907 && !isAllowedWhileBooting(info) 2908 && !allowWhileBooting) { 2909 if (!mProcessesOnHold.contains(app)) { 2910 mProcessesOnHold.add(app); 2911 } 2912 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2913 return app; 2914 } 2915 2916 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2917 return (app.pid != 0) ? app : null; 2918 } 2919 2920 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2921 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2922 } 2923 2924 private final void startProcessLocked(ProcessRecord app, 2925 String hostingType, String hostingNameStr, String abiOverride) { 2926 if (app.pid > 0 && app.pid != MY_PID) { 2927 synchronized (mPidsSelfLocked) { 2928 mPidsSelfLocked.remove(app.pid); 2929 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2930 } 2931 app.setPid(0); 2932 } 2933 2934 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2935 "startProcessLocked removing on hold: " + app); 2936 mProcessesOnHold.remove(app); 2937 2938 updateCpuStats(); 2939 2940 try { 2941 int uid = app.uid; 2942 2943 int[] gids = null; 2944 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2945 if (!app.isolated) { 2946 int[] permGids = null; 2947 try { 2948 final PackageManager pm = mContext.getPackageManager(); 2949 permGids = pm.getPackageGids(app.info.packageName); 2950 2951 if (Environment.isExternalStorageEmulated()) { 2952 if (pm.checkPermission( 2953 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2954 app.info.packageName) == PERMISSION_GRANTED) { 2955 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2956 } else { 2957 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2958 } 2959 } 2960 } catch (PackageManager.NameNotFoundException e) { 2961 Slog.w(TAG, "Unable to retrieve gids", e); 2962 } 2963 2964 /* 2965 * Add shared application and profile GIDs so applications can share some 2966 * resources like shared libraries and access user-wide resources 2967 */ 2968 if (permGids == null) { 2969 gids = new int[2]; 2970 } else { 2971 gids = new int[permGids.length + 2]; 2972 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2973 } 2974 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2975 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2976 } 2977 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2978 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2979 && mTopComponent != null 2980 && app.processName.equals(mTopComponent.getPackageName())) { 2981 uid = 0; 2982 } 2983 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2984 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2985 uid = 0; 2986 } 2987 } 2988 int debugFlags = 0; 2989 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2991 // Also turn on CheckJNI for debuggable apps. It's quite 2992 // awkward to turn on otherwise. 2993 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2994 } 2995 // Run the app in safe mode if its manifest requests so or the 2996 // system is booted in safe mode. 2997 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2998 mSafeMode == true) { 2999 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3000 } 3001 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3002 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3003 } 3004 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3005 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3006 } 3007 if ("1".equals(SystemProperties.get("debug.assert"))) { 3008 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3009 } 3010 3011 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3012 if (requiredAbi == null) { 3013 requiredAbi = Build.SUPPORTED_ABIS[0]; 3014 } 3015 3016 // Start the process. It will either succeed and return a result containing 3017 // the PID of the new process, or else throw a RuntimeException. 3018 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 3019 app.processName, uid, uid, gids, debugFlags, mountExternal, 3020 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3021 3022 if (app.isolated) { 3023 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3024 } 3025 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3026 3027 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3028 UserHandle.getUserId(uid), startResult.pid, uid, 3029 app.processName, hostingType, 3030 hostingNameStr != null ? hostingNameStr : ""); 3031 3032 if (app.persistent) { 3033 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3034 } 3035 3036 StringBuilder buf = mStringBuilder; 3037 buf.setLength(0); 3038 buf.append("Start proc "); 3039 buf.append(app.processName); 3040 buf.append(" for "); 3041 buf.append(hostingType); 3042 if (hostingNameStr != null) { 3043 buf.append(" "); 3044 buf.append(hostingNameStr); 3045 } 3046 buf.append(": pid="); 3047 buf.append(startResult.pid); 3048 buf.append(" uid="); 3049 buf.append(uid); 3050 buf.append(" gids={"); 3051 if (gids != null) { 3052 for (int gi=0; gi<gids.length; gi++) { 3053 if (gi != 0) buf.append(", "); 3054 buf.append(gids[gi]); 3055 3056 } 3057 } 3058 buf.append("}"); 3059 if (requiredAbi != null) { 3060 buf.append(" abi="); 3061 buf.append(requiredAbi); 3062 } 3063 Slog.i(TAG, buf.toString()); 3064 app.setPid(startResult.pid); 3065 app.usingWrapper = startResult.usingWrapper; 3066 app.removed = false; 3067 app.killedByAm = false; 3068 synchronized (mPidsSelfLocked) { 3069 this.mPidsSelfLocked.put(startResult.pid, app); 3070 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3071 msg.obj = app; 3072 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3073 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3074 } 3075 } catch (RuntimeException e) { 3076 // XXX do better error recovery. 3077 app.setPid(0); 3078 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3079 if (app.isolated) { 3080 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3081 } 3082 Slog.e(TAG, "Failure starting process " + app.processName, e); 3083 } 3084 } 3085 3086 void updateUsageStats(ActivityRecord component, boolean resumed) { 3087 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3088 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3089 if (resumed) { 3090 mUsageStatsService.noteResumeComponent(component.realActivity); 3091 synchronized (stats) { 3092 stats.noteActivityResumedLocked(component.app.uid); 3093 } 3094 } else { 3095 mUsageStatsService.notePauseComponent(component.realActivity); 3096 synchronized (stats) { 3097 stats.noteActivityPausedLocked(component.app.uid); 3098 } 3099 } 3100 } 3101 3102 Intent getHomeIntent() { 3103 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3104 intent.setComponent(mTopComponent); 3105 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3106 intent.addCategory(Intent.CATEGORY_HOME); 3107 } 3108 return intent; 3109 } 3110 3111 boolean startHomeActivityLocked(int userId) { 3112 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3113 && mTopAction == null) { 3114 // We are running in factory test mode, but unable to find 3115 // the factory test app, so just sit around displaying the 3116 // error message and don't try to start anything. 3117 return false; 3118 } 3119 Intent intent = getHomeIntent(); 3120 ActivityInfo aInfo = 3121 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3122 if (aInfo != null) { 3123 intent.setComponent(new ComponentName( 3124 aInfo.applicationInfo.packageName, aInfo.name)); 3125 // Don't do this if the home app is currently being 3126 // instrumented. 3127 aInfo = new ActivityInfo(aInfo); 3128 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3129 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3130 aInfo.applicationInfo.uid, true); 3131 if (app == null || app.instrumentationClass == null) { 3132 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3133 mStackSupervisor.startHomeActivity(intent, aInfo); 3134 } 3135 } 3136 3137 return true; 3138 } 3139 3140 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3141 ActivityInfo ai = null; 3142 ComponentName comp = intent.getComponent(); 3143 try { 3144 if (comp != null) { 3145 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3146 } else { 3147 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3148 intent, 3149 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3150 flags, userId); 3151 3152 if (info != null) { 3153 ai = info.activityInfo; 3154 } 3155 } 3156 } catch (RemoteException e) { 3157 // ignore 3158 } 3159 3160 return ai; 3161 } 3162 3163 /** 3164 * Starts the "new version setup screen" if appropriate. 3165 */ 3166 void startSetupActivityLocked() { 3167 // Only do this once per boot. 3168 if (mCheckedForSetup) { 3169 return; 3170 } 3171 3172 // We will show this screen if the current one is a different 3173 // version than the last one shown, and we are not running in 3174 // low-level factory test mode. 3175 final ContentResolver resolver = mContext.getContentResolver(); 3176 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3177 Settings.Global.getInt(resolver, 3178 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3179 mCheckedForSetup = true; 3180 3181 // See if we should be showing the platform update setup UI. 3182 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3183 List<ResolveInfo> ris = mContext.getPackageManager() 3184 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3185 3186 // We don't allow third party apps to replace this. 3187 ResolveInfo ri = null; 3188 for (int i=0; ris != null && i<ris.size(); i++) { 3189 if ((ris.get(i).activityInfo.applicationInfo.flags 3190 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3191 ri = ris.get(i); 3192 break; 3193 } 3194 } 3195 3196 if (ri != null) { 3197 String vers = ri.activityInfo.metaData != null 3198 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3199 : null; 3200 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3201 vers = ri.activityInfo.applicationInfo.metaData.getString( 3202 Intent.METADATA_SETUP_VERSION); 3203 } 3204 String lastVers = Settings.Secure.getString( 3205 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3206 if (vers != null && !vers.equals(lastVers)) { 3207 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3208 intent.setComponent(new ComponentName( 3209 ri.activityInfo.packageName, ri.activityInfo.name)); 3210 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3211 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3212 } 3213 } 3214 } 3215 } 3216 3217 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3218 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3219 } 3220 3221 void enforceNotIsolatedCaller(String caller) { 3222 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3223 throw new SecurityException("Isolated process not allowed to call " + caller); 3224 } 3225 } 3226 3227 @Override 3228 public int getFrontActivityScreenCompatMode() { 3229 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3230 synchronized (this) { 3231 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3232 } 3233 } 3234 3235 @Override 3236 public void setFrontActivityScreenCompatMode(int mode) { 3237 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3238 "setFrontActivityScreenCompatMode"); 3239 synchronized (this) { 3240 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3241 } 3242 } 3243 3244 @Override 3245 public int getPackageScreenCompatMode(String packageName) { 3246 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3247 synchronized (this) { 3248 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3249 } 3250 } 3251 3252 @Override 3253 public void setPackageScreenCompatMode(String packageName, int mode) { 3254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3255 "setPackageScreenCompatMode"); 3256 synchronized (this) { 3257 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3258 } 3259 } 3260 3261 @Override 3262 public boolean getPackageAskScreenCompat(String packageName) { 3263 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3264 synchronized (this) { 3265 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3266 } 3267 } 3268 3269 @Override 3270 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3271 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3272 "setPackageAskScreenCompat"); 3273 synchronized (this) { 3274 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3275 } 3276 } 3277 3278 private void dispatchProcessesChanged() { 3279 int N; 3280 synchronized (this) { 3281 N = mPendingProcessChanges.size(); 3282 if (mActiveProcessChanges.length < N) { 3283 mActiveProcessChanges = new ProcessChangeItem[N]; 3284 } 3285 mPendingProcessChanges.toArray(mActiveProcessChanges); 3286 mAvailProcessChanges.addAll(mPendingProcessChanges); 3287 mPendingProcessChanges.clear(); 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3289 } 3290 3291 int i = mProcessObservers.beginBroadcast(); 3292 while (i > 0) { 3293 i--; 3294 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3295 if (observer != null) { 3296 try { 3297 for (int j=0; j<N; j++) { 3298 ProcessChangeItem item = mActiveProcessChanges[j]; 3299 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3300 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3301 + item.pid + " uid=" + item.uid + ": " 3302 + item.foregroundActivities); 3303 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3304 item.foregroundActivities); 3305 } 3306 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3308 + item.pid + " uid=" + item.uid + ": " + item.processState); 3309 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3310 } 3311 } 3312 } catch (RemoteException e) { 3313 } 3314 } 3315 } 3316 mProcessObservers.finishBroadcast(); 3317 } 3318 3319 private void dispatchProcessDied(int pid, int uid) { 3320 int i = mProcessObservers.beginBroadcast(); 3321 while (i > 0) { 3322 i--; 3323 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3324 if (observer != null) { 3325 try { 3326 observer.onProcessDied(pid, uid); 3327 } catch (RemoteException e) { 3328 } 3329 } 3330 } 3331 mProcessObservers.finishBroadcast(); 3332 } 3333 3334 final void doPendingActivityLaunchesLocked(boolean doResume) { 3335 final int N = mPendingActivityLaunches.size(); 3336 if (N <= 0) { 3337 return; 3338 } 3339 for (int i=0; i<N; i++) { 3340 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3341 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3342 doResume && i == (N-1), null); 3343 } 3344 mPendingActivityLaunches.clear(); 3345 } 3346 3347 @Override 3348 public final int startActivity(IApplicationThread caller, String callingPackage, 3349 Intent intent, String resolvedType, IBinder resultTo, 3350 String resultWho, int requestCode, int startFlags, 3351 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3352 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3353 resultWho, requestCode, 3354 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3355 } 3356 3357 @Override 3358 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3359 Intent intent, String resolvedType, IBinder resultTo, 3360 String resultWho, int requestCode, int startFlags, 3361 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3362 enforceNotIsolatedCaller("startActivity"); 3363 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3364 false, ALLOW_FULL_ONLY, "startActivity", null); 3365 // TODO: Switch to user app stacks here. 3366 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3367 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3368 null, null, options, userId, null); 3369 } 3370 3371 @Override 3372 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3373 Intent intent, String resolvedType, IBinder resultTo, 3374 String resultWho, int requestCode, int startFlags, String profileFile, 3375 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3376 enforceNotIsolatedCaller("startActivityAndWait"); 3377 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3378 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3379 WaitResult res = new WaitResult(); 3380 // TODO: Switch to user app stacks here. 3381 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3382 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3383 res, null, options, userId, null); 3384 return res; 3385 } 3386 3387 @Override 3388 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3389 Intent intent, String resolvedType, IBinder resultTo, 3390 String resultWho, int requestCode, int startFlags, Configuration config, 3391 Bundle options, int userId) { 3392 enforceNotIsolatedCaller("startActivityWithConfig"); 3393 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3394 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3395 // TODO: Switch to user app stacks here. 3396 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3397 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3398 null, null, null, config, options, userId, null); 3399 return ret; 3400 } 3401 3402 @Override 3403 public int startActivityIntentSender(IApplicationThread caller, 3404 IntentSender intent, Intent fillInIntent, String resolvedType, 3405 IBinder resultTo, String resultWho, int requestCode, 3406 int flagsMask, int flagsValues, Bundle options) { 3407 enforceNotIsolatedCaller("startActivityIntentSender"); 3408 // Refuse possible leaked file descriptors 3409 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3410 throw new IllegalArgumentException("File descriptors passed in Intent"); 3411 } 3412 3413 IIntentSender sender = intent.getTarget(); 3414 if (!(sender instanceof PendingIntentRecord)) { 3415 throw new IllegalArgumentException("Bad PendingIntent object"); 3416 } 3417 3418 PendingIntentRecord pir = (PendingIntentRecord)sender; 3419 3420 synchronized (this) { 3421 // If this is coming from the currently resumed activity, it is 3422 // effectively saying that app switches are allowed at this point. 3423 final ActivityStack stack = getFocusedStack(); 3424 if (stack.mResumedActivity != null && 3425 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3426 mAppSwitchesAllowedTime = 0; 3427 } 3428 } 3429 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3430 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3431 return ret; 3432 } 3433 3434 @Override 3435 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3436 Intent intent, String resolvedType, IVoiceInteractionSession session, 3437 IVoiceInteractor interactor, int startFlags, String profileFile, 3438 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3439 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3440 != PackageManager.PERMISSION_GRANTED) { 3441 String msg = "Permission Denial: startVoiceActivity() from pid=" 3442 + Binder.getCallingPid() 3443 + ", uid=" + Binder.getCallingUid() 3444 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3445 Slog.w(TAG, msg); 3446 throw new SecurityException(msg); 3447 } 3448 if (session == null || interactor == null) { 3449 throw new NullPointerException("null session or interactor"); 3450 } 3451 userId = handleIncomingUser(callingPid, callingUid, userId, 3452 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3453 // TODO: Switch to user app stacks here. 3454 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3455 resolvedType, session, interactor, null, null, 0, startFlags, 3456 profileFile, profileFd, null, null, options, userId, null); 3457 } 3458 3459 @Override 3460 public boolean startNextMatchingActivity(IBinder callingActivity, 3461 Intent intent, Bundle options) { 3462 // Refuse possible leaked file descriptors 3463 if (intent != null && intent.hasFileDescriptors() == true) { 3464 throw new IllegalArgumentException("File descriptors passed in Intent"); 3465 } 3466 3467 synchronized (this) { 3468 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3469 if (r == null) { 3470 ActivityOptions.abort(options); 3471 return false; 3472 } 3473 if (r.app == null || r.app.thread == null) { 3474 // The caller is not running... d'oh! 3475 ActivityOptions.abort(options); 3476 return false; 3477 } 3478 intent = new Intent(intent); 3479 // The caller is not allowed to change the data. 3480 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3481 // And we are resetting to find the next component... 3482 intent.setComponent(null); 3483 3484 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3485 3486 ActivityInfo aInfo = null; 3487 try { 3488 List<ResolveInfo> resolves = 3489 AppGlobals.getPackageManager().queryIntentActivities( 3490 intent, r.resolvedType, 3491 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3492 UserHandle.getCallingUserId()); 3493 3494 // Look for the original activity in the list... 3495 final int N = resolves != null ? resolves.size() : 0; 3496 for (int i=0; i<N; i++) { 3497 ResolveInfo rInfo = resolves.get(i); 3498 if (rInfo.activityInfo.packageName.equals(r.packageName) 3499 && rInfo.activityInfo.name.equals(r.info.name)) { 3500 // We found the current one... the next matching is 3501 // after it. 3502 i++; 3503 if (i<N) { 3504 aInfo = resolves.get(i).activityInfo; 3505 } 3506 if (debug) { 3507 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3508 + "/" + r.info.name); 3509 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3510 + "/" + aInfo.name); 3511 } 3512 break; 3513 } 3514 } 3515 } catch (RemoteException e) { 3516 } 3517 3518 if (aInfo == null) { 3519 // Nobody who is next! 3520 ActivityOptions.abort(options); 3521 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3522 return false; 3523 } 3524 3525 intent.setComponent(new ComponentName( 3526 aInfo.applicationInfo.packageName, aInfo.name)); 3527 intent.setFlags(intent.getFlags()&~( 3528 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3529 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3530 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3531 Intent.FLAG_ACTIVITY_NEW_TASK)); 3532 3533 // Okay now we need to start the new activity, replacing the 3534 // currently running activity. This is a little tricky because 3535 // we want to start the new one as if the current one is finished, 3536 // but not finish the current one first so that there is no flicker. 3537 // And thus... 3538 final boolean wasFinishing = r.finishing; 3539 r.finishing = true; 3540 3541 // Propagate reply information over to the new activity. 3542 final ActivityRecord resultTo = r.resultTo; 3543 final String resultWho = r.resultWho; 3544 final int requestCode = r.requestCode; 3545 r.resultTo = null; 3546 if (resultTo != null) { 3547 resultTo.removeResultsLocked(r, resultWho, requestCode); 3548 } 3549 3550 final long origId = Binder.clearCallingIdentity(); 3551 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3552 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3553 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3554 options, false, null, null); 3555 Binder.restoreCallingIdentity(origId); 3556 3557 r.finishing = wasFinishing; 3558 if (res != ActivityManager.START_SUCCESS) { 3559 return false; 3560 } 3561 return true; 3562 } 3563 } 3564 3565 final int startActivityInPackage(int uid, String callingPackage, 3566 Intent intent, String resolvedType, IBinder resultTo, 3567 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3568 IActivityContainer container) { 3569 3570 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3571 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3572 3573 // TODO: Switch to user app stacks here. 3574 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3575 null, null, resultTo, resultWho, requestCode, startFlags, 3576 null, null, null, null, options, userId, container); 3577 return ret; 3578 } 3579 3580 @Override 3581 public final int startActivities(IApplicationThread caller, String callingPackage, 3582 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3583 int userId) { 3584 enforceNotIsolatedCaller("startActivities"); 3585 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3586 false, ALLOW_FULL_ONLY, "startActivity", null); 3587 // TODO: Switch to user app stacks here. 3588 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3589 resolvedTypes, resultTo, options, userId); 3590 return ret; 3591 } 3592 3593 final int startActivitiesInPackage(int uid, String callingPackage, 3594 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3595 Bundle options, int userId) { 3596 3597 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3598 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3599 // TODO: Switch to user app stacks here. 3600 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3601 resultTo, options, userId); 3602 return ret; 3603 } 3604 3605 final void addRecentTaskLocked(TaskRecord task) { 3606 int N = mRecentTasks.size(); 3607 // Quick case: check if the top-most recent task is the same. 3608 if (N > 0 && mRecentTasks.get(0) == task) { 3609 return; 3610 } 3611 // Another quick case: never add voice sessions. 3612 if (task.voiceSession != null) { 3613 return; 3614 } 3615 // Remove any existing entries that are the same kind of task. 3616 final Intent intent = task.intent; 3617 final boolean document = intent != null && intent.isDocument(); 3618 final ComponentName comp = intent.getComponent(); 3619 3620 int maxRecents = task.maxRecents - 1; 3621 for (int i=0; i<N; i++) { 3622 final TaskRecord tr = mRecentTasks.get(i); 3623 if (task != tr) { 3624 if (task.userId != tr.userId) { 3625 continue; 3626 } 3627 if (i > MAX_RECENT_BITMAPS) { 3628 tr.freeLastThumbnail(); 3629 } 3630 final Intent trIntent = tr.intent; 3631 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3632 (intent == null || !intent.filterEquals(trIntent))) { 3633 continue; 3634 } 3635 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3636 if (document && trIsDocument) { 3637 // These are the same document activity (not necessarily the same doc). 3638 if (maxRecents > 0) { 3639 --maxRecents; 3640 continue; 3641 } 3642 // Hit the maximum number of documents for this task. Fall through 3643 // and remove this document from recents. 3644 } else if (document || trIsDocument) { 3645 // Only one of these is a document. Not the droid we're looking for. 3646 continue; 3647 } 3648 } 3649 3650 // Either task and tr are the same or, their affinities match or their intents match 3651 // and neither of them is a document, or they are documents using the same activity 3652 // and their maxRecents has been reached. 3653 tr.disposeThumbnail(); 3654 mRecentTasks.remove(i); 3655 if (task != tr) { 3656 tr.closeRecentsChain(); 3657 } 3658 i--; 3659 N--; 3660 if (task.intent == null) { 3661 // If the new recent task we are adding is not fully 3662 // specified, then replace it with the existing recent task. 3663 task = tr; 3664 } 3665 mTaskPersister.notify(tr, false); 3666 } 3667 if (N >= MAX_RECENT_TASKS) { 3668 final TaskRecord tr = mRecentTasks.remove(N - 1); 3669 tr.disposeThumbnail(); 3670 tr.closeRecentsChain(); 3671 } 3672 mRecentTasks.add(0, task); 3673 } 3674 3675 @Override 3676 public void reportActivityFullyDrawn(IBinder token) { 3677 synchronized (this) { 3678 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3679 if (r == null) { 3680 return; 3681 } 3682 r.reportFullyDrawnLocked(); 3683 } 3684 } 3685 3686 @Override 3687 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3688 synchronized (this) { 3689 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3690 if (r == null) { 3691 return; 3692 } 3693 final long origId = Binder.clearCallingIdentity(); 3694 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3695 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3696 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3697 if (config != null) { 3698 r.frozenBeforeDestroy = true; 3699 if (!updateConfigurationLocked(config, r, false, false)) { 3700 mStackSupervisor.resumeTopActivitiesLocked(); 3701 } 3702 } 3703 Binder.restoreCallingIdentity(origId); 3704 } 3705 } 3706 3707 @Override 3708 public int getRequestedOrientation(IBinder token) { 3709 synchronized (this) { 3710 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3711 if (r == null) { 3712 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3713 } 3714 return mWindowManager.getAppOrientation(r.appToken); 3715 } 3716 } 3717 3718 /** 3719 * This is the internal entry point for handling Activity.finish(). 3720 * 3721 * @param token The Binder token referencing the Activity we want to finish. 3722 * @param resultCode Result code, if any, from this Activity. 3723 * @param resultData Result data (Intent), if any, from this Activity. 3724 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3725 * the root Activity in the task. 3726 * 3727 * @return Returns true if the activity successfully finished, or false if it is still running. 3728 */ 3729 @Override 3730 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3731 boolean finishTask) { 3732 // Refuse possible leaked file descriptors 3733 if (resultData != null && resultData.hasFileDescriptors() == true) { 3734 throw new IllegalArgumentException("File descriptors passed in Intent"); 3735 } 3736 3737 synchronized(this) { 3738 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3739 if (r == null) { 3740 return true; 3741 } 3742 // Keep track of the root activity of the task before we finish it 3743 TaskRecord tr = r.task; 3744 ActivityRecord rootR = tr.getRootActivity(); 3745 // Do not allow task to finish in Lock Task mode. 3746 if (tr == mStackSupervisor.mLockTaskModeTask) { 3747 if (rootR == r) { 3748 mStackSupervisor.showLockTaskToast(); 3749 return false; 3750 } 3751 } 3752 if (mController != null) { 3753 // Find the first activity that is not finishing. 3754 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3755 if (next != null) { 3756 // ask watcher if this is allowed 3757 boolean resumeOK = true; 3758 try { 3759 resumeOK = mController.activityResuming(next.packageName); 3760 } catch (RemoteException e) { 3761 mController = null; 3762 Watchdog.getInstance().setActivityController(null); 3763 } 3764 3765 if (!resumeOK) { 3766 return false; 3767 } 3768 } 3769 } 3770 final long origId = Binder.clearCallingIdentity(); 3771 try { 3772 boolean res; 3773 if (finishTask && r == rootR) { 3774 // If requested, remove the task that is associated to this activity only if it 3775 // was the root activity in the task. The result code and data is ignored because 3776 // we don't support returning them across task boundaries. 3777 res = removeTaskByIdLocked(tr.taskId, 0); 3778 } else { 3779 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3780 resultData, "app-request", true); 3781 } 3782 return res; 3783 } finally { 3784 Binder.restoreCallingIdentity(origId); 3785 } 3786 } 3787 } 3788 3789 @Override 3790 public final void finishHeavyWeightApp() { 3791 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3792 != PackageManager.PERMISSION_GRANTED) { 3793 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3794 + Binder.getCallingPid() 3795 + ", uid=" + Binder.getCallingUid() 3796 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3797 Slog.w(TAG, msg); 3798 throw new SecurityException(msg); 3799 } 3800 3801 synchronized(this) { 3802 if (mHeavyWeightProcess == null) { 3803 return; 3804 } 3805 3806 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3807 mHeavyWeightProcess.activities); 3808 for (int i=0; i<activities.size(); i++) { 3809 ActivityRecord r = activities.get(i); 3810 if (!r.finishing) { 3811 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3812 null, "finish-heavy", true); 3813 } 3814 } 3815 3816 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3817 mHeavyWeightProcess.userId, 0)); 3818 mHeavyWeightProcess = null; 3819 } 3820 } 3821 3822 @Override 3823 public void crashApplication(int uid, int initialPid, String packageName, 3824 String message) { 3825 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3826 != PackageManager.PERMISSION_GRANTED) { 3827 String msg = "Permission Denial: crashApplication() from pid=" 3828 + Binder.getCallingPid() 3829 + ", uid=" + Binder.getCallingUid() 3830 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3831 Slog.w(TAG, msg); 3832 throw new SecurityException(msg); 3833 } 3834 3835 synchronized(this) { 3836 ProcessRecord proc = null; 3837 3838 // Figure out which process to kill. We don't trust that initialPid 3839 // still has any relation to current pids, so must scan through the 3840 // list. 3841 synchronized (mPidsSelfLocked) { 3842 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3843 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3844 if (p.uid != uid) { 3845 continue; 3846 } 3847 if (p.pid == initialPid) { 3848 proc = p; 3849 break; 3850 } 3851 if (p.pkgList.containsKey(packageName)) { 3852 proc = p; 3853 } 3854 } 3855 } 3856 3857 if (proc == null) { 3858 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3859 + " initialPid=" + initialPid 3860 + " packageName=" + packageName); 3861 return; 3862 } 3863 3864 if (proc.thread != null) { 3865 if (proc.pid == Process.myPid()) { 3866 Log.w(TAG, "crashApplication: trying to crash self!"); 3867 return; 3868 } 3869 long ident = Binder.clearCallingIdentity(); 3870 try { 3871 proc.thread.scheduleCrash(message); 3872 } catch (RemoteException e) { 3873 } 3874 Binder.restoreCallingIdentity(ident); 3875 } 3876 } 3877 } 3878 3879 @Override 3880 public final void finishSubActivity(IBinder token, String resultWho, 3881 int requestCode) { 3882 synchronized(this) { 3883 final long origId = Binder.clearCallingIdentity(); 3884 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3885 if (r != null) { 3886 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3887 } 3888 Binder.restoreCallingIdentity(origId); 3889 } 3890 } 3891 3892 @Override 3893 public boolean finishActivityAffinity(IBinder token) { 3894 synchronized(this) { 3895 final long origId = Binder.clearCallingIdentity(); 3896 try { 3897 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3898 3899 ActivityRecord rootR = r.task.getRootActivity(); 3900 // Do not allow task to finish in Lock Task mode. 3901 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3902 if (rootR == r) { 3903 mStackSupervisor.showLockTaskToast(); 3904 return false; 3905 } 3906 } 3907 boolean res = false; 3908 if (r != null) { 3909 res = r.task.stack.finishActivityAffinityLocked(r); 3910 } 3911 return res; 3912 } finally { 3913 Binder.restoreCallingIdentity(origId); 3914 } 3915 } 3916 } 3917 3918 @Override 3919 public void finishVoiceTask(IVoiceInteractionSession session) { 3920 synchronized(this) { 3921 final long origId = Binder.clearCallingIdentity(); 3922 try { 3923 mStackSupervisor.finishVoiceTask(session); 3924 } finally { 3925 Binder.restoreCallingIdentity(origId); 3926 } 3927 } 3928 3929 } 3930 3931 @Override 3932 public boolean willActivityBeVisible(IBinder token) { 3933 synchronized(this) { 3934 ActivityStack stack = ActivityRecord.getStackLocked(token); 3935 if (stack != null) { 3936 return stack.willActivityBeVisibleLocked(token); 3937 } 3938 return false; 3939 } 3940 } 3941 3942 @Override 3943 public void overridePendingTransition(IBinder token, String packageName, 3944 int enterAnim, int exitAnim) { 3945 synchronized(this) { 3946 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3947 if (self == null) { 3948 return; 3949 } 3950 3951 final long origId = Binder.clearCallingIdentity(); 3952 3953 if (self.state == ActivityState.RESUMED 3954 || self.state == ActivityState.PAUSING) { 3955 mWindowManager.overridePendingAppTransition(packageName, 3956 enterAnim, exitAnim, null); 3957 } 3958 3959 Binder.restoreCallingIdentity(origId); 3960 } 3961 } 3962 3963 /** 3964 * Main function for removing an existing process from the activity manager 3965 * as a result of that process going away. Clears out all connections 3966 * to the process. 3967 */ 3968 private final void handleAppDiedLocked(ProcessRecord app, 3969 boolean restarting, boolean allowRestart) { 3970 int pid = app.pid; 3971 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3972 if (!restarting) { 3973 removeLruProcessLocked(app); 3974 if (pid > 0) { 3975 ProcessList.remove(pid); 3976 } 3977 } 3978 3979 if (mProfileProc == app) { 3980 clearProfilerLocked(); 3981 } 3982 3983 // Remove this application's activities from active lists. 3984 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3985 3986 app.activities.clear(); 3987 3988 if (app.instrumentationClass != null) { 3989 Slog.w(TAG, "Crash of app " + app.processName 3990 + " running instrumentation " + app.instrumentationClass); 3991 Bundle info = new Bundle(); 3992 info.putString("shortMsg", "Process crashed."); 3993 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3994 } 3995 3996 if (!restarting) { 3997 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3998 // If there was nothing to resume, and we are not already 3999 // restarting this process, but there is a visible activity that 4000 // is hosted by the process... then make sure all visible 4001 // activities are running, taking care of restarting this 4002 // process. 4003 if (hasVisibleActivities) { 4004 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4005 } 4006 } 4007 } 4008 } 4009 4010 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4011 IBinder threadBinder = thread.asBinder(); 4012 // Find the application record. 4013 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4014 ProcessRecord rec = mLruProcesses.get(i); 4015 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4016 return i; 4017 } 4018 } 4019 return -1; 4020 } 4021 4022 final ProcessRecord getRecordForAppLocked( 4023 IApplicationThread thread) { 4024 if (thread == null) { 4025 return null; 4026 } 4027 4028 int appIndex = getLRURecordIndexForAppLocked(thread); 4029 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4030 } 4031 4032 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4033 // If there are no longer any background processes running, 4034 // and the app that died was not running instrumentation, 4035 // then tell everyone we are now low on memory. 4036 boolean haveBg = false; 4037 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4038 ProcessRecord rec = mLruProcesses.get(i); 4039 if (rec.thread != null 4040 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4041 haveBg = true; 4042 break; 4043 } 4044 } 4045 4046 if (!haveBg) { 4047 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4048 if (doReport) { 4049 long now = SystemClock.uptimeMillis(); 4050 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4051 doReport = false; 4052 } else { 4053 mLastMemUsageReportTime = now; 4054 } 4055 } 4056 final ArrayList<ProcessMemInfo> memInfos 4057 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4058 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4059 long now = SystemClock.uptimeMillis(); 4060 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4061 ProcessRecord rec = mLruProcesses.get(i); 4062 if (rec == dyingProc || rec.thread == null) { 4063 continue; 4064 } 4065 if (doReport) { 4066 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4067 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4068 } 4069 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4070 // The low memory report is overriding any current 4071 // state for a GC request. Make sure to do 4072 // heavy/important/visible/foreground processes first. 4073 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4074 rec.lastRequestedGc = 0; 4075 } else { 4076 rec.lastRequestedGc = rec.lastLowMemory; 4077 } 4078 rec.reportLowMemory = true; 4079 rec.lastLowMemory = now; 4080 mProcessesToGc.remove(rec); 4081 addProcessToGcListLocked(rec); 4082 } 4083 } 4084 if (doReport) { 4085 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4086 mHandler.sendMessage(msg); 4087 } 4088 scheduleAppGcsLocked(); 4089 } 4090 } 4091 4092 final void appDiedLocked(ProcessRecord app, int pid, 4093 IApplicationThread thread) { 4094 4095 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4096 synchronized (stats) { 4097 stats.noteProcessDiedLocked(app.info.uid, pid); 4098 } 4099 4100 Process.killProcessGroup(app.info.uid, pid); 4101 4102 // Clean up already done if the process has been re-started. 4103 if (app.pid == pid && app.thread != null && 4104 app.thread.asBinder() == thread.asBinder()) { 4105 boolean doLowMem = app.instrumentationClass == null; 4106 boolean doOomAdj = doLowMem; 4107 if (!app.killedByAm) { 4108 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4109 + ") has died."); 4110 mAllowLowerMemLevel = true; 4111 } else { 4112 // Note that we always want to do oom adj to update our state with the 4113 // new number of procs. 4114 mAllowLowerMemLevel = false; 4115 doLowMem = false; 4116 } 4117 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4118 if (DEBUG_CLEANUP) Slog.v( 4119 TAG, "Dying app: " + app + ", pid: " + pid 4120 + ", thread: " + thread.asBinder()); 4121 handleAppDiedLocked(app, false, true); 4122 4123 if (doOomAdj) { 4124 updateOomAdjLocked(); 4125 } 4126 if (doLowMem) { 4127 doLowMemReportIfNeededLocked(app); 4128 } 4129 } else if (app.pid != pid) { 4130 // A new process has already been started. 4131 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4132 + ") has died and restarted (pid " + app.pid + ")."); 4133 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4134 } else if (DEBUG_PROCESSES) { 4135 Slog.d(TAG, "Received spurious death notification for thread " 4136 + thread.asBinder()); 4137 } 4138 } 4139 4140 /** 4141 * If a stack trace dump file is configured, dump process stack traces. 4142 * @param clearTraces causes the dump file to be erased prior to the new 4143 * traces being written, if true; when false, the new traces will be 4144 * appended to any existing file content. 4145 * @param firstPids of dalvik VM processes to dump stack traces for first 4146 * @param lastPids of dalvik VM processes to dump stack traces for last 4147 * @param nativeProcs optional list of native process names to dump stack crawls 4148 * @return file containing stack traces, or null if no dump file is configured 4149 */ 4150 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4151 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4152 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4153 if (tracesPath == null || tracesPath.length() == 0) { 4154 return null; 4155 } 4156 4157 File tracesFile = new File(tracesPath); 4158 try { 4159 File tracesDir = tracesFile.getParentFile(); 4160 if (!tracesDir.exists()) { 4161 tracesFile.mkdirs(); 4162 if (!SELinux.restorecon(tracesDir)) { 4163 return null; 4164 } 4165 } 4166 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4167 4168 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4169 tracesFile.createNewFile(); 4170 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4171 } catch (IOException e) { 4172 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4173 return null; 4174 } 4175 4176 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4177 return tracesFile; 4178 } 4179 4180 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4181 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4182 // Use a FileObserver to detect when traces finish writing. 4183 // The order of traces is considered important to maintain for legibility. 4184 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4185 @Override 4186 public synchronized void onEvent(int event, String path) { notify(); } 4187 }; 4188 4189 try { 4190 observer.startWatching(); 4191 4192 // First collect all of the stacks of the most important pids. 4193 if (firstPids != null) { 4194 try { 4195 int num = firstPids.size(); 4196 for (int i = 0; i < num; i++) { 4197 synchronized (observer) { 4198 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4199 observer.wait(200); // Wait for write-close, give up after 200msec 4200 } 4201 } 4202 } catch (InterruptedException e) { 4203 Log.wtf(TAG, e); 4204 } 4205 } 4206 4207 // Next collect the stacks of the native pids 4208 if (nativeProcs != null) { 4209 int[] pids = Process.getPidsForCommands(nativeProcs); 4210 if (pids != null) { 4211 for (int pid : pids) { 4212 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4213 } 4214 } 4215 } 4216 4217 // Lastly, measure CPU usage. 4218 if (processCpuTracker != null) { 4219 processCpuTracker.init(); 4220 System.gc(); 4221 processCpuTracker.update(); 4222 try { 4223 synchronized (processCpuTracker) { 4224 processCpuTracker.wait(500); // measure over 1/2 second. 4225 } 4226 } catch (InterruptedException e) { 4227 } 4228 processCpuTracker.update(); 4229 4230 // We'll take the stack crawls of just the top apps using CPU. 4231 final int N = processCpuTracker.countWorkingStats(); 4232 int numProcs = 0; 4233 for (int i=0; i<N && numProcs<5; i++) { 4234 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4235 if (lastPids.indexOfKey(stats.pid) >= 0) { 4236 numProcs++; 4237 try { 4238 synchronized (observer) { 4239 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4240 observer.wait(200); // Wait for write-close, give up after 200msec 4241 } 4242 } catch (InterruptedException e) { 4243 Log.wtf(TAG, e); 4244 } 4245 4246 } 4247 } 4248 } 4249 } finally { 4250 observer.stopWatching(); 4251 } 4252 } 4253 4254 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4255 if (true || IS_USER_BUILD) { 4256 return; 4257 } 4258 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4259 if (tracesPath == null || tracesPath.length() == 0) { 4260 return; 4261 } 4262 4263 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4264 StrictMode.allowThreadDiskWrites(); 4265 try { 4266 final File tracesFile = new File(tracesPath); 4267 final File tracesDir = tracesFile.getParentFile(); 4268 final File tracesTmp = new File(tracesDir, "__tmp__"); 4269 try { 4270 if (!tracesDir.exists()) { 4271 tracesFile.mkdirs(); 4272 if (!SELinux.restorecon(tracesDir.getPath())) { 4273 return; 4274 } 4275 } 4276 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4277 4278 if (tracesFile.exists()) { 4279 tracesTmp.delete(); 4280 tracesFile.renameTo(tracesTmp); 4281 } 4282 StringBuilder sb = new StringBuilder(); 4283 Time tobj = new Time(); 4284 tobj.set(System.currentTimeMillis()); 4285 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4286 sb.append(": "); 4287 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4288 sb.append(" since "); 4289 sb.append(msg); 4290 FileOutputStream fos = new FileOutputStream(tracesFile); 4291 fos.write(sb.toString().getBytes()); 4292 if (app == null) { 4293 fos.write("\n*** No application process!".getBytes()); 4294 } 4295 fos.close(); 4296 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4297 } catch (IOException e) { 4298 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4299 return; 4300 } 4301 4302 if (app != null) { 4303 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4304 firstPids.add(app.pid); 4305 dumpStackTraces(tracesPath, firstPids, null, null, null); 4306 } 4307 4308 File lastTracesFile = null; 4309 File curTracesFile = null; 4310 for (int i=9; i>=0; i--) { 4311 String name = String.format(Locale.US, "slow%02d.txt", i); 4312 curTracesFile = new File(tracesDir, name); 4313 if (curTracesFile.exists()) { 4314 if (lastTracesFile != null) { 4315 curTracesFile.renameTo(lastTracesFile); 4316 } else { 4317 curTracesFile.delete(); 4318 } 4319 } 4320 lastTracesFile = curTracesFile; 4321 } 4322 tracesFile.renameTo(curTracesFile); 4323 if (tracesTmp.exists()) { 4324 tracesTmp.renameTo(tracesFile); 4325 } 4326 } finally { 4327 StrictMode.setThreadPolicy(oldPolicy); 4328 } 4329 } 4330 4331 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4332 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4333 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4334 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4335 4336 if (mController != null) { 4337 try { 4338 // 0 == continue, -1 = kill process immediately 4339 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4340 if (res < 0 && app.pid != MY_PID) { 4341 Process.killProcess(app.pid); 4342 Process.killProcessGroup(app.info.uid, app.pid); 4343 } 4344 } catch (RemoteException e) { 4345 mController = null; 4346 Watchdog.getInstance().setActivityController(null); 4347 } 4348 } 4349 4350 long anrTime = SystemClock.uptimeMillis(); 4351 if (MONITOR_CPU_USAGE) { 4352 updateCpuStatsNow(); 4353 } 4354 4355 synchronized (this) { 4356 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4357 if (mShuttingDown) { 4358 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4359 return; 4360 } else if (app.notResponding) { 4361 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4362 return; 4363 } else if (app.crashing) { 4364 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4365 return; 4366 } 4367 4368 // In case we come through here for the same app before completing 4369 // this one, mark as anring now so we will bail out. 4370 app.notResponding = true; 4371 4372 // Log the ANR to the event log. 4373 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4374 app.processName, app.info.flags, annotation); 4375 4376 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4377 firstPids.add(app.pid); 4378 4379 int parentPid = app.pid; 4380 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4381 if (parentPid != app.pid) firstPids.add(parentPid); 4382 4383 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4384 4385 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4386 ProcessRecord r = mLruProcesses.get(i); 4387 if (r != null && r.thread != null) { 4388 int pid = r.pid; 4389 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4390 if (r.persistent) { 4391 firstPids.add(pid); 4392 } else { 4393 lastPids.put(pid, Boolean.TRUE); 4394 } 4395 } 4396 } 4397 } 4398 } 4399 4400 // Log the ANR to the main log. 4401 StringBuilder info = new StringBuilder(); 4402 info.setLength(0); 4403 info.append("ANR in ").append(app.processName); 4404 if (activity != null && activity.shortComponentName != null) { 4405 info.append(" (").append(activity.shortComponentName).append(")"); 4406 } 4407 info.append("\n"); 4408 info.append("PID: ").append(app.pid).append("\n"); 4409 if (annotation != null) { 4410 info.append("Reason: ").append(annotation).append("\n"); 4411 } 4412 if (parent != null && parent != activity) { 4413 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4414 } 4415 4416 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4417 4418 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4419 NATIVE_STACKS_OF_INTEREST); 4420 4421 String cpuInfo = null; 4422 if (MONITOR_CPU_USAGE) { 4423 updateCpuStatsNow(); 4424 synchronized (mProcessCpuThread) { 4425 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4426 } 4427 info.append(processCpuTracker.printCurrentLoad()); 4428 info.append(cpuInfo); 4429 } 4430 4431 info.append(processCpuTracker.printCurrentState(anrTime)); 4432 4433 Slog.e(TAG, info.toString()); 4434 if (tracesFile == null) { 4435 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4436 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4437 } 4438 4439 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4440 cpuInfo, tracesFile, null); 4441 4442 if (mController != null) { 4443 try { 4444 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4445 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4446 if (res != 0) { 4447 if (res < 0 && app.pid != MY_PID) { 4448 Process.killProcess(app.pid); 4449 Process.killProcessGroup(app.info.uid, app.pid); 4450 } else { 4451 synchronized (this) { 4452 mServices.scheduleServiceTimeoutLocked(app); 4453 } 4454 } 4455 return; 4456 } 4457 } catch (RemoteException e) { 4458 mController = null; 4459 Watchdog.getInstance().setActivityController(null); 4460 } 4461 } 4462 4463 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4464 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4465 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4466 4467 synchronized (this) { 4468 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4469 killUnneededProcessLocked(app, "background ANR"); 4470 return; 4471 } 4472 4473 // Set the app's notResponding state, and look up the errorReportReceiver 4474 makeAppNotRespondingLocked(app, 4475 activity != null ? activity.shortComponentName : null, 4476 annotation != null ? "ANR " + annotation : "ANR", 4477 info.toString()); 4478 4479 // Bring up the infamous App Not Responding dialog 4480 Message msg = Message.obtain(); 4481 HashMap<String, Object> map = new HashMap<String, Object>(); 4482 msg.what = SHOW_NOT_RESPONDING_MSG; 4483 msg.obj = map; 4484 msg.arg1 = aboveSystem ? 1 : 0; 4485 map.put("app", app); 4486 if (activity != null) { 4487 map.put("activity", activity); 4488 } 4489 4490 mHandler.sendMessage(msg); 4491 } 4492 } 4493 4494 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4495 if (!mLaunchWarningShown) { 4496 mLaunchWarningShown = true; 4497 mHandler.post(new Runnable() { 4498 @Override 4499 public void run() { 4500 synchronized (ActivityManagerService.this) { 4501 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4502 d.show(); 4503 mHandler.postDelayed(new Runnable() { 4504 @Override 4505 public void run() { 4506 synchronized (ActivityManagerService.this) { 4507 d.dismiss(); 4508 mLaunchWarningShown = false; 4509 } 4510 } 4511 }, 4000); 4512 } 4513 } 4514 }); 4515 } 4516 } 4517 4518 @Override 4519 public boolean clearApplicationUserData(final String packageName, 4520 final IPackageDataObserver observer, int userId) { 4521 enforceNotIsolatedCaller("clearApplicationUserData"); 4522 int uid = Binder.getCallingUid(); 4523 int pid = Binder.getCallingPid(); 4524 userId = handleIncomingUser(pid, uid, 4525 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4526 long callingId = Binder.clearCallingIdentity(); 4527 try { 4528 IPackageManager pm = AppGlobals.getPackageManager(); 4529 int pkgUid = -1; 4530 synchronized(this) { 4531 try { 4532 pkgUid = pm.getPackageUid(packageName, userId); 4533 } catch (RemoteException e) { 4534 } 4535 if (pkgUid == -1) { 4536 Slog.w(TAG, "Invalid packageName: " + packageName); 4537 if (observer != null) { 4538 try { 4539 observer.onRemoveCompleted(packageName, false); 4540 } catch (RemoteException e) { 4541 Slog.i(TAG, "Observer no longer exists."); 4542 } 4543 } 4544 return false; 4545 } 4546 if (uid == pkgUid || checkComponentPermission( 4547 android.Manifest.permission.CLEAR_APP_USER_DATA, 4548 pid, uid, -1, true) 4549 == PackageManager.PERMISSION_GRANTED) { 4550 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4551 } else { 4552 throw new SecurityException("PID " + pid + " does not have permission " 4553 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4554 + " of package " + packageName); 4555 } 4556 } 4557 4558 try { 4559 // Clear application user data 4560 pm.clearApplicationUserData(packageName, observer, userId); 4561 4562 // Remove all permissions granted from/to this package 4563 removeUriPermissionsForPackageLocked(packageName, userId, true); 4564 4565 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4566 Uri.fromParts("package", packageName, null)); 4567 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4568 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4569 null, null, 0, null, null, null, false, false, userId); 4570 } catch (RemoteException e) { 4571 } 4572 } finally { 4573 Binder.restoreCallingIdentity(callingId); 4574 } 4575 return true; 4576 } 4577 4578 @Override 4579 public void killBackgroundProcesses(final String packageName, int userId) { 4580 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4581 != PackageManager.PERMISSION_GRANTED && 4582 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4583 != PackageManager.PERMISSION_GRANTED) { 4584 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4585 + Binder.getCallingPid() 4586 + ", uid=" + Binder.getCallingUid() 4587 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4588 Slog.w(TAG, msg); 4589 throw new SecurityException(msg); 4590 } 4591 4592 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4593 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4594 long callingId = Binder.clearCallingIdentity(); 4595 try { 4596 IPackageManager pm = AppGlobals.getPackageManager(); 4597 synchronized(this) { 4598 int appId = -1; 4599 try { 4600 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4601 } catch (RemoteException e) { 4602 } 4603 if (appId == -1) { 4604 Slog.w(TAG, "Invalid packageName: " + packageName); 4605 return; 4606 } 4607 killPackageProcessesLocked(packageName, appId, userId, 4608 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4609 } 4610 } finally { 4611 Binder.restoreCallingIdentity(callingId); 4612 } 4613 } 4614 4615 @Override 4616 public void killAllBackgroundProcesses() { 4617 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4618 != PackageManager.PERMISSION_GRANTED) { 4619 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4620 + Binder.getCallingPid() 4621 + ", uid=" + Binder.getCallingUid() 4622 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4623 Slog.w(TAG, msg); 4624 throw new SecurityException(msg); 4625 } 4626 4627 long callingId = Binder.clearCallingIdentity(); 4628 try { 4629 synchronized(this) { 4630 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4631 final int NP = mProcessNames.getMap().size(); 4632 for (int ip=0; ip<NP; ip++) { 4633 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4634 final int NA = apps.size(); 4635 for (int ia=0; ia<NA; ia++) { 4636 ProcessRecord app = apps.valueAt(ia); 4637 if (app.persistent) { 4638 // we don't kill persistent processes 4639 continue; 4640 } 4641 if (app.removed) { 4642 procs.add(app); 4643 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4644 app.removed = true; 4645 procs.add(app); 4646 } 4647 } 4648 } 4649 4650 int N = procs.size(); 4651 for (int i=0; i<N; i++) { 4652 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4653 } 4654 mAllowLowerMemLevel = true; 4655 updateOomAdjLocked(); 4656 doLowMemReportIfNeededLocked(null); 4657 } 4658 } finally { 4659 Binder.restoreCallingIdentity(callingId); 4660 } 4661 } 4662 4663 @Override 4664 public void forceStopPackage(final String packageName, int userId) { 4665 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4666 != PackageManager.PERMISSION_GRANTED) { 4667 String msg = "Permission Denial: forceStopPackage() from pid=" 4668 + Binder.getCallingPid() 4669 + ", uid=" + Binder.getCallingUid() 4670 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4671 Slog.w(TAG, msg); 4672 throw new SecurityException(msg); 4673 } 4674 final int callingPid = Binder.getCallingPid(); 4675 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4676 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4677 long callingId = Binder.clearCallingIdentity(); 4678 try { 4679 IPackageManager pm = AppGlobals.getPackageManager(); 4680 synchronized(this) { 4681 int[] users = userId == UserHandle.USER_ALL 4682 ? getUsersLocked() : new int[] { userId }; 4683 for (int user : users) { 4684 int pkgUid = -1; 4685 try { 4686 pkgUid = pm.getPackageUid(packageName, user); 4687 } catch (RemoteException e) { 4688 } 4689 if (pkgUid == -1) { 4690 Slog.w(TAG, "Invalid packageName: " + packageName); 4691 continue; 4692 } 4693 try { 4694 pm.setPackageStoppedState(packageName, true, user); 4695 } catch (RemoteException e) { 4696 } catch (IllegalArgumentException e) { 4697 Slog.w(TAG, "Failed trying to unstop package " 4698 + packageName + ": " + e); 4699 } 4700 if (isUserRunningLocked(user, false)) { 4701 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4702 } 4703 } 4704 } 4705 } finally { 4706 Binder.restoreCallingIdentity(callingId); 4707 } 4708 } 4709 4710 /* 4711 * The pkg name and app id have to be specified. 4712 */ 4713 @Override 4714 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4715 if (pkg == null) { 4716 return; 4717 } 4718 // Make sure the uid is valid. 4719 if (appid < 0) { 4720 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4721 return; 4722 } 4723 int callerUid = Binder.getCallingUid(); 4724 // Only the system server can kill an application 4725 if (callerUid == Process.SYSTEM_UID) { 4726 // Post an aysnc message to kill the application 4727 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4728 msg.arg1 = appid; 4729 msg.arg2 = 0; 4730 Bundle bundle = new Bundle(); 4731 bundle.putString("pkg", pkg); 4732 bundle.putString("reason", reason); 4733 msg.obj = bundle; 4734 mHandler.sendMessage(msg); 4735 } else { 4736 throw new SecurityException(callerUid + " cannot kill pkg: " + 4737 pkg); 4738 } 4739 } 4740 4741 @Override 4742 public void closeSystemDialogs(String reason) { 4743 enforceNotIsolatedCaller("closeSystemDialogs"); 4744 4745 final int pid = Binder.getCallingPid(); 4746 final int uid = Binder.getCallingUid(); 4747 final long origId = Binder.clearCallingIdentity(); 4748 try { 4749 synchronized (this) { 4750 // Only allow this from foreground processes, so that background 4751 // applications can't abuse it to prevent system UI from being shown. 4752 if (uid >= Process.FIRST_APPLICATION_UID) { 4753 ProcessRecord proc; 4754 synchronized (mPidsSelfLocked) { 4755 proc = mPidsSelfLocked.get(pid); 4756 } 4757 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4758 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4759 + " from background process " + proc); 4760 return; 4761 } 4762 } 4763 closeSystemDialogsLocked(reason); 4764 } 4765 } finally { 4766 Binder.restoreCallingIdentity(origId); 4767 } 4768 } 4769 4770 void closeSystemDialogsLocked(String reason) { 4771 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4772 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4773 | Intent.FLAG_RECEIVER_FOREGROUND); 4774 if (reason != null) { 4775 intent.putExtra("reason", reason); 4776 } 4777 mWindowManager.closeSystemDialogs(reason); 4778 4779 mStackSupervisor.closeSystemDialogsLocked(); 4780 4781 broadcastIntentLocked(null, null, intent, null, 4782 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4783 Process.SYSTEM_UID, UserHandle.USER_ALL); 4784 } 4785 4786 @Override 4787 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4788 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4789 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4790 for (int i=pids.length-1; i>=0; i--) { 4791 ProcessRecord proc; 4792 int oomAdj; 4793 synchronized (this) { 4794 synchronized (mPidsSelfLocked) { 4795 proc = mPidsSelfLocked.get(pids[i]); 4796 oomAdj = proc != null ? proc.setAdj : 0; 4797 } 4798 } 4799 infos[i] = new Debug.MemoryInfo(); 4800 Debug.getMemoryInfo(pids[i], infos[i]); 4801 if (proc != null) { 4802 synchronized (this) { 4803 if (proc.thread != null && proc.setAdj == oomAdj) { 4804 // Record this for posterity if the process has been stable. 4805 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4806 infos[i].getTotalUss(), false, proc.pkgList); 4807 } 4808 } 4809 } 4810 } 4811 return infos; 4812 } 4813 4814 @Override 4815 public long[] getProcessPss(int[] pids) { 4816 enforceNotIsolatedCaller("getProcessPss"); 4817 long[] pss = new long[pids.length]; 4818 for (int i=pids.length-1; i>=0; i--) { 4819 ProcessRecord proc; 4820 int oomAdj; 4821 synchronized (this) { 4822 synchronized (mPidsSelfLocked) { 4823 proc = mPidsSelfLocked.get(pids[i]); 4824 oomAdj = proc != null ? proc.setAdj : 0; 4825 } 4826 } 4827 long[] tmpUss = new long[1]; 4828 pss[i] = Debug.getPss(pids[i], tmpUss); 4829 if (proc != null) { 4830 synchronized (this) { 4831 if (proc.thread != null && proc.setAdj == oomAdj) { 4832 // Record this for posterity if the process has been stable. 4833 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4834 } 4835 } 4836 } 4837 } 4838 return pss; 4839 } 4840 4841 @Override 4842 public void killApplicationProcess(String processName, int uid) { 4843 if (processName == null) { 4844 return; 4845 } 4846 4847 int callerUid = Binder.getCallingUid(); 4848 // Only the system server can kill an application 4849 if (callerUid == Process.SYSTEM_UID) { 4850 synchronized (this) { 4851 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4852 if (app != null && app.thread != null) { 4853 try { 4854 app.thread.scheduleSuicide(); 4855 } catch (RemoteException e) { 4856 // If the other end already died, then our work here is done. 4857 } 4858 } else { 4859 Slog.w(TAG, "Process/uid not found attempting kill of " 4860 + processName + " / " + uid); 4861 } 4862 } 4863 } else { 4864 throw new SecurityException(callerUid + " cannot kill app process: " + 4865 processName); 4866 } 4867 } 4868 4869 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4870 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4871 false, true, false, false, UserHandle.getUserId(uid), reason); 4872 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4873 Uri.fromParts("package", packageName, null)); 4874 if (!mProcessesReady) { 4875 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4876 | Intent.FLAG_RECEIVER_FOREGROUND); 4877 } 4878 intent.putExtra(Intent.EXTRA_UID, uid); 4879 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4880 broadcastIntentLocked(null, null, intent, 4881 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4882 false, false, 4883 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4884 } 4885 4886 private void forceStopUserLocked(int userId, String reason) { 4887 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4888 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4889 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4890 | Intent.FLAG_RECEIVER_FOREGROUND); 4891 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4892 broadcastIntentLocked(null, null, intent, 4893 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4894 false, false, 4895 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4896 } 4897 4898 private final boolean killPackageProcessesLocked(String packageName, int appId, 4899 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4900 boolean doit, boolean evenPersistent, String reason) { 4901 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4902 4903 // Remove all processes this package may have touched: all with the 4904 // same UID (except for the system or root user), and all whose name 4905 // matches the package name. 4906 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4907 final int NP = mProcessNames.getMap().size(); 4908 for (int ip=0; ip<NP; ip++) { 4909 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4910 final int NA = apps.size(); 4911 for (int ia=0; ia<NA; ia++) { 4912 ProcessRecord app = apps.valueAt(ia); 4913 if (app.persistent && !evenPersistent) { 4914 // we don't kill persistent processes 4915 continue; 4916 } 4917 if (app.removed) { 4918 if (doit) { 4919 procs.add(app); 4920 } 4921 continue; 4922 } 4923 4924 // Skip process if it doesn't meet our oom adj requirement. 4925 if (app.setAdj < minOomAdj) { 4926 continue; 4927 } 4928 4929 // If no package is specified, we call all processes under the 4930 // give user id. 4931 if (packageName == null) { 4932 if (app.userId != userId) { 4933 continue; 4934 } 4935 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4936 continue; 4937 } 4938 // Package has been specified, we want to hit all processes 4939 // that match it. We need to qualify this by the processes 4940 // that are running under the specified app and user ID. 4941 } else { 4942 if (UserHandle.getAppId(app.uid) != appId) { 4943 continue; 4944 } 4945 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4946 continue; 4947 } 4948 if (!app.pkgList.containsKey(packageName)) { 4949 continue; 4950 } 4951 } 4952 4953 // Process has passed all conditions, kill it! 4954 if (!doit) { 4955 return true; 4956 } 4957 app.removed = true; 4958 procs.add(app); 4959 } 4960 } 4961 4962 int N = procs.size(); 4963 for (int i=0; i<N; i++) { 4964 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4965 } 4966 updateOomAdjLocked(); 4967 return N > 0; 4968 } 4969 4970 private final boolean forceStopPackageLocked(String name, int appId, 4971 boolean callerWillRestart, boolean purgeCache, boolean doit, 4972 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4973 int i; 4974 int N; 4975 4976 if (userId == UserHandle.USER_ALL && name == null) { 4977 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4978 } 4979 4980 if (appId < 0 && name != null) { 4981 try { 4982 appId = UserHandle.getAppId( 4983 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4984 } catch (RemoteException e) { 4985 } 4986 } 4987 4988 if (doit) { 4989 if (name != null) { 4990 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4991 + " user=" + userId + ": " + reason); 4992 } else { 4993 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4994 } 4995 4996 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4997 for (int ip=pmap.size()-1; ip>=0; ip--) { 4998 SparseArray<Long> ba = pmap.valueAt(ip); 4999 for (i=ba.size()-1; i>=0; i--) { 5000 boolean remove = false; 5001 final int entUid = ba.keyAt(i); 5002 if (name != null) { 5003 if (userId == UserHandle.USER_ALL) { 5004 if (UserHandle.getAppId(entUid) == appId) { 5005 remove = true; 5006 } 5007 } else { 5008 if (entUid == UserHandle.getUid(userId, appId)) { 5009 remove = true; 5010 } 5011 } 5012 } else if (UserHandle.getUserId(entUid) == userId) { 5013 remove = true; 5014 } 5015 if (remove) { 5016 ba.removeAt(i); 5017 } 5018 } 5019 if (ba.size() == 0) { 5020 pmap.removeAt(ip); 5021 } 5022 } 5023 } 5024 5025 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5026 -100, callerWillRestart, true, doit, evenPersistent, 5027 name == null ? ("stop user " + userId) : ("stop " + name)); 5028 5029 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5030 if (!doit) { 5031 return true; 5032 } 5033 didSomething = true; 5034 } 5035 5036 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5037 if (!doit) { 5038 return true; 5039 } 5040 didSomething = true; 5041 } 5042 5043 if (name == null) { 5044 // Remove all sticky broadcasts from this user. 5045 mStickyBroadcasts.remove(userId); 5046 } 5047 5048 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5049 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5050 userId, providers)) { 5051 if (!doit) { 5052 return true; 5053 } 5054 didSomething = true; 5055 } 5056 N = providers.size(); 5057 for (i=0; i<N; i++) { 5058 removeDyingProviderLocked(null, providers.get(i), true); 5059 } 5060 5061 // Remove transient permissions granted from/to this package/user 5062 removeUriPermissionsForPackageLocked(name, userId, false); 5063 5064 if (name == null || uninstalling) { 5065 // Remove pending intents. For now we only do this when force 5066 // stopping users, because we have some problems when doing this 5067 // for packages -- app widgets are not currently cleaned up for 5068 // such packages, so they can be left with bad pending intents. 5069 if (mIntentSenderRecords.size() > 0) { 5070 Iterator<WeakReference<PendingIntentRecord>> it 5071 = mIntentSenderRecords.values().iterator(); 5072 while (it.hasNext()) { 5073 WeakReference<PendingIntentRecord> wpir = it.next(); 5074 if (wpir == null) { 5075 it.remove(); 5076 continue; 5077 } 5078 PendingIntentRecord pir = wpir.get(); 5079 if (pir == null) { 5080 it.remove(); 5081 continue; 5082 } 5083 if (name == null) { 5084 // Stopping user, remove all objects for the user. 5085 if (pir.key.userId != userId) { 5086 // Not the same user, skip it. 5087 continue; 5088 } 5089 } else { 5090 if (UserHandle.getAppId(pir.uid) != appId) { 5091 // Different app id, skip it. 5092 continue; 5093 } 5094 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5095 // Different user, skip it. 5096 continue; 5097 } 5098 if (!pir.key.packageName.equals(name)) { 5099 // Different package, skip it. 5100 continue; 5101 } 5102 } 5103 if (!doit) { 5104 return true; 5105 } 5106 didSomething = true; 5107 it.remove(); 5108 pir.canceled = true; 5109 if (pir.key.activity != null) { 5110 pir.key.activity.pendingResults.remove(pir.ref); 5111 } 5112 } 5113 } 5114 } 5115 5116 if (doit) { 5117 if (purgeCache && name != null) { 5118 AttributeCache ac = AttributeCache.instance(); 5119 if (ac != null) { 5120 ac.removePackage(name); 5121 } 5122 } 5123 if (mBooted) { 5124 mStackSupervisor.resumeTopActivitiesLocked(); 5125 mStackSupervisor.scheduleIdleLocked(); 5126 } 5127 } 5128 5129 return didSomething; 5130 } 5131 5132 private final boolean removeProcessLocked(ProcessRecord app, 5133 boolean callerWillRestart, boolean allowRestart, String reason) { 5134 final String name = app.processName; 5135 final int uid = app.uid; 5136 if (DEBUG_PROCESSES) Slog.d( 5137 TAG, "Force removing proc " + app.toShortString() + " (" + name 5138 + "/" + uid + ")"); 5139 5140 mProcessNames.remove(name, uid); 5141 mIsolatedProcesses.remove(app.uid); 5142 if (mHeavyWeightProcess == app) { 5143 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5144 mHeavyWeightProcess.userId, 0)); 5145 mHeavyWeightProcess = null; 5146 } 5147 boolean needRestart = false; 5148 if (app.pid > 0 && app.pid != MY_PID) { 5149 int pid = app.pid; 5150 synchronized (mPidsSelfLocked) { 5151 mPidsSelfLocked.remove(pid); 5152 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5153 } 5154 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5155 if (app.isolated) { 5156 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5157 } 5158 killUnneededProcessLocked(app, reason); 5159 Process.killProcessGroup(app.info.uid, app.pid); 5160 handleAppDiedLocked(app, true, allowRestart); 5161 removeLruProcessLocked(app); 5162 5163 if (app.persistent && !app.isolated) { 5164 if (!callerWillRestart) { 5165 addAppLocked(app.info, false, null /* ABI override */); 5166 } else { 5167 needRestart = true; 5168 } 5169 } 5170 } else { 5171 mRemovedProcesses.add(app); 5172 } 5173 5174 return needRestart; 5175 } 5176 5177 private final void processStartTimedOutLocked(ProcessRecord app) { 5178 final int pid = app.pid; 5179 boolean gone = false; 5180 synchronized (mPidsSelfLocked) { 5181 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5182 if (knownApp != null && knownApp.thread == null) { 5183 mPidsSelfLocked.remove(pid); 5184 gone = true; 5185 } 5186 } 5187 5188 if (gone) { 5189 Slog.w(TAG, "Process " + app + " failed to attach"); 5190 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5191 pid, app.uid, app.processName); 5192 mProcessNames.remove(app.processName, app.uid); 5193 mIsolatedProcesses.remove(app.uid); 5194 if (mHeavyWeightProcess == app) { 5195 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5196 mHeavyWeightProcess.userId, 0)); 5197 mHeavyWeightProcess = null; 5198 } 5199 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5200 if (app.isolated) { 5201 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5202 } 5203 // Take care of any launching providers waiting for this process. 5204 checkAppInLaunchingProvidersLocked(app, true); 5205 // Take care of any services that are waiting for the process. 5206 mServices.processStartTimedOutLocked(app); 5207 killUnneededProcessLocked(app, "start timeout"); 5208 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5209 Slog.w(TAG, "Unattached app died before backup, skipping"); 5210 try { 5211 IBackupManager bm = IBackupManager.Stub.asInterface( 5212 ServiceManager.getService(Context.BACKUP_SERVICE)); 5213 bm.agentDisconnected(app.info.packageName); 5214 } catch (RemoteException e) { 5215 // Can't happen; the backup manager is local 5216 } 5217 } 5218 if (isPendingBroadcastProcessLocked(pid)) { 5219 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5220 skipPendingBroadcastLocked(pid); 5221 } 5222 } else { 5223 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5224 } 5225 } 5226 5227 private final boolean attachApplicationLocked(IApplicationThread thread, 5228 int pid) { 5229 5230 // Find the application record that is being attached... either via 5231 // the pid if we are running in multiple processes, or just pull the 5232 // next app record if we are emulating process with anonymous threads. 5233 ProcessRecord app; 5234 if (pid != MY_PID && pid >= 0) { 5235 synchronized (mPidsSelfLocked) { 5236 app = mPidsSelfLocked.get(pid); 5237 } 5238 } else { 5239 app = null; 5240 } 5241 5242 if (app == null) { 5243 Slog.w(TAG, "No pending application record for pid " + pid 5244 + " (IApplicationThread " + thread + "); dropping process"); 5245 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5246 if (pid > 0 && pid != MY_PID) { 5247 Process.killProcessQuiet(pid); 5248 //TODO: Process.killProcessGroup(app.info.uid, pid); 5249 } else { 5250 try { 5251 thread.scheduleExit(); 5252 } catch (Exception e) { 5253 // Ignore exceptions. 5254 } 5255 } 5256 return false; 5257 } 5258 5259 // If this application record is still attached to a previous 5260 // process, clean it up now. 5261 if (app.thread != null) { 5262 handleAppDiedLocked(app, true, true); 5263 } 5264 5265 // Tell the process all about itself. 5266 5267 if (localLOGV) Slog.v( 5268 TAG, "Binding process pid " + pid + " to record " + app); 5269 5270 final String processName = app.processName; 5271 try { 5272 AppDeathRecipient adr = new AppDeathRecipient( 5273 app, pid, thread); 5274 thread.asBinder().linkToDeath(adr, 0); 5275 app.deathRecipient = adr; 5276 } catch (RemoteException e) { 5277 app.resetPackageList(mProcessStats); 5278 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5279 return false; 5280 } 5281 5282 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5283 5284 app.makeActive(thread, mProcessStats); 5285 app.curAdj = app.setAdj = -100; 5286 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5287 app.forcingToForeground = null; 5288 updateProcessForegroundLocked(app, false, false); 5289 app.hasShownUi = false; 5290 app.debugging = false; 5291 app.cached = false; 5292 5293 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5294 5295 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5296 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5297 5298 if (!normalMode) { 5299 Slog.i(TAG, "Launching preboot mode app: " + app); 5300 } 5301 5302 if (localLOGV) Slog.v( 5303 TAG, "New app record " + app 5304 + " thread=" + thread.asBinder() + " pid=" + pid); 5305 try { 5306 int testMode = IApplicationThread.DEBUG_OFF; 5307 if (mDebugApp != null && mDebugApp.equals(processName)) { 5308 testMode = mWaitForDebugger 5309 ? IApplicationThread.DEBUG_WAIT 5310 : IApplicationThread.DEBUG_ON; 5311 app.debugging = true; 5312 if (mDebugTransient) { 5313 mDebugApp = mOrigDebugApp; 5314 mWaitForDebugger = mOrigWaitForDebugger; 5315 } 5316 } 5317 String profileFile = app.instrumentationProfileFile; 5318 ParcelFileDescriptor profileFd = null; 5319 boolean profileAutoStop = false; 5320 if (mProfileApp != null && mProfileApp.equals(processName)) { 5321 mProfileProc = app; 5322 profileFile = mProfileFile; 5323 profileFd = mProfileFd; 5324 profileAutoStop = mAutoStopProfiler; 5325 } 5326 boolean enableOpenGlTrace = false; 5327 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5328 enableOpenGlTrace = true; 5329 mOpenGlTraceApp = null; 5330 } 5331 5332 // If the app is being launched for restore or full backup, set it up specially 5333 boolean isRestrictedBackupMode = false; 5334 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5335 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5336 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5337 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5338 } 5339 5340 ensurePackageDexOpt(app.instrumentationInfo != null 5341 ? app.instrumentationInfo.packageName 5342 : app.info.packageName); 5343 if (app.instrumentationClass != null) { 5344 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5345 } 5346 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5347 + processName + " with config " + mConfiguration); 5348 ApplicationInfo appInfo = app.instrumentationInfo != null 5349 ? app.instrumentationInfo : app.info; 5350 app.compat = compatibilityInfoForPackageLocked(appInfo); 5351 if (profileFd != null) { 5352 profileFd = profileFd.dup(); 5353 } 5354 thread.bindApplication(processName, appInfo, providers, 5355 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5356 app.instrumentationArguments, app.instrumentationWatcher, 5357 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5358 isRestrictedBackupMode || !normalMode, app.persistent, 5359 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5360 mCoreSettingsObserver.getCoreSettingsLocked()); 5361 updateLruProcessLocked(app, false, null); 5362 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5363 } catch (Exception e) { 5364 // todo: Yikes! What should we do? For now we will try to 5365 // start another process, but that could easily get us in 5366 // an infinite loop of restarting processes... 5367 Slog.w(TAG, "Exception thrown during bind!", e); 5368 5369 app.resetPackageList(mProcessStats); 5370 app.unlinkDeathRecipient(); 5371 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5372 return false; 5373 } 5374 5375 // Remove this record from the list of starting applications. 5376 mPersistentStartingProcesses.remove(app); 5377 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5378 "Attach application locked removing on hold: " + app); 5379 mProcessesOnHold.remove(app); 5380 5381 boolean badApp = false; 5382 boolean didSomething = false; 5383 5384 // See if the top visible activity is waiting to run in this process... 5385 if (normalMode) { 5386 try { 5387 if (mStackSupervisor.attachApplicationLocked(app)) { 5388 didSomething = true; 5389 } 5390 } catch (Exception e) { 5391 badApp = true; 5392 } 5393 } 5394 5395 // Find any services that should be running in this process... 5396 if (!badApp) { 5397 try { 5398 didSomething |= mServices.attachApplicationLocked(app, processName); 5399 } catch (Exception e) { 5400 badApp = true; 5401 } 5402 } 5403 5404 // Check if a next-broadcast receiver is in this process... 5405 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5406 try { 5407 didSomething |= sendPendingBroadcastsLocked(app); 5408 } catch (Exception e) { 5409 // If the app died trying to launch the receiver we declare it 'bad' 5410 badApp = true; 5411 } 5412 } 5413 5414 // Check whether the next backup agent is in this process... 5415 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5416 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5417 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5418 try { 5419 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5420 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5421 mBackupTarget.backupMode); 5422 } catch (Exception e) { 5423 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5424 e.printStackTrace(); 5425 } 5426 } 5427 5428 if (badApp) { 5429 // todo: Also need to kill application to deal with all 5430 // kinds of exceptions. 5431 handleAppDiedLocked(app, false, true); 5432 return false; 5433 } 5434 5435 if (!didSomething) { 5436 updateOomAdjLocked(); 5437 } 5438 5439 return true; 5440 } 5441 5442 @Override 5443 public final void attachApplication(IApplicationThread thread) { 5444 synchronized (this) { 5445 int callingPid = Binder.getCallingPid(); 5446 final long origId = Binder.clearCallingIdentity(); 5447 attachApplicationLocked(thread, callingPid); 5448 Binder.restoreCallingIdentity(origId); 5449 } 5450 } 5451 5452 @Override 5453 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5454 final long origId = Binder.clearCallingIdentity(); 5455 synchronized (this) { 5456 ActivityStack stack = ActivityRecord.getStackLocked(token); 5457 if (stack != null) { 5458 ActivityRecord r = 5459 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5460 if (stopProfiling) { 5461 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5462 try { 5463 mProfileFd.close(); 5464 } catch (IOException e) { 5465 } 5466 clearProfilerLocked(); 5467 } 5468 } 5469 } 5470 } 5471 Binder.restoreCallingIdentity(origId); 5472 } 5473 5474 void enableScreenAfterBoot() { 5475 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5476 SystemClock.uptimeMillis()); 5477 mWindowManager.enableScreenAfterBoot(); 5478 5479 synchronized (this) { 5480 updateEventDispatchingLocked(); 5481 } 5482 } 5483 5484 @Override 5485 public void showBootMessage(final CharSequence msg, final boolean always) { 5486 enforceNotIsolatedCaller("showBootMessage"); 5487 mWindowManager.showBootMessage(msg, always); 5488 } 5489 5490 @Override 5491 public void dismissKeyguardOnNextActivity() { 5492 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5493 final long token = Binder.clearCallingIdentity(); 5494 try { 5495 synchronized (this) { 5496 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5497 if (mLockScreenShown) { 5498 mLockScreenShown = false; 5499 comeOutOfSleepIfNeededLocked(); 5500 } 5501 mStackSupervisor.setDismissKeyguard(true); 5502 } 5503 } finally { 5504 Binder.restoreCallingIdentity(token); 5505 } 5506 } 5507 5508 final void finishBooting() { 5509 // Register receivers to handle package update events 5510 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5511 5512 synchronized (this) { 5513 // Ensure that any processes we had put on hold are now started 5514 // up. 5515 final int NP = mProcessesOnHold.size(); 5516 if (NP > 0) { 5517 ArrayList<ProcessRecord> procs = 5518 new ArrayList<ProcessRecord>(mProcessesOnHold); 5519 for (int ip=0; ip<NP; ip++) { 5520 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5521 + procs.get(ip)); 5522 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5523 } 5524 } 5525 5526 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5527 // Start looking for apps that are abusing wake locks. 5528 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5529 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5530 // Tell anyone interested that we are done booting! 5531 SystemProperties.set("sys.boot_completed", "1"); 5532 SystemProperties.set("dev.bootcomplete", "1"); 5533 for (int i=0; i<mStartedUsers.size(); i++) { 5534 UserStartedState uss = mStartedUsers.valueAt(i); 5535 if (uss.mState == UserStartedState.STATE_BOOTING) { 5536 uss.mState = UserStartedState.STATE_RUNNING; 5537 final int userId = mStartedUsers.keyAt(i); 5538 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5539 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5540 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5541 broadcastIntentLocked(null, null, intent, null, 5542 new IIntentReceiver.Stub() { 5543 @Override 5544 public void performReceive(Intent intent, int resultCode, 5545 String data, Bundle extras, boolean ordered, 5546 boolean sticky, int sendingUser) { 5547 synchronized (ActivityManagerService.this) { 5548 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5549 true, false); 5550 } 5551 } 5552 }, 5553 0, null, null, 5554 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5555 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5556 userId); 5557 } 5558 } 5559 scheduleStartProfilesLocked(); 5560 } 5561 } 5562 } 5563 5564 final void ensureBootCompleted() { 5565 boolean booting; 5566 boolean enableScreen; 5567 synchronized (this) { 5568 booting = mBooting; 5569 mBooting = false; 5570 enableScreen = !mBooted; 5571 mBooted = true; 5572 } 5573 5574 if (booting) { 5575 finishBooting(); 5576 } 5577 5578 if (enableScreen) { 5579 enableScreenAfterBoot(); 5580 } 5581 } 5582 5583 @Override 5584 public final void activityResumed(IBinder token) { 5585 final long origId = Binder.clearCallingIdentity(); 5586 synchronized(this) { 5587 ActivityStack stack = ActivityRecord.getStackLocked(token); 5588 if (stack != null) { 5589 ActivityRecord.activityResumedLocked(token); 5590 } 5591 } 5592 Binder.restoreCallingIdentity(origId); 5593 } 5594 5595 @Override 5596 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5597 final long origId = Binder.clearCallingIdentity(); 5598 synchronized(this) { 5599 ActivityStack stack = ActivityRecord.getStackLocked(token); 5600 if (stack != null) { 5601 stack.activityPausedLocked(token, false, persistentState); 5602 } 5603 } 5604 Binder.restoreCallingIdentity(origId); 5605 } 5606 5607 @Override 5608 public final void activityStopped(IBinder token, Bundle icicle, 5609 PersistableBundle persistentState, CharSequence description) { 5610 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5611 5612 // Refuse possible leaked file descriptors 5613 if (icicle != null && icicle.hasFileDescriptors()) { 5614 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5615 } 5616 5617 final long origId = Binder.clearCallingIdentity(); 5618 5619 synchronized (this) { 5620 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5621 if (r != null) { 5622 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5623 } 5624 } 5625 5626 trimApplications(); 5627 5628 Binder.restoreCallingIdentity(origId); 5629 } 5630 5631 @Override 5632 public final void activityDestroyed(IBinder token) { 5633 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5634 synchronized (this) { 5635 ActivityStack stack = ActivityRecord.getStackLocked(token); 5636 if (stack != null) { 5637 stack.activityDestroyedLocked(token); 5638 } 5639 } 5640 } 5641 5642 @Override 5643 public final void mediaResourcesReleased(IBinder token) { 5644 final long origId = Binder.clearCallingIdentity(); 5645 try { 5646 synchronized (this) { 5647 ActivityStack stack = ActivityRecord.getStackLocked(token); 5648 if (stack != null) { 5649 stack.mediaResourcesReleased(token); 5650 } 5651 } 5652 } finally { 5653 Binder.restoreCallingIdentity(origId); 5654 } 5655 } 5656 5657 @Override 5658 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5659 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5660 } 5661 5662 @Override 5663 public String getCallingPackage(IBinder token) { 5664 synchronized (this) { 5665 ActivityRecord r = getCallingRecordLocked(token); 5666 return r != null ? r.info.packageName : null; 5667 } 5668 } 5669 5670 @Override 5671 public ComponentName getCallingActivity(IBinder token) { 5672 synchronized (this) { 5673 ActivityRecord r = getCallingRecordLocked(token); 5674 return r != null ? r.intent.getComponent() : null; 5675 } 5676 } 5677 5678 private ActivityRecord getCallingRecordLocked(IBinder token) { 5679 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5680 if (r == null) { 5681 return null; 5682 } 5683 return r.resultTo; 5684 } 5685 5686 @Override 5687 public ComponentName getActivityClassForToken(IBinder token) { 5688 synchronized(this) { 5689 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5690 if (r == null) { 5691 return null; 5692 } 5693 return r.intent.getComponent(); 5694 } 5695 } 5696 5697 @Override 5698 public String getPackageForToken(IBinder token) { 5699 synchronized(this) { 5700 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5701 if (r == null) { 5702 return null; 5703 } 5704 return r.packageName; 5705 } 5706 } 5707 5708 @Override 5709 public IIntentSender getIntentSender(int type, 5710 String packageName, IBinder token, String resultWho, 5711 int requestCode, Intent[] intents, String[] resolvedTypes, 5712 int flags, Bundle options, int userId) { 5713 enforceNotIsolatedCaller("getIntentSender"); 5714 // Refuse possible leaked file descriptors 5715 if (intents != null) { 5716 if (intents.length < 1) { 5717 throw new IllegalArgumentException("Intents array length must be >= 1"); 5718 } 5719 for (int i=0; i<intents.length; i++) { 5720 Intent intent = intents[i]; 5721 if (intent != null) { 5722 if (intent.hasFileDescriptors()) { 5723 throw new IllegalArgumentException("File descriptors passed in Intent"); 5724 } 5725 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5726 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5727 throw new IllegalArgumentException( 5728 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5729 } 5730 intents[i] = new Intent(intent); 5731 } 5732 } 5733 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5734 throw new IllegalArgumentException( 5735 "Intent array length does not match resolvedTypes length"); 5736 } 5737 } 5738 if (options != null) { 5739 if (options.hasFileDescriptors()) { 5740 throw new IllegalArgumentException("File descriptors passed in options"); 5741 } 5742 } 5743 5744 synchronized(this) { 5745 int callingUid = Binder.getCallingUid(); 5746 int origUserId = userId; 5747 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5748 type == ActivityManager.INTENT_SENDER_BROADCAST, 5749 ALLOW_NON_FULL, "getIntentSender", null); 5750 if (origUserId == UserHandle.USER_CURRENT) { 5751 // We don't want to evaluate this until the pending intent is 5752 // actually executed. However, we do want to always do the 5753 // security checking for it above. 5754 userId = UserHandle.USER_CURRENT; 5755 } 5756 try { 5757 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5758 int uid = AppGlobals.getPackageManager() 5759 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5760 if (!UserHandle.isSameApp(callingUid, uid)) { 5761 String msg = "Permission Denial: getIntentSender() from pid=" 5762 + Binder.getCallingPid() 5763 + ", uid=" + Binder.getCallingUid() 5764 + ", (need uid=" + uid + ")" 5765 + " is not allowed to send as package " + packageName; 5766 Slog.w(TAG, msg); 5767 throw new SecurityException(msg); 5768 } 5769 } 5770 5771 return getIntentSenderLocked(type, packageName, callingUid, userId, 5772 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5773 5774 } catch (RemoteException e) { 5775 throw new SecurityException(e); 5776 } 5777 } 5778 } 5779 5780 IIntentSender getIntentSenderLocked(int type, String packageName, 5781 int callingUid, int userId, IBinder token, String resultWho, 5782 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5783 Bundle options) { 5784 if (DEBUG_MU) 5785 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5786 ActivityRecord activity = null; 5787 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5788 activity = ActivityRecord.isInStackLocked(token); 5789 if (activity == null) { 5790 return null; 5791 } 5792 if (activity.finishing) { 5793 return null; 5794 } 5795 } 5796 5797 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5798 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5799 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5800 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5801 |PendingIntent.FLAG_UPDATE_CURRENT); 5802 5803 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5804 type, packageName, activity, resultWho, 5805 requestCode, intents, resolvedTypes, flags, options, userId); 5806 WeakReference<PendingIntentRecord> ref; 5807 ref = mIntentSenderRecords.get(key); 5808 PendingIntentRecord rec = ref != null ? ref.get() : null; 5809 if (rec != null) { 5810 if (!cancelCurrent) { 5811 if (updateCurrent) { 5812 if (rec.key.requestIntent != null) { 5813 rec.key.requestIntent.replaceExtras(intents != null ? 5814 intents[intents.length - 1] : null); 5815 } 5816 if (intents != null) { 5817 intents[intents.length-1] = rec.key.requestIntent; 5818 rec.key.allIntents = intents; 5819 rec.key.allResolvedTypes = resolvedTypes; 5820 } else { 5821 rec.key.allIntents = null; 5822 rec.key.allResolvedTypes = null; 5823 } 5824 } 5825 return rec; 5826 } 5827 rec.canceled = true; 5828 mIntentSenderRecords.remove(key); 5829 } 5830 if (noCreate) { 5831 return rec; 5832 } 5833 rec = new PendingIntentRecord(this, key, callingUid); 5834 mIntentSenderRecords.put(key, rec.ref); 5835 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5836 if (activity.pendingResults == null) { 5837 activity.pendingResults 5838 = new HashSet<WeakReference<PendingIntentRecord>>(); 5839 } 5840 activity.pendingResults.add(rec.ref); 5841 } 5842 return rec; 5843 } 5844 5845 @Override 5846 public void cancelIntentSender(IIntentSender sender) { 5847 if (!(sender instanceof PendingIntentRecord)) { 5848 return; 5849 } 5850 synchronized(this) { 5851 PendingIntentRecord rec = (PendingIntentRecord)sender; 5852 try { 5853 int uid = AppGlobals.getPackageManager() 5854 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5855 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5856 String msg = "Permission Denial: cancelIntentSender() from pid=" 5857 + Binder.getCallingPid() 5858 + ", uid=" + Binder.getCallingUid() 5859 + " is not allowed to cancel packges " 5860 + rec.key.packageName; 5861 Slog.w(TAG, msg); 5862 throw new SecurityException(msg); 5863 } 5864 } catch (RemoteException e) { 5865 throw new SecurityException(e); 5866 } 5867 cancelIntentSenderLocked(rec, true); 5868 } 5869 } 5870 5871 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5872 rec.canceled = true; 5873 mIntentSenderRecords.remove(rec.key); 5874 if (cleanActivity && rec.key.activity != null) { 5875 rec.key.activity.pendingResults.remove(rec.ref); 5876 } 5877 } 5878 5879 @Override 5880 public String getPackageForIntentSender(IIntentSender pendingResult) { 5881 if (!(pendingResult instanceof PendingIntentRecord)) { 5882 return null; 5883 } 5884 try { 5885 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5886 return res.key.packageName; 5887 } catch (ClassCastException e) { 5888 } 5889 return null; 5890 } 5891 5892 @Override 5893 public int getUidForIntentSender(IIntentSender sender) { 5894 if (sender instanceof PendingIntentRecord) { 5895 try { 5896 PendingIntentRecord res = (PendingIntentRecord)sender; 5897 return res.uid; 5898 } catch (ClassCastException e) { 5899 } 5900 } 5901 return -1; 5902 } 5903 5904 @Override 5905 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5906 if (!(pendingResult instanceof PendingIntentRecord)) { 5907 return false; 5908 } 5909 try { 5910 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5911 if (res.key.allIntents == null) { 5912 return false; 5913 } 5914 for (int i=0; i<res.key.allIntents.length; i++) { 5915 Intent intent = res.key.allIntents[i]; 5916 if (intent.getPackage() != null && intent.getComponent() != null) { 5917 return false; 5918 } 5919 } 5920 return true; 5921 } catch (ClassCastException e) { 5922 } 5923 return false; 5924 } 5925 5926 @Override 5927 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5928 if (!(pendingResult instanceof PendingIntentRecord)) { 5929 return false; 5930 } 5931 try { 5932 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5933 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5934 return true; 5935 } 5936 return false; 5937 } catch (ClassCastException e) { 5938 } 5939 return false; 5940 } 5941 5942 @Override 5943 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5944 if (!(pendingResult instanceof PendingIntentRecord)) { 5945 return null; 5946 } 5947 try { 5948 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5949 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5950 } catch (ClassCastException e) { 5951 } 5952 return null; 5953 } 5954 5955 @Override 5956 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5957 if (!(pendingResult instanceof PendingIntentRecord)) { 5958 return null; 5959 } 5960 try { 5961 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5962 Intent intent = res.key.requestIntent; 5963 if (intent != null) { 5964 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5965 || res.lastTagPrefix.equals(prefix))) { 5966 return res.lastTag; 5967 } 5968 res.lastTagPrefix = prefix; 5969 StringBuilder sb = new StringBuilder(128); 5970 if (prefix != null) { 5971 sb.append(prefix); 5972 } 5973 if (intent.getAction() != null) { 5974 sb.append(intent.getAction()); 5975 } else if (intent.getComponent() != null) { 5976 intent.getComponent().appendShortString(sb); 5977 } else { 5978 sb.append("?"); 5979 } 5980 return res.lastTag = sb.toString(); 5981 } 5982 } catch (ClassCastException e) { 5983 } 5984 return null; 5985 } 5986 5987 @Override 5988 public void setProcessLimit(int max) { 5989 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5990 "setProcessLimit()"); 5991 synchronized (this) { 5992 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5993 mProcessLimitOverride = max; 5994 } 5995 trimApplications(); 5996 } 5997 5998 @Override 5999 public int getProcessLimit() { 6000 synchronized (this) { 6001 return mProcessLimitOverride; 6002 } 6003 } 6004 6005 void foregroundTokenDied(ForegroundToken token) { 6006 synchronized (ActivityManagerService.this) { 6007 synchronized (mPidsSelfLocked) { 6008 ForegroundToken cur 6009 = mForegroundProcesses.get(token.pid); 6010 if (cur != token) { 6011 return; 6012 } 6013 mForegroundProcesses.remove(token.pid); 6014 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6015 if (pr == null) { 6016 return; 6017 } 6018 pr.forcingToForeground = null; 6019 updateProcessForegroundLocked(pr, false, false); 6020 } 6021 updateOomAdjLocked(); 6022 } 6023 } 6024 6025 @Override 6026 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6027 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6028 "setProcessForeground()"); 6029 synchronized(this) { 6030 boolean changed = false; 6031 6032 synchronized (mPidsSelfLocked) { 6033 ProcessRecord pr = mPidsSelfLocked.get(pid); 6034 if (pr == null && isForeground) { 6035 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6036 return; 6037 } 6038 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6039 if (oldToken != null) { 6040 oldToken.token.unlinkToDeath(oldToken, 0); 6041 mForegroundProcesses.remove(pid); 6042 if (pr != null) { 6043 pr.forcingToForeground = null; 6044 } 6045 changed = true; 6046 } 6047 if (isForeground && token != null) { 6048 ForegroundToken newToken = new ForegroundToken() { 6049 @Override 6050 public void binderDied() { 6051 foregroundTokenDied(this); 6052 } 6053 }; 6054 newToken.pid = pid; 6055 newToken.token = token; 6056 try { 6057 token.linkToDeath(newToken, 0); 6058 mForegroundProcesses.put(pid, newToken); 6059 pr.forcingToForeground = token; 6060 changed = true; 6061 } catch (RemoteException e) { 6062 // If the process died while doing this, we will later 6063 // do the cleanup with the process death link. 6064 } 6065 } 6066 } 6067 6068 if (changed) { 6069 updateOomAdjLocked(); 6070 } 6071 } 6072 } 6073 6074 // ========================================================= 6075 // PERMISSIONS 6076 // ========================================================= 6077 6078 static class PermissionController extends IPermissionController.Stub { 6079 ActivityManagerService mActivityManagerService; 6080 PermissionController(ActivityManagerService activityManagerService) { 6081 mActivityManagerService = activityManagerService; 6082 } 6083 6084 @Override 6085 public boolean checkPermission(String permission, int pid, int uid) { 6086 return mActivityManagerService.checkPermission(permission, pid, 6087 uid) == PackageManager.PERMISSION_GRANTED; 6088 } 6089 } 6090 6091 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6092 @Override 6093 public int checkComponentPermission(String permission, int pid, int uid, 6094 int owningUid, boolean exported) { 6095 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6096 owningUid, exported); 6097 } 6098 6099 @Override 6100 public Object getAMSLock() { 6101 return ActivityManagerService.this; 6102 } 6103 } 6104 6105 /** 6106 * This can be called with or without the global lock held. 6107 */ 6108 int checkComponentPermission(String permission, int pid, int uid, 6109 int owningUid, boolean exported) { 6110 // We might be performing an operation on behalf of an indirect binder 6111 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6112 // client identity accordingly before proceeding. 6113 Identity tlsIdentity = sCallerIdentity.get(); 6114 if (tlsIdentity != null) { 6115 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6116 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6117 uid = tlsIdentity.uid; 6118 pid = tlsIdentity.pid; 6119 } 6120 6121 if (pid == MY_PID) { 6122 return PackageManager.PERMISSION_GRANTED; 6123 } 6124 6125 return ActivityManager.checkComponentPermission(permission, uid, 6126 owningUid, exported); 6127 } 6128 6129 /** 6130 * As the only public entry point for permissions checking, this method 6131 * can enforce the semantic that requesting a check on a null global 6132 * permission is automatically denied. (Internally a null permission 6133 * string is used when calling {@link #checkComponentPermission} in cases 6134 * when only uid-based security is needed.) 6135 * 6136 * This can be called with or without the global lock held. 6137 */ 6138 @Override 6139 public int checkPermission(String permission, int pid, int uid) { 6140 if (permission == null) { 6141 return PackageManager.PERMISSION_DENIED; 6142 } 6143 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6144 } 6145 6146 /** 6147 * Binder IPC calls go through the public entry point. 6148 * This can be called with or without the global lock held. 6149 */ 6150 int checkCallingPermission(String permission) { 6151 return checkPermission(permission, 6152 Binder.getCallingPid(), 6153 UserHandle.getAppId(Binder.getCallingUid())); 6154 } 6155 6156 /** 6157 * This can be called with or without the global lock held. 6158 */ 6159 void enforceCallingPermission(String permission, String func) { 6160 if (checkCallingPermission(permission) 6161 == PackageManager.PERMISSION_GRANTED) { 6162 return; 6163 } 6164 6165 String msg = "Permission Denial: " + func + " from pid=" 6166 + Binder.getCallingPid() 6167 + ", uid=" + Binder.getCallingUid() 6168 + " requires " + permission; 6169 Slog.w(TAG, msg); 6170 throw new SecurityException(msg); 6171 } 6172 6173 /** 6174 * Determine if UID is holding permissions required to access {@link Uri} in 6175 * the given {@link ProviderInfo}. Final permission checking is always done 6176 * in {@link ContentProvider}. 6177 */ 6178 private final boolean checkHoldingPermissionsLocked( 6179 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6180 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6181 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6182 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6183 return false; 6184 } 6185 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6186 } 6187 6188 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6189 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6190 if (pi.applicationInfo.uid == uid) { 6191 return true; 6192 } else if (!pi.exported) { 6193 return false; 6194 } 6195 6196 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6197 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6198 try { 6199 // check if target holds top-level <provider> permissions 6200 if (!readMet && pi.readPermission != null && considerUidPermissions 6201 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6202 readMet = true; 6203 } 6204 if (!writeMet && pi.writePermission != null && considerUidPermissions 6205 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6206 writeMet = true; 6207 } 6208 6209 // track if unprotected read/write is allowed; any denied 6210 // <path-permission> below removes this ability 6211 boolean allowDefaultRead = pi.readPermission == null; 6212 boolean allowDefaultWrite = pi.writePermission == null; 6213 6214 // check if target holds any <path-permission> that match uri 6215 final PathPermission[] pps = pi.pathPermissions; 6216 if (pps != null) { 6217 final String path = grantUri.uri.getPath(); 6218 int i = pps.length; 6219 while (i > 0 && (!readMet || !writeMet)) { 6220 i--; 6221 PathPermission pp = pps[i]; 6222 if (pp.match(path)) { 6223 if (!readMet) { 6224 final String pprperm = pp.getReadPermission(); 6225 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6226 + pprperm + " for " + pp.getPath() 6227 + ": match=" + pp.match(path) 6228 + " check=" + pm.checkUidPermission(pprperm, uid)); 6229 if (pprperm != null) { 6230 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6231 == PERMISSION_GRANTED) { 6232 readMet = true; 6233 } else { 6234 allowDefaultRead = false; 6235 } 6236 } 6237 } 6238 if (!writeMet) { 6239 final String ppwperm = pp.getWritePermission(); 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6241 + ppwperm + " for " + pp.getPath() 6242 + ": match=" + pp.match(path) 6243 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6244 if (ppwperm != null) { 6245 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6246 == PERMISSION_GRANTED) { 6247 writeMet = true; 6248 } else { 6249 allowDefaultWrite = false; 6250 } 6251 } 6252 } 6253 } 6254 } 6255 } 6256 6257 // grant unprotected <provider> read/write, if not blocked by 6258 // <path-permission> above 6259 if (allowDefaultRead) readMet = true; 6260 if (allowDefaultWrite) writeMet = true; 6261 6262 } catch (RemoteException e) { 6263 return false; 6264 } 6265 6266 return readMet && writeMet; 6267 } 6268 6269 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6270 ProviderInfo pi = null; 6271 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6272 if (cpr != null) { 6273 pi = cpr.info; 6274 } else { 6275 try { 6276 pi = AppGlobals.getPackageManager().resolveContentProvider( 6277 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6278 } catch (RemoteException ex) { 6279 } 6280 } 6281 return pi; 6282 } 6283 6284 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6285 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6286 if (targetUris != null) { 6287 return targetUris.get(grantUri); 6288 } 6289 return null; 6290 } 6291 6292 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6293 String targetPkg, int targetUid, GrantUri grantUri) { 6294 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6295 if (targetUris == null) { 6296 targetUris = Maps.newArrayMap(); 6297 mGrantedUriPermissions.put(targetUid, targetUris); 6298 } 6299 6300 UriPermission perm = targetUris.get(grantUri); 6301 if (perm == null) { 6302 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6303 targetUris.put(grantUri, perm); 6304 } 6305 6306 return perm; 6307 } 6308 6309 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6310 final int modeFlags) { 6311 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6312 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6313 : UriPermission.STRENGTH_OWNED; 6314 6315 // Root gets to do everything. 6316 if (uid == 0) { 6317 return true; 6318 } 6319 6320 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6321 if (perms == null) return false; 6322 6323 // First look for exact match 6324 final UriPermission exactPerm = perms.get(grantUri); 6325 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6326 return true; 6327 } 6328 6329 // No exact match, look for prefixes 6330 final int N = perms.size(); 6331 for (int i = 0; i < N; i++) { 6332 final UriPermission perm = perms.valueAt(i); 6333 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6334 && perm.getStrength(modeFlags) >= minStrength) { 6335 return true; 6336 } 6337 } 6338 6339 return false; 6340 } 6341 6342 @Override 6343 public int checkUriPermission(Uri uri, int pid, int uid, 6344 final int modeFlags, int userId) { 6345 enforceNotIsolatedCaller("checkUriPermission"); 6346 6347 // Another redirected-binder-call permissions check as in 6348 // {@link checkComponentPermission}. 6349 Identity tlsIdentity = sCallerIdentity.get(); 6350 if (tlsIdentity != null) { 6351 uid = tlsIdentity.uid; 6352 pid = tlsIdentity.pid; 6353 } 6354 6355 // Our own process gets to do everything. 6356 if (pid == MY_PID) { 6357 return PackageManager.PERMISSION_GRANTED; 6358 } 6359 synchronized (this) { 6360 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6361 ? PackageManager.PERMISSION_GRANTED 6362 : PackageManager.PERMISSION_DENIED; 6363 } 6364 } 6365 6366 /** 6367 * Check if the targetPkg can be granted permission to access uri by 6368 * the callingUid using the given modeFlags. Throws a security exception 6369 * if callingUid is not allowed to do this. Returns the uid of the target 6370 * if the URI permission grant should be performed; returns -1 if it is not 6371 * needed (for example targetPkg already has permission to access the URI). 6372 * If you already know the uid of the target, you can supply it in 6373 * lastTargetUid else set that to -1. 6374 */ 6375 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6376 final int modeFlags, int lastTargetUid) { 6377 if (!Intent.isAccessUriMode(modeFlags)) { 6378 return -1; 6379 } 6380 6381 if (targetPkg != null) { 6382 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6383 "Checking grant " + targetPkg + " permission to " + grantUri); 6384 } 6385 6386 final IPackageManager pm = AppGlobals.getPackageManager(); 6387 6388 // If this is not a content: uri, we can't do anything with it. 6389 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6390 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6391 "Can't grant URI permission for non-content URI: " + grantUri); 6392 return -1; 6393 } 6394 6395 final String authority = grantUri.uri.getAuthority(); 6396 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6397 if (pi == null) { 6398 Slog.w(TAG, "No content provider found for permission check: " + 6399 grantUri.uri.toSafeString()); 6400 return -1; 6401 } 6402 6403 int targetUid = lastTargetUid; 6404 if (targetUid < 0 && targetPkg != null) { 6405 try { 6406 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6407 if (targetUid < 0) { 6408 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6409 "Can't grant URI permission no uid for: " + targetPkg); 6410 return -1; 6411 } 6412 } catch (RemoteException ex) { 6413 return -1; 6414 } 6415 } 6416 6417 if (targetUid >= 0) { 6418 // First... does the target actually need this permission? 6419 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6420 // No need to grant the target this permission. 6421 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6422 "Target " + targetPkg + " already has full permission to " + grantUri); 6423 return -1; 6424 } 6425 } else { 6426 // First... there is no target package, so can anyone access it? 6427 boolean allowed = pi.exported; 6428 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6429 if (pi.readPermission != null) { 6430 allowed = false; 6431 } 6432 } 6433 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6434 if (pi.writePermission != null) { 6435 allowed = false; 6436 } 6437 } 6438 if (allowed) { 6439 return -1; 6440 } 6441 } 6442 6443 /* There is a special cross user grant if: 6444 * - The target is on another user. 6445 * - Apps on the current user can access the uri without any uid permissions. 6446 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6447 * grant uri permissions. 6448 */ 6449 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6450 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6451 modeFlags, false /*without considering the uid permissions*/); 6452 6453 // Second... is the provider allowing granting of URI permissions? 6454 if (!specialCrossUserGrant) { 6455 if (!pi.grantUriPermissions) { 6456 throw new SecurityException("Provider " + pi.packageName 6457 + "/" + pi.name 6458 + " does not allow granting of Uri permissions (uri " 6459 + grantUri + ")"); 6460 } 6461 if (pi.uriPermissionPatterns != null) { 6462 final int N = pi.uriPermissionPatterns.length; 6463 boolean allowed = false; 6464 for (int i=0; i<N; i++) { 6465 if (pi.uriPermissionPatterns[i] != null 6466 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6467 allowed = true; 6468 break; 6469 } 6470 } 6471 if (!allowed) { 6472 throw new SecurityException("Provider " + pi.packageName 6473 + "/" + pi.name 6474 + " does not allow granting of permission to path of Uri " 6475 + grantUri); 6476 } 6477 } 6478 } 6479 6480 // Third... does the caller itself have permission to access 6481 // this uri? 6482 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6483 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6484 // Require they hold a strong enough Uri permission 6485 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6486 throw new SecurityException("Uid " + callingUid 6487 + " does not have permission to uri " + grantUri); 6488 } 6489 } 6490 } 6491 return targetUid; 6492 } 6493 6494 @Override 6495 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6496 final int modeFlags, int userId) { 6497 enforceNotIsolatedCaller("checkGrantUriPermission"); 6498 synchronized(this) { 6499 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6500 new GrantUri(userId, uri, false), modeFlags, -1); 6501 } 6502 } 6503 6504 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6505 final int modeFlags, UriPermissionOwner owner) { 6506 if (!Intent.isAccessUriMode(modeFlags)) { 6507 return; 6508 } 6509 6510 // So here we are: the caller has the assumed permission 6511 // to the uri, and the target doesn't. Let's now give this to 6512 // the target. 6513 6514 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6515 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6516 6517 final String authority = grantUri.uri.getAuthority(); 6518 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6519 if (pi == null) { 6520 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6521 return; 6522 } 6523 6524 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6525 grantUri.prefix = true; 6526 } 6527 final UriPermission perm = findOrCreateUriPermissionLocked( 6528 pi.packageName, targetPkg, targetUid, grantUri); 6529 perm.grantModes(modeFlags, owner); 6530 } 6531 6532 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6533 final int modeFlags, UriPermissionOwner owner) { 6534 if (targetPkg == null) { 6535 throw new NullPointerException("targetPkg"); 6536 } 6537 6538 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6539 -1); 6540 if (targetUid < 0) { 6541 return; 6542 } 6543 6544 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6545 owner); 6546 } 6547 6548 static class NeededUriGrants extends ArrayList<GrantUri> { 6549 final String targetPkg; 6550 final int targetUid; 6551 final int flags; 6552 6553 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6554 this.targetPkg = targetPkg; 6555 this.targetUid = targetUid; 6556 this.flags = flags; 6557 } 6558 } 6559 6560 /** 6561 * Like checkGrantUriPermissionLocked, but takes an Intent. 6562 */ 6563 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6564 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6565 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6566 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6567 + " clip=" + (intent != null ? intent.getClipData() : null) 6568 + " from " + intent + "; flags=0x" 6569 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6570 6571 if (targetPkg == null) { 6572 throw new NullPointerException("targetPkg"); 6573 } 6574 6575 if (intent == null) { 6576 return null; 6577 } 6578 Uri data = intent.getData(); 6579 ClipData clip = intent.getClipData(); 6580 if (data == null && clip == null) { 6581 return null; 6582 } 6583 final IPackageManager pm = AppGlobals.getPackageManager(); 6584 int targetUid; 6585 if (needed != null) { 6586 targetUid = needed.targetUid; 6587 } else { 6588 try { 6589 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6590 } catch (RemoteException ex) { 6591 return null; 6592 } 6593 if (targetUid < 0) { 6594 if (DEBUG_URI_PERMISSION) { 6595 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6596 + " on user " + targetUserId); 6597 } 6598 return null; 6599 } 6600 } 6601 if (data != null) { 6602 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6603 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6604 targetUid); 6605 if (targetUid > 0) { 6606 if (needed == null) { 6607 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6608 } 6609 needed.add(grantUri); 6610 } 6611 } 6612 if (clip != null) { 6613 for (int i=0; i<clip.getItemCount(); i++) { 6614 Uri uri = clip.getItemAt(i).getUri(); 6615 if (uri != null) { 6616 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6617 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6618 targetUid); 6619 if (targetUid > 0) { 6620 if (needed == null) { 6621 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6622 } 6623 needed.add(grantUri); 6624 } 6625 } else { 6626 Intent clipIntent = clip.getItemAt(i).getIntent(); 6627 if (clipIntent != null) { 6628 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6629 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6630 if (newNeeded != null) { 6631 needed = newNeeded; 6632 } 6633 } 6634 } 6635 } 6636 } 6637 6638 return needed; 6639 } 6640 6641 /** 6642 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6643 */ 6644 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6645 UriPermissionOwner owner) { 6646 if (needed != null) { 6647 for (int i=0; i<needed.size(); i++) { 6648 GrantUri grantUri = needed.get(i); 6649 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6650 grantUri, needed.flags, owner); 6651 } 6652 } 6653 } 6654 6655 void grantUriPermissionFromIntentLocked(int callingUid, 6656 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6657 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6658 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6659 if (needed == null) { 6660 return; 6661 } 6662 6663 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6664 } 6665 6666 @Override 6667 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6668 final int modeFlags, int userId) { 6669 enforceNotIsolatedCaller("grantUriPermission"); 6670 GrantUri grantUri = new GrantUri(userId, uri, false); 6671 synchronized(this) { 6672 final ProcessRecord r = getRecordForAppLocked(caller); 6673 if (r == null) { 6674 throw new SecurityException("Unable to find app for caller " 6675 + caller 6676 + " when granting permission to uri " + grantUri); 6677 } 6678 if (targetPkg == null) { 6679 throw new IllegalArgumentException("null target"); 6680 } 6681 if (grantUri == null) { 6682 throw new IllegalArgumentException("null uri"); 6683 } 6684 6685 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6686 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6687 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6688 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6689 6690 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6691 } 6692 } 6693 6694 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6695 if (perm.modeFlags == 0) { 6696 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6697 perm.targetUid); 6698 if (perms != null) { 6699 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6700 "Removing " + perm.targetUid + " permission to " + perm.uri); 6701 6702 perms.remove(perm.uri); 6703 if (perms.isEmpty()) { 6704 mGrantedUriPermissions.remove(perm.targetUid); 6705 } 6706 } 6707 } 6708 } 6709 6710 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6711 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6712 6713 final IPackageManager pm = AppGlobals.getPackageManager(); 6714 final String authority = grantUri.uri.getAuthority(); 6715 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6716 if (pi == null) { 6717 Slog.w(TAG, "No content provider found for permission revoke: " 6718 + grantUri.toSafeString()); 6719 return; 6720 } 6721 6722 // Does the caller have this permission on the URI? 6723 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6724 // Right now, if you are not the original owner of the permission, 6725 // you are not allowed to revoke it. 6726 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6727 throw new SecurityException("Uid " + callingUid 6728 + " does not have permission to uri " + grantUri); 6729 //} 6730 } 6731 6732 boolean persistChanged = false; 6733 6734 // Go through all of the permissions and remove any that match. 6735 int N = mGrantedUriPermissions.size(); 6736 for (int i = 0; i < N; i++) { 6737 final int targetUid = mGrantedUriPermissions.keyAt(i); 6738 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6739 6740 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6741 final UriPermission perm = it.next(); 6742 if (perm.uri.sourceUserId == grantUri.sourceUserId 6743 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6744 if (DEBUG_URI_PERMISSION) 6745 Slog.v(TAG, 6746 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6747 persistChanged |= perm.revokeModes( 6748 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6749 if (perm.modeFlags == 0) { 6750 it.remove(); 6751 } 6752 } 6753 } 6754 6755 if (perms.isEmpty()) { 6756 mGrantedUriPermissions.remove(targetUid); 6757 N--; 6758 i--; 6759 } 6760 } 6761 6762 if (persistChanged) { 6763 schedulePersistUriGrants(); 6764 } 6765 } 6766 6767 @Override 6768 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6769 int userId) { 6770 enforceNotIsolatedCaller("revokeUriPermission"); 6771 synchronized(this) { 6772 final ProcessRecord r = getRecordForAppLocked(caller); 6773 if (r == null) { 6774 throw new SecurityException("Unable to find app for caller " 6775 + caller 6776 + " when revoking permission to uri " + uri); 6777 } 6778 if (uri == null) { 6779 Slog.w(TAG, "revokeUriPermission: null uri"); 6780 return; 6781 } 6782 6783 if (!Intent.isAccessUriMode(modeFlags)) { 6784 return; 6785 } 6786 6787 final IPackageManager pm = AppGlobals.getPackageManager(); 6788 final String authority = uri.getAuthority(); 6789 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6790 if (pi == null) { 6791 Slog.w(TAG, "No content provider found for permission revoke: " 6792 + uri.toSafeString()); 6793 return; 6794 } 6795 6796 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6797 } 6798 } 6799 6800 /** 6801 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6802 * given package. 6803 * 6804 * @param packageName Package name to match, or {@code null} to apply to all 6805 * packages. 6806 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6807 * to all users. 6808 * @param persistable If persistable grants should be removed. 6809 */ 6810 private void removeUriPermissionsForPackageLocked( 6811 String packageName, int userHandle, boolean persistable) { 6812 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6813 throw new IllegalArgumentException("Must narrow by either package or user"); 6814 } 6815 6816 boolean persistChanged = false; 6817 6818 int N = mGrantedUriPermissions.size(); 6819 for (int i = 0; i < N; i++) { 6820 final int targetUid = mGrantedUriPermissions.keyAt(i); 6821 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6822 6823 // Only inspect grants matching user 6824 if (userHandle == UserHandle.USER_ALL 6825 || userHandle == UserHandle.getUserId(targetUid)) { 6826 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6827 final UriPermission perm = it.next(); 6828 6829 // Only inspect grants matching package 6830 if (packageName == null || perm.sourcePkg.equals(packageName) 6831 || perm.targetPkg.equals(packageName)) { 6832 persistChanged |= perm.revokeModes( 6833 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6834 6835 // Only remove when no modes remain; any persisted grants 6836 // will keep this alive. 6837 if (perm.modeFlags == 0) { 6838 it.remove(); 6839 } 6840 } 6841 } 6842 6843 if (perms.isEmpty()) { 6844 mGrantedUriPermissions.remove(targetUid); 6845 N--; 6846 i--; 6847 } 6848 } 6849 } 6850 6851 if (persistChanged) { 6852 schedulePersistUriGrants(); 6853 } 6854 } 6855 6856 @Override 6857 public IBinder newUriPermissionOwner(String name) { 6858 enforceNotIsolatedCaller("newUriPermissionOwner"); 6859 synchronized(this) { 6860 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6861 return owner.getExternalTokenLocked(); 6862 } 6863 } 6864 6865 @Override 6866 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6867 final int modeFlags, int userId) { 6868 synchronized(this) { 6869 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6870 if (owner == null) { 6871 throw new IllegalArgumentException("Unknown owner: " + token); 6872 } 6873 if (fromUid != Binder.getCallingUid()) { 6874 if (Binder.getCallingUid() != Process.myUid()) { 6875 // Only system code can grant URI permissions on behalf 6876 // of other users. 6877 throw new SecurityException("nice try"); 6878 } 6879 } 6880 if (targetPkg == null) { 6881 throw new IllegalArgumentException("null target"); 6882 } 6883 if (uri == null) { 6884 throw new IllegalArgumentException("null uri"); 6885 } 6886 6887 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6888 modeFlags, owner); 6889 } 6890 } 6891 6892 @Override 6893 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6894 synchronized(this) { 6895 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6896 if (owner == null) { 6897 throw new IllegalArgumentException("Unknown owner: " + token); 6898 } 6899 6900 if (uri == null) { 6901 owner.removeUriPermissionsLocked(mode); 6902 } else { 6903 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6904 } 6905 } 6906 } 6907 6908 private void schedulePersistUriGrants() { 6909 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6910 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6911 10 * DateUtils.SECOND_IN_MILLIS); 6912 } 6913 } 6914 6915 private void writeGrantedUriPermissions() { 6916 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6917 6918 // Snapshot permissions so we can persist without lock 6919 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6920 synchronized (this) { 6921 final int size = mGrantedUriPermissions.size(); 6922 for (int i = 0; i < size; i++) { 6923 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6924 for (UriPermission perm : perms.values()) { 6925 if (perm.persistedModeFlags != 0) { 6926 persist.add(perm.snapshot()); 6927 } 6928 } 6929 } 6930 } 6931 6932 FileOutputStream fos = null; 6933 try { 6934 fos = mGrantFile.startWrite(); 6935 6936 XmlSerializer out = new FastXmlSerializer(); 6937 out.setOutput(fos, "utf-8"); 6938 out.startDocument(null, true); 6939 out.startTag(null, TAG_URI_GRANTS); 6940 for (UriPermission.Snapshot perm : persist) { 6941 out.startTag(null, TAG_URI_GRANT); 6942 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6943 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6944 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6945 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6946 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6947 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6948 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6949 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6950 out.endTag(null, TAG_URI_GRANT); 6951 } 6952 out.endTag(null, TAG_URI_GRANTS); 6953 out.endDocument(); 6954 6955 mGrantFile.finishWrite(fos); 6956 } catch (IOException e) { 6957 if (fos != null) { 6958 mGrantFile.failWrite(fos); 6959 } 6960 } 6961 } 6962 6963 private void readGrantedUriPermissionsLocked() { 6964 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6965 6966 final long now = System.currentTimeMillis(); 6967 6968 FileInputStream fis = null; 6969 try { 6970 fis = mGrantFile.openRead(); 6971 final XmlPullParser in = Xml.newPullParser(); 6972 in.setInput(fis, null); 6973 6974 int type; 6975 while ((type = in.next()) != END_DOCUMENT) { 6976 final String tag = in.getName(); 6977 if (type == START_TAG) { 6978 if (TAG_URI_GRANT.equals(tag)) { 6979 final int sourceUserId; 6980 final int targetUserId; 6981 final int userHandle = readIntAttribute(in, 6982 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6983 if (userHandle != UserHandle.USER_NULL) { 6984 // For backwards compatibility. 6985 sourceUserId = userHandle; 6986 targetUserId = userHandle; 6987 } else { 6988 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6989 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6990 } 6991 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6992 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6993 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6994 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6995 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6996 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6997 6998 // Sanity check that provider still belongs to source package 6999 final ProviderInfo pi = getProviderInfoLocked( 7000 uri.getAuthority(), sourceUserId); 7001 if (pi != null && sourcePkg.equals(pi.packageName)) { 7002 int targetUid = -1; 7003 try { 7004 targetUid = AppGlobals.getPackageManager() 7005 .getPackageUid(targetPkg, targetUserId); 7006 } catch (RemoteException e) { 7007 } 7008 if (targetUid != -1) { 7009 final UriPermission perm = findOrCreateUriPermissionLocked( 7010 sourcePkg, targetPkg, targetUid, 7011 new GrantUri(sourceUserId, uri, prefix)); 7012 perm.initPersistedModes(modeFlags, createdTime); 7013 } 7014 } else { 7015 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7016 + " but instead found " + pi); 7017 } 7018 } 7019 } 7020 } 7021 } catch (FileNotFoundException e) { 7022 // Missing grants is okay 7023 } catch (IOException e) { 7024 Log.wtf(TAG, "Failed reading Uri grants", e); 7025 } catch (XmlPullParserException e) { 7026 Log.wtf(TAG, "Failed reading Uri grants", e); 7027 } finally { 7028 IoUtils.closeQuietly(fis); 7029 } 7030 } 7031 7032 @Override 7033 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7034 enforceNotIsolatedCaller("takePersistableUriPermission"); 7035 7036 Preconditions.checkFlagsArgument(modeFlags, 7037 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7038 7039 synchronized (this) { 7040 final int callingUid = Binder.getCallingUid(); 7041 boolean persistChanged = false; 7042 GrantUri grantUri = new GrantUri(userId, uri, false); 7043 7044 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7045 new GrantUri(userId, uri, false)); 7046 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7047 new GrantUri(userId, uri, true)); 7048 7049 final boolean exactValid = (exactPerm != null) 7050 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7051 final boolean prefixValid = (prefixPerm != null) 7052 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7053 7054 if (!(exactValid || prefixValid)) { 7055 throw new SecurityException("No persistable permission grants found for UID " 7056 + callingUid + " and Uri " + grantUri.toSafeString()); 7057 } 7058 7059 if (exactValid) { 7060 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7061 } 7062 if (prefixValid) { 7063 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7064 } 7065 7066 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7067 7068 if (persistChanged) { 7069 schedulePersistUriGrants(); 7070 } 7071 } 7072 } 7073 7074 @Override 7075 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7076 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7077 7078 Preconditions.checkFlagsArgument(modeFlags, 7079 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7080 7081 synchronized (this) { 7082 final int callingUid = Binder.getCallingUid(); 7083 boolean persistChanged = false; 7084 7085 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7086 new GrantUri(userId, uri, false)); 7087 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7088 new GrantUri(userId, uri, true)); 7089 if (exactPerm == null && prefixPerm == null) { 7090 throw new SecurityException("No permission grants found for UID " + callingUid 7091 + " and Uri " + uri.toSafeString()); 7092 } 7093 7094 if (exactPerm != null) { 7095 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7096 removeUriPermissionIfNeededLocked(exactPerm); 7097 } 7098 if (prefixPerm != null) { 7099 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7100 removeUriPermissionIfNeededLocked(prefixPerm); 7101 } 7102 7103 if (persistChanged) { 7104 schedulePersistUriGrants(); 7105 } 7106 } 7107 } 7108 7109 /** 7110 * Prune any older {@link UriPermission} for the given UID until outstanding 7111 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7112 * 7113 * @return if any mutations occured that require persisting. 7114 */ 7115 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7116 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7117 if (perms == null) return false; 7118 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7119 7120 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7121 for (UriPermission perm : perms.values()) { 7122 if (perm.persistedModeFlags != 0) { 7123 persisted.add(perm); 7124 } 7125 } 7126 7127 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7128 if (trimCount <= 0) return false; 7129 7130 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7131 for (int i = 0; i < trimCount; i++) { 7132 final UriPermission perm = persisted.get(i); 7133 7134 if (DEBUG_URI_PERMISSION) { 7135 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7136 } 7137 7138 perm.releasePersistableModes(~0); 7139 removeUriPermissionIfNeededLocked(perm); 7140 } 7141 7142 return true; 7143 } 7144 7145 @Override 7146 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7147 String packageName, boolean incoming) { 7148 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7149 Preconditions.checkNotNull(packageName, "packageName"); 7150 7151 final int callingUid = Binder.getCallingUid(); 7152 final IPackageManager pm = AppGlobals.getPackageManager(); 7153 try { 7154 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7155 if (packageUid != callingUid) { 7156 throw new SecurityException( 7157 "Package " + packageName + " does not belong to calling UID " + callingUid); 7158 } 7159 } catch (RemoteException e) { 7160 throw new SecurityException("Failed to verify package name ownership"); 7161 } 7162 7163 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7164 synchronized (this) { 7165 if (incoming) { 7166 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7167 callingUid); 7168 if (perms == null) { 7169 Slog.w(TAG, "No permission grants found for " + packageName); 7170 } else { 7171 for (UriPermission perm : perms.values()) { 7172 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7173 result.add(perm.buildPersistedPublicApiObject()); 7174 } 7175 } 7176 } 7177 } else { 7178 final int size = mGrantedUriPermissions.size(); 7179 for (int i = 0; i < size; i++) { 7180 final ArrayMap<GrantUri, UriPermission> perms = 7181 mGrantedUriPermissions.valueAt(i); 7182 for (UriPermission perm : perms.values()) { 7183 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7184 result.add(perm.buildPersistedPublicApiObject()); 7185 } 7186 } 7187 } 7188 } 7189 } 7190 return new ParceledListSlice<android.content.UriPermission>(result); 7191 } 7192 7193 @Override 7194 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7195 synchronized (this) { 7196 ProcessRecord app = 7197 who != null ? getRecordForAppLocked(who) : null; 7198 if (app == null) return; 7199 7200 Message msg = Message.obtain(); 7201 msg.what = WAIT_FOR_DEBUGGER_MSG; 7202 msg.obj = app; 7203 msg.arg1 = waiting ? 1 : 0; 7204 mHandler.sendMessage(msg); 7205 } 7206 } 7207 7208 @Override 7209 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7210 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7211 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7212 outInfo.availMem = Process.getFreeMemory(); 7213 outInfo.totalMem = Process.getTotalMemory(); 7214 outInfo.threshold = homeAppMem; 7215 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7216 outInfo.hiddenAppThreshold = cachedAppMem; 7217 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7218 ProcessList.SERVICE_ADJ); 7219 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7220 ProcessList.VISIBLE_APP_ADJ); 7221 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7222 ProcessList.FOREGROUND_APP_ADJ); 7223 } 7224 7225 // ========================================================= 7226 // TASK MANAGEMENT 7227 // ========================================================= 7228 7229 @Override 7230 public List<IAppTask> getAppTasks() { 7231 final PackageManager pm = mContext.getPackageManager(); 7232 int callingUid = Binder.getCallingUid(); 7233 long ident = Binder.clearCallingIdentity(); 7234 7235 // Compose the list of packages for this id to test against 7236 HashSet<String> packages = new HashSet<String>(); 7237 String[] uidPackages = pm.getPackagesForUid(callingUid); 7238 for (int i = 0; i < uidPackages.length; i++) { 7239 packages.add(uidPackages[i]); 7240 } 7241 7242 synchronized(this) { 7243 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7244 try { 7245 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7246 7247 final int N = mRecentTasks.size(); 7248 for (int i = 0; i < N; i++) { 7249 TaskRecord tr = mRecentTasks.get(i); 7250 // Skip tasks that are not created by the caller 7251 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7252 ActivityManager.RecentTaskInfo taskInfo = 7253 createRecentTaskInfoFromTaskRecord(tr); 7254 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7255 list.add(taskImpl); 7256 } 7257 } 7258 } finally { 7259 Binder.restoreCallingIdentity(ident); 7260 } 7261 return list; 7262 } 7263 } 7264 7265 @Override 7266 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7267 final int callingUid = Binder.getCallingUid(); 7268 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7269 7270 synchronized(this) { 7271 if (localLOGV) Slog.v( 7272 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7273 7274 final boolean allowed = checkCallingPermission( 7275 android.Manifest.permission.GET_TASKS) 7276 == PackageManager.PERMISSION_GRANTED; 7277 if (!allowed) { 7278 Slog.w(TAG, "getTasks: caller " + callingUid 7279 + " does not hold GET_TASKS; limiting output"); 7280 } 7281 7282 // TODO: Improve with MRU list from all ActivityStacks. 7283 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7284 } 7285 7286 return list; 7287 } 7288 7289 TaskRecord getMostRecentTask() { 7290 return mRecentTasks.get(0); 7291 } 7292 7293 /** 7294 * Creates a new RecentTaskInfo from a TaskRecord. 7295 */ 7296 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7297 // Update the task description to reflect any changes in the task stack 7298 tr.updateTaskDescription(); 7299 7300 // Compose the recent task info 7301 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7302 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7303 rti.persistentId = tr.taskId; 7304 rti.baseIntent = new Intent(tr.getBaseIntent()); 7305 rti.origActivity = tr.origActivity; 7306 rti.description = tr.lastDescription; 7307 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7308 rti.userId = tr.userId; 7309 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7310 rti.firstActiveTime = tr.firstActiveTime; 7311 rti.lastActiveTime = tr.lastActiveTime; 7312 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7313 return rti; 7314 } 7315 7316 @Override 7317 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7318 final int callingUid = Binder.getCallingUid(); 7319 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7320 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7321 7322 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7323 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7324 synchronized (this) { 7325 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7326 == PackageManager.PERMISSION_GRANTED; 7327 if (!allowed) { 7328 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7329 + " does not hold GET_TASKS; limiting output"); 7330 } 7331 final boolean detailed = checkCallingPermission( 7332 android.Manifest.permission.GET_DETAILED_TASKS) 7333 == PackageManager.PERMISSION_GRANTED; 7334 7335 IPackageManager pm = AppGlobals.getPackageManager(); 7336 7337 final int N = mRecentTasks.size(); 7338 ArrayList<ActivityManager.RecentTaskInfo> res 7339 = new ArrayList<ActivityManager.RecentTaskInfo>( 7340 maxNum < N ? maxNum : N); 7341 7342 final Set<Integer> includedUsers; 7343 if (includeProfiles) { 7344 includedUsers = getProfileIdsLocked(userId); 7345 } else { 7346 includedUsers = new HashSet<Integer>(); 7347 } 7348 includedUsers.add(Integer.valueOf(userId)); 7349 7350 // Regroup affiliated tasks together. 7351 for (int i = 0; i < N; ) { 7352 TaskRecord task = mRecentTasks.remove(i); 7353 if (mTmpRecents.contains(task)) { 7354 continue; 7355 } 7356 int affiliatedTaskId = task.mAffiliatedTaskId; 7357 while (true) { 7358 TaskRecord next = task.mNextAffiliate; 7359 if (next == null) { 7360 break; 7361 } 7362 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7363 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7364 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7365 task.setNextAffiliate(null); 7366 if (next.mPrevAffiliate == task) { 7367 next.setPrevAffiliate(null); 7368 } 7369 break; 7370 } 7371 if (next.mPrevAffiliate != task) { 7372 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7373 next.mPrevAffiliate + " task=" + task); 7374 next.setPrevAffiliate(null); 7375 break; 7376 } 7377 if (!mRecentTasks.contains(next)) { 7378 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7379 task.setNextAffiliate(null); 7380 if (next.mPrevAffiliate == task) { 7381 next.setPrevAffiliate(null); 7382 } 7383 break; 7384 } 7385 task = next; 7386 } 7387 // task is now the end of the list 7388 do { 7389 mRecentTasks.remove(task); 7390 mRecentTasks.add(i++, task); 7391 mTmpRecents.add(task); 7392 } while ((task = task.mPrevAffiliate) != null); 7393 } 7394 mTmpRecents.clear(); 7395 // mRecentTasks is now in sorted, affiliated order. 7396 7397 for (int i=0; i<N && maxNum > 0; i++) { 7398 TaskRecord tr = mRecentTasks.get(i); 7399 // Only add calling user or related users recent tasks 7400 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7401 7402 // Return the entry if desired by the caller. We always return 7403 // the first entry, because callers always expect this to be the 7404 // foreground app. We may filter others if the caller has 7405 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7406 // we should exclude the entry. 7407 7408 if (i == 0 7409 || withExcluded 7410 || (tr.intent == null) 7411 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7412 == 0)) { 7413 if (!allowed) { 7414 // If the caller doesn't have the GET_TASKS permission, then only 7415 // allow them to see a small subset of tasks -- their own and home. 7416 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7417 continue; 7418 } 7419 } 7420 if (tr.intent != null && 7421 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7422 != 0 && tr.getTopActivity() == null) { 7423 // Don't include auto remove tasks that are finished or finishing. 7424 continue; 7425 } 7426 7427 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7428 if (!detailed) { 7429 rti.baseIntent.replaceExtras((Bundle)null); 7430 } 7431 7432 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7433 // Check whether this activity is currently available. 7434 try { 7435 if (rti.origActivity != null) { 7436 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7437 == null) { 7438 continue; 7439 } 7440 } else if (rti.baseIntent != null) { 7441 if (pm.queryIntentActivities(rti.baseIntent, 7442 null, 0, userId) == null) { 7443 continue; 7444 } 7445 } 7446 } catch (RemoteException e) { 7447 // Will never happen. 7448 } 7449 } 7450 7451 res.add(rti); 7452 maxNum--; 7453 } 7454 } 7455 return res; 7456 } 7457 } 7458 7459 private TaskRecord recentTaskForIdLocked(int id) { 7460 final int N = mRecentTasks.size(); 7461 for (int i=0; i<N; i++) { 7462 TaskRecord tr = mRecentTasks.get(i); 7463 if (tr.taskId == id) { 7464 return tr; 7465 } 7466 } 7467 return null; 7468 } 7469 7470 @Override 7471 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7472 synchronized (this) { 7473 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7474 "getTaskThumbnail()"); 7475 TaskRecord tr = recentTaskForIdLocked(id); 7476 if (tr != null) { 7477 return tr.getTaskThumbnailLocked(); 7478 } 7479 } 7480 return null; 7481 } 7482 7483 @Override 7484 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7485 synchronized (this) { 7486 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7487 if (r != null) { 7488 r.taskDescription = td; 7489 r.task.updateTaskDescription(); 7490 } 7491 } 7492 } 7493 7494 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7495 if (!pr.killedByAm) { 7496 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7497 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7498 pr.processName, pr.setAdj, reason); 7499 pr.killedByAm = true; 7500 Process.killProcessQuiet(pr.pid); 7501 Process.killProcessGroup(pr.info.uid, pr.pid); 7502 } 7503 } 7504 7505 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7506 tr.disposeThumbnail(); 7507 mRecentTasks.remove(tr); 7508 tr.closeRecentsChain(); 7509 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7510 Intent baseIntent = new Intent( 7511 tr.intent != null ? tr.intent : tr.affinityIntent); 7512 ComponentName component = baseIntent.getComponent(); 7513 if (component == null) { 7514 Slog.w(TAG, "Now component for base intent of task: " + tr); 7515 return; 7516 } 7517 7518 // Find any running services associated with this app. 7519 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7520 7521 if (killProcesses) { 7522 // Find any running processes associated with this app. 7523 final String pkg = component.getPackageName(); 7524 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7525 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7526 for (int i=0; i<pmap.size(); i++) { 7527 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7528 for (int j=0; j<uids.size(); j++) { 7529 ProcessRecord proc = uids.valueAt(j); 7530 if (proc.userId != tr.userId) { 7531 continue; 7532 } 7533 if (!proc.pkgList.containsKey(pkg)) { 7534 continue; 7535 } 7536 procs.add(proc); 7537 } 7538 } 7539 7540 // Kill the running processes. 7541 for (int i=0; i<procs.size(); i++) { 7542 ProcessRecord pr = procs.get(i); 7543 if (pr == mHomeProcess) { 7544 // Don't kill the home process along with tasks from the same package. 7545 continue; 7546 } 7547 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7548 killUnneededProcessLocked(pr, "remove task"); 7549 } else { 7550 pr.waitingToKill = "remove task"; 7551 } 7552 } 7553 } 7554 } 7555 7556 /** 7557 * Removes the task with the specified task id. 7558 * 7559 * @param taskId Identifier of the task to be removed. 7560 * @param flags Additional operational flags. May be 0 or 7561 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7562 * @return Returns true if the given task was found and removed. 7563 */ 7564 private boolean removeTaskByIdLocked(int taskId, int flags) { 7565 TaskRecord tr = recentTaskForIdLocked(taskId); 7566 if (tr != null) { 7567 tr.removeTaskActivitiesLocked(); 7568 cleanUpRemovedTaskLocked(tr, flags); 7569 if (tr.isPersistable) { 7570 notifyTaskPersisterLocked(tr, true); 7571 } 7572 return true; 7573 } 7574 return false; 7575 } 7576 7577 @Override 7578 public boolean removeTask(int taskId, int flags) { 7579 synchronized (this) { 7580 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7581 "removeTask()"); 7582 long ident = Binder.clearCallingIdentity(); 7583 try { 7584 return removeTaskByIdLocked(taskId, flags); 7585 } finally { 7586 Binder.restoreCallingIdentity(ident); 7587 } 7588 } 7589 } 7590 7591 /** 7592 * TODO: Add mController hook 7593 */ 7594 @Override 7595 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7596 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7597 "moveTaskToFront()"); 7598 7599 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7600 synchronized(this) { 7601 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7602 Binder.getCallingUid(), "Task to front")) { 7603 ActivityOptions.abort(options); 7604 return; 7605 } 7606 final long origId = Binder.clearCallingIdentity(); 7607 try { 7608 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7609 if (task == null) { 7610 return; 7611 } 7612 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7613 mStackSupervisor.showLockTaskToast(); 7614 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7615 return; 7616 } 7617 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7618 if (prev != null && prev.isRecentsActivity()) { 7619 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7620 } 7621 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7622 } finally { 7623 Binder.restoreCallingIdentity(origId); 7624 } 7625 ActivityOptions.abort(options); 7626 } 7627 } 7628 7629 @Override 7630 public void moveTaskToBack(int taskId) { 7631 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7632 "moveTaskToBack()"); 7633 7634 synchronized(this) { 7635 TaskRecord tr = recentTaskForIdLocked(taskId); 7636 if (tr != null) { 7637 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7638 ActivityStack stack = tr.stack; 7639 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7640 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7641 Binder.getCallingUid(), "Task to back")) { 7642 return; 7643 } 7644 } 7645 final long origId = Binder.clearCallingIdentity(); 7646 try { 7647 stack.moveTaskToBackLocked(taskId, null); 7648 } finally { 7649 Binder.restoreCallingIdentity(origId); 7650 } 7651 } 7652 } 7653 } 7654 7655 /** 7656 * Moves an activity, and all of the other activities within the same task, to the bottom 7657 * of the history stack. The activity's order within the task is unchanged. 7658 * 7659 * @param token A reference to the activity we wish to move 7660 * @param nonRoot If false then this only works if the activity is the root 7661 * of a task; if true it will work for any activity in a task. 7662 * @return Returns true if the move completed, false if not. 7663 */ 7664 @Override 7665 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7666 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7667 synchronized(this) { 7668 final long origId = Binder.clearCallingIdentity(); 7669 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7670 if (taskId >= 0) { 7671 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7672 } 7673 Binder.restoreCallingIdentity(origId); 7674 } 7675 return false; 7676 } 7677 7678 @Override 7679 public void moveTaskBackwards(int task) { 7680 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7681 "moveTaskBackwards()"); 7682 7683 synchronized(this) { 7684 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7685 Binder.getCallingUid(), "Task backwards")) { 7686 return; 7687 } 7688 final long origId = Binder.clearCallingIdentity(); 7689 moveTaskBackwardsLocked(task); 7690 Binder.restoreCallingIdentity(origId); 7691 } 7692 } 7693 7694 private final void moveTaskBackwardsLocked(int task) { 7695 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7696 } 7697 7698 @Override 7699 public IBinder getHomeActivityToken() throws RemoteException { 7700 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7701 "getHomeActivityToken()"); 7702 synchronized (this) { 7703 return mStackSupervisor.getHomeActivityToken(); 7704 } 7705 } 7706 7707 @Override 7708 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7709 IActivityContainerCallback callback) throws RemoteException { 7710 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7711 "createActivityContainer()"); 7712 synchronized (this) { 7713 if (parentActivityToken == null) { 7714 throw new IllegalArgumentException("parent token must not be null"); 7715 } 7716 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7717 if (r == null) { 7718 return null; 7719 } 7720 if (callback == null) { 7721 throw new IllegalArgumentException("callback must not be null"); 7722 } 7723 return mStackSupervisor.createActivityContainer(r, callback); 7724 } 7725 } 7726 7727 @Override 7728 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7729 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7730 "deleteActivityContainer()"); 7731 synchronized (this) { 7732 mStackSupervisor.deleteActivityContainer(container); 7733 } 7734 } 7735 7736 @Override 7737 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7738 throws RemoteException { 7739 synchronized (this) { 7740 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7741 if (stack != null) { 7742 return stack.mActivityContainer; 7743 } 7744 return null; 7745 } 7746 } 7747 7748 @Override 7749 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7750 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7751 "moveTaskToStack()"); 7752 if (stackId == HOME_STACK_ID) { 7753 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7754 new RuntimeException("here").fillInStackTrace()); 7755 } 7756 synchronized (this) { 7757 long ident = Binder.clearCallingIdentity(); 7758 try { 7759 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7760 + stackId + " toTop=" + toTop); 7761 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7762 } finally { 7763 Binder.restoreCallingIdentity(ident); 7764 } 7765 } 7766 } 7767 7768 @Override 7769 public void resizeStack(int stackBoxId, Rect bounds) { 7770 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7771 "resizeStackBox()"); 7772 long ident = Binder.clearCallingIdentity(); 7773 try { 7774 mWindowManager.resizeStack(stackBoxId, bounds); 7775 } finally { 7776 Binder.restoreCallingIdentity(ident); 7777 } 7778 } 7779 7780 @Override 7781 public List<StackInfo> getAllStackInfos() { 7782 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7783 "getAllStackInfos()"); 7784 long ident = Binder.clearCallingIdentity(); 7785 try { 7786 synchronized (this) { 7787 return mStackSupervisor.getAllStackInfosLocked(); 7788 } 7789 } finally { 7790 Binder.restoreCallingIdentity(ident); 7791 } 7792 } 7793 7794 @Override 7795 public StackInfo getStackInfo(int stackId) { 7796 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7797 "getStackInfo()"); 7798 long ident = Binder.clearCallingIdentity(); 7799 try { 7800 synchronized (this) { 7801 return mStackSupervisor.getStackInfoLocked(stackId); 7802 } 7803 } finally { 7804 Binder.restoreCallingIdentity(ident); 7805 } 7806 } 7807 7808 @Override 7809 public boolean isInHomeStack(int taskId) { 7810 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7811 "getStackInfo()"); 7812 long ident = Binder.clearCallingIdentity(); 7813 try { 7814 synchronized (this) { 7815 TaskRecord tr = recentTaskForIdLocked(taskId); 7816 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7817 } 7818 } finally { 7819 Binder.restoreCallingIdentity(ident); 7820 } 7821 } 7822 7823 @Override 7824 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7825 synchronized(this) { 7826 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7827 } 7828 } 7829 7830 private boolean isLockTaskAuthorized(String pkg) { 7831 final DevicePolicyManager dpm = (DevicePolicyManager) 7832 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7833 try { 7834 int uid = mContext.getPackageManager().getPackageUid(pkg, 7835 Binder.getCallingUserHandle().getIdentifier()); 7836 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7837 } catch (NameNotFoundException e) { 7838 return false; 7839 } 7840 } 7841 7842 void startLockTaskMode(TaskRecord task) { 7843 final String pkg; 7844 synchronized (this) { 7845 pkg = task.intent.getComponent().getPackageName(); 7846 } 7847 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7848 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7849 final TaskRecord taskRecord = task; 7850 mHandler.post(new Runnable() { 7851 @Override 7852 public void run() { 7853 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7854 } 7855 }); 7856 return; 7857 } 7858 long ident = Binder.clearCallingIdentity(); 7859 try { 7860 synchronized (this) { 7861 // Since we lost lock on task, make sure it is still there. 7862 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7863 if (task != null) { 7864 if (!isSystemInitiated 7865 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7866 throw new IllegalArgumentException("Invalid task, not in foreground"); 7867 } 7868 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7869 } 7870 } 7871 } finally { 7872 Binder.restoreCallingIdentity(ident); 7873 } 7874 } 7875 7876 @Override 7877 public void startLockTaskMode(int taskId) { 7878 final TaskRecord task; 7879 long ident = Binder.clearCallingIdentity(); 7880 try { 7881 synchronized (this) { 7882 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7883 } 7884 } finally { 7885 Binder.restoreCallingIdentity(ident); 7886 } 7887 if (task != null) { 7888 startLockTaskMode(task); 7889 } 7890 } 7891 7892 @Override 7893 public void startLockTaskMode(IBinder token) { 7894 final TaskRecord task; 7895 long ident = Binder.clearCallingIdentity(); 7896 try { 7897 synchronized (this) { 7898 final ActivityRecord r = ActivityRecord.forToken(token); 7899 if (r == null) { 7900 return; 7901 } 7902 task = r.task; 7903 } 7904 } finally { 7905 Binder.restoreCallingIdentity(ident); 7906 } 7907 if (task != null) { 7908 startLockTaskMode(task); 7909 } 7910 } 7911 7912 @Override 7913 public void startLockTaskModeOnCurrent() throws RemoteException { 7914 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7915 ActivityRecord r = null; 7916 synchronized (this) { 7917 r = mStackSupervisor.topRunningActivityLocked(); 7918 } 7919 startLockTaskMode(r.task); 7920 } 7921 7922 @Override 7923 public void stopLockTaskMode() { 7924 // Verify that the user matches the package of the intent for the TaskRecord 7925 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7926 // and stopLockTaskMode. 7927 final int callingUid = Binder.getCallingUid(); 7928 if (callingUid != Process.SYSTEM_UID) { 7929 try { 7930 String pkg = 7931 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7932 int uid = mContext.getPackageManager().getPackageUid(pkg, 7933 Binder.getCallingUserHandle().getIdentifier()); 7934 if (uid != callingUid) { 7935 throw new SecurityException("Invalid uid, expected " + uid); 7936 } 7937 } catch (NameNotFoundException e) { 7938 Log.d(TAG, "stopLockTaskMode " + e); 7939 return; 7940 } 7941 } 7942 long ident = Binder.clearCallingIdentity(); 7943 try { 7944 Log.d(TAG, "stopLockTaskMode"); 7945 // Stop lock task 7946 synchronized (this) { 7947 mStackSupervisor.setLockTaskModeLocked(null, false); 7948 } 7949 } finally { 7950 Binder.restoreCallingIdentity(ident); 7951 } 7952 } 7953 7954 @Override 7955 public void stopLockTaskModeOnCurrent() throws RemoteException { 7956 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7957 long ident = Binder.clearCallingIdentity(); 7958 try { 7959 stopLockTaskMode(); 7960 } finally { 7961 Binder.restoreCallingIdentity(ident); 7962 } 7963 } 7964 7965 @Override 7966 public boolean isInLockTaskMode() { 7967 synchronized (this) { 7968 return mStackSupervisor.isInLockTaskMode(); 7969 } 7970 } 7971 7972 // ========================================================= 7973 // CONTENT PROVIDERS 7974 // ========================================================= 7975 7976 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7977 List<ProviderInfo> providers = null; 7978 try { 7979 providers = AppGlobals.getPackageManager(). 7980 queryContentProviders(app.processName, app.uid, 7981 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7982 } catch (RemoteException ex) { 7983 } 7984 if (DEBUG_MU) 7985 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7986 int userId = app.userId; 7987 if (providers != null) { 7988 int N = providers.size(); 7989 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7990 for (int i=0; i<N; i++) { 7991 ProviderInfo cpi = 7992 (ProviderInfo)providers.get(i); 7993 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7994 cpi.name, cpi.flags); 7995 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7996 // This is a singleton provider, but a user besides the 7997 // default user is asking to initialize a process it runs 7998 // in... well, no, it doesn't actually run in this process, 7999 // it runs in the process of the default user. Get rid of it. 8000 providers.remove(i); 8001 N--; 8002 i--; 8003 continue; 8004 } 8005 8006 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8007 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8008 if (cpr == null) { 8009 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8010 mProviderMap.putProviderByClass(comp, cpr); 8011 } 8012 if (DEBUG_MU) 8013 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8014 app.pubProviders.put(cpi.name, cpr); 8015 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8016 // Don't add this if it is a platform component that is marked 8017 // to run in multiple processes, because this is actually 8018 // part of the framework so doesn't make sense to track as a 8019 // separate apk in the process. 8020 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8021 mProcessStats); 8022 } 8023 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8024 } 8025 } 8026 return providers; 8027 } 8028 8029 /** 8030 * Check if {@link ProcessRecord} has a possible chance at accessing the 8031 * given {@link ProviderInfo}. Final permission checking is always done 8032 * in {@link ContentProvider}. 8033 */ 8034 private final String checkContentProviderPermissionLocked( 8035 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8036 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8037 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8038 boolean checkedGrants = false; 8039 if (checkUser) { 8040 // Looking for cross-user grants before enforcing the typical cross-users permissions 8041 int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid)); 8042 if (tmpTargetUserId != userId) { 8043 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8044 return null; 8045 } 8046 checkedGrants = true; 8047 } 8048 userId = handleIncomingUser(callingPid, callingUid, userId, 8049 false, ALLOW_NON_FULL_IN_PROFILE, 8050 "checkContentProviderPermissionLocked " + cpi.authority, null); 8051 if (userId != tmpTargetUserId) { 8052 // When we actually went to determine the final targer user ID, this ended 8053 // up different than our initial check for the authority. This is because 8054 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8055 // SELF. So we need to re-check the grants again. 8056 checkedGrants = false; 8057 } 8058 } 8059 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8060 cpi.applicationInfo.uid, cpi.exported) 8061 == PackageManager.PERMISSION_GRANTED) { 8062 return null; 8063 } 8064 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8065 cpi.applicationInfo.uid, cpi.exported) 8066 == PackageManager.PERMISSION_GRANTED) { 8067 return null; 8068 } 8069 8070 PathPermission[] pps = cpi.pathPermissions; 8071 if (pps != null) { 8072 int i = pps.length; 8073 while (i > 0) { 8074 i--; 8075 PathPermission pp = pps[i]; 8076 String pprperm = pp.getReadPermission(); 8077 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8078 cpi.applicationInfo.uid, cpi.exported) 8079 == PackageManager.PERMISSION_GRANTED) { 8080 return null; 8081 } 8082 String ppwperm = pp.getWritePermission(); 8083 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8084 cpi.applicationInfo.uid, cpi.exported) 8085 == PackageManager.PERMISSION_GRANTED) { 8086 return null; 8087 } 8088 } 8089 } 8090 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8091 return null; 8092 } 8093 8094 String msg; 8095 if (!cpi.exported) { 8096 msg = "Permission Denial: opening provider " + cpi.name 8097 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8098 + ", uid=" + callingUid + ") that is not exported from uid " 8099 + cpi.applicationInfo.uid; 8100 } else { 8101 msg = "Permission Denial: opening provider " + cpi.name 8102 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8103 + ", uid=" + callingUid + ") requires " 8104 + cpi.readPermission + " or " + cpi.writePermission; 8105 } 8106 Slog.w(TAG, msg); 8107 return msg; 8108 } 8109 8110 /** 8111 * Returns if the ContentProvider has granted a uri to callingUid 8112 */ 8113 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8114 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8115 if (perms != null) { 8116 for (int i=perms.size()-1; i>=0; i--) { 8117 GrantUri grantUri = perms.keyAt(i); 8118 if (grantUri.sourceUserId == userId || !checkUser) { 8119 if (matchesProvider(grantUri.uri, cpi)) { 8120 return true; 8121 } 8122 } 8123 } 8124 } 8125 return false; 8126 } 8127 8128 /** 8129 * Returns true if the uri authority is one of the authorities specified in the provider. 8130 */ 8131 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8132 String uriAuth = uri.getAuthority(); 8133 String cpiAuth = cpi.authority; 8134 if (cpiAuth.indexOf(';') == -1) { 8135 return cpiAuth.equals(uriAuth); 8136 } 8137 String[] cpiAuths = cpiAuth.split(";"); 8138 int length = cpiAuths.length; 8139 for (int i = 0; i < length; i++) { 8140 if (cpiAuths[i].equals(uriAuth)) return true; 8141 } 8142 return false; 8143 } 8144 8145 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8146 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8147 if (r != null) { 8148 for (int i=0; i<r.conProviders.size(); i++) { 8149 ContentProviderConnection conn = r.conProviders.get(i); 8150 if (conn.provider == cpr) { 8151 if (DEBUG_PROVIDER) Slog.v(TAG, 8152 "Adding provider requested by " 8153 + r.processName + " from process " 8154 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8155 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8156 if (stable) { 8157 conn.stableCount++; 8158 conn.numStableIncs++; 8159 } else { 8160 conn.unstableCount++; 8161 conn.numUnstableIncs++; 8162 } 8163 return conn; 8164 } 8165 } 8166 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8167 if (stable) { 8168 conn.stableCount = 1; 8169 conn.numStableIncs = 1; 8170 } else { 8171 conn.unstableCount = 1; 8172 conn.numUnstableIncs = 1; 8173 } 8174 cpr.connections.add(conn); 8175 r.conProviders.add(conn); 8176 return conn; 8177 } 8178 cpr.addExternalProcessHandleLocked(externalProcessToken); 8179 return null; 8180 } 8181 8182 boolean decProviderCountLocked(ContentProviderConnection conn, 8183 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8184 if (conn != null) { 8185 cpr = conn.provider; 8186 if (DEBUG_PROVIDER) Slog.v(TAG, 8187 "Removing provider requested by " 8188 + conn.client.processName + " from process " 8189 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8190 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8191 if (stable) { 8192 conn.stableCount--; 8193 } else { 8194 conn.unstableCount--; 8195 } 8196 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8197 cpr.connections.remove(conn); 8198 conn.client.conProviders.remove(conn); 8199 return true; 8200 } 8201 return false; 8202 } 8203 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8204 return false; 8205 } 8206 8207 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8208 String name, IBinder token, boolean stable, int userId) { 8209 ContentProviderRecord cpr; 8210 ContentProviderConnection conn = null; 8211 ProviderInfo cpi = null; 8212 8213 synchronized(this) { 8214 ProcessRecord r = null; 8215 if (caller != null) { 8216 r = getRecordForAppLocked(caller); 8217 if (r == null) { 8218 throw new SecurityException( 8219 "Unable to find app for caller " + caller 8220 + " (pid=" + Binder.getCallingPid() 8221 + ") when getting content provider " + name); 8222 } 8223 } 8224 8225 boolean checkCrossUser = true; 8226 8227 // First check if this content provider has been published... 8228 cpr = mProviderMap.getProviderByName(name, userId); 8229 // If that didn't work, check if it exists for user 0 and then 8230 // verify that it's a singleton provider before using it. 8231 if (cpr == null && userId != UserHandle.USER_OWNER) { 8232 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8233 if (cpr != null) { 8234 cpi = cpr.info; 8235 if (isSingleton(cpi.processName, cpi.applicationInfo, 8236 cpi.name, cpi.flags) 8237 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8238 userId = UserHandle.USER_OWNER; 8239 checkCrossUser = false; 8240 } else { 8241 cpr = null; 8242 cpi = null; 8243 } 8244 } 8245 } 8246 8247 boolean providerRunning = cpr != null; 8248 if (providerRunning) { 8249 cpi = cpr.info; 8250 String msg; 8251 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8252 != null) { 8253 throw new SecurityException(msg); 8254 } 8255 8256 if (r != null && cpr.canRunHere(r)) { 8257 // This provider has been published or is in the process 8258 // of being published... but it is also allowed to run 8259 // in the caller's process, so don't make a connection 8260 // and just let the caller instantiate its own instance. 8261 ContentProviderHolder holder = cpr.newHolder(null); 8262 // don't give caller the provider object, it needs 8263 // to make its own. 8264 holder.provider = null; 8265 return holder; 8266 } 8267 8268 final long origId = Binder.clearCallingIdentity(); 8269 8270 // In this case the provider instance already exists, so we can 8271 // return it right away. 8272 conn = incProviderCountLocked(r, cpr, token, stable); 8273 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8274 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8275 // If this is a perceptible app accessing the provider, 8276 // make sure to count it as being accessed and thus 8277 // back up on the LRU list. This is good because 8278 // content providers are often expensive to start. 8279 updateLruProcessLocked(cpr.proc, false, null); 8280 } 8281 } 8282 8283 if (cpr.proc != null) { 8284 if (false) { 8285 if (cpr.name.flattenToShortString().equals( 8286 "com.android.providers.calendar/.CalendarProvider2")) { 8287 Slog.v(TAG, "****************** KILLING " 8288 + cpr.name.flattenToShortString()); 8289 Process.killProcess(cpr.proc.pid); 8290 } 8291 } 8292 boolean success = updateOomAdjLocked(cpr.proc); 8293 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8294 // NOTE: there is still a race here where a signal could be 8295 // pending on the process even though we managed to update its 8296 // adj level. Not sure what to do about this, but at least 8297 // the race is now smaller. 8298 if (!success) { 8299 // Uh oh... it looks like the provider's process 8300 // has been killed on us. We need to wait for a new 8301 // process to be started, and make sure its death 8302 // doesn't kill our process. 8303 Slog.i(TAG, 8304 "Existing provider " + cpr.name.flattenToShortString() 8305 + " is crashing; detaching " + r); 8306 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8307 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8308 if (!lastRef) { 8309 // This wasn't the last ref our process had on 8310 // the provider... we have now been killed, bail. 8311 return null; 8312 } 8313 providerRunning = false; 8314 conn = null; 8315 } 8316 } 8317 8318 Binder.restoreCallingIdentity(origId); 8319 } 8320 8321 boolean singleton; 8322 if (!providerRunning) { 8323 try { 8324 cpi = AppGlobals.getPackageManager(). 8325 resolveContentProvider(name, 8326 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8327 } catch (RemoteException ex) { 8328 } 8329 if (cpi == null) { 8330 return null; 8331 } 8332 // If the provider is a singleton AND 8333 // (it's a call within the same user || the provider is a 8334 // privileged app) 8335 // Then allow connecting to the singleton provider 8336 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8337 cpi.name, cpi.flags) 8338 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8339 if (singleton) { 8340 userId = UserHandle.USER_OWNER; 8341 } 8342 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8343 8344 String msg; 8345 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8346 != null) { 8347 throw new SecurityException(msg); 8348 } 8349 8350 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8351 && !cpi.processName.equals("system")) { 8352 // If this content provider does not run in the system 8353 // process, and the system is not yet ready to run other 8354 // processes, then fail fast instead of hanging. 8355 throw new IllegalArgumentException( 8356 "Attempt to launch content provider before system ready"); 8357 } 8358 8359 // Make sure that the user who owns this provider is started. If not, 8360 // we don't want to allow it to run. 8361 if (mStartedUsers.get(userId) == null) { 8362 Slog.w(TAG, "Unable to launch app " 8363 + cpi.applicationInfo.packageName + "/" 8364 + cpi.applicationInfo.uid + " for provider " 8365 + name + ": user " + userId + " is stopped"); 8366 return null; 8367 } 8368 8369 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8370 cpr = mProviderMap.getProviderByClass(comp, userId); 8371 final boolean firstClass = cpr == null; 8372 if (firstClass) { 8373 try { 8374 ApplicationInfo ai = 8375 AppGlobals.getPackageManager(). 8376 getApplicationInfo( 8377 cpi.applicationInfo.packageName, 8378 STOCK_PM_FLAGS, userId); 8379 if (ai == null) { 8380 Slog.w(TAG, "No package info for content provider " 8381 + cpi.name); 8382 return null; 8383 } 8384 ai = getAppInfoForUser(ai, userId); 8385 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8386 } catch (RemoteException ex) { 8387 // pm is in same process, this will never happen. 8388 } 8389 } 8390 8391 if (r != null && cpr.canRunHere(r)) { 8392 // If this is a multiprocess provider, then just return its 8393 // info and allow the caller to instantiate it. Only do 8394 // this if the provider is the same user as the caller's 8395 // process, or can run as root (so can be in any process). 8396 return cpr.newHolder(null); 8397 } 8398 8399 if (DEBUG_PROVIDER) { 8400 RuntimeException e = new RuntimeException("here"); 8401 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8402 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8403 } 8404 8405 // This is single process, and our app is now connecting to it. 8406 // See if we are already in the process of launching this 8407 // provider. 8408 final int N = mLaunchingProviders.size(); 8409 int i; 8410 for (i=0; i<N; i++) { 8411 if (mLaunchingProviders.get(i) == cpr) { 8412 break; 8413 } 8414 } 8415 8416 // If the provider is not already being launched, then get it 8417 // started. 8418 if (i >= N) { 8419 final long origId = Binder.clearCallingIdentity(); 8420 8421 try { 8422 // Content provider is now in use, its package can't be stopped. 8423 try { 8424 AppGlobals.getPackageManager().setPackageStoppedState( 8425 cpr.appInfo.packageName, false, userId); 8426 } catch (RemoteException e) { 8427 } catch (IllegalArgumentException e) { 8428 Slog.w(TAG, "Failed trying to unstop package " 8429 + cpr.appInfo.packageName + ": " + e); 8430 } 8431 8432 // Use existing process if already started 8433 ProcessRecord proc = getProcessRecordLocked( 8434 cpi.processName, cpr.appInfo.uid, false); 8435 if (proc != null && proc.thread != null) { 8436 if (DEBUG_PROVIDER) { 8437 Slog.d(TAG, "Installing in existing process " + proc); 8438 } 8439 proc.pubProviders.put(cpi.name, cpr); 8440 try { 8441 proc.thread.scheduleInstallProvider(cpi); 8442 } catch (RemoteException e) { 8443 } 8444 } else { 8445 proc = startProcessLocked(cpi.processName, 8446 cpr.appInfo, false, 0, "content provider", 8447 new ComponentName(cpi.applicationInfo.packageName, 8448 cpi.name), false, false, false); 8449 if (proc == null) { 8450 Slog.w(TAG, "Unable to launch app " 8451 + cpi.applicationInfo.packageName + "/" 8452 + cpi.applicationInfo.uid + " for provider " 8453 + name + ": process is bad"); 8454 return null; 8455 } 8456 } 8457 cpr.launchingApp = proc; 8458 mLaunchingProviders.add(cpr); 8459 } finally { 8460 Binder.restoreCallingIdentity(origId); 8461 } 8462 } 8463 8464 // Make sure the provider is published (the same provider class 8465 // may be published under multiple names). 8466 if (firstClass) { 8467 mProviderMap.putProviderByClass(comp, cpr); 8468 } 8469 8470 mProviderMap.putProviderByName(name, cpr); 8471 conn = incProviderCountLocked(r, cpr, token, stable); 8472 if (conn != null) { 8473 conn.waiting = true; 8474 } 8475 } 8476 } 8477 8478 // Wait for the provider to be published... 8479 synchronized (cpr) { 8480 while (cpr.provider == null) { 8481 if (cpr.launchingApp == null) { 8482 Slog.w(TAG, "Unable to launch app " 8483 + cpi.applicationInfo.packageName + "/" 8484 + cpi.applicationInfo.uid + " for provider " 8485 + name + ": launching app became null"); 8486 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8487 UserHandle.getUserId(cpi.applicationInfo.uid), 8488 cpi.applicationInfo.packageName, 8489 cpi.applicationInfo.uid, name); 8490 return null; 8491 } 8492 try { 8493 if (DEBUG_MU) { 8494 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8495 + cpr.launchingApp); 8496 } 8497 if (conn != null) { 8498 conn.waiting = true; 8499 } 8500 cpr.wait(); 8501 } catch (InterruptedException ex) { 8502 } finally { 8503 if (conn != null) { 8504 conn.waiting = false; 8505 } 8506 } 8507 } 8508 } 8509 return cpr != null ? cpr.newHolder(conn) : null; 8510 } 8511 8512 @Override 8513 public final ContentProviderHolder getContentProvider( 8514 IApplicationThread caller, String name, int userId, boolean stable) { 8515 enforceNotIsolatedCaller("getContentProvider"); 8516 if (caller == null) { 8517 String msg = "null IApplicationThread when getting content provider " 8518 + name; 8519 Slog.w(TAG, msg); 8520 throw new SecurityException(msg); 8521 } 8522 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8523 // with cross-user grant. 8524 return getContentProviderImpl(caller, name, null, stable, userId); 8525 } 8526 8527 public ContentProviderHolder getContentProviderExternal( 8528 String name, int userId, IBinder token) { 8529 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8530 "Do not have permission in call getContentProviderExternal()"); 8531 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8532 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8533 return getContentProviderExternalUnchecked(name, token, userId); 8534 } 8535 8536 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8537 IBinder token, int userId) { 8538 return getContentProviderImpl(null, name, token, true, userId); 8539 } 8540 8541 /** 8542 * Drop a content provider from a ProcessRecord's bookkeeping 8543 */ 8544 public void removeContentProvider(IBinder connection, boolean stable) { 8545 enforceNotIsolatedCaller("removeContentProvider"); 8546 long ident = Binder.clearCallingIdentity(); 8547 try { 8548 synchronized (this) { 8549 ContentProviderConnection conn; 8550 try { 8551 conn = (ContentProviderConnection)connection; 8552 } catch (ClassCastException e) { 8553 String msg ="removeContentProvider: " + connection 8554 + " not a ContentProviderConnection"; 8555 Slog.w(TAG, msg); 8556 throw new IllegalArgumentException(msg); 8557 } 8558 if (conn == null) { 8559 throw new NullPointerException("connection is null"); 8560 } 8561 if (decProviderCountLocked(conn, null, null, stable)) { 8562 updateOomAdjLocked(); 8563 } 8564 } 8565 } finally { 8566 Binder.restoreCallingIdentity(ident); 8567 } 8568 } 8569 8570 public void removeContentProviderExternal(String name, IBinder token) { 8571 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8572 "Do not have permission in call removeContentProviderExternal()"); 8573 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8574 } 8575 8576 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8577 synchronized (this) { 8578 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8579 if(cpr == null) { 8580 //remove from mProvidersByClass 8581 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8582 return; 8583 } 8584 8585 //update content provider record entry info 8586 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8587 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8588 if (localCpr.hasExternalProcessHandles()) { 8589 if (localCpr.removeExternalProcessHandleLocked(token)) { 8590 updateOomAdjLocked(); 8591 } else { 8592 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8593 + " with no external reference for token: " 8594 + token + "."); 8595 } 8596 } else { 8597 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8598 + " with no external references."); 8599 } 8600 } 8601 } 8602 8603 public final void publishContentProviders(IApplicationThread caller, 8604 List<ContentProviderHolder> providers) { 8605 if (providers == null) { 8606 return; 8607 } 8608 8609 enforceNotIsolatedCaller("publishContentProviders"); 8610 synchronized (this) { 8611 final ProcessRecord r = getRecordForAppLocked(caller); 8612 if (DEBUG_MU) 8613 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8614 if (r == null) { 8615 throw new SecurityException( 8616 "Unable to find app for caller " + caller 8617 + " (pid=" + Binder.getCallingPid() 8618 + ") when publishing content providers"); 8619 } 8620 8621 final long origId = Binder.clearCallingIdentity(); 8622 8623 final int N = providers.size(); 8624 for (int i=0; i<N; i++) { 8625 ContentProviderHolder src = providers.get(i); 8626 if (src == null || src.info == null || src.provider == null) { 8627 continue; 8628 } 8629 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8630 if (DEBUG_MU) 8631 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8632 if (dst != null) { 8633 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8634 mProviderMap.putProviderByClass(comp, dst); 8635 String names[] = dst.info.authority.split(";"); 8636 for (int j = 0; j < names.length; j++) { 8637 mProviderMap.putProviderByName(names[j], dst); 8638 } 8639 8640 int NL = mLaunchingProviders.size(); 8641 int j; 8642 for (j=0; j<NL; j++) { 8643 if (mLaunchingProviders.get(j) == dst) { 8644 mLaunchingProviders.remove(j); 8645 j--; 8646 NL--; 8647 } 8648 } 8649 synchronized (dst) { 8650 dst.provider = src.provider; 8651 dst.proc = r; 8652 dst.notifyAll(); 8653 } 8654 updateOomAdjLocked(r); 8655 } 8656 } 8657 8658 Binder.restoreCallingIdentity(origId); 8659 } 8660 } 8661 8662 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8663 ContentProviderConnection conn; 8664 try { 8665 conn = (ContentProviderConnection)connection; 8666 } catch (ClassCastException e) { 8667 String msg ="refContentProvider: " + connection 8668 + " not a ContentProviderConnection"; 8669 Slog.w(TAG, msg); 8670 throw new IllegalArgumentException(msg); 8671 } 8672 if (conn == null) { 8673 throw new NullPointerException("connection is null"); 8674 } 8675 8676 synchronized (this) { 8677 if (stable > 0) { 8678 conn.numStableIncs += stable; 8679 } 8680 stable = conn.stableCount + stable; 8681 if (stable < 0) { 8682 throw new IllegalStateException("stableCount < 0: " + stable); 8683 } 8684 8685 if (unstable > 0) { 8686 conn.numUnstableIncs += unstable; 8687 } 8688 unstable = conn.unstableCount + unstable; 8689 if (unstable < 0) { 8690 throw new IllegalStateException("unstableCount < 0: " + unstable); 8691 } 8692 8693 if ((stable+unstable) <= 0) { 8694 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8695 + stable + " unstable=" + unstable); 8696 } 8697 conn.stableCount = stable; 8698 conn.unstableCount = unstable; 8699 return !conn.dead; 8700 } 8701 } 8702 8703 public void unstableProviderDied(IBinder connection) { 8704 ContentProviderConnection conn; 8705 try { 8706 conn = (ContentProviderConnection)connection; 8707 } catch (ClassCastException e) { 8708 String msg ="refContentProvider: " + connection 8709 + " not a ContentProviderConnection"; 8710 Slog.w(TAG, msg); 8711 throw new IllegalArgumentException(msg); 8712 } 8713 if (conn == null) { 8714 throw new NullPointerException("connection is null"); 8715 } 8716 8717 // Safely retrieve the content provider associated with the connection. 8718 IContentProvider provider; 8719 synchronized (this) { 8720 provider = conn.provider.provider; 8721 } 8722 8723 if (provider == null) { 8724 // Um, yeah, we're way ahead of you. 8725 return; 8726 } 8727 8728 // Make sure the caller is being honest with us. 8729 if (provider.asBinder().pingBinder()) { 8730 // Er, no, still looks good to us. 8731 synchronized (this) { 8732 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8733 + " says " + conn + " died, but we don't agree"); 8734 return; 8735 } 8736 } 8737 8738 // Well look at that! It's dead! 8739 synchronized (this) { 8740 if (conn.provider.provider != provider) { 8741 // But something changed... good enough. 8742 return; 8743 } 8744 8745 ProcessRecord proc = conn.provider.proc; 8746 if (proc == null || proc.thread == null) { 8747 // Seems like the process is already cleaned up. 8748 return; 8749 } 8750 8751 // As far as we're concerned, this is just like receiving a 8752 // death notification... just a bit prematurely. 8753 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8754 + ") early provider death"); 8755 final long ident = Binder.clearCallingIdentity(); 8756 try { 8757 appDiedLocked(proc, proc.pid, proc.thread); 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 } 8762 } 8763 8764 @Override 8765 public void appNotRespondingViaProvider(IBinder connection) { 8766 enforceCallingPermission( 8767 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8768 8769 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8770 if (conn == null) { 8771 Slog.w(TAG, "ContentProviderConnection is null"); 8772 return; 8773 } 8774 8775 final ProcessRecord host = conn.provider.proc; 8776 if (host == null) { 8777 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8778 return; 8779 } 8780 8781 final long token = Binder.clearCallingIdentity(); 8782 try { 8783 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8784 } finally { 8785 Binder.restoreCallingIdentity(token); 8786 } 8787 } 8788 8789 public final void installSystemProviders() { 8790 List<ProviderInfo> providers; 8791 synchronized (this) { 8792 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8793 providers = generateApplicationProvidersLocked(app); 8794 if (providers != null) { 8795 for (int i=providers.size()-1; i>=0; i--) { 8796 ProviderInfo pi = (ProviderInfo)providers.get(i); 8797 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8798 Slog.w(TAG, "Not installing system proc provider " + pi.name 8799 + ": not system .apk"); 8800 providers.remove(i); 8801 } 8802 } 8803 } 8804 } 8805 if (providers != null) { 8806 mSystemThread.installSystemProviders(providers); 8807 } 8808 8809 mCoreSettingsObserver = new CoreSettingsObserver(this); 8810 8811 mUsageStatsService.monitorPackages(); 8812 } 8813 8814 /** 8815 * Allows app to retrieve the MIME type of a URI without having permission 8816 * to access its content provider. 8817 * 8818 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8819 * 8820 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8821 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8822 */ 8823 public String getProviderMimeType(Uri uri, int userId) { 8824 enforceNotIsolatedCaller("getProviderMimeType"); 8825 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8826 userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null); 8827 final String name = uri.getAuthority(); 8828 final long ident = Binder.clearCallingIdentity(); 8829 ContentProviderHolder holder = null; 8830 8831 try { 8832 holder = getContentProviderExternalUnchecked(name, null, userId); 8833 if (holder != null) { 8834 return holder.provider.getType(uri); 8835 } 8836 } catch (RemoteException e) { 8837 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8838 return null; 8839 } finally { 8840 if (holder != null) { 8841 removeContentProviderExternalUnchecked(name, null, userId); 8842 } 8843 Binder.restoreCallingIdentity(ident); 8844 } 8845 8846 return null; 8847 } 8848 8849 // ========================================================= 8850 // GLOBAL MANAGEMENT 8851 // ========================================================= 8852 8853 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8854 boolean isolated) { 8855 String proc = customProcess != null ? customProcess : info.processName; 8856 BatteryStatsImpl.Uid.Proc ps = null; 8857 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8858 int uid = info.uid; 8859 if (isolated) { 8860 int userId = UserHandle.getUserId(uid); 8861 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8862 while (true) { 8863 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8864 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8865 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8866 } 8867 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8868 mNextIsolatedProcessUid++; 8869 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8870 // No process for this uid, use it. 8871 break; 8872 } 8873 stepsLeft--; 8874 if (stepsLeft <= 0) { 8875 return null; 8876 } 8877 } 8878 } 8879 return new ProcessRecord(stats, info, proc, uid); 8880 } 8881 8882 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8883 String abiOverride) { 8884 ProcessRecord app; 8885 if (!isolated) { 8886 app = getProcessRecordLocked(info.processName, info.uid, true); 8887 } else { 8888 app = null; 8889 } 8890 8891 if (app == null) { 8892 app = newProcessRecordLocked(info, null, isolated); 8893 mProcessNames.put(info.processName, app.uid, app); 8894 if (isolated) { 8895 mIsolatedProcesses.put(app.uid, app); 8896 } 8897 updateLruProcessLocked(app, false, null); 8898 updateOomAdjLocked(); 8899 } 8900 8901 // This package really, really can not be stopped. 8902 try { 8903 AppGlobals.getPackageManager().setPackageStoppedState( 8904 info.packageName, false, UserHandle.getUserId(app.uid)); 8905 } catch (RemoteException e) { 8906 } catch (IllegalArgumentException e) { 8907 Slog.w(TAG, "Failed trying to unstop package " 8908 + info.packageName + ": " + e); 8909 } 8910 8911 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8912 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8913 app.persistent = true; 8914 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8915 } 8916 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8917 mPersistentStartingProcesses.add(app); 8918 startProcessLocked(app, "added application", app.processName, 8919 abiOverride); 8920 } 8921 8922 return app; 8923 } 8924 8925 public void unhandledBack() { 8926 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8927 "unhandledBack()"); 8928 8929 synchronized(this) { 8930 final long origId = Binder.clearCallingIdentity(); 8931 try { 8932 getFocusedStack().unhandledBackLocked(); 8933 } finally { 8934 Binder.restoreCallingIdentity(origId); 8935 } 8936 } 8937 } 8938 8939 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8940 enforceNotIsolatedCaller("openContentUri"); 8941 final int userId = UserHandle.getCallingUserId(); 8942 String name = uri.getAuthority(); 8943 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8944 ParcelFileDescriptor pfd = null; 8945 if (cph != null) { 8946 // We record the binder invoker's uid in thread-local storage before 8947 // going to the content provider to open the file. Later, in the code 8948 // that handles all permissions checks, we look for this uid and use 8949 // that rather than the Activity Manager's own uid. The effect is that 8950 // we do the check against the caller's permissions even though it looks 8951 // to the content provider like the Activity Manager itself is making 8952 // the request. 8953 sCallerIdentity.set(new Identity( 8954 Binder.getCallingPid(), Binder.getCallingUid())); 8955 try { 8956 pfd = cph.provider.openFile(null, uri, "r", null); 8957 } catch (FileNotFoundException e) { 8958 // do nothing; pfd will be returned null 8959 } finally { 8960 // Ensure that whatever happens, we clean up the identity state 8961 sCallerIdentity.remove(); 8962 } 8963 8964 // We've got the fd now, so we're done with the provider. 8965 removeContentProviderExternalUnchecked(name, null, userId); 8966 } else { 8967 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8968 } 8969 return pfd; 8970 } 8971 8972 // Actually is sleeping or shutting down or whatever else in the future 8973 // is an inactive state. 8974 public boolean isSleepingOrShuttingDown() { 8975 return mSleeping || mShuttingDown; 8976 } 8977 8978 public boolean isSleeping() { 8979 return mSleeping; 8980 } 8981 8982 void goingToSleep() { 8983 synchronized(this) { 8984 mWentToSleep = true; 8985 updateEventDispatchingLocked(); 8986 goToSleepIfNeededLocked(); 8987 } 8988 } 8989 8990 void finishRunningVoiceLocked() { 8991 if (mRunningVoice) { 8992 mRunningVoice = false; 8993 goToSleepIfNeededLocked(); 8994 } 8995 } 8996 8997 void goToSleepIfNeededLocked() { 8998 if (mWentToSleep && !mRunningVoice) { 8999 if (!mSleeping) { 9000 mSleeping = true; 9001 mStackSupervisor.goingToSleepLocked(); 9002 9003 // Initialize the wake times of all processes. 9004 checkExcessivePowerUsageLocked(false); 9005 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9006 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9007 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9008 } 9009 } 9010 } 9011 9012 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9013 mTaskPersister.notify(task, flush); 9014 } 9015 9016 @Override 9017 public boolean shutdown(int timeout) { 9018 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9019 != PackageManager.PERMISSION_GRANTED) { 9020 throw new SecurityException("Requires permission " 9021 + android.Manifest.permission.SHUTDOWN); 9022 } 9023 9024 boolean timedout = false; 9025 9026 synchronized(this) { 9027 mShuttingDown = true; 9028 updateEventDispatchingLocked(); 9029 timedout = mStackSupervisor.shutdownLocked(timeout); 9030 } 9031 9032 mAppOpsService.shutdown(); 9033 mUsageStatsService.shutdown(); 9034 mBatteryStatsService.shutdown(); 9035 synchronized (this) { 9036 mProcessStats.shutdownLocked(); 9037 } 9038 notifyTaskPersisterLocked(null, true); 9039 9040 return timedout; 9041 } 9042 9043 public final void activitySlept(IBinder token) { 9044 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9045 9046 final long origId = Binder.clearCallingIdentity(); 9047 9048 synchronized (this) { 9049 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9050 if (r != null) { 9051 mStackSupervisor.activitySleptLocked(r); 9052 } 9053 } 9054 9055 Binder.restoreCallingIdentity(origId); 9056 } 9057 9058 void logLockScreen(String msg) { 9059 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9060 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9061 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 9062 mStackSupervisor.mDismissKeyguardOnNextActivity); 9063 } 9064 9065 private void comeOutOfSleepIfNeededLocked() { 9066 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9067 if (mSleeping) { 9068 mSleeping = false; 9069 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9070 } 9071 } 9072 } 9073 9074 void wakingUp() { 9075 synchronized(this) { 9076 mWentToSleep = false; 9077 updateEventDispatchingLocked(); 9078 comeOutOfSleepIfNeededLocked(); 9079 } 9080 } 9081 9082 void startRunningVoiceLocked() { 9083 if (!mRunningVoice) { 9084 mRunningVoice = true; 9085 comeOutOfSleepIfNeededLocked(); 9086 } 9087 } 9088 9089 private void updateEventDispatchingLocked() { 9090 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9091 } 9092 9093 public void setLockScreenShown(boolean shown) { 9094 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9095 != PackageManager.PERMISSION_GRANTED) { 9096 throw new SecurityException("Requires permission " 9097 + android.Manifest.permission.DEVICE_POWER); 9098 } 9099 9100 synchronized(this) { 9101 long ident = Binder.clearCallingIdentity(); 9102 try { 9103 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9104 mLockScreenShown = shown; 9105 comeOutOfSleepIfNeededLocked(); 9106 } finally { 9107 Binder.restoreCallingIdentity(ident); 9108 } 9109 } 9110 } 9111 9112 public void stopAppSwitches() { 9113 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9114 != PackageManager.PERMISSION_GRANTED) { 9115 throw new SecurityException("Requires permission " 9116 + android.Manifest.permission.STOP_APP_SWITCHES); 9117 } 9118 9119 synchronized(this) { 9120 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9121 + APP_SWITCH_DELAY_TIME; 9122 mDidAppSwitch = false; 9123 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9124 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9125 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9126 } 9127 } 9128 9129 public void resumeAppSwitches() { 9130 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9131 != PackageManager.PERMISSION_GRANTED) { 9132 throw new SecurityException("Requires permission " 9133 + android.Manifest.permission.STOP_APP_SWITCHES); 9134 } 9135 9136 synchronized(this) { 9137 // Note that we don't execute any pending app switches... we will 9138 // let those wait until either the timeout, or the next start 9139 // activity request. 9140 mAppSwitchesAllowedTime = 0; 9141 } 9142 } 9143 9144 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9145 String name) { 9146 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9147 return true; 9148 } 9149 9150 final int perm = checkComponentPermission( 9151 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9152 callingUid, -1, true); 9153 if (perm == PackageManager.PERMISSION_GRANTED) { 9154 return true; 9155 } 9156 9157 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9158 return false; 9159 } 9160 9161 public void setDebugApp(String packageName, boolean waitForDebugger, 9162 boolean persistent) { 9163 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9164 "setDebugApp()"); 9165 9166 long ident = Binder.clearCallingIdentity(); 9167 try { 9168 // Note that this is not really thread safe if there are multiple 9169 // callers into it at the same time, but that's not a situation we 9170 // care about. 9171 if (persistent) { 9172 final ContentResolver resolver = mContext.getContentResolver(); 9173 Settings.Global.putString( 9174 resolver, Settings.Global.DEBUG_APP, 9175 packageName); 9176 Settings.Global.putInt( 9177 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9178 waitForDebugger ? 1 : 0); 9179 } 9180 9181 synchronized (this) { 9182 if (!persistent) { 9183 mOrigDebugApp = mDebugApp; 9184 mOrigWaitForDebugger = mWaitForDebugger; 9185 } 9186 mDebugApp = packageName; 9187 mWaitForDebugger = waitForDebugger; 9188 mDebugTransient = !persistent; 9189 if (packageName != null) { 9190 forceStopPackageLocked(packageName, -1, false, false, true, true, 9191 false, UserHandle.USER_ALL, "set debug app"); 9192 } 9193 } 9194 } finally { 9195 Binder.restoreCallingIdentity(ident); 9196 } 9197 } 9198 9199 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9200 synchronized (this) { 9201 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9202 if (!isDebuggable) { 9203 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9204 throw new SecurityException("Process not debuggable: " + app.packageName); 9205 } 9206 } 9207 9208 mOpenGlTraceApp = processName; 9209 } 9210 } 9211 9212 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9213 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9214 synchronized (this) { 9215 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9216 if (!isDebuggable) { 9217 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9218 throw new SecurityException("Process not debuggable: " + app.packageName); 9219 } 9220 } 9221 mProfileApp = processName; 9222 mProfileFile = profileFile; 9223 if (mProfileFd != null) { 9224 try { 9225 mProfileFd.close(); 9226 } catch (IOException e) { 9227 } 9228 mProfileFd = null; 9229 } 9230 mProfileFd = profileFd; 9231 mProfileType = 0; 9232 mAutoStopProfiler = autoStopProfiler; 9233 } 9234 } 9235 9236 @Override 9237 public void setAlwaysFinish(boolean enabled) { 9238 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9239 "setAlwaysFinish()"); 9240 9241 Settings.Global.putInt( 9242 mContext.getContentResolver(), 9243 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9244 9245 synchronized (this) { 9246 mAlwaysFinishActivities = enabled; 9247 } 9248 } 9249 9250 @Override 9251 public void setActivityController(IActivityController controller) { 9252 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9253 "setActivityController()"); 9254 synchronized (this) { 9255 mController = controller; 9256 Watchdog.getInstance().setActivityController(controller); 9257 } 9258 } 9259 9260 @Override 9261 public void setUserIsMonkey(boolean userIsMonkey) { 9262 synchronized (this) { 9263 synchronized (mPidsSelfLocked) { 9264 final int callingPid = Binder.getCallingPid(); 9265 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9266 if (precessRecord == null) { 9267 throw new SecurityException("Unknown process: " + callingPid); 9268 } 9269 if (precessRecord.instrumentationUiAutomationConnection == null) { 9270 throw new SecurityException("Only an instrumentation process " 9271 + "with a UiAutomation can call setUserIsMonkey"); 9272 } 9273 } 9274 mUserIsMonkey = userIsMonkey; 9275 } 9276 } 9277 9278 @Override 9279 public boolean isUserAMonkey() { 9280 synchronized (this) { 9281 // If there is a controller also implies the user is a monkey. 9282 return (mUserIsMonkey || mController != null); 9283 } 9284 } 9285 9286 public void requestBugReport() { 9287 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9288 SystemProperties.set("ctl.start", "bugreport"); 9289 } 9290 9291 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9292 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9293 } 9294 9295 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9296 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9297 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9298 } 9299 return KEY_DISPATCHING_TIMEOUT; 9300 } 9301 9302 @Override 9303 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9304 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9305 != PackageManager.PERMISSION_GRANTED) { 9306 throw new SecurityException("Requires permission " 9307 + android.Manifest.permission.FILTER_EVENTS); 9308 } 9309 ProcessRecord proc; 9310 long timeout; 9311 synchronized (this) { 9312 synchronized (mPidsSelfLocked) { 9313 proc = mPidsSelfLocked.get(pid); 9314 } 9315 timeout = getInputDispatchingTimeoutLocked(proc); 9316 } 9317 9318 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9319 return -1; 9320 } 9321 9322 return timeout; 9323 } 9324 9325 /** 9326 * Handle input dispatching timeouts. 9327 * Returns whether input dispatching should be aborted or not. 9328 */ 9329 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9330 final ActivityRecord activity, final ActivityRecord parent, 9331 final boolean aboveSystem, String reason) { 9332 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9333 != PackageManager.PERMISSION_GRANTED) { 9334 throw new SecurityException("Requires permission " 9335 + android.Manifest.permission.FILTER_EVENTS); 9336 } 9337 9338 final String annotation; 9339 if (reason == null) { 9340 annotation = "Input dispatching timed out"; 9341 } else { 9342 annotation = "Input dispatching timed out (" + reason + ")"; 9343 } 9344 9345 if (proc != null) { 9346 synchronized (this) { 9347 if (proc.debugging) { 9348 return false; 9349 } 9350 9351 if (mDidDexOpt) { 9352 // Give more time since we were dexopting. 9353 mDidDexOpt = false; 9354 return false; 9355 } 9356 9357 if (proc.instrumentationClass != null) { 9358 Bundle info = new Bundle(); 9359 info.putString("shortMsg", "keyDispatchingTimedOut"); 9360 info.putString("longMsg", annotation); 9361 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9362 return true; 9363 } 9364 } 9365 mHandler.post(new Runnable() { 9366 @Override 9367 public void run() { 9368 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9369 } 9370 }); 9371 } 9372 9373 return true; 9374 } 9375 9376 public Bundle getAssistContextExtras(int requestType) { 9377 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9378 "getAssistContextExtras()"); 9379 PendingAssistExtras pae; 9380 Bundle extras = new Bundle(); 9381 synchronized (this) { 9382 ActivityRecord activity = getFocusedStack().mResumedActivity; 9383 if (activity == null) { 9384 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9385 return null; 9386 } 9387 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9388 if (activity.app == null || activity.app.thread == null) { 9389 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9390 return extras; 9391 } 9392 if (activity.app.pid == Binder.getCallingPid()) { 9393 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9394 return extras; 9395 } 9396 pae = new PendingAssistExtras(activity); 9397 try { 9398 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9399 requestType); 9400 mPendingAssistExtras.add(pae); 9401 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9402 } catch (RemoteException e) { 9403 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9404 return extras; 9405 } 9406 } 9407 synchronized (pae) { 9408 while (!pae.haveResult) { 9409 try { 9410 pae.wait(); 9411 } catch (InterruptedException e) { 9412 } 9413 } 9414 if (pae.result != null) { 9415 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9416 } 9417 } 9418 synchronized (this) { 9419 mPendingAssistExtras.remove(pae); 9420 mHandler.removeCallbacks(pae); 9421 } 9422 return extras; 9423 } 9424 9425 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9426 PendingAssistExtras pae = (PendingAssistExtras)token; 9427 synchronized (pae) { 9428 pae.result = extras; 9429 pae.haveResult = true; 9430 pae.notifyAll(); 9431 } 9432 } 9433 9434 public void registerProcessObserver(IProcessObserver observer) { 9435 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9436 "registerProcessObserver()"); 9437 synchronized (this) { 9438 mProcessObservers.register(observer); 9439 } 9440 } 9441 9442 @Override 9443 public void unregisterProcessObserver(IProcessObserver observer) { 9444 synchronized (this) { 9445 mProcessObservers.unregister(observer); 9446 } 9447 } 9448 9449 @Override 9450 public boolean convertFromTranslucent(IBinder token) { 9451 final long origId = Binder.clearCallingIdentity(); 9452 try { 9453 synchronized (this) { 9454 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9455 if (r == null) { 9456 return false; 9457 } 9458 if (r.changeWindowTranslucency(true)) { 9459 mWindowManager.setAppFullscreen(token, true); 9460 r.task.stack.releaseMediaResources(); 9461 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9462 return true; 9463 } 9464 return false; 9465 } 9466 } finally { 9467 Binder.restoreCallingIdentity(origId); 9468 } 9469 } 9470 9471 @Override 9472 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9473 final long origId = Binder.clearCallingIdentity(); 9474 try { 9475 synchronized (this) { 9476 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9477 if (r == null) { 9478 return false; 9479 } 9480 if (r.changeWindowTranslucency(false)) { 9481 r.task.stack.convertToTranslucent(r, options); 9482 mWindowManager.setAppFullscreen(token, false); 9483 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9484 return true; 9485 } else { 9486 r.task.stack.mReturningActivityOptions = options; 9487 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9488 return false; 9489 } 9490 } 9491 } finally { 9492 Binder.restoreCallingIdentity(origId); 9493 } 9494 } 9495 9496 @Override 9497 public boolean setMediaPlaying(IBinder token, boolean playing) { 9498 final long origId = Binder.clearCallingIdentity(); 9499 try { 9500 synchronized (this) { 9501 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9502 if (r != null) { 9503 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9504 } 9505 } 9506 return false; 9507 } finally { 9508 Binder.restoreCallingIdentity(origId); 9509 } 9510 } 9511 9512 @Override 9513 public boolean isBackgroundMediaPlaying(IBinder token) { 9514 final long origId = Binder.clearCallingIdentity(); 9515 try { 9516 synchronized (this) { 9517 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9518 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9519 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9520 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9521 return playing; 9522 } 9523 } finally { 9524 Binder.restoreCallingIdentity(origId); 9525 } 9526 } 9527 9528 @Override 9529 public ActivityOptions getActivityOptions(IBinder token) { 9530 final long origId = Binder.clearCallingIdentity(); 9531 try { 9532 synchronized (this) { 9533 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9534 if (r != null) { 9535 final ActivityOptions activityOptions = r.pendingOptions; 9536 r.pendingOptions = null; 9537 return activityOptions; 9538 } 9539 return null; 9540 } 9541 } finally { 9542 Binder.restoreCallingIdentity(origId); 9543 } 9544 } 9545 9546 @Override 9547 public void setImmersive(IBinder token, boolean immersive) { 9548 synchronized(this) { 9549 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9550 if (r == null) { 9551 throw new IllegalArgumentException(); 9552 } 9553 r.immersive = immersive; 9554 9555 // update associated state if we're frontmost 9556 if (r == mFocusedActivity) { 9557 if (DEBUG_IMMERSIVE) { 9558 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9559 } 9560 applyUpdateLockStateLocked(r); 9561 } 9562 } 9563 } 9564 9565 @Override 9566 public boolean isImmersive(IBinder token) { 9567 synchronized (this) { 9568 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9569 if (r == null) { 9570 throw new IllegalArgumentException(); 9571 } 9572 return r.immersive; 9573 } 9574 } 9575 9576 public boolean isTopActivityImmersive() { 9577 enforceNotIsolatedCaller("startActivity"); 9578 synchronized (this) { 9579 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9580 return (r != null) ? r.immersive : false; 9581 } 9582 } 9583 9584 @Override 9585 public boolean isTopOfTask(IBinder token) { 9586 synchronized (this) { 9587 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9588 if (r == null) { 9589 throw new IllegalArgumentException(); 9590 } 9591 return r.task.getTopActivity() == r; 9592 } 9593 } 9594 9595 public final void enterSafeMode() { 9596 synchronized(this) { 9597 // It only makes sense to do this before the system is ready 9598 // and started launching other packages. 9599 if (!mSystemReady) { 9600 try { 9601 AppGlobals.getPackageManager().enterSafeMode(); 9602 } catch (RemoteException e) { 9603 } 9604 } 9605 9606 mSafeMode = true; 9607 } 9608 } 9609 9610 public final void showSafeModeOverlay() { 9611 View v = LayoutInflater.from(mContext).inflate( 9612 com.android.internal.R.layout.safe_mode, null); 9613 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9614 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9615 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9616 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9617 lp.gravity = Gravity.BOTTOM | Gravity.START; 9618 lp.format = v.getBackground().getOpacity(); 9619 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9620 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9621 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9622 ((WindowManager)mContext.getSystemService( 9623 Context.WINDOW_SERVICE)).addView(v, lp); 9624 } 9625 9626 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9627 if (!(sender instanceof PendingIntentRecord)) { 9628 return; 9629 } 9630 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9631 synchronized (stats) { 9632 if (mBatteryStatsService.isOnBattery()) { 9633 mBatteryStatsService.enforceCallingPermission(); 9634 PendingIntentRecord rec = (PendingIntentRecord)sender; 9635 int MY_UID = Binder.getCallingUid(); 9636 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9637 BatteryStatsImpl.Uid.Pkg pkg = 9638 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9639 sourcePkg != null ? sourcePkg : rec.key.packageName); 9640 pkg.incWakeupsLocked(); 9641 } 9642 } 9643 } 9644 9645 public boolean killPids(int[] pids, String pReason, boolean secure) { 9646 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9647 throw new SecurityException("killPids only available to the system"); 9648 } 9649 String reason = (pReason == null) ? "Unknown" : pReason; 9650 // XXX Note: don't acquire main activity lock here, because the window 9651 // manager calls in with its locks held. 9652 9653 boolean killed = false; 9654 synchronized (mPidsSelfLocked) { 9655 int[] types = new int[pids.length]; 9656 int worstType = 0; 9657 for (int i=0; i<pids.length; i++) { 9658 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9659 if (proc != null) { 9660 int type = proc.setAdj; 9661 types[i] = type; 9662 if (type > worstType) { 9663 worstType = type; 9664 } 9665 } 9666 } 9667 9668 // If the worst oom_adj is somewhere in the cached proc LRU range, 9669 // then constrain it so we will kill all cached procs. 9670 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9671 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9672 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9673 } 9674 9675 // If this is not a secure call, don't let it kill processes that 9676 // are important. 9677 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9678 worstType = ProcessList.SERVICE_ADJ; 9679 } 9680 9681 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9682 for (int i=0; i<pids.length; i++) { 9683 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9684 if (proc == null) { 9685 continue; 9686 } 9687 int adj = proc.setAdj; 9688 if (adj >= worstType && !proc.killedByAm) { 9689 killUnneededProcessLocked(proc, reason); 9690 killed = true; 9691 } 9692 } 9693 } 9694 return killed; 9695 } 9696 9697 @Override 9698 public void killUid(int uid, String reason) { 9699 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9700 throw new SecurityException("killUid only available to the system"); 9701 } 9702 synchronized (this) { 9703 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9704 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9705 reason != null ? reason : "kill uid"); 9706 } 9707 } 9708 9709 @Override 9710 public boolean killProcessesBelowForeground(String reason) { 9711 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9712 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9713 } 9714 9715 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9716 } 9717 9718 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9719 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9720 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9721 } 9722 9723 boolean killed = false; 9724 synchronized (mPidsSelfLocked) { 9725 final int size = mPidsSelfLocked.size(); 9726 for (int i = 0; i < size; i++) { 9727 final int pid = mPidsSelfLocked.keyAt(i); 9728 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9729 if (proc == null) continue; 9730 9731 final int adj = proc.setAdj; 9732 if (adj > belowAdj && !proc.killedByAm) { 9733 killUnneededProcessLocked(proc, reason); 9734 killed = true; 9735 } 9736 } 9737 } 9738 return killed; 9739 } 9740 9741 @Override 9742 public void hang(final IBinder who, boolean allowRestart) { 9743 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9744 != PackageManager.PERMISSION_GRANTED) { 9745 throw new SecurityException("Requires permission " 9746 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9747 } 9748 9749 final IBinder.DeathRecipient death = new DeathRecipient() { 9750 @Override 9751 public void binderDied() { 9752 synchronized (this) { 9753 notifyAll(); 9754 } 9755 } 9756 }; 9757 9758 try { 9759 who.linkToDeath(death, 0); 9760 } catch (RemoteException e) { 9761 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9762 return; 9763 } 9764 9765 synchronized (this) { 9766 Watchdog.getInstance().setAllowRestart(allowRestart); 9767 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9768 synchronized (death) { 9769 while (who.isBinderAlive()) { 9770 try { 9771 death.wait(); 9772 } catch (InterruptedException e) { 9773 } 9774 } 9775 } 9776 Watchdog.getInstance().setAllowRestart(true); 9777 } 9778 } 9779 9780 @Override 9781 public void restart() { 9782 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9783 != PackageManager.PERMISSION_GRANTED) { 9784 throw new SecurityException("Requires permission " 9785 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9786 } 9787 9788 Log.i(TAG, "Sending shutdown broadcast..."); 9789 9790 BroadcastReceiver br = new BroadcastReceiver() { 9791 @Override public void onReceive(Context context, Intent intent) { 9792 // Now the broadcast is done, finish up the low-level shutdown. 9793 Log.i(TAG, "Shutting down activity manager..."); 9794 shutdown(10000); 9795 Log.i(TAG, "Shutdown complete, restarting!"); 9796 Process.killProcess(Process.myPid()); 9797 System.exit(10); 9798 } 9799 }; 9800 9801 // First send the high-level shut down broadcast. 9802 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9803 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9804 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9805 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9806 mContext.sendOrderedBroadcastAsUser(intent, 9807 UserHandle.ALL, null, br, mHandler, 0, null, null); 9808 */ 9809 br.onReceive(mContext, intent); 9810 } 9811 9812 private long getLowRamTimeSinceIdle(long now) { 9813 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9814 } 9815 9816 @Override 9817 public void performIdleMaintenance() { 9818 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9819 != PackageManager.PERMISSION_GRANTED) { 9820 throw new SecurityException("Requires permission " 9821 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9822 } 9823 9824 synchronized (this) { 9825 final long now = SystemClock.uptimeMillis(); 9826 final long timeSinceLastIdle = now - mLastIdleTime; 9827 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9828 mLastIdleTime = now; 9829 mLowRamTimeSinceLastIdle = 0; 9830 if (mLowRamStartTime != 0) { 9831 mLowRamStartTime = now; 9832 } 9833 9834 StringBuilder sb = new StringBuilder(128); 9835 sb.append("Idle maintenance over "); 9836 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9837 sb.append(" low RAM for "); 9838 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9839 Slog.i(TAG, sb.toString()); 9840 9841 // If at least 1/3 of our time since the last idle period has been spent 9842 // with RAM low, then we want to kill processes. 9843 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9844 9845 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9846 ProcessRecord proc = mLruProcesses.get(i); 9847 if (proc.notCachedSinceIdle) { 9848 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9849 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9850 if (doKilling && proc.initialIdlePss != 0 9851 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9852 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9853 + " from " + proc.initialIdlePss + ")"); 9854 } 9855 } 9856 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9857 proc.notCachedSinceIdle = true; 9858 proc.initialIdlePss = 0; 9859 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9860 isSleeping(), now); 9861 } 9862 } 9863 9864 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9865 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9866 } 9867 } 9868 9869 private void retrieveSettings() { 9870 final ContentResolver resolver = mContext.getContentResolver(); 9871 String debugApp = Settings.Global.getString( 9872 resolver, Settings.Global.DEBUG_APP); 9873 boolean waitForDebugger = Settings.Global.getInt( 9874 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9875 boolean alwaysFinishActivities = Settings.Global.getInt( 9876 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9877 boolean forceRtl = Settings.Global.getInt( 9878 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9879 // Transfer any global setting for forcing RTL layout, into a System Property 9880 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9881 9882 Configuration configuration = new Configuration(); 9883 Settings.System.getConfiguration(resolver, configuration); 9884 if (forceRtl) { 9885 // This will take care of setting the correct layout direction flags 9886 configuration.setLayoutDirection(configuration.locale); 9887 } 9888 9889 synchronized (this) { 9890 mDebugApp = mOrigDebugApp = debugApp; 9891 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9892 mAlwaysFinishActivities = alwaysFinishActivities; 9893 // This happens before any activities are started, so we can 9894 // change mConfiguration in-place. 9895 updateConfigurationLocked(configuration, null, false, true); 9896 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9897 } 9898 } 9899 9900 public boolean testIsSystemReady() { 9901 // no need to synchronize(this) just to read & return the value 9902 return mSystemReady; 9903 } 9904 9905 private static File getCalledPreBootReceiversFile() { 9906 File dataDir = Environment.getDataDirectory(); 9907 File systemDir = new File(dataDir, "system"); 9908 File fname = new File(systemDir, "called_pre_boots.dat"); 9909 return fname; 9910 } 9911 9912 static final int LAST_DONE_VERSION = 10000; 9913 9914 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9915 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9916 File file = getCalledPreBootReceiversFile(); 9917 FileInputStream fis = null; 9918 try { 9919 fis = new FileInputStream(file); 9920 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9921 int fvers = dis.readInt(); 9922 if (fvers == LAST_DONE_VERSION) { 9923 String vers = dis.readUTF(); 9924 String codename = dis.readUTF(); 9925 String build = dis.readUTF(); 9926 if (android.os.Build.VERSION.RELEASE.equals(vers) 9927 && android.os.Build.VERSION.CODENAME.equals(codename) 9928 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9929 int num = dis.readInt(); 9930 while (num > 0) { 9931 num--; 9932 String pkg = dis.readUTF(); 9933 String cls = dis.readUTF(); 9934 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9935 } 9936 } 9937 } 9938 } catch (FileNotFoundException e) { 9939 } catch (IOException e) { 9940 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9941 } finally { 9942 if (fis != null) { 9943 try { 9944 fis.close(); 9945 } catch (IOException e) { 9946 } 9947 } 9948 } 9949 return lastDoneReceivers; 9950 } 9951 9952 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9953 File file = getCalledPreBootReceiversFile(); 9954 FileOutputStream fos = null; 9955 DataOutputStream dos = null; 9956 try { 9957 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9958 fos = new FileOutputStream(file); 9959 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9960 dos.writeInt(LAST_DONE_VERSION); 9961 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9962 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9963 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9964 dos.writeInt(list.size()); 9965 for (int i=0; i<list.size(); i++) { 9966 dos.writeUTF(list.get(i).getPackageName()); 9967 dos.writeUTF(list.get(i).getClassName()); 9968 } 9969 } catch (IOException e) { 9970 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9971 file.delete(); 9972 } finally { 9973 FileUtils.sync(fos); 9974 if (dos != null) { 9975 try { 9976 dos.close(); 9977 } catch (IOException e) { 9978 // TODO Auto-generated catch block 9979 e.printStackTrace(); 9980 } 9981 } 9982 } 9983 } 9984 9985 public void systemReady(final Runnable goingCallback) { 9986 synchronized(this) { 9987 if (mSystemReady) { 9988 if (goingCallback != null) goingCallback.run(); 9989 return; 9990 } 9991 9992 // Make sure we have the current profile info, since it is needed for 9993 // security checks. 9994 updateCurrentProfileIdsLocked(); 9995 9996 if (mRecentTasks == null) { 9997 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9998 if (!mRecentTasks.isEmpty()) { 9999 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10000 } 10001 mTaskPersister.startPersisting(); 10002 } 10003 10004 // Check to see if there are any update receivers to run. 10005 if (!mDidUpdate) { 10006 if (mWaitingUpdate) { 10007 return; 10008 } 10009 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10010 List<ResolveInfo> ris = null; 10011 try { 10012 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10013 intent, null, 0, 0); 10014 } catch (RemoteException e) { 10015 } 10016 if (ris != null) { 10017 for (int i=ris.size()-1; i>=0; i--) { 10018 if ((ris.get(i).activityInfo.applicationInfo.flags 10019 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10020 ris.remove(i); 10021 } 10022 } 10023 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10024 10025 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10026 10027 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10028 for (int i=0; i<ris.size(); i++) { 10029 ActivityInfo ai = ris.get(i).activityInfo; 10030 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10031 if (lastDoneReceivers.contains(comp)) { 10032 // We already did the pre boot receiver for this app with the current 10033 // platform version, so don't do it again... 10034 ris.remove(i); 10035 i--; 10036 // ...however, do keep it as one that has been done, so we don't 10037 // forget about it when rewriting the file of last done receivers. 10038 doneReceivers.add(comp); 10039 } 10040 } 10041 10042 final int[] users = getUsersLocked(); 10043 for (int i=0; i<ris.size(); i++) { 10044 ActivityInfo ai = ris.get(i).activityInfo; 10045 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10046 doneReceivers.add(comp); 10047 intent.setComponent(comp); 10048 for (int j=0; j<users.length; j++) { 10049 IIntentReceiver finisher = null; 10050 if (i == ris.size()-1 && j == users.length-1) { 10051 finisher = new IIntentReceiver.Stub() { 10052 public void performReceive(Intent intent, int resultCode, 10053 String data, Bundle extras, boolean ordered, 10054 boolean sticky, int sendingUser) { 10055 // The raw IIntentReceiver interface is called 10056 // with the AM lock held, so redispatch to 10057 // execute our code without the lock. 10058 mHandler.post(new Runnable() { 10059 public void run() { 10060 synchronized (ActivityManagerService.this) { 10061 mDidUpdate = true; 10062 } 10063 writeLastDonePreBootReceivers(doneReceivers); 10064 showBootMessage(mContext.getText( 10065 R.string.android_upgrading_complete), 10066 false); 10067 systemReady(goingCallback); 10068 } 10069 }); 10070 } 10071 }; 10072 } 10073 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10074 + " for user " + users[j]); 10075 broadcastIntentLocked(null, null, intent, null, finisher, 10076 0, null, null, null, AppOpsManager.OP_NONE, 10077 true, false, MY_PID, Process.SYSTEM_UID, 10078 users[j]); 10079 if (finisher != null) { 10080 mWaitingUpdate = true; 10081 } 10082 } 10083 } 10084 } 10085 if (mWaitingUpdate) { 10086 return; 10087 } 10088 mDidUpdate = true; 10089 } 10090 10091 mAppOpsService.systemReady(); 10092 mUsageStatsService.systemReady(); 10093 mSystemReady = true; 10094 } 10095 10096 ArrayList<ProcessRecord> procsToKill = null; 10097 synchronized(mPidsSelfLocked) { 10098 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10099 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10100 if (!isAllowedWhileBooting(proc.info)){ 10101 if (procsToKill == null) { 10102 procsToKill = new ArrayList<ProcessRecord>(); 10103 } 10104 procsToKill.add(proc); 10105 } 10106 } 10107 } 10108 10109 synchronized(this) { 10110 if (procsToKill != null) { 10111 for (int i=procsToKill.size()-1; i>=0; i--) { 10112 ProcessRecord proc = procsToKill.get(i); 10113 Slog.i(TAG, "Removing system update proc: " + proc); 10114 removeProcessLocked(proc, true, false, "system update done"); 10115 } 10116 } 10117 10118 // Now that we have cleaned up any update processes, we 10119 // are ready to start launching real processes and know that 10120 // we won't trample on them any more. 10121 mProcessesReady = true; 10122 } 10123 10124 Slog.i(TAG, "System now ready"); 10125 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10126 SystemClock.uptimeMillis()); 10127 10128 synchronized(this) { 10129 // Make sure we have no pre-ready processes sitting around. 10130 10131 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10132 ResolveInfo ri = mContext.getPackageManager() 10133 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10134 STOCK_PM_FLAGS); 10135 CharSequence errorMsg = null; 10136 if (ri != null) { 10137 ActivityInfo ai = ri.activityInfo; 10138 ApplicationInfo app = ai.applicationInfo; 10139 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10140 mTopAction = Intent.ACTION_FACTORY_TEST; 10141 mTopData = null; 10142 mTopComponent = new ComponentName(app.packageName, 10143 ai.name); 10144 } else { 10145 errorMsg = mContext.getResources().getText( 10146 com.android.internal.R.string.factorytest_not_system); 10147 } 10148 } else { 10149 errorMsg = mContext.getResources().getText( 10150 com.android.internal.R.string.factorytest_no_action); 10151 } 10152 if (errorMsg != null) { 10153 mTopAction = null; 10154 mTopData = null; 10155 mTopComponent = null; 10156 Message msg = Message.obtain(); 10157 msg.what = SHOW_FACTORY_ERROR_MSG; 10158 msg.getData().putCharSequence("msg", errorMsg); 10159 mHandler.sendMessage(msg); 10160 } 10161 } 10162 } 10163 10164 retrieveSettings(); 10165 10166 synchronized (this) { 10167 readGrantedUriPermissionsLocked(); 10168 } 10169 10170 if (goingCallback != null) goingCallback.run(); 10171 10172 mSystemServiceManager.startUser(mCurrentUserId); 10173 10174 synchronized (this) { 10175 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10176 try { 10177 List apps = AppGlobals.getPackageManager(). 10178 getPersistentApplications(STOCK_PM_FLAGS); 10179 if (apps != null) { 10180 int N = apps.size(); 10181 int i; 10182 for (i=0; i<N; i++) { 10183 ApplicationInfo info 10184 = (ApplicationInfo)apps.get(i); 10185 if (info != null && 10186 !info.packageName.equals("android")) { 10187 addAppLocked(info, false, null /* ABI override */); 10188 } 10189 } 10190 } 10191 } catch (RemoteException ex) { 10192 // pm is in same process, this will never happen. 10193 } 10194 } 10195 10196 // Start up initial activity. 10197 mBooting = true; 10198 10199 try { 10200 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10201 Message msg = Message.obtain(); 10202 msg.what = SHOW_UID_ERROR_MSG; 10203 mHandler.sendMessage(msg); 10204 } 10205 } catch (RemoteException e) { 10206 } 10207 10208 long ident = Binder.clearCallingIdentity(); 10209 try { 10210 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10212 | Intent.FLAG_RECEIVER_FOREGROUND); 10213 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10214 broadcastIntentLocked(null, null, intent, 10215 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10216 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10217 intent = new Intent(Intent.ACTION_USER_STARTING); 10218 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10219 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10220 broadcastIntentLocked(null, null, intent, 10221 null, new IIntentReceiver.Stub() { 10222 @Override 10223 public void performReceive(Intent intent, int resultCode, String data, 10224 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10225 throws RemoteException { 10226 } 10227 }, 0, null, null, 10228 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10229 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10230 } catch (Throwable t) { 10231 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10232 } finally { 10233 Binder.restoreCallingIdentity(ident); 10234 } 10235 mStackSupervisor.resumeTopActivitiesLocked(); 10236 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10237 } 10238 } 10239 10240 private boolean makeAppCrashingLocked(ProcessRecord app, 10241 String shortMsg, String longMsg, String stackTrace) { 10242 app.crashing = true; 10243 app.crashingReport = generateProcessError(app, 10244 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10245 startAppProblemLocked(app); 10246 app.stopFreezingAllLocked(); 10247 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10248 } 10249 10250 private void makeAppNotRespondingLocked(ProcessRecord app, 10251 String activity, String shortMsg, String longMsg) { 10252 app.notResponding = true; 10253 app.notRespondingReport = generateProcessError(app, 10254 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10255 activity, shortMsg, longMsg, null); 10256 startAppProblemLocked(app); 10257 app.stopFreezingAllLocked(); 10258 } 10259 10260 /** 10261 * Generate a process error record, suitable for attachment to a ProcessRecord. 10262 * 10263 * @param app The ProcessRecord in which the error occurred. 10264 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10265 * ActivityManager.AppErrorStateInfo 10266 * @param activity The activity associated with the crash, if known. 10267 * @param shortMsg Short message describing the crash. 10268 * @param longMsg Long message describing the crash. 10269 * @param stackTrace Full crash stack trace, may be null. 10270 * 10271 * @return Returns a fully-formed AppErrorStateInfo record. 10272 */ 10273 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10274 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10275 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10276 10277 report.condition = condition; 10278 report.processName = app.processName; 10279 report.pid = app.pid; 10280 report.uid = app.info.uid; 10281 report.tag = activity; 10282 report.shortMsg = shortMsg; 10283 report.longMsg = longMsg; 10284 report.stackTrace = stackTrace; 10285 10286 return report; 10287 } 10288 10289 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10290 synchronized (this) { 10291 app.crashing = false; 10292 app.crashingReport = null; 10293 app.notResponding = false; 10294 app.notRespondingReport = null; 10295 if (app.anrDialog == fromDialog) { 10296 app.anrDialog = null; 10297 } 10298 if (app.waitDialog == fromDialog) { 10299 app.waitDialog = null; 10300 } 10301 if (app.pid > 0 && app.pid != MY_PID) { 10302 handleAppCrashLocked(app, null, null, null); 10303 killUnneededProcessLocked(app, "user request after error"); 10304 } 10305 } 10306 } 10307 10308 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10309 String stackTrace) { 10310 long now = SystemClock.uptimeMillis(); 10311 10312 Long crashTime; 10313 if (!app.isolated) { 10314 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10315 } else { 10316 crashTime = null; 10317 } 10318 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10319 // This process loses! 10320 Slog.w(TAG, "Process " + app.info.processName 10321 + " has crashed too many times: killing!"); 10322 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10323 app.userId, app.info.processName, app.uid); 10324 mStackSupervisor.handleAppCrashLocked(app); 10325 if (!app.persistent) { 10326 // We don't want to start this process again until the user 10327 // explicitly does so... but for persistent process, we really 10328 // need to keep it running. If a persistent process is actually 10329 // repeatedly crashing, then badness for everyone. 10330 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10331 app.info.processName); 10332 if (!app.isolated) { 10333 // XXX We don't have a way to mark isolated processes 10334 // as bad, since they don't have a peristent identity. 10335 mBadProcesses.put(app.info.processName, app.uid, 10336 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10337 mProcessCrashTimes.remove(app.info.processName, app.uid); 10338 } 10339 app.bad = true; 10340 app.removed = true; 10341 // Don't let services in this process be restarted and potentially 10342 // annoy the user repeatedly. Unless it is persistent, since those 10343 // processes run critical code. 10344 removeProcessLocked(app, false, false, "crash"); 10345 mStackSupervisor.resumeTopActivitiesLocked(); 10346 return false; 10347 } 10348 mStackSupervisor.resumeTopActivitiesLocked(); 10349 } else { 10350 mStackSupervisor.finishTopRunningActivityLocked(app); 10351 } 10352 10353 // Bump up the crash count of any services currently running in the proc. 10354 for (int i=app.services.size()-1; i>=0; i--) { 10355 // Any services running in the application need to be placed 10356 // back in the pending list. 10357 ServiceRecord sr = app.services.valueAt(i); 10358 sr.crashCount++; 10359 } 10360 10361 // If the crashing process is what we consider to be the "home process" and it has been 10362 // replaced by a third-party app, clear the package preferred activities from packages 10363 // with a home activity running in the process to prevent a repeatedly crashing app 10364 // from blocking the user to manually clear the list. 10365 final ArrayList<ActivityRecord> activities = app.activities; 10366 if (app == mHomeProcess && activities.size() > 0 10367 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10368 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10369 final ActivityRecord r = activities.get(activityNdx); 10370 if (r.isHomeActivity()) { 10371 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10372 try { 10373 ActivityThread.getPackageManager() 10374 .clearPackagePreferredActivities(r.packageName); 10375 } catch (RemoteException c) { 10376 // pm is in same process, this will never happen. 10377 } 10378 } 10379 } 10380 } 10381 10382 if (!app.isolated) { 10383 // XXX Can't keep track of crash times for isolated processes, 10384 // because they don't have a perisistent identity. 10385 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10386 } 10387 10388 return true; 10389 } 10390 10391 void startAppProblemLocked(ProcessRecord app) { 10392 if (app.userId == mCurrentUserId) { 10393 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10394 mContext, app.info.packageName, app.info.flags); 10395 } else { 10396 // If this app is not running under the current user, then we 10397 // can't give it a report button because that would require 10398 // launching the report UI under a different user. 10399 app.errorReportReceiver = null; 10400 } 10401 skipCurrentReceiverLocked(app); 10402 } 10403 10404 void skipCurrentReceiverLocked(ProcessRecord app) { 10405 for (BroadcastQueue queue : mBroadcastQueues) { 10406 queue.skipCurrentReceiverLocked(app); 10407 } 10408 } 10409 10410 /** 10411 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10412 * The application process will exit immediately after this call returns. 10413 * @param app object of the crashing app, null for the system server 10414 * @param crashInfo describing the exception 10415 */ 10416 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10417 ProcessRecord r = findAppProcess(app, "Crash"); 10418 final String processName = app == null ? "system_server" 10419 : (r == null ? "unknown" : r.processName); 10420 10421 handleApplicationCrashInner("crash", r, processName, crashInfo); 10422 } 10423 10424 /* Native crash reporting uses this inner version because it needs to be somewhat 10425 * decoupled from the AM-managed cleanup lifecycle 10426 */ 10427 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10428 ApplicationErrorReport.CrashInfo crashInfo) { 10429 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10430 UserHandle.getUserId(Binder.getCallingUid()), processName, 10431 r == null ? -1 : r.info.flags, 10432 crashInfo.exceptionClassName, 10433 crashInfo.exceptionMessage, 10434 crashInfo.throwFileName, 10435 crashInfo.throwLineNumber); 10436 10437 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10438 10439 crashApplication(r, crashInfo); 10440 } 10441 10442 public void handleApplicationStrictModeViolation( 10443 IBinder app, 10444 int violationMask, 10445 StrictMode.ViolationInfo info) { 10446 ProcessRecord r = findAppProcess(app, "StrictMode"); 10447 if (r == null) { 10448 return; 10449 } 10450 10451 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10452 Integer stackFingerprint = info.hashCode(); 10453 boolean logIt = true; 10454 synchronized (mAlreadyLoggedViolatedStacks) { 10455 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10456 logIt = false; 10457 // TODO: sub-sample into EventLog for these, with 10458 // the info.durationMillis? Then we'd get 10459 // the relative pain numbers, without logging all 10460 // the stack traces repeatedly. We'd want to do 10461 // likewise in the client code, which also does 10462 // dup suppression, before the Binder call. 10463 } else { 10464 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10465 mAlreadyLoggedViolatedStacks.clear(); 10466 } 10467 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10468 } 10469 } 10470 if (logIt) { 10471 logStrictModeViolationToDropBox(r, info); 10472 } 10473 } 10474 10475 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10476 AppErrorResult result = new AppErrorResult(); 10477 synchronized (this) { 10478 final long origId = Binder.clearCallingIdentity(); 10479 10480 Message msg = Message.obtain(); 10481 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10482 HashMap<String, Object> data = new HashMap<String, Object>(); 10483 data.put("result", result); 10484 data.put("app", r); 10485 data.put("violationMask", violationMask); 10486 data.put("info", info); 10487 msg.obj = data; 10488 mHandler.sendMessage(msg); 10489 10490 Binder.restoreCallingIdentity(origId); 10491 } 10492 int res = result.get(); 10493 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10494 } 10495 } 10496 10497 // Depending on the policy in effect, there could be a bunch of 10498 // these in quick succession so we try to batch these together to 10499 // minimize disk writes, number of dropbox entries, and maximize 10500 // compression, by having more fewer, larger records. 10501 private void logStrictModeViolationToDropBox( 10502 ProcessRecord process, 10503 StrictMode.ViolationInfo info) { 10504 if (info == null) { 10505 return; 10506 } 10507 final boolean isSystemApp = process == null || 10508 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10509 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10510 final String processName = process == null ? "unknown" : process.processName; 10511 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10512 final DropBoxManager dbox = (DropBoxManager) 10513 mContext.getSystemService(Context.DROPBOX_SERVICE); 10514 10515 // Exit early if the dropbox isn't configured to accept this report type. 10516 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10517 10518 boolean bufferWasEmpty; 10519 boolean needsFlush; 10520 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10521 synchronized (sb) { 10522 bufferWasEmpty = sb.length() == 0; 10523 appendDropBoxProcessHeaders(process, processName, sb); 10524 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10525 sb.append("System-App: ").append(isSystemApp).append("\n"); 10526 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10527 if (info.violationNumThisLoop != 0) { 10528 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10529 } 10530 if (info.numAnimationsRunning != 0) { 10531 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10532 } 10533 if (info.broadcastIntentAction != null) { 10534 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10535 } 10536 if (info.durationMillis != -1) { 10537 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10538 } 10539 if (info.numInstances != -1) { 10540 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10541 } 10542 if (info.tags != null) { 10543 for (String tag : info.tags) { 10544 sb.append("Span-Tag: ").append(tag).append("\n"); 10545 } 10546 } 10547 sb.append("\n"); 10548 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10549 sb.append(info.crashInfo.stackTrace); 10550 } 10551 sb.append("\n"); 10552 10553 // Only buffer up to ~64k. Various logging bits truncate 10554 // things at 128k. 10555 needsFlush = (sb.length() > 64 * 1024); 10556 } 10557 10558 // Flush immediately if the buffer's grown too large, or this 10559 // is a non-system app. Non-system apps are isolated with a 10560 // different tag & policy and not batched. 10561 // 10562 // Batching is useful during internal testing with 10563 // StrictMode settings turned up high. Without batching, 10564 // thousands of separate files could be created on boot. 10565 if (!isSystemApp || needsFlush) { 10566 new Thread("Error dump: " + dropboxTag) { 10567 @Override 10568 public void run() { 10569 String report; 10570 synchronized (sb) { 10571 report = sb.toString(); 10572 sb.delete(0, sb.length()); 10573 sb.trimToSize(); 10574 } 10575 if (report.length() != 0) { 10576 dbox.addText(dropboxTag, report); 10577 } 10578 } 10579 }.start(); 10580 return; 10581 } 10582 10583 // System app batching: 10584 if (!bufferWasEmpty) { 10585 // An existing dropbox-writing thread is outstanding, so 10586 // we don't need to start it up. The existing thread will 10587 // catch the buffer appends we just did. 10588 return; 10589 } 10590 10591 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10592 // (After this point, we shouldn't access AMS internal data structures.) 10593 new Thread("Error dump: " + dropboxTag) { 10594 @Override 10595 public void run() { 10596 // 5 second sleep to let stacks arrive and be batched together 10597 try { 10598 Thread.sleep(5000); // 5 seconds 10599 } catch (InterruptedException e) {} 10600 10601 String errorReport; 10602 synchronized (mStrictModeBuffer) { 10603 errorReport = mStrictModeBuffer.toString(); 10604 if (errorReport.length() == 0) { 10605 return; 10606 } 10607 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10608 mStrictModeBuffer.trimToSize(); 10609 } 10610 dbox.addText(dropboxTag, errorReport); 10611 } 10612 }.start(); 10613 } 10614 10615 /** 10616 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10617 * @param app object of the crashing app, null for the system server 10618 * @param tag reported by the caller 10619 * @param crashInfo describing the context of the error 10620 * @return true if the process should exit immediately (WTF is fatal) 10621 */ 10622 public boolean handleApplicationWtf(IBinder app, String tag, 10623 ApplicationErrorReport.CrashInfo crashInfo) { 10624 ProcessRecord r = findAppProcess(app, "WTF"); 10625 final String processName = app == null ? "system_server" 10626 : (r == null ? "unknown" : r.processName); 10627 10628 EventLog.writeEvent(EventLogTags.AM_WTF, 10629 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10630 processName, 10631 r == null ? -1 : r.info.flags, 10632 tag, crashInfo.exceptionMessage); 10633 10634 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10635 10636 if (r != null && r.pid != Process.myPid() && 10637 Settings.Global.getInt(mContext.getContentResolver(), 10638 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10639 crashApplication(r, crashInfo); 10640 return true; 10641 } else { 10642 return false; 10643 } 10644 } 10645 10646 /** 10647 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10648 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10649 */ 10650 private ProcessRecord findAppProcess(IBinder app, String reason) { 10651 if (app == null) { 10652 return null; 10653 } 10654 10655 synchronized (this) { 10656 final int NP = mProcessNames.getMap().size(); 10657 for (int ip=0; ip<NP; ip++) { 10658 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10659 final int NA = apps.size(); 10660 for (int ia=0; ia<NA; ia++) { 10661 ProcessRecord p = apps.valueAt(ia); 10662 if (p.thread != null && p.thread.asBinder() == app) { 10663 return p; 10664 } 10665 } 10666 } 10667 10668 Slog.w(TAG, "Can't find mystery application for " + reason 10669 + " from pid=" + Binder.getCallingPid() 10670 + " uid=" + Binder.getCallingUid() + ": " + app); 10671 return null; 10672 } 10673 } 10674 10675 /** 10676 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10677 * to append various headers to the dropbox log text. 10678 */ 10679 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10680 StringBuilder sb) { 10681 // Watchdog thread ends up invoking this function (with 10682 // a null ProcessRecord) to add the stack file to dropbox. 10683 // Do not acquire a lock on this (am) in such cases, as it 10684 // could cause a potential deadlock, if and when watchdog 10685 // is invoked due to unavailability of lock on am and it 10686 // would prevent watchdog from killing system_server. 10687 if (process == null) { 10688 sb.append("Process: ").append(processName).append("\n"); 10689 return; 10690 } 10691 // Note: ProcessRecord 'process' is guarded by the service 10692 // instance. (notably process.pkgList, which could otherwise change 10693 // concurrently during execution of this method) 10694 synchronized (this) { 10695 sb.append("Process: ").append(processName).append("\n"); 10696 int flags = process.info.flags; 10697 IPackageManager pm = AppGlobals.getPackageManager(); 10698 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10699 for (int ip=0; ip<process.pkgList.size(); ip++) { 10700 String pkg = process.pkgList.keyAt(ip); 10701 sb.append("Package: ").append(pkg); 10702 try { 10703 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10704 if (pi != null) { 10705 sb.append(" v").append(pi.versionCode); 10706 if (pi.versionName != null) { 10707 sb.append(" (").append(pi.versionName).append(")"); 10708 } 10709 } 10710 } catch (RemoteException e) { 10711 Slog.e(TAG, "Error getting package info: " + pkg, e); 10712 } 10713 sb.append("\n"); 10714 } 10715 } 10716 } 10717 10718 private static String processClass(ProcessRecord process) { 10719 if (process == null || process.pid == MY_PID) { 10720 return "system_server"; 10721 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10722 return "system_app"; 10723 } else { 10724 return "data_app"; 10725 } 10726 } 10727 10728 /** 10729 * Write a description of an error (crash, WTF, ANR) to the drop box. 10730 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10731 * @param process which caused the error, null means the system server 10732 * @param activity which triggered the error, null if unknown 10733 * @param parent activity related to the error, null if unknown 10734 * @param subject line related to the error, null if absent 10735 * @param report in long form describing the error, null if absent 10736 * @param logFile to include in the report, null if none 10737 * @param crashInfo giving an application stack trace, null if absent 10738 */ 10739 public void addErrorToDropBox(String eventType, 10740 ProcessRecord process, String processName, ActivityRecord activity, 10741 ActivityRecord parent, String subject, 10742 final String report, final File logFile, 10743 final ApplicationErrorReport.CrashInfo crashInfo) { 10744 // NOTE -- this must never acquire the ActivityManagerService lock, 10745 // otherwise the watchdog may be prevented from resetting the system. 10746 10747 final String dropboxTag = processClass(process) + "_" + eventType; 10748 final DropBoxManager dbox = (DropBoxManager) 10749 mContext.getSystemService(Context.DROPBOX_SERVICE); 10750 10751 // Exit early if the dropbox isn't configured to accept this report type. 10752 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10753 10754 final StringBuilder sb = new StringBuilder(1024); 10755 appendDropBoxProcessHeaders(process, processName, sb); 10756 if (activity != null) { 10757 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10758 } 10759 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10760 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10761 } 10762 if (parent != null && parent != activity) { 10763 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10764 } 10765 if (subject != null) { 10766 sb.append("Subject: ").append(subject).append("\n"); 10767 } 10768 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10769 if (Debug.isDebuggerConnected()) { 10770 sb.append("Debugger: Connected\n"); 10771 } 10772 sb.append("\n"); 10773 10774 // Do the rest in a worker thread to avoid blocking the caller on I/O 10775 // (After this point, we shouldn't access AMS internal data structures.) 10776 Thread worker = new Thread("Error dump: " + dropboxTag) { 10777 @Override 10778 public void run() { 10779 if (report != null) { 10780 sb.append(report); 10781 } 10782 if (logFile != null) { 10783 try { 10784 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10785 "\n\n[[TRUNCATED]]")); 10786 } catch (IOException e) { 10787 Slog.e(TAG, "Error reading " + logFile, e); 10788 } 10789 } 10790 if (crashInfo != null && crashInfo.stackTrace != null) { 10791 sb.append(crashInfo.stackTrace); 10792 } 10793 10794 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10795 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10796 if (lines > 0) { 10797 sb.append("\n"); 10798 10799 // Merge several logcat streams, and take the last N lines 10800 InputStreamReader input = null; 10801 try { 10802 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10803 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10804 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10805 10806 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10807 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10808 input = new InputStreamReader(logcat.getInputStream()); 10809 10810 int num; 10811 char[] buf = new char[8192]; 10812 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10813 } catch (IOException e) { 10814 Slog.e(TAG, "Error running logcat", e); 10815 } finally { 10816 if (input != null) try { input.close(); } catch (IOException e) {} 10817 } 10818 } 10819 10820 dbox.addText(dropboxTag, sb.toString()); 10821 } 10822 }; 10823 10824 if (process == null) { 10825 // If process is null, we are being called from some internal code 10826 // and may be about to die -- run this synchronously. 10827 worker.run(); 10828 } else { 10829 worker.start(); 10830 } 10831 } 10832 10833 /** 10834 * Bring up the "unexpected error" dialog box for a crashing app. 10835 * Deal with edge cases (intercepts from instrumented applications, 10836 * ActivityController, error intent receivers, that sort of thing). 10837 * @param r the application crashing 10838 * @param crashInfo describing the failure 10839 */ 10840 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10841 long timeMillis = System.currentTimeMillis(); 10842 String shortMsg = crashInfo.exceptionClassName; 10843 String longMsg = crashInfo.exceptionMessage; 10844 String stackTrace = crashInfo.stackTrace; 10845 if (shortMsg != null && longMsg != null) { 10846 longMsg = shortMsg + ": " + longMsg; 10847 } else if (shortMsg != null) { 10848 longMsg = shortMsg; 10849 } 10850 10851 AppErrorResult result = new AppErrorResult(); 10852 synchronized (this) { 10853 if (mController != null) { 10854 try { 10855 String name = r != null ? r.processName : null; 10856 int pid = r != null ? r.pid : Binder.getCallingPid(); 10857 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10858 if (!mController.appCrashed(name, pid, 10859 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10860 Slog.w(TAG, "Force-killing crashed app " + name 10861 + " at watcher's request"); 10862 Process.killProcess(pid); 10863 if (r != null) { 10864 Process.killProcessGroup(uid, pid); 10865 } 10866 return; 10867 } 10868 } catch (RemoteException e) { 10869 mController = null; 10870 Watchdog.getInstance().setActivityController(null); 10871 } 10872 } 10873 10874 final long origId = Binder.clearCallingIdentity(); 10875 10876 // If this process is running instrumentation, finish it. 10877 if (r != null && r.instrumentationClass != null) { 10878 Slog.w(TAG, "Error in app " + r.processName 10879 + " running instrumentation " + r.instrumentationClass + ":"); 10880 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10881 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10882 Bundle info = new Bundle(); 10883 info.putString("shortMsg", shortMsg); 10884 info.putString("longMsg", longMsg); 10885 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10886 Binder.restoreCallingIdentity(origId); 10887 return; 10888 } 10889 10890 // If we can't identify the process or it's already exceeded its crash quota, 10891 // quit right away without showing a crash dialog. 10892 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10893 Binder.restoreCallingIdentity(origId); 10894 return; 10895 } 10896 10897 Message msg = Message.obtain(); 10898 msg.what = SHOW_ERROR_MSG; 10899 HashMap data = new HashMap(); 10900 data.put("result", result); 10901 data.put("app", r); 10902 msg.obj = data; 10903 mHandler.sendMessage(msg); 10904 10905 Binder.restoreCallingIdentity(origId); 10906 } 10907 10908 int res = result.get(); 10909 10910 Intent appErrorIntent = null; 10911 synchronized (this) { 10912 if (r != null && !r.isolated) { 10913 // XXX Can't keep track of crash time for isolated processes, 10914 // since they don't have a persistent identity. 10915 mProcessCrashTimes.put(r.info.processName, r.uid, 10916 SystemClock.uptimeMillis()); 10917 } 10918 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10919 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10920 } 10921 } 10922 10923 if (appErrorIntent != null) { 10924 try { 10925 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10926 } catch (ActivityNotFoundException e) { 10927 Slog.w(TAG, "bug report receiver dissappeared", e); 10928 } 10929 } 10930 } 10931 10932 Intent createAppErrorIntentLocked(ProcessRecord r, 10933 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10934 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10935 if (report == null) { 10936 return null; 10937 } 10938 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10939 result.setComponent(r.errorReportReceiver); 10940 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10941 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10942 return result; 10943 } 10944 10945 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10946 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10947 if (r.errorReportReceiver == null) { 10948 return null; 10949 } 10950 10951 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10952 return null; 10953 } 10954 10955 ApplicationErrorReport report = new ApplicationErrorReport(); 10956 report.packageName = r.info.packageName; 10957 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10958 report.processName = r.processName; 10959 report.time = timeMillis; 10960 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10961 10962 if (r.crashing || r.forceCrashReport) { 10963 report.type = ApplicationErrorReport.TYPE_CRASH; 10964 report.crashInfo = crashInfo; 10965 } else if (r.notResponding) { 10966 report.type = ApplicationErrorReport.TYPE_ANR; 10967 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10968 10969 report.anrInfo.activity = r.notRespondingReport.tag; 10970 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10971 report.anrInfo.info = r.notRespondingReport.longMsg; 10972 } 10973 10974 return report; 10975 } 10976 10977 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10978 enforceNotIsolatedCaller("getProcessesInErrorState"); 10979 // assume our apps are happy - lazy create the list 10980 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10981 10982 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10983 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10984 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10985 10986 synchronized (this) { 10987 10988 // iterate across all processes 10989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10990 ProcessRecord app = mLruProcesses.get(i); 10991 if (!allUsers && app.userId != userId) { 10992 continue; 10993 } 10994 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10995 // This one's in trouble, so we'll generate a report for it 10996 // crashes are higher priority (in case there's a crash *and* an anr) 10997 ActivityManager.ProcessErrorStateInfo report = null; 10998 if (app.crashing) { 10999 report = app.crashingReport; 11000 } else if (app.notResponding) { 11001 report = app.notRespondingReport; 11002 } 11003 11004 if (report != null) { 11005 if (errList == null) { 11006 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11007 } 11008 errList.add(report); 11009 } else { 11010 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11011 " crashing = " + app.crashing + 11012 " notResponding = " + app.notResponding); 11013 } 11014 } 11015 } 11016 } 11017 11018 return errList; 11019 } 11020 11021 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 11022 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 11023 if (currApp != null) { 11024 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 11025 } 11026 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 11027 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 11028 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 11029 } else if (adj >= ProcessList.HOME_APP_ADJ) { 11030 if (currApp != null) { 11031 currApp.lru = 0; 11032 } 11033 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 11034 } else if (adj >= ProcessList.SERVICE_ADJ) { 11035 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 11036 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 11037 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 11038 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 11039 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 11040 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 11041 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 11042 } else { 11043 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 11044 } 11045 } 11046 11047 private void fillInProcMemInfo(ProcessRecord app, 11048 ActivityManager.RunningAppProcessInfo outInfo) { 11049 outInfo.pid = app.pid; 11050 outInfo.uid = app.info.uid; 11051 if (mHeavyWeightProcess == app) { 11052 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11053 } 11054 if (app.persistent) { 11055 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11056 } 11057 if (app.activities.size() > 0) { 11058 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11059 } 11060 outInfo.lastTrimLevel = app.trimMemoryLevel; 11061 int adj = app.curAdj; 11062 outInfo.importance = oomAdjToImportance(adj, outInfo); 11063 outInfo.importanceReasonCode = app.adjTypeCode; 11064 outInfo.processState = app.curProcState; 11065 } 11066 11067 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11068 enforceNotIsolatedCaller("getRunningAppProcesses"); 11069 // Lazy instantiation of list 11070 List<ActivityManager.RunningAppProcessInfo> runList = null; 11071 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11072 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11073 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11074 synchronized (this) { 11075 // Iterate across all processes 11076 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11077 ProcessRecord app = mLruProcesses.get(i); 11078 if (!allUsers && app.userId != userId) { 11079 continue; 11080 } 11081 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11082 // Generate process state info for running application 11083 ActivityManager.RunningAppProcessInfo currApp = 11084 new ActivityManager.RunningAppProcessInfo(app.processName, 11085 app.pid, app.getPackageList()); 11086 fillInProcMemInfo(app, currApp); 11087 if (app.adjSource instanceof ProcessRecord) { 11088 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11089 currApp.importanceReasonImportance = oomAdjToImportance( 11090 app.adjSourceOom, null); 11091 } else if (app.adjSource instanceof ActivityRecord) { 11092 ActivityRecord r = (ActivityRecord)app.adjSource; 11093 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11094 } 11095 if (app.adjTarget instanceof ComponentName) { 11096 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11097 } 11098 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11099 // + " lru=" + currApp.lru); 11100 if (runList == null) { 11101 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11102 } 11103 runList.add(currApp); 11104 } 11105 } 11106 } 11107 return runList; 11108 } 11109 11110 public List<ApplicationInfo> getRunningExternalApplications() { 11111 enforceNotIsolatedCaller("getRunningExternalApplications"); 11112 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11113 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11114 if (runningApps != null && runningApps.size() > 0) { 11115 Set<String> extList = new HashSet<String>(); 11116 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11117 if (app.pkgList != null) { 11118 for (String pkg : app.pkgList) { 11119 extList.add(pkg); 11120 } 11121 } 11122 } 11123 IPackageManager pm = AppGlobals.getPackageManager(); 11124 for (String pkg : extList) { 11125 try { 11126 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11127 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11128 retList.add(info); 11129 } 11130 } catch (RemoteException e) { 11131 } 11132 } 11133 } 11134 return retList; 11135 } 11136 11137 @Override 11138 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11139 enforceNotIsolatedCaller("getMyMemoryState"); 11140 synchronized (this) { 11141 ProcessRecord proc; 11142 synchronized (mPidsSelfLocked) { 11143 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11144 } 11145 fillInProcMemInfo(proc, outInfo); 11146 } 11147 } 11148 11149 @Override 11150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11151 if (checkCallingPermission(android.Manifest.permission.DUMP) 11152 != PackageManager.PERMISSION_GRANTED) { 11153 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11154 + Binder.getCallingPid() 11155 + ", uid=" + Binder.getCallingUid() 11156 + " without permission " 11157 + android.Manifest.permission.DUMP); 11158 return; 11159 } 11160 11161 boolean dumpAll = false; 11162 boolean dumpClient = false; 11163 String dumpPackage = null; 11164 11165 int opti = 0; 11166 while (opti < args.length) { 11167 String opt = args[opti]; 11168 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11169 break; 11170 } 11171 opti++; 11172 if ("-a".equals(opt)) { 11173 dumpAll = true; 11174 } else if ("-c".equals(opt)) { 11175 dumpClient = true; 11176 } else if ("-h".equals(opt)) { 11177 pw.println("Activity manager dump options:"); 11178 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11179 pw.println(" cmd may be one of:"); 11180 pw.println(" a[ctivities]: activity stack state"); 11181 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11182 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11183 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11184 pw.println(" o[om]: out of memory management"); 11185 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11186 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11187 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11188 pw.println(" service [COMP_SPEC]: service client-side state"); 11189 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11190 pw.println(" all: dump all activities"); 11191 pw.println(" top: dump the top activity"); 11192 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11193 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11194 pw.println(" a partial substring in a component name, a"); 11195 pw.println(" hex object identifier."); 11196 pw.println(" -a: include all available server state."); 11197 pw.println(" -c: include client state."); 11198 return; 11199 } else { 11200 pw.println("Unknown argument: " + opt + "; use -h for help"); 11201 } 11202 } 11203 11204 long origId = Binder.clearCallingIdentity(); 11205 boolean more = false; 11206 // Is the caller requesting to dump a particular piece of data? 11207 if (opti < args.length) { 11208 String cmd = args[opti]; 11209 opti++; 11210 if ("activities".equals(cmd) || "a".equals(cmd)) { 11211 synchronized (this) { 11212 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11213 } 11214 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11215 String[] newArgs; 11216 String name; 11217 if (opti >= args.length) { 11218 name = null; 11219 newArgs = EMPTY_STRING_ARRAY; 11220 } else { 11221 name = args[opti]; 11222 opti++; 11223 newArgs = new String[args.length - opti]; 11224 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11225 args.length - opti); 11226 } 11227 synchronized (this) { 11228 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11229 } 11230 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11231 String[] newArgs; 11232 String name; 11233 if (opti >= args.length) { 11234 name = null; 11235 newArgs = EMPTY_STRING_ARRAY; 11236 } else { 11237 name = args[opti]; 11238 opti++; 11239 newArgs = new String[args.length - opti]; 11240 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11241 args.length - opti); 11242 } 11243 synchronized (this) { 11244 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11245 } 11246 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11247 String[] newArgs; 11248 String name; 11249 if (opti >= args.length) { 11250 name = null; 11251 newArgs = EMPTY_STRING_ARRAY; 11252 } else { 11253 name = args[opti]; 11254 opti++; 11255 newArgs = new String[args.length - opti]; 11256 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11257 args.length - opti); 11258 } 11259 synchronized (this) { 11260 dumpProcessesLocked(fd, pw, args, opti, true, name); 11261 } 11262 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11263 synchronized (this) { 11264 dumpOomLocked(fd, pw, args, opti, true); 11265 } 11266 } else if ("provider".equals(cmd)) { 11267 String[] newArgs; 11268 String name; 11269 if (opti >= args.length) { 11270 name = null; 11271 newArgs = EMPTY_STRING_ARRAY; 11272 } else { 11273 name = args[opti]; 11274 opti++; 11275 newArgs = new String[args.length - opti]; 11276 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11277 } 11278 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11279 pw.println("No providers match: " + name); 11280 pw.println("Use -h for help."); 11281 } 11282 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11283 synchronized (this) { 11284 dumpProvidersLocked(fd, pw, args, opti, true, null); 11285 } 11286 } else if ("service".equals(cmd)) { 11287 String[] newArgs; 11288 String name; 11289 if (opti >= args.length) { 11290 name = null; 11291 newArgs = EMPTY_STRING_ARRAY; 11292 } else { 11293 name = args[opti]; 11294 opti++; 11295 newArgs = new String[args.length - opti]; 11296 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11297 args.length - opti); 11298 } 11299 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11300 pw.println("No services match: " + name); 11301 pw.println("Use -h for help."); 11302 } 11303 } else if ("package".equals(cmd)) { 11304 String[] newArgs; 11305 if (opti >= args.length) { 11306 pw.println("package: no package name specified"); 11307 pw.println("Use -h for help."); 11308 } else { 11309 dumpPackage = args[opti]; 11310 opti++; 11311 newArgs = new String[args.length - opti]; 11312 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11313 args.length - opti); 11314 args = newArgs; 11315 opti = 0; 11316 more = true; 11317 } 11318 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11319 synchronized (this) { 11320 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11321 } 11322 } else { 11323 // Dumping a single activity? 11324 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11325 pw.println("Bad activity command, or no activities match: " + cmd); 11326 pw.println("Use -h for help."); 11327 } 11328 } 11329 if (!more) { 11330 Binder.restoreCallingIdentity(origId); 11331 return; 11332 } 11333 } 11334 11335 // No piece of data specified, dump everything. 11336 synchronized (this) { 11337 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11338 pw.println(); 11339 if (dumpAll) { 11340 pw.println("-------------------------------------------------------------------------------"); 11341 } 11342 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11343 pw.println(); 11344 if (dumpAll) { 11345 pw.println("-------------------------------------------------------------------------------"); 11346 } 11347 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11348 pw.println(); 11349 if (dumpAll) { 11350 pw.println("-------------------------------------------------------------------------------"); 11351 } 11352 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11353 pw.println(); 11354 if (dumpAll) { 11355 pw.println("-------------------------------------------------------------------------------"); 11356 } 11357 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11358 pw.println(); 11359 if (dumpAll) { 11360 pw.println("-------------------------------------------------------------------------------"); 11361 } 11362 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11363 } 11364 Binder.restoreCallingIdentity(origId); 11365 } 11366 11367 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11368 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11369 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11370 11371 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11372 dumpPackage); 11373 boolean needSep = printedAnything; 11374 11375 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11376 dumpPackage, needSep, " mFocusedActivity: "); 11377 if (printed) { 11378 printedAnything = true; 11379 needSep = false; 11380 } 11381 11382 if (dumpPackage == null) { 11383 if (needSep) { 11384 pw.println(); 11385 } 11386 needSep = true; 11387 printedAnything = true; 11388 mStackSupervisor.dump(pw, " "); 11389 } 11390 11391 if (mRecentTasks.size() > 0) { 11392 boolean printedHeader = false; 11393 11394 final int N = mRecentTasks.size(); 11395 for (int i=0; i<N; i++) { 11396 TaskRecord tr = mRecentTasks.get(i); 11397 if (dumpPackage != null) { 11398 if (tr.realActivity == null || 11399 !dumpPackage.equals(tr.realActivity)) { 11400 continue; 11401 } 11402 } 11403 if (!printedHeader) { 11404 if (needSep) { 11405 pw.println(); 11406 } 11407 pw.println(" Recent tasks:"); 11408 printedHeader = true; 11409 printedAnything = true; 11410 } 11411 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11412 pw.println(tr); 11413 if (dumpAll) { 11414 mRecentTasks.get(i).dump(pw, " "); 11415 } 11416 } 11417 } 11418 11419 if (!printedAnything) { 11420 pw.println(" (nothing)"); 11421 } 11422 } 11423 11424 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11425 int opti, boolean dumpAll, String dumpPackage) { 11426 boolean needSep = false; 11427 boolean printedAnything = false; 11428 int numPers = 0; 11429 11430 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11431 11432 if (dumpAll) { 11433 final int NP = mProcessNames.getMap().size(); 11434 for (int ip=0; ip<NP; ip++) { 11435 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11436 final int NA = procs.size(); 11437 for (int ia=0; ia<NA; ia++) { 11438 ProcessRecord r = procs.valueAt(ia); 11439 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11440 continue; 11441 } 11442 if (!needSep) { 11443 pw.println(" All known processes:"); 11444 needSep = true; 11445 printedAnything = true; 11446 } 11447 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11448 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11449 pw.print(" "); pw.println(r); 11450 r.dump(pw, " "); 11451 if (r.persistent) { 11452 numPers++; 11453 } 11454 } 11455 } 11456 } 11457 11458 if (mIsolatedProcesses.size() > 0) { 11459 boolean printed = false; 11460 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11461 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11462 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11463 continue; 11464 } 11465 if (!printed) { 11466 if (needSep) { 11467 pw.println(); 11468 } 11469 pw.println(" Isolated process list (sorted by uid):"); 11470 printedAnything = true; 11471 printed = true; 11472 needSep = true; 11473 } 11474 pw.println(String.format("%sIsolated #%2d: %s", 11475 " ", i, r.toString())); 11476 } 11477 } 11478 11479 if (mLruProcesses.size() > 0) { 11480 if (needSep) { 11481 pw.println(); 11482 } 11483 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11484 pw.print(" total, non-act at "); 11485 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11486 pw.print(", non-svc at "); 11487 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11488 pw.println("):"); 11489 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11490 needSep = true; 11491 printedAnything = true; 11492 } 11493 11494 if (dumpAll || dumpPackage != null) { 11495 synchronized (mPidsSelfLocked) { 11496 boolean printed = false; 11497 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11498 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11499 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11500 continue; 11501 } 11502 if (!printed) { 11503 if (needSep) pw.println(); 11504 needSep = true; 11505 pw.println(" PID mappings:"); 11506 printed = true; 11507 printedAnything = true; 11508 } 11509 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11510 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11511 } 11512 } 11513 } 11514 11515 if (mForegroundProcesses.size() > 0) { 11516 synchronized (mPidsSelfLocked) { 11517 boolean printed = false; 11518 for (int i=0; i<mForegroundProcesses.size(); i++) { 11519 ProcessRecord r = mPidsSelfLocked.get( 11520 mForegroundProcesses.valueAt(i).pid); 11521 if (dumpPackage != null && (r == null 11522 || !r.pkgList.containsKey(dumpPackage))) { 11523 continue; 11524 } 11525 if (!printed) { 11526 if (needSep) pw.println(); 11527 needSep = true; 11528 pw.println(" Foreground Processes:"); 11529 printed = true; 11530 printedAnything = true; 11531 } 11532 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11533 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11534 } 11535 } 11536 } 11537 11538 if (mPersistentStartingProcesses.size() > 0) { 11539 if (needSep) pw.println(); 11540 needSep = true; 11541 printedAnything = true; 11542 pw.println(" Persisent processes that are starting:"); 11543 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11544 "Starting Norm", "Restarting PERS", dumpPackage); 11545 } 11546 11547 if (mRemovedProcesses.size() > 0) { 11548 if (needSep) pw.println(); 11549 needSep = true; 11550 printedAnything = true; 11551 pw.println(" Processes that are being removed:"); 11552 dumpProcessList(pw, this, mRemovedProcesses, " ", 11553 "Removed Norm", "Removed PERS", dumpPackage); 11554 } 11555 11556 if (mProcessesOnHold.size() > 0) { 11557 if (needSep) pw.println(); 11558 needSep = true; 11559 printedAnything = true; 11560 pw.println(" Processes that are on old until the system is ready:"); 11561 dumpProcessList(pw, this, mProcessesOnHold, " ", 11562 "OnHold Norm", "OnHold PERS", dumpPackage); 11563 } 11564 11565 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11566 11567 if (mProcessCrashTimes.getMap().size() > 0) { 11568 boolean printed = false; 11569 long now = SystemClock.uptimeMillis(); 11570 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11571 final int NP = pmap.size(); 11572 for (int ip=0; ip<NP; ip++) { 11573 String pname = pmap.keyAt(ip); 11574 SparseArray<Long> uids = pmap.valueAt(ip); 11575 final int N = uids.size(); 11576 for (int i=0; i<N; i++) { 11577 int puid = uids.keyAt(i); 11578 ProcessRecord r = mProcessNames.get(pname, puid); 11579 if (dumpPackage != null && (r == null 11580 || !r.pkgList.containsKey(dumpPackage))) { 11581 continue; 11582 } 11583 if (!printed) { 11584 if (needSep) pw.println(); 11585 needSep = true; 11586 pw.println(" Time since processes crashed:"); 11587 printed = true; 11588 printedAnything = true; 11589 } 11590 pw.print(" Process "); pw.print(pname); 11591 pw.print(" uid "); pw.print(puid); 11592 pw.print(": last crashed "); 11593 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11594 pw.println(" ago"); 11595 } 11596 } 11597 } 11598 11599 if (mBadProcesses.getMap().size() > 0) { 11600 boolean printed = false; 11601 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11602 final int NP = pmap.size(); 11603 for (int ip=0; ip<NP; ip++) { 11604 String pname = pmap.keyAt(ip); 11605 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11606 final int N = uids.size(); 11607 for (int i=0; i<N; i++) { 11608 int puid = uids.keyAt(i); 11609 ProcessRecord r = mProcessNames.get(pname, puid); 11610 if (dumpPackage != null && (r == null 11611 || !r.pkgList.containsKey(dumpPackage))) { 11612 continue; 11613 } 11614 if (!printed) { 11615 if (needSep) pw.println(); 11616 needSep = true; 11617 pw.println(" Bad processes:"); 11618 printedAnything = true; 11619 } 11620 BadProcessInfo info = uids.valueAt(i); 11621 pw.print(" Bad process "); pw.print(pname); 11622 pw.print(" uid "); pw.print(puid); 11623 pw.print(": crashed at time "); pw.println(info.time); 11624 if (info.shortMsg != null) { 11625 pw.print(" Short msg: "); pw.println(info.shortMsg); 11626 } 11627 if (info.longMsg != null) { 11628 pw.print(" Long msg: "); pw.println(info.longMsg); 11629 } 11630 if (info.stack != null) { 11631 pw.println(" Stack:"); 11632 int lastPos = 0; 11633 for (int pos=0; pos<info.stack.length(); pos++) { 11634 if (info.stack.charAt(pos) == '\n') { 11635 pw.print(" "); 11636 pw.write(info.stack, lastPos, pos-lastPos); 11637 pw.println(); 11638 lastPos = pos+1; 11639 } 11640 } 11641 if (lastPos < info.stack.length()) { 11642 pw.print(" "); 11643 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11644 pw.println(); 11645 } 11646 } 11647 } 11648 } 11649 } 11650 11651 if (dumpPackage == null) { 11652 pw.println(); 11653 needSep = false; 11654 pw.println(" mStartedUsers:"); 11655 for (int i=0; i<mStartedUsers.size(); i++) { 11656 UserStartedState uss = mStartedUsers.valueAt(i); 11657 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11658 pw.print(": "); uss.dump("", pw); 11659 } 11660 pw.print(" mStartedUserArray: ["); 11661 for (int i=0; i<mStartedUserArray.length; i++) { 11662 if (i > 0) pw.print(", "); 11663 pw.print(mStartedUserArray[i]); 11664 } 11665 pw.println("]"); 11666 pw.print(" mUserLru: ["); 11667 for (int i=0; i<mUserLru.size(); i++) { 11668 if (i > 0) pw.print(", "); 11669 pw.print(mUserLru.get(i)); 11670 } 11671 pw.println("]"); 11672 if (dumpAll) { 11673 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11674 } 11675 synchronized (mUserProfileGroupIdsSelfLocked) { 11676 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 11677 pw.println(" mUserProfileGroupIds:"); 11678 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 11679 pw.print(" User #"); 11680 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 11681 pw.print(" -> profile #"); 11682 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 11683 } 11684 } 11685 } 11686 } 11687 if (mHomeProcess != null && (dumpPackage == null 11688 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11689 if (needSep) { 11690 pw.println(); 11691 needSep = false; 11692 } 11693 pw.println(" mHomeProcess: " + mHomeProcess); 11694 } 11695 if (mPreviousProcess != null && (dumpPackage == null 11696 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11697 if (needSep) { 11698 pw.println(); 11699 needSep = false; 11700 } 11701 pw.println(" mPreviousProcess: " + mPreviousProcess); 11702 } 11703 if (dumpAll) { 11704 StringBuilder sb = new StringBuilder(128); 11705 sb.append(" mPreviousProcessVisibleTime: "); 11706 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11707 pw.println(sb); 11708 } 11709 if (mHeavyWeightProcess != null && (dumpPackage == null 11710 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11711 if (needSep) { 11712 pw.println(); 11713 needSep = false; 11714 } 11715 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11716 } 11717 if (dumpPackage == null) { 11718 pw.println(" mConfiguration: " + mConfiguration); 11719 } 11720 if (dumpAll) { 11721 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11722 if (mCompatModePackages.getPackages().size() > 0) { 11723 boolean printed = false; 11724 for (Map.Entry<String, Integer> entry 11725 : mCompatModePackages.getPackages().entrySet()) { 11726 String pkg = entry.getKey(); 11727 int mode = entry.getValue(); 11728 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11729 continue; 11730 } 11731 if (!printed) { 11732 pw.println(" mScreenCompatPackages:"); 11733 printed = true; 11734 } 11735 pw.print(" "); pw.print(pkg); pw.print(": "); 11736 pw.print(mode); pw.println(); 11737 } 11738 } 11739 } 11740 if (dumpPackage == null) { 11741 if (mSleeping || mWentToSleep || mLockScreenShown) { 11742 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11743 + " mLockScreenShown " + mLockScreenShown); 11744 } 11745 if (mShuttingDown || mRunningVoice) { 11746 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11747 } 11748 } 11749 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11750 || mOrigWaitForDebugger) { 11751 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11752 || dumpPackage.equals(mOrigDebugApp)) { 11753 if (needSep) { 11754 pw.println(); 11755 needSep = false; 11756 } 11757 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11758 + " mDebugTransient=" + mDebugTransient 11759 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11760 } 11761 } 11762 if (mOpenGlTraceApp != null) { 11763 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11764 if (needSep) { 11765 pw.println(); 11766 needSep = false; 11767 } 11768 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11769 } 11770 } 11771 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11772 || mProfileFd != null) { 11773 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11774 if (needSep) { 11775 pw.println(); 11776 needSep = false; 11777 } 11778 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11779 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11780 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11781 + mAutoStopProfiler); 11782 } 11783 } 11784 if (dumpPackage == null) { 11785 if (mAlwaysFinishActivities || mController != null) { 11786 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11787 + " mController=" + mController); 11788 } 11789 if (dumpAll) { 11790 pw.println(" Total persistent processes: " + numPers); 11791 pw.println(" mProcessesReady=" + mProcessesReady 11792 + " mSystemReady=" + mSystemReady); 11793 pw.println(" mBooting=" + mBooting 11794 + " mBooted=" + mBooted 11795 + " mFactoryTest=" + mFactoryTest); 11796 pw.print(" mLastPowerCheckRealtime="); 11797 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11798 pw.println(""); 11799 pw.print(" mLastPowerCheckUptime="); 11800 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11801 pw.println(""); 11802 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11803 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11804 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11805 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11806 + " (" + mLruProcesses.size() + " total)" 11807 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11808 + " mNumServiceProcs=" + mNumServiceProcs 11809 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11810 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11811 + " mLastMemoryLevel" + mLastMemoryLevel 11812 + " mLastNumProcesses" + mLastNumProcesses); 11813 long now = SystemClock.uptimeMillis(); 11814 pw.print(" mLastIdleTime="); 11815 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11816 pw.print(" mLowRamSinceLastIdle="); 11817 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11818 pw.println(); 11819 } 11820 } 11821 11822 if (!printedAnything) { 11823 pw.println(" (nothing)"); 11824 } 11825 } 11826 11827 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11828 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11829 if (mProcessesToGc.size() > 0) { 11830 boolean printed = false; 11831 long now = SystemClock.uptimeMillis(); 11832 for (int i=0; i<mProcessesToGc.size(); i++) { 11833 ProcessRecord proc = mProcessesToGc.get(i); 11834 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11835 continue; 11836 } 11837 if (!printed) { 11838 if (needSep) pw.println(); 11839 needSep = true; 11840 pw.println(" Processes that are waiting to GC:"); 11841 printed = true; 11842 } 11843 pw.print(" Process "); pw.println(proc); 11844 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11845 pw.print(", last gced="); 11846 pw.print(now-proc.lastRequestedGc); 11847 pw.print(" ms ago, last lowMem="); 11848 pw.print(now-proc.lastLowMemory); 11849 pw.println(" ms ago"); 11850 11851 } 11852 } 11853 return needSep; 11854 } 11855 11856 void printOomLevel(PrintWriter pw, String name, int adj) { 11857 pw.print(" "); 11858 if (adj >= 0) { 11859 pw.print(' '); 11860 if (adj < 10) pw.print(' '); 11861 } else { 11862 if (adj > -10) pw.print(' '); 11863 } 11864 pw.print(adj); 11865 pw.print(": "); 11866 pw.print(name); 11867 pw.print(" ("); 11868 pw.print(mProcessList.getMemLevel(adj)/1024); 11869 pw.println(" kB)"); 11870 } 11871 11872 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11873 int opti, boolean dumpAll) { 11874 boolean needSep = false; 11875 11876 if (mLruProcesses.size() > 0) { 11877 if (needSep) pw.println(); 11878 needSep = true; 11879 pw.println(" OOM levels:"); 11880 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11881 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11882 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11883 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11884 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11885 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11886 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11887 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11888 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11889 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11890 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11891 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11892 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11893 11894 if (needSep) pw.println(); 11895 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11896 pw.print(" total, non-act at "); 11897 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11898 pw.print(", non-svc at "); 11899 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11900 pw.println("):"); 11901 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11902 needSep = true; 11903 } 11904 11905 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11906 11907 pw.println(); 11908 pw.println(" mHomeProcess: " + mHomeProcess); 11909 pw.println(" mPreviousProcess: " + mPreviousProcess); 11910 if (mHeavyWeightProcess != null) { 11911 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11912 } 11913 11914 return true; 11915 } 11916 11917 /** 11918 * There are three ways to call this: 11919 * - no provider specified: dump all the providers 11920 * - a flattened component name that matched an existing provider was specified as the 11921 * first arg: dump that one provider 11922 * - the first arg isn't the flattened component name of an existing provider: 11923 * dump all providers whose component contains the first arg as a substring 11924 */ 11925 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11926 int opti, boolean dumpAll) { 11927 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11928 } 11929 11930 static class ItemMatcher { 11931 ArrayList<ComponentName> components; 11932 ArrayList<String> strings; 11933 ArrayList<Integer> objects; 11934 boolean all; 11935 11936 ItemMatcher() { 11937 all = true; 11938 } 11939 11940 void build(String name) { 11941 ComponentName componentName = ComponentName.unflattenFromString(name); 11942 if (componentName != null) { 11943 if (components == null) { 11944 components = new ArrayList<ComponentName>(); 11945 } 11946 components.add(componentName); 11947 all = false; 11948 } else { 11949 int objectId = 0; 11950 // Not a '/' separated full component name; maybe an object ID? 11951 try { 11952 objectId = Integer.parseInt(name, 16); 11953 if (objects == null) { 11954 objects = new ArrayList<Integer>(); 11955 } 11956 objects.add(objectId); 11957 all = false; 11958 } catch (RuntimeException e) { 11959 // Not an integer; just do string match. 11960 if (strings == null) { 11961 strings = new ArrayList<String>(); 11962 } 11963 strings.add(name); 11964 all = false; 11965 } 11966 } 11967 } 11968 11969 int build(String[] args, int opti) { 11970 for (; opti<args.length; opti++) { 11971 String name = args[opti]; 11972 if ("--".equals(name)) { 11973 return opti+1; 11974 } 11975 build(name); 11976 } 11977 return opti; 11978 } 11979 11980 boolean match(Object object, ComponentName comp) { 11981 if (all) { 11982 return true; 11983 } 11984 if (components != null) { 11985 for (int i=0; i<components.size(); i++) { 11986 if (components.get(i).equals(comp)) { 11987 return true; 11988 } 11989 } 11990 } 11991 if (objects != null) { 11992 for (int i=0; i<objects.size(); i++) { 11993 if (System.identityHashCode(object) == objects.get(i)) { 11994 return true; 11995 } 11996 } 11997 } 11998 if (strings != null) { 11999 String flat = comp.flattenToString(); 12000 for (int i=0; i<strings.size(); i++) { 12001 if (flat.contains(strings.get(i))) { 12002 return true; 12003 } 12004 } 12005 } 12006 return false; 12007 } 12008 } 12009 12010 /** 12011 * There are three things that cmd can be: 12012 * - a flattened component name that matches an existing activity 12013 * - the cmd arg isn't the flattened component name of an existing activity: 12014 * dump all activity whose component contains the cmd as a substring 12015 * - A hex number of the ActivityRecord object instance. 12016 */ 12017 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12018 int opti, boolean dumpAll) { 12019 ArrayList<ActivityRecord> activities; 12020 12021 synchronized (this) { 12022 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12023 } 12024 12025 if (activities.size() <= 0) { 12026 return false; 12027 } 12028 12029 String[] newArgs = new String[args.length - opti]; 12030 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12031 12032 TaskRecord lastTask = null; 12033 boolean needSep = false; 12034 for (int i=activities.size()-1; i>=0; i--) { 12035 ActivityRecord r = activities.get(i); 12036 if (needSep) { 12037 pw.println(); 12038 } 12039 needSep = true; 12040 synchronized (this) { 12041 if (lastTask != r.task) { 12042 lastTask = r.task; 12043 pw.print("TASK "); pw.print(lastTask.affinity); 12044 pw.print(" id="); pw.println(lastTask.taskId); 12045 if (dumpAll) { 12046 lastTask.dump(pw, " "); 12047 } 12048 } 12049 } 12050 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12051 } 12052 return true; 12053 } 12054 12055 /** 12056 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12057 * there is a thread associated with the activity. 12058 */ 12059 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12060 final ActivityRecord r, String[] args, boolean dumpAll) { 12061 String innerPrefix = prefix + " "; 12062 synchronized (this) { 12063 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12064 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12065 pw.print(" pid="); 12066 if (r.app != null) pw.println(r.app.pid); 12067 else pw.println("(not running)"); 12068 if (dumpAll) { 12069 r.dump(pw, innerPrefix); 12070 } 12071 } 12072 if (r.app != null && r.app.thread != null) { 12073 // flush anything that is already in the PrintWriter since the thread is going 12074 // to write to the file descriptor directly 12075 pw.flush(); 12076 try { 12077 TransferPipe tp = new TransferPipe(); 12078 try { 12079 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12080 r.appToken, innerPrefix, args); 12081 tp.go(fd); 12082 } finally { 12083 tp.kill(); 12084 } 12085 } catch (IOException e) { 12086 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12087 } catch (RemoteException e) { 12088 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12089 } 12090 } 12091 } 12092 12093 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12094 int opti, boolean dumpAll, String dumpPackage) { 12095 boolean needSep = false; 12096 boolean onlyHistory = false; 12097 boolean printedAnything = false; 12098 12099 if ("history".equals(dumpPackage)) { 12100 if (opti < args.length && "-s".equals(args[opti])) { 12101 dumpAll = false; 12102 } 12103 onlyHistory = true; 12104 dumpPackage = null; 12105 } 12106 12107 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12108 if (!onlyHistory && dumpAll) { 12109 if (mRegisteredReceivers.size() > 0) { 12110 boolean printed = false; 12111 Iterator it = mRegisteredReceivers.values().iterator(); 12112 while (it.hasNext()) { 12113 ReceiverList r = (ReceiverList)it.next(); 12114 if (dumpPackage != null && (r.app == null || 12115 !dumpPackage.equals(r.app.info.packageName))) { 12116 continue; 12117 } 12118 if (!printed) { 12119 pw.println(" Registered Receivers:"); 12120 needSep = true; 12121 printed = true; 12122 printedAnything = true; 12123 } 12124 pw.print(" * "); pw.println(r); 12125 r.dump(pw, " "); 12126 } 12127 } 12128 12129 if (mReceiverResolver.dump(pw, needSep ? 12130 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12131 " ", dumpPackage, false)) { 12132 needSep = true; 12133 printedAnything = true; 12134 } 12135 } 12136 12137 for (BroadcastQueue q : mBroadcastQueues) { 12138 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12139 printedAnything |= needSep; 12140 } 12141 12142 needSep = true; 12143 12144 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12145 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12146 if (needSep) { 12147 pw.println(); 12148 } 12149 needSep = true; 12150 printedAnything = true; 12151 pw.print(" Sticky broadcasts for user "); 12152 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12153 StringBuilder sb = new StringBuilder(128); 12154 for (Map.Entry<String, ArrayList<Intent>> ent 12155 : mStickyBroadcasts.valueAt(user).entrySet()) { 12156 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12157 if (dumpAll) { 12158 pw.println(":"); 12159 ArrayList<Intent> intents = ent.getValue(); 12160 final int N = intents.size(); 12161 for (int i=0; i<N; i++) { 12162 sb.setLength(0); 12163 sb.append(" Intent: "); 12164 intents.get(i).toShortString(sb, false, true, false, false); 12165 pw.println(sb.toString()); 12166 Bundle bundle = intents.get(i).getExtras(); 12167 if (bundle != null) { 12168 pw.print(" "); 12169 pw.println(bundle.toString()); 12170 } 12171 } 12172 } else { 12173 pw.println(""); 12174 } 12175 } 12176 } 12177 } 12178 12179 if (!onlyHistory && dumpAll) { 12180 pw.println(); 12181 for (BroadcastQueue queue : mBroadcastQueues) { 12182 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12183 + queue.mBroadcastsScheduled); 12184 } 12185 pw.println(" mHandler:"); 12186 mHandler.dump(new PrintWriterPrinter(pw), " "); 12187 needSep = true; 12188 printedAnything = true; 12189 } 12190 12191 if (!printedAnything) { 12192 pw.println(" (nothing)"); 12193 } 12194 } 12195 12196 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12197 int opti, boolean dumpAll, String dumpPackage) { 12198 boolean needSep; 12199 boolean printedAnything = false; 12200 12201 ItemMatcher matcher = new ItemMatcher(); 12202 matcher.build(args, opti); 12203 12204 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12205 12206 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12207 printedAnything |= needSep; 12208 12209 if (mLaunchingProviders.size() > 0) { 12210 boolean printed = false; 12211 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12212 ContentProviderRecord r = mLaunchingProviders.get(i); 12213 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12214 continue; 12215 } 12216 if (!printed) { 12217 if (needSep) pw.println(); 12218 needSep = true; 12219 pw.println(" Launching content providers:"); 12220 printed = true; 12221 printedAnything = true; 12222 } 12223 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12224 pw.println(r); 12225 } 12226 } 12227 12228 if (mGrantedUriPermissions.size() > 0) { 12229 boolean printed = false; 12230 int dumpUid = -2; 12231 if (dumpPackage != null) { 12232 try { 12233 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12234 } catch (NameNotFoundException e) { 12235 dumpUid = -1; 12236 } 12237 } 12238 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12239 int uid = mGrantedUriPermissions.keyAt(i); 12240 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12241 continue; 12242 } 12243 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12244 if (!printed) { 12245 if (needSep) pw.println(); 12246 needSep = true; 12247 pw.println(" Granted Uri Permissions:"); 12248 printed = true; 12249 printedAnything = true; 12250 } 12251 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12252 for (UriPermission perm : perms.values()) { 12253 pw.print(" "); pw.println(perm); 12254 if (dumpAll) { 12255 perm.dump(pw, " "); 12256 } 12257 } 12258 } 12259 } 12260 12261 if (!printedAnything) { 12262 pw.println(" (nothing)"); 12263 } 12264 } 12265 12266 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12267 int opti, boolean dumpAll, String dumpPackage) { 12268 boolean printed = false; 12269 12270 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12271 12272 if (mIntentSenderRecords.size() > 0) { 12273 Iterator<WeakReference<PendingIntentRecord>> it 12274 = mIntentSenderRecords.values().iterator(); 12275 while (it.hasNext()) { 12276 WeakReference<PendingIntentRecord> ref = it.next(); 12277 PendingIntentRecord rec = ref != null ? ref.get(): null; 12278 if (dumpPackage != null && (rec == null 12279 || !dumpPackage.equals(rec.key.packageName))) { 12280 continue; 12281 } 12282 printed = true; 12283 if (rec != null) { 12284 pw.print(" * "); pw.println(rec); 12285 if (dumpAll) { 12286 rec.dump(pw, " "); 12287 } 12288 } else { 12289 pw.print(" * "); pw.println(ref); 12290 } 12291 } 12292 } 12293 12294 if (!printed) { 12295 pw.println(" (nothing)"); 12296 } 12297 } 12298 12299 private static final int dumpProcessList(PrintWriter pw, 12300 ActivityManagerService service, List list, 12301 String prefix, String normalLabel, String persistentLabel, 12302 String dumpPackage) { 12303 int numPers = 0; 12304 final int N = list.size()-1; 12305 for (int i=N; i>=0; i--) { 12306 ProcessRecord r = (ProcessRecord)list.get(i); 12307 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12308 continue; 12309 } 12310 pw.println(String.format("%s%s #%2d: %s", 12311 prefix, (r.persistent ? persistentLabel : normalLabel), 12312 i, r.toString())); 12313 if (r.persistent) { 12314 numPers++; 12315 } 12316 } 12317 return numPers; 12318 } 12319 12320 private static final boolean dumpProcessOomList(PrintWriter pw, 12321 ActivityManagerService service, List<ProcessRecord> origList, 12322 String prefix, String normalLabel, String persistentLabel, 12323 boolean inclDetails, String dumpPackage) { 12324 12325 ArrayList<Pair<ProcessRecord, Integer>> list 12326 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12327 for (int i=0; i<origList.size(); i++) { 12328 ProcessRecord r = origList.get(i); 12329 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12330 continue; 12331 } 12332 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12333 } 12334 12335 if (list.size() <= 0) { 12336 return false; 12337 } 12338 12339 Comparator<Pair<ProcessRecord, Integer>> comparator 12340 = new Comparator<Pair<ProcessRecord, Integer>>() { 12341 @Override 12342 public int compare(Pair<ProcessRecord, Integer> object1, 12343 Pair<ProcessRecord, Integer> object2) { 12344 if (object1.first.setAdj != object2.first.setAdj) { 12345 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12346 } 12347 if (object1.second.intValue() != object2.second.intValue()) { 12348 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12349 } 12350 return 0; 12351 } 12352 }; 12353 12354 Collections.sort(list, comparator); 12355 12356 final long curRealtime = SystemClock.elapsedRealtime(); 12357 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12358 final long curUptime = SystemClock.uptimeMillis(); 12359 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12360 12361 for (int i=list.size()-1; i>=0; i--) { 12362 ProcessRecord r = list.get(i).first; 12363 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12364 char schedGroup; 12365 switch (r.setSchedGroup) { 12366 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12367 schedGroup = 'B'; 12368 break; 12369 case Process.THREAD_GROUP_DEFAULT: 12370 schedGroup = 'F'; 12371 break; 12372 default: 12373 schedGroup = '?'; 12374 break; 12375 } 12376 char foreground; 12377 if (r.foregroundActivities) { 12378 foreground = 'A'; 12379 } else if (r.foregroundServices) { 12380 foreground = 'S'; 12381 } else { 12382 foreground = ' '; 12383 } 12384 String procState = ProcessList.makeProcStateString(r.curProcState); 12385 pw.print(prefix); 12386 pw.print(r.persistent ? persistentLabel : normalLabel); 12387 pw.print(" #"); 12388 int num = (origList.size()-1)-list.get(i).second; 12389 if (num < 10) pw.print(' '); 12390 pw.print(num); 12391 pw.print(": "); 12392 pw.print(oomAdj); 12393 pw.print(' '); 12394 pw.print(schedGroup); 12395 pw.print('/'); 12396 pw.print(foreground); 12397 pw.print('/'); 12398 pw.print(procState); 12399 pw.print(" trm:"); 12400 if (r.trimMemoryLevel < 10) pw.print(' '); 12401 pw.print(r.trimMemoryLevel); 12402 pw.print(' '); 12403 pw.print(r.toShortString()); 12404 pw.print(" ("); 12405 pw.print(r.adjType); 12406 pw.println(')'); 12407 if (r.adjSource != null || r.adjTarget != null) { 12408 pw.print(prefix); 12409 pw.print(" "); 12410 if (r.adjTarget instanceof ComponentName) { 12411 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12412 } else if (r.adjTarget != null) { 12413 pw.print(r.adjTarget.toString()); 12414 } else { 12415 pw.print("{null}"); 12416 } 12417 pw.print("<="); 12418 if (r.adjSource instanceof ProcessRecord) { 12419 pw.print("Proc{"); 12420 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12421 pw.println("}"); 12422 } else if (r.adjSource != null) { 12423 pw.println(r.adjSource.toString()); 12424 } else { 12425 pw.println("{null}"); 12426 } 12427 } 12428 if (inclDetails) { 12429 pw.print(prefix); 12430 pw.print(" "); 12431 pw.print("oom: max="); pw.print(r.maxAdj); 12432 pw.print(" curRaw="); pw.print(r.curRawAdj); 12433 pw.print(" setRaw="); pw.print(r.setRawAdj); 12434 pw.print(" cur="); pw.print(r.curAdj); 12435 pw.print(" set="); pw.println(r.setAdj); 12436 pw.print(prefix); 12437 pw.print(" "); 12438 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12439 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12440 pw.print(" lastPss="); pw.print(r.lastPss); 12441 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12442 pw.print(prefix); 12443 pw.print(" "); 12444 pw.print("keeping="); pw.print(r.keeping); 12445 pw.print(" cached="); pw.print(r.cached); 12446 pw.print(" empty="); pw.print(r.empty); 12447 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12448 12449 if (!r.keeping) { 12450 if (r.lastWakeTime != 0) { 12451 long wtime; 12452 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12453 synchronized (stats) { 12454 wtime = stats.getProcessWakeTime(r.info.uid, 12455 r.pid, curRealtime); 12456 } 12457 long timeUsed = wtime - r.lastWakeTime; 12458 pw.print(prefix); 12459 pw.print(" "); 12460 pw.print("keep awake over "); 12461 TimeUtils.formatDuration(realtimeSince, pw); 12462 pw.print(" used "); 12463 TimeUtils.formatDuration(timeUsed, pw); 12464 pw.print(" ("); 12465 pw.print((timeUsed*100)/realtimeSince); 12466 pw.println("%)"); 12467 } 12468 if (r.lastCpuTime != 0) { 12469 long timeUsed = r.curCpuTime - r.lastCpuTime; 12470 pw.print(prefix); 12471 pw.print(" "); 12472 pw.print("run cpu over "); 12473 TimeUtils.formatDuration(uptimeSince, pw); 12474 pw.print(" used "); 12475 TimeUtils.formatDuration(timeUsed, pw); 12476 pw.print(" ("); 12477 pw.print((timeUsed*100)/uptimeSince); 12478 pw.println("%)"); 12479 } 12480 } 12481 } 12482 } 12483 return true; 12484 } 12485 12486 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12487 ArrayList<ProcessRecord> procs; 12488 synchronized (this) { 12489 if (args != null && args.length > start 12490 && args[start].charAt(0) != '-') { 12491 procs = new ArrayList<ProcessRecord>(); 12492 int pid = -1; 12493 try { 12494 pid = Integer.parseInt(args[start]); 12495 } catch (NumberFormatException e) { 12496 } 12497 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12498 ProcessRecord proc = mLruProcesses.get(i); 12499 if (proc.pid == pid) { 12500 procs.add(proc); 12501 } else if (proc.processName.equals(args[start])) { 12502 procs.add(proc); 12503 } 12504 } 12505 if (procs.size() <= 0) { 12506 return null; 12507 } 12508 } else { 12509 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12510 } 12511 } 12512 return procs; 12513 } 12514 12515 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12516 PrintWriter pw, String[] args) { 12517 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12518 if (procs == null) { 12519 pw.println("No process found for: " + args[0]); 12520 return; 12521 } 12522 12523 long uptime = SystemClock.uptimeMillis(); 12524 long realtime = SystemClock.elapsedRealtime(); 12525 pw.println("Applications Graphics Acceleration Info:"); 12526 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12527 12528 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12529 ProcessRecord r = procs.get(i); 12530 if (r.thread != null) { 12531 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12532 pw.flush(); 12533 try { 12534 TransferPipe tp = new TransferPipe(); 12535 try { 12536 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12537 tp.go(fd); 12538 } finally { 12539 tp.kill(); 12540 } 12541 } catch (IOException e) { 12542 pw.println("Failure while dumping the app: " + r); 12543 pw.flush(); 12544 } catch (RemoteException e) { 12545 pw.println("Got a RemoteException while dumping the app " + r); 12546 pw.flush(); 12547 } 12548 } 12549 } 12550 } 12551 12552 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12553 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12554 if (procs == null) { 12555 pw.println("No process found for: " + args[0]); 12556 return; 12557 } 12558 12559 pw.println("Applications Database Info:"); 12560 12561 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12562 ProcessRecord r = procs.get(i); 12563 if (r.thread != null) { 12564 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12565 pw.flush(); 12566 try { 12567 TransferPipe tp = new TransferPipe(); 12568 try { 12569 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12570 tp.go(fd); 12571 } finally { 12572 tp.kill(); 12573 } 12574 } catch (IOException e) { 12575 pw.println("Failure while dumping the app: " + r); 12576 pw.flush(); 12577 } catch (RemoteException e) { 12578 pw.println("Got a RemoteException while dumping the app " + r); 12579 pw.flush(); 12580 } 12581 } 12582 } 12583 } 12584 12585 final static class MemItem { 12586 final boolean isProc; 12587 final String label; 12588 final String shortLabel; 12589 final long pss; 12590 final int id; 12591 final boolean hasActivities; 12592 ArrayList<MemItem> subitems; 12593 12594 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12595 boolean _hasActivities) { 12596 isProc = true; 12597 label = _label; 12598 shortLabel = _shortLabel; 12599 pss = _pss; 12600 id = _id; 12601 hasActivities = _hasActivities; 12602 } 12603 12604 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12605 isProc = false; 12606 label = _label; 12607 shortLabel = _shortLabel; 12608 pss = _pss; 12609 id = _id; 12610 hasActivities = false; 12611 } 12612 } 12613 12614 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12615 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12616 if (sort && !isCompact) { 12617 Collections.sort(items, new Comparator<MemItem>() { 12618 @Override 12619 public int compare(MemItem lhs, MemItem rhs) { 12620 if (lhs.pss < rhs.pss) { 12621 return 1; 12622 } else if (lhs.pss > rhs.pss) { 12623 return -1; 12624 } 12625 return 0; 12626 } 12627 }); 12628 } 12629 12630 for (int i=0; i<items.size(); i++) { 12631 MemItem mi = items.get(i); 12632 if (!isCompact) { 12633 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12634 } else if (mi.isProc) { 12635 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12636 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12637 pw.println(mi.hasActivities ? ",a" : ",e"); 12638 } else { 12639 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12640 pw.println(mi.pss); 12641 } 12642 if (mi.subitems != null) { 12643 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12644 true, isCompact); 12645 } 12646 } 12647 } 12648 12649 // These are in KB. 12650 static final long[] DUMP_MEM_BUCKETS = new long[] { 12651 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12652 120*1024, 160*1024, 200*1024, 12653 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12654 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12655 }; 12656 12657 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12658 boolean stackLike) { 12659 int start = label.lastIndexOf('.'); 12660 if (start >= 0) start++; 12661 else start = 0; 12662 int end = label.length(); 12663 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12664 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12665 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12666 out.append(bucket); 12667 out.append(stackLike ? "MB." : "MB "); 12668 out.append(label, start, end); 12669 return; 12670 } 12671 } 12672 out.append(memKB/1024); 12673 out.append(stackLike ? "MB." : "MB "); 12674 out.append(label, start, end); 12675 } 12676 12677 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12678 ProcessList.NATIVE_ADJ, 12679 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12680 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12681 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12682 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12683 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12684 }; 12685 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12686 "Native", 12687 "System", "Persistent", "Foreground", 12688 "Visible", "Perceptible", 12689 "Heavy Weight", "Backup", 12690 "A Services", "Home", 12691 "Previous", "B Services", "Cached" 12692 }; 12693 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12694 "native", 12695 "sys", "pers", "fore", 12696 "vis", "percept", 12697 "heavy", "backup", 12698 "servicea", "home", 12699 "prev", "serviceb", "cached" 12700 }; 12701 12702 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12703 long realtime, boolean isCheckinRequest, boolean isCompact) { 12704 if (isCheckinRequest || isCompact) { 12705 // short checkin version 12706 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12707 } else { 12708 pw.println("Applications Memory Usage (kB):"); 12709 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12710 } 12711 } 12712 12713 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12714 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12715 boolean dumpDetails = false; 12716 boolean dumpFullDetails = false; 12717 boolean dumpDalvik = false; 12718 boolean oomOnly = false; 12719 boolean isCompact = false; 12720 boolean localOnly = false; 12721 12722 int opti = 0; 12723 while (opti < args.length) { 12724 String opt = args[opti]; 12725 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12726 break; 12727 } 12728 opti++; 12729 if ("-a".equals(opt)) { 12730 dumpDetails = true; 12731 dumpFullDetails = true; 12732 dumpDalvik = true; 12733 } else if ("-d".equals(opt)) { 12734 dumpDalvik = true; 12735 } else if ("-c".equals(opt)) { 12736 isCompact = true; 12737 } else if ("--oom".equals(opt)) { 12738 oomOnly = true; 12739 } else if ("--local".equals(opt)) { 12740 localOnly = true; 12741 } else if ("-h".equals(opt)) { 12742 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12743 pw.println(" -a: include all available information for each process."); 12744 pw.println(" -d: include dalvik details when dumping process details."); 12745 pw.println(" -c: dump in a compact machine-parseable representation."); 12746 pw.println(" --oom: only show processes organized by oom adj."); 12747 pw.println(" --local: only collect details locally, don't call process."); 12748 pw.println("If [process] is specified it can be the name or "); 12749 pw.println("pid of a specific process to dump."); 12750 return; 12751 } else { 12752 pw.println("Unknown argument: " + opt + "; use -h for help"); 12753 } 12754 } 12755 12756 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12757 long uptime = SystemClock.uptimeMillis(); 12758 long realtime = SystemClock.elapsedRealtime(); 12759 final long[] tmpLong = new long[1]; 12760 12761 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12762 if (procs == null) { 12763 // No Java processes. Maybe they want to print a native process. 12764 if (args != null && args.length > opti 12765 && args[opti].charAt(0) != '-') { 12766 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12767 = new ArrayList<ProcessCpuTracker.Stats>(); 12768 updateCpuStatsNow(); 12769 int findPid = -1; 12770 try { 12771 findPid = Integer.parseInt(args[opti]); 12772 } catch (NumberFormatException e) { 12773 } 12774 synchronized (mProcessCpuThread) { 12775 final int N = mProcessCpuTracker.countStats(); 12776 for (int i=0; i<N; i++) { 12777 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12778 if (st.pid == findPid || (st.baseName != null 12779 && st.baseName.equals(args[opti]))) { 12780 nativeProcs.add(st); 12781 } 12782 } 12783 } 12784 if (nativeProcs.size() > 0) { 12785 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12786 isCompact); 12787 Debug.MemoryInfo mi = null; 12788 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12789 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12790 final int pid = r.pid; 12791 if (!isCheckinRequest && dumpDetails) { 12792 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12793 } 12794 if (mi == null) { 12795 mi = new Debug.MemoryInfo(); 12796 } 12797 if (dumpDetails || (!brief && !oomOnly)) { 12798 Debug.getMemoryInfo(pid, mi); 12799 } else { 12800 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12801 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12802 } 12803 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12804 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12805 if (isCheckinRequest) { 12806 pw.println(); 12807 } 12808 } 12809 return; 12810 } 12811 } 12812 pw.println("No process found for: " + args[opti]); 12813 return; 12814 } 12815 12816 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12817 dumpDetails = true; 12818 } 12819 12820 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12821 12822 String[] innerArgs = new String[args.length-opti]; 12823 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12824 12825 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12826 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12827 long nativePss=0, dalvikPss=0, otherPss=0; 12828 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12829 12830 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12831 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12832 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12833 12834 long totalPss = 0; 12835 long cachedPss = 0; 12836 12837 Debug.MemoryInfo mi = null; 12838 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12839 final ProcessRecord r = procs.get(i); 12840 final IApplicationThread thread; 12841 final int pid; 12842 final int oomAdj; 12843 final boolean hasActivities; 12844 synchronized (this) { 12845 thread = r.thread; 12846 pid = r.pid; 12847 oomAdj = r.getSetAdjWithServices(); 12848 hasActivities = r.activities.size() > 0; 12849 } 12850 if (thread != null) { 12851 if (!isCheckinRequest && dumpDetails) { 12852 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12853 } 12854 if (mi == null) { 12855 mi = new Debug.MemoryInfo(); 12856 } 12857 if (dumpDetails || (!brief && !oomOnly)) { 12858 Debug.getMemoryInfo(pid, mi); 12859 } else { 12860 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12861 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12862 } 12863 if (dumpDetails) { 12864 if (localOnly) { 12865 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12866 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12867 if (isCheckinRequest) { 12868 pw.println(); 12869 } 12870 } else { 12871 try { 12872 pw.flush(); 12873 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12874 dumpDalvik, innerArgs); 12875 } catch (RemoteException e) { 12876 if (!isCheckinRequest) { 12877 pw.println("Got RemoteException!"); 12878 pw.flush(); 12879 } 12880 } 12881 } 12882 } 12883 12884 final long myTotalPss = mi.getTotalPss(); 12885 final long myTotalUss = mi.getTotalUss(); 12886 12887 synchronized (this) { 12888 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12889 // Record this for posterity if the process has been stable. 12890 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12891 } 12892 } 12893 12894 if (!isCheckinRequest && mi != null) { 12895 totalPss += myTotalPss; 12896 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12897 (hasActivities ? " / activities)" : ")"), 12898 r.processName, myTotalPss, pid, hasActivities); 12899 procMems.add(pssItem); 12900 procMemsMap.put(pid, pssItem); 12901 12902 nativePss += mi.nativePss; 12903 dalvikPss += mi.dalvikPss; 12904 otherPss += mi.otherPss; 12905 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12906 long mem = mi.getOtherPss(j); 12907 miscPss[j] += mem; 12908 otherPss -= mem; 12909 } 12910 12911 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12912 cachedPss += myTotalPss; 12913 } 12914 12915 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12916 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12917 || oomIndex == (oomPss.length-1)) { 12918 oomPss[oomIndex] += myTotalPss; 12919 if (oomProcs[oomIndex] == null) { 12920 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12921 } 12922 oomProcs[oomIndex].add(pssItem); 12923 break; 12924 } 12925 } 12926 } 12927 } 12928 } 12929 12930 long nativeProcTotalPss = 0; 12931 12932 if (!isCheckinRequest && procs.size() > 1) { 12933 // If we are showing aggregations, also look for native processes to 12934 // include so that our aggregations are more accurate. 12935 updateCpuStatsNow(); 12936 synchronized (mProcessCpuThread) { 12937 final int N = mProcessCpuTracker.countStats(); 12938 for (int i=0; i<N; i++) { 12939 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12940 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12941 if (mi == null) { 12942 mi = new Debug.MemoryInfo(); 12943 } 12944 if (!brief && !oomOnly) { 12945 Debug.getMemoryInfo(st.pid, mi); 12946 } else { 12947 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12948 mi.nativePrivateDirty = (int)tmpLong[0]; 12949 } 12950 12951 final long myTotalPss = mi.getTotalPss(); 12952 totalPss += myTotalPss; 12953 nativeProcTotalPss += myTotalPss; 12954 12955 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12956 st.name, myTotalPss, st.pid, false); 12957 procMems.add(pssItem); 12958 12959 nativePss += mi.nativePss; 12960 dalvikPss += mi.dalvikPss; 12961 otherPss += mi.otherPss; 12962 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12963 long mem = mi.getOtherPss(j); 12964 miscPss[j] += mem; 12965 otherPss -= mem; 12966 } 12967 oomPss[0] += myTotalPss; 12968 if (oomProcs[0] == null) { 12969 oomProcs[0] = new ArrayList<MemItem>(); 12970 } 12971 oomProcs[0].add(pssItem); 12972 } 12973 } 12974 } 12975 12976 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12977 12978 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12979 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12980 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12981 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12982 String label = Debug.MemoryInfo.getOtherLabel(j); 12983 catMems.add(new MemItem(label, label, miscPss[j], j)); 12984 } 12985 12986 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12987 for (int j=0; j<oomPss.length; j++) { 12988 if (oomPss[j] != 0) { 12989 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12990 : DUMP_MEM_OOM_LABEL[j]; 12991 MemItem item = new MemItem(label, label, oomPss[j], 12992 DUMP_MEM_OOM_ADJ[j]); 12993 item.subitems = oomProcs[j]; 12994 oomMems.add(item); 12995 } 12996 } 12997 12998 if (!brief && !oomOnly && !isCompact) { 12999 pw.println(); 13000 pw.println("Total PSS by process:"); 13001 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13002 pw.println(); 13003 } 13004 if (!isCompact) { 13005 pw.println("Total PSS by OOM adjustment:"); 13006 } 13007 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13008 if (!brief && !oomOnly) { 13009 PrintWriter out = categoryPw != null ? categoryPw : pw; 13010 if (!isCompact) { 13011 out.println(); 13012 out.println("Total PSS by category:"); 13013 } 13014 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13015 } 13016 if (!isCompact) { 13017 pw.println(); 13018 } 13019 MemInfoReader memInfo = new MemInfoReader(); 13020 memInfo.readMemInfo(); 13021 if (nativeProcTotalPss > 0) { 13022 synchronized (this) { 13023 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13024 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13025 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13026 nativeProcTotalPss); 13027 } 13028 } 13029 if (!brief) { 13030 if (!isCompact) { 13031 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13032 pw.print(" kB (status "); 13033 switch (mLastMemoryLevel) { 13034 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13035 pw.println("normal)"); 13036 break; 13037 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13038 pw.println("moderate)"); 13039 break; 13040 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13041 pw.println("low)"); 13042 break; 13043 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13044 pw.println("critical)"); 13045 break; 13046 default: 13047 pw.print(mLastMemoryLevel); 13048 pw.println(")"); 13049 break; 13050 } 13051 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13052 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13053 pw.print(cachedPss); pw.print(" cached pss + "); 13054 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13055 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13056 } else { 13057 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13058 pw.print(cachedPss + memInfo.getCachedSizeKb() 13059 + memInfo.getFreeSizeKb()); pw.print(","); 13060 pw.println(totalPss - cachedPss); 13061 } 13062 } 13063 if (!isCompact) { 13064 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13065 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13066 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13067 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13068 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13069 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13070 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13071 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13072 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13073 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13074 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13075 } 13076 if (!brief) { 13077 if (memInfo.getZramTotalSizeKb() != 0) { 13078 if (!isCompact) { 13079 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13080 pw.print(" kB physical used for "); 13081 pw.print(memInfo.getSwapTotalSizeKb() 13082 - memInfo.getSwapFreeSizeKb()); 13083 pw.print(" kB in swap ("); 13084 pw.print(memInfo.getSwapTotalSizeKb()); 13085 pw.println(" kB total swap)"); 13086 } else { 13087 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13088 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13089 pw.println(memInfo.getSwapFreeSizeKb()); 13090 } 13091 } 13092 final int[] SINGLE_LONG_FORMAT = new int[] { 13093 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13094 }; 13095 long[] longOut = new long[1]; 13096 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13097 SINGLE_LONG_FORMAT, null, longOut, null); 13098 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13099 longOut[0] = 0; 13100 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13101 SINGLE_LONG_FORMAT, null, longOut, null); 13102 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13103 longOut[0] = 0; 13104 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13105 SINGLE_LONG_FORMAT, null, longOut, null); 13106 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13107 longOut[0] = 0; 13108 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13109 SINGLE_LONG_FORMAT, null, longOut, null); 13110 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13111 if (!isCompact) { 13112 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13113 pw.print(" KSM: "); pw.print(sharing); 13114 pw.print(" kB saved from shared "); 13115 pw.print(shared); pw.println(" kB"); 13116 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13117 pw.print(voltile); pw.println(" kB volatile"); 13118 } 13119 pw.print(" Tuning: "); 13120 pw.print(ActivityManager.staticGetMemoryClass()); 13121 pw.print(" (large "); 13122 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13123 pw.print("), oom "); 13124 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13125 pw.print(" kB"); 13126 pw.print(", restore limit "); 13127 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13128 pw.print(" kB"); 13129 if (ActivityManager.isLowRamDeviceStatic()) { 13130 pw.print(" (low-ram)"); 13131 } 13132 if (ActivityManager.isHighEndGfx()) { 13133 pw.print(" (high-end-gfx)"); 13134 } 13135 pw.println(); 13136 } else { 13137 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13138 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13139 pw.println(voltile); 13140 pw.print("tuning,"); 13141 pw.print(ActivityManager.staticGetMemoryClass()); 13142 pw.print(','); 13143 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13144 pw.print(','); 13145 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13146 if (ActivityManager.isLowRamDeviceStatic()) { 13147 pw.print(",low-ram"); 13148 } 13149 if (ActivityManager.isHighEndGfx()) { 13150 pw.print(",high-end-gfx"); 13151 } 13152 pw.println(); 13153 } 13154 } 13155 } 13156 } 13157 13158 /** 13159 * Searches array of arguments for the specified string 13160 * @param args array of argument strings 13161 * @param value value to search for 13162 * @return true if the value is contained in the array 13163 */ 13164 private static boolean scanArgs(String[] args, String value) { 13165 if (args != null) { 13166 for (String arg : args) { 13167 if (value.equals(arg)) { 13168 return true; 13169 } 13170 } 13171 } 13172 return false; 13173 } 13174 13175 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13176 ContentProviderRecord cpr, boolean always) { 13177 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13178 13179 if (!inLaunching || always) { 13180 synchronized (cpr) { 13181 cpr.launchingApp = null; 13182 cpr.notifyAll(); 13183 } 13184 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13185 String names[] = cpr.info.authority.split(";"); 13186 for (int j = 0; j < names.length; j++) { 13187 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13188 } 13189 } 13190 13191 for (int i=0; i<cpr.connections.size(); i++) { 13192 ContentProviderConnection conn = cpr.connections.get(i); 13193 if (conn.waiting) { 13194 // If this connection is waiting for the provider, then we don't 13195 // need to mess with its process unless we are always removing 13196 // or for some reason the provider is not currently launching. 13197 if (inLaunching && !always) { 13198 continue; 13199 } 13200 } 13201 ProcessRecord capp = conn.client; 13202 conn.dead = true; 13203 if (conn.stableCount > 0) { 13204 if (!capp.persistent && capp.thread != null 13205 && capp.pid != 0 13206 && capp.pid != MY_PID) { 13207 killUnneededProcessLocked(capp, "depends on provider " 13208 + cpr.name.flattenToShortString() 13209 + " in dying proc " + (proc != null ? proc.processName : "??")); 13210 } 13211 } else if (capp.thread != null && conn.provider.provider != null) { 13212 try { 13213 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13214 } catch (RemoteException e) { 13215 } 13216 // In the protocol here, we don't expect the client to correctly 13217 // clean up this connection, we'll just remove it. 13218 cpr.connections.remove(i); 13219 conn.client.conProviders.remove(conn); 13220 } 13221 } 13222 13223 if (inLaunching && always) { 13224 mLaunchingProviders.remove(cpr); 13225 } 13226 return inLaunching; 13227 } 13228 13229 /** 13230 * Main code for cleaning up a process when it has gone away. This is 13231 * called both as a result of the process dying, or directly when stopping 13232 * a process when running in single process mode. 13233 */ 13234 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13235 boolean restarting, boolean allowRestart, int index) { 13236 if (index >= 0) { 13237 removeLruProcessLocked(app); 13238 ProcessList.remove(app.pid); 13239 } 13240 13241 mProcessesToGc.remove(app); 13242 mPendingPssProcesses.remove(app); 13243 13244 // Dismiss any open dialogs. 13245 if (app.crashDialog != null && !app.forceCrashReport) { 13246 app.crashDialog.dismiss(); 13247 app.crashDialog = null; 13248 } 13249 if (app.anrDialog != null) { 13250 app.anrDialog.dismiss(); 13251 app.anrDialog = null; 13252 } 13253 if (app.waitDialog != null) { 13254 app.waitDialog.dismiss(); 13255 app.waitDialog = null; 13256 } 13257 13258 app.crashing = false; 13259 app.notResponding = false; 13260 13261 app.resetPackageList(mProcessStats); 13262 app.unlinkDeathRecipient(); 13263 app.makeInactive(mProcessStats); 13264 app.waitingToKill = null; 13265 app.forcingToForeground = null; 13266 updateProcessForegroundLocked(app, false, false); 13267 app.foregroundActivities = false; 13268 app.hasShownUi = false; 13269 app.treatLikeActivity = false; 13270 app.hasAboveClient = false; 13271 app.hasClientActivities = false; 13272 13273 mServices.killServicesLocked(app, allowRestart); 13274 13275 boolean restart = false; 13276 13277 // Remove published content providers. 13278 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13279 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13280 final boolean always = app.bad || !allowRestart; 13281 if (removeDyingProviderLocked(app, cpr, always) || always) { 13282 // We left the provider in the launching list, need to 13283 // restart it. 13284 restart = true; 13285 } 13286 13287 cpr.provider = null; 13288 cpr.proc = null; 13289 } 13290 app.pubProviders.clear(); 13291 13292 // Take care of any launching providers waiting for this process. 13293 if (checkAppInLaunchingProvidersLocked(app, false)) { 13294 restart = true; 13295 } 13296 13297 // Unregister from connected content providers. 13298 if (!app.conProviders.isEmpty()) { 13299 for (int i=0; i<app.conProviders.size(); i++) { 13300 ContentProviderConnection conn = app.conProviders.get(i); 13301 conn.provider.connections.remove(conn); 13302 } 13303 app.conProviders.clear(); 13304 } 13305 13306 // At this point there may be remaining entries in mLaunchingProviders 13307 // where we were the only one waiting, so they are no longer of use. 13308 // Look for these and clean up if found. 13309 // XXX Commented out for now. Trying to figure out a way to reproduce 13310 // the actual situation to identify what is actually going on. 13311 if (false) { 13312 for (int i=0; i<mLaunchingProviders.size(); i++) { 13313 ContentProviderRecord cpr = (ContentProviderRecord) 13314 mLaunchingProviders.get(i); 13315 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13316 synchronized (cpr) { 13317 cpr.launchingApp = null; 13318 cpr.notifyAll(); 13319 } 13320 } 13321 } 13322 } 13323 13324 skipCurrentReceiverLocked(app); 13325 13326 // Unregister any receivers. 13327 for (int i=app.receivers.size()-1; i>=0; i--) { 13328 removeReceiverLocked(app.receivers.valueAt(i)); 13329 } 13330 app.receivers.clear(); 13331 13332 // If the app is undergoing backup, tell the backup manager about it 13333 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13334 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13335 + mBackupTarget.appInfo + " died during backup"); 13336 try { 13337 IBackupManager bm = IBackupManager.Stub.asInterface( 13338 ServiceManager.getService(Context.BACKUP_SERVICE)); 13339 bm.agentDisconnected(app.info.packageName); 13340 } catch (RemoteException e) { 13341 // can't happen; backup manager is local 13342 } 13343 } 13344 13345 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13346 ProcessChangeItem item = mPendingProcessChanges.get(i); 13347 if (item.pid == app.pid) { 13348 mPendingProcessChanges.remove(i); 13349 mAvailProcessChanges.add(item); 13350 } 13351 } 13352 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13353 13354 // If the caller is restarting this app, then leave it in its 13355 // current lists and let the caller take care of it. 13356 if (restarting) { 13357 return; 13358 } 13359 13360 if (!app.persistent || app.isolated) { 13361 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13362 "Removing non-persistent process during cleanup: " + app); 13363 mProcessNames.remove(app.processName, app.uid); 13364 mIsolatedProcesses.remove(app.uid); 13365 if (mHeavyWeightProcess == app) { 13366 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13367 mHeavyWeightProcess.userId, 0)); 13368 mHeavyWeightProcess = null; 13369 } 13370 } else if (!app.removed) { 13371 // This app is persistent, so we need to keep its record around. 13372 // If it is not already on the pending app list, add it there 13373 // and start a new process for it. 13374 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13375 mPersistentStartingProcesses.add(app); 13376 restart = true; 13377 } 13378 } 13379 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13380 "Clean-up removing on hold: " + app); 13381 mProcessesOnHold.remove(app); 13382 13383 if (app == mHomeProcess) { 13384 mHomeProcess = null; 13385 } 13386 if (app == mPreviousProcess) { 13387 mPreviousProcess = null; 13388 } 13389 13390 if (restart && !app.isolated) { 13391 // We have components that still need to be running in the 13392 // process, so re-launch it. 13393 mProcessNames.put(app.processName, app.uid, app); 13394 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13395 } else if (app.pid > 0 && app.pid != MY_PID) { 13396 // Goodbye! 13397 boolean removed; 13398 synchronized (mPidsSelfLocked) { 13399 mPidsSelfLocked.remove(app.pid); 13400 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13401 } 13402 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13403 if (app.isolated) { 13404 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13405 } 13406 app.setPid(0); 13407 } 13408 } 13409 13410 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13411 // Look through the content providers we are waiting to have launched, 13412 // and if any run in this process then either schedule a restart of 13413 // the process or kill the client waiting for it if this process has 13414 // gone bad. 13415 int NL = mLaunchingProviders.size(); 13416 boolean restart = false; 13417 for (int i=0; i<NL; i++) { 13418 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13419 if (cpr.launchingApp == app) { 13420 if (!alwaysBad && !app.bad) { 13421 restart = true; 13422 } else { 13423 removeDyingProviderLocked(app, cpr, true); 13424 // cpr should have been removed from mLaunchingProviders 13425 NL = mLaunchingProviders.size(); 13426 i--; 13427 } 13428 } 13429 } 13430 return restart; 13431 } 13432 13433 // ========================================================= 13434 // SERVICES 13435 // ========================================================= 13436 13437 @Override 13438 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13439 int flags) { 13440 enforceNotIsolatedCaller("getServices"); 13441 synchronized (this) { 13442 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13443 } 13444 } 13445 13446 @Override 13447 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13448 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13449 synchronized (this) { 13450 return mServices.getRunningServiceControlPanelLocked(name); 13451 } 13452 } 13453 13454 @Override 13455 public ComponentName startService(IApplicationThread caller, Intent service, 13456 String resolvedType, int userId) { 13457 enforceNotIsolatedCaller("startService"); 13458 // Refuse possible leaked file descriptors 13459 if (service != null && service.hasFileDescriptors() == true) { 13460 throw new IllegalArgumentException("File descriptors passed in Intent"); 13461 } 13462 13463 if (DEBUG_SERVICE) 13464 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13465 synchronized(this) { 13466 final int callingPid = Binder.getCallingPid(); 13467 final int callingUid = Binder.getCallingUid(); 13468 final long origId = Binder.clearCallingIdentity(); 13469 ComponentName res = mServices.startServiceLocked(caller, service, 13470 resolvedType, callingPid, callingUid, userId); 13471 Binder.restoreCallingIdentity(origId); 13472 return res; 13473 } 13474 } 13475 13476 ComponentName startServiceInPackage(int uid, 13477 Intent service, String resolvedType, int userId) { 13478 synchronized(this) { 13479 if (DEBUG_SERVICE) 13480 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13481 final long origId = Binder.clearCallingIdentity(); 13482 ComponentName res = mServices.startServiceLocked(null, service, 13483 resolvedType, -1, uid, userId); 13484 Binder.restoreCallingIdentity(origId); 13485 return res; 13486 } 13487 } 13488 13489 @Override 13490 public int stopService(IApplicationThread caller, Intent service, 13491 String resolvedType, int userId) { 13492 enforceNotIsolatedCaller("stopService"); 13493 // Refuse possible leaked file descriptors 13494 if (service != null && service.hasFileDescriptors() == true) { 13495 throw new IllegalArgumentException("File descriptors passed in Intent"); 13496 } 13497 13498 synchronized(this) { 13499 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13500 } 13501 } 13502 13503 @Override 13504 public IBinder peekService(Intent service, String resolvedType) { 13505 enforceNotIsolatedCaller("peekService"); 13506 // Refuse possible leaked file descriptors 13507 if (service != null && service.hasFileDescriptors() == true) { 13508 throw new IllegalArgumentException("File descriptors passed in Intent"); 13509 } 13510 synchronized(this) { 13511 return mServices.peekServiceLocked(service, resolvedType); 13512 } 13513 } 13514 13515 @Override 13516 public boolean stopServiceToken(ComponentName className, IBinder token, 13517 int startId) { 13518 synchronized(this) { 13519 return mServices.stopServiceTokenLocked(className, token, startId); 13520 } 13521 } 13522 13523 @Override 13524 public void setServiceForeground(ComponentName className, IBinder token, 13525 int id, Notification notification, boolean removeNotification) { 13526 synchronized(this) { 13527 mServices.setServiceForegroundLocked(className, token, id, notification, 13528 removeNotification); 13529 } 13530 } 13531 13532 @Override 13533 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13534 boolean requireFull, String name, String callerPackage) { 13535 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13536 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13537 } 13538 13539 int unsafeConvertIncomingUser(int userId) { 13540 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13541 ? mCurrentUserId : userId; 13542 } 13543 13544 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13545 int allowMode, String name, String callerPackage) { 13546 final int callingUserId = UserHandle.getUserId(callingUid); 13547 if (callingUserId == userId) { 13548 return userId; 13549 } 13550 13551 // Note that we may be accessing mCurrentUserId outside of a lock... 13552 // shouldn't be a big deal, if this is being called outside 13553 // of a locked context there is intrinsically a race with 13554 // the value the caller will receive and someone else changing it. 13555 // We assume that USER_CURRENT_OR_SELF will use the current user; later 13556 // we will switch to the calling user if access to the current user fails. 13557 int targetUserId = unsafeConvertIncomingUser(userId); 13558 13559 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13560 final boolean allow; 13561 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 13562 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 13563 // If the caller has this permission, they always pass go. And collect $200. 13564 allow = true; 13565 } else if (allowMode == ALLOW_FULL_ONLY) { 13566 // We require full access, sucks to be you. 13567 allow = false; 13568 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 13569 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 13570 // If the caller does not have either permission, they are always doomed. 13571 allow = false; 13572 } else if (allowMode == ALLOW_NON_FULL) { 13573 // We are blanket allowing non-full access, you lucky caller! 13574 allow = true; 13575 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 13576 // We may or may not allow this depending on whether the two users are 13577 // in the same profile. 13578 synchronized (mUserProfileGroupIdsSelfLocked) { 13579 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 13580 UserInfo.NO_PROFILE_GROUP_ID); 13581 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 13582 UserInfo.NO_PROFILE_GROUP_ID); 13583 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 13584 && callingProfile == targetProfile; 13585 } 13586 } else { 13587 throw new IllegalArgumentException("Unknown mode: " + allowMode); 13588 } 13589 if (!allow) { 13590 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13591 // In this case, they would like to just execute as their 13592 // owner user instead of failing. 13593 targetUserId = callingUserId; 13594 } else { 13595 StringBuilder builder = new StringBuilder(128); 13596 builder.append("Permission Denial: "); 13597 builder.append(name); 13598 if (callerPackage != null) { 13599 builder.append(" from "); 13600 builder.append(callerPackage); 13601 } 13602 builder.append(" asks to run as user "); 13603 builder.append(userId); 13604 builder.append(" but is calling from user "); 13605 builder.append(UserHandle.getUserId(callingUid)); 13606 builder.append("; this requires "); 13607 builder.append(INTERACT_ACROSS_USERS_FULL); 13608 if (allowMode != ALLOW_FULL_ONLY) { 13609 builder.append(" or "); 13610 builder.append(INTERACT_ACROSS_USERS); 13611 } 13612 String msg = builder.toString(); 13613 Slog.w(TAG, msg); 13614 throw new SecurityException(msg); 13615 } 13616 } 13617 } 13618 if (!allowAll && targetUserId < 0) { 13619 throw new IllegalArgumentException( 13620 "Call does not support special user #" + targetUserId); 13621 } 13622 return targetUserId; 13623 } 13624 13625 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13626 String className, int flags) { 13627 boolean result = false; 13628 // For apps that don't have pre-defined UIDs, check for permission 13629 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13630 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13631 if (ActivityManager.checkUidPermission( 13632 INTERACT_ACROSS_USERS, 13633 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13634 ComponentName comp = new ComponentName(aInfo.packageName, className); 13635 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13636 + " requests FLAG_SINGLE_USER, but app does not hold " 13637 + INTERACT_ACROSS_USERS; 13638 Slog.w(TAG, msg); 13639 throw new SecurityException(msg); 13640 } 13641 // Permission passed 13642 result = true; 13643 } 13644 } else if ("system".equals(componentProcessName)) { 13645 result = true; 13646 } else { 13647 // App with pre-defined UID, check if it's a persistent app 13648 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13649 } 13650 if (DEBUG_MU) { 13651 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13652 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13653 } 13654 return result; 13655 } 13656 13657 /** 13658 * Checks to see if the caller is in the same app as the singleton 13659 * component, or the component is in a special app. It allows special apps 13660 * to export singleton components but prevents exporting singleton 13661 * components for regular apps. 13662 */ 13663 boolean isValidSingletonCall(int callingUid, int componentUid) { 13664 int componentAppId = UserHandle.getAppId(componentUid); 13665 return UserHandle.isSameApp(callingUid, componentUid) 13666 || componentAppId == Process.SYSTEM_UID 13667 || componentAppId == Process.PHONE_UID 13668 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13669 == PackageManager.PERMISSION_GRANTED; 13670 } 13671 13672 public int bindService(IApplicationThread caller, IBinder token, 13673 Intent service, String resolvedType, 13674 IServiceConnection connection, int flags, int userId) { 13675 enforceNotIsolatedCaller("bindService"); 13676 // Refuse possible leaked file descriptors 13677 if (service != null && service.hasFileDescriptors() == true) { 13678 throw new IllegalArgumentException("File descriptors passed in Intent"); 13679 } 13680 13681 synchronized(this) { 13682 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13683 connection, flags, userId); 13684 } 13685 } 13686 13687 public boolean unbindService(IServiceConnection connection) { 13688 synchronized (this) { 13689 return mServices.unbindServiceLocked(connection); 13690 } 13691 } 13692 13693 public void publishService(IBinder token, Intent intent, IBinder service) { 13694 // Refuse possible leaked file descriptors 13695 if (intent != null && intent.hasFileDescriptors() == true) { 13696 throw new IllegalArgumentException("File descriptors passed in Intent"); 13697 } 13698 13699 synchronized(this) { 13700 if (!(token instanceof ServiceRecord)) { 13701 throw new IllegalArgumentException("Invalid service token"); 13702 } 13703 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13704 } 13705 } 13706 13707 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13708 // Refuse possible leaked file descriptors 13709 if (intent != null && intent.hasFileDescriptors() == true) { 13710 throw new IllegalArgumentException("File descriptors passed in Intent"); 13711 } 13712 13713 synchronized(this) { 13714 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13715 } 13716 } 13717 13718 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13719 synchronized(this) { 13720 if (!(token instanceof ServiceRecord)) { 13721 throw new IllegalArgumentException("Invalid service token"); 13722 } 13723 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13724 } 13725 } 13726 13727 // ========================================================= 13728 // BACKUP AND RESTORE 13729 // ========================================================= 13730 13731 // Cause the target app to be launched if necessary and its backup agent 13732 // instantiated. The backup agent will invoke backupAgentCreated() on the 13733 // activity manager to announce its creation. 13734 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13735 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13736 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13737 13738 synchronized(this) { 13739 // !!! TODO: currently no check here that we're already bound 13740 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13741 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13742 synchronized (stats) { 13743 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13744 } 13745 13746 // Backup agent is now in use, its package can't be stopped. 13747 try { 13748 AppGlobals.getPackageManager().setPackageStoppedState( 13749 app.packageName, false, UserHandle.getUserId(app.uid)); 13750 } catch (RemoteException e) { 13751 } catch (IllegalArgumentException e) { 13752 Slog.w(TAG, "Failed trying to unstop package " 13753 + app.packageName + ": " + e); 13754 } 13755 13756 BackupRecord r = new BackupRecord(ss, app, backupMode); 13757 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13758 ? new ComponentName(app.packageName, app.backupAgentName) 13759 : new ComponentName("android", "FullBackupAgent"); 13760 // startProcessLocked() returns existing proc's record if it's already running 13761 ProcessRecord proc = startProcessLocked(app.processName, app, 13762 false, 0, "backup", hostingName, false, false, false); 13763 if (proc == null) { 13764 Slog.e(TAG, "Unable to start backup agent process " + r); 13765 return false; 13766 } 13767 13768 r.app = proc; 13769 mBackupTarget = r; 13770 mBackupAppName = app.packageName; 13771 13772 // Try not to kill the process during backup 13773 updateOomAdjLocked(proc); 13774 13775 // If the process is already attached, schedule the creation of the backup agent now. 13776 // If it is not yet live, this will be done when it attaches to the framework. 13777 if (proc.thread != null) { 13778 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13779 try { 13780 proc.thread.scheduleCreateBackupAgent(app, 13781 compatibilityInfoForPackageLocked(app), backupMode); 13782 } catch (RemoteException e) { 13783 // Will time out on the backup manager side 13784 } 13785 } else { 13786 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13787 } 13788 // Invariants: at this point, the target app process exists and the application 13789 // is either already running or in the process of coming up. mBackupTarget and 13790 // mBackupAppName describe the app, so that when it binds back to the AM we 13791 // know that it's scheduled for a backup-agent operation. 13792 } 13793 13794 return true; 13795 } 13796 13797 @Override 13798 public void clearPendingBackup() { 13799 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13800 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13801 13802 synchronized (this) { 13803 mBackupTarget = null; 13804 mBackupAppName = null; 13805 } 13806 } 13807 13808 // A backup agent has just come up 13809 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13810 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13811 + " = " + agent); 13812 13813 synchronized(this) { 13814 if (!agentPackageName.equals(mBackupAppName)) { 13815 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13816 return; 13817 } 13818 } 13819 13820 long oldIdent = Binder.clearCallingIdentity(); 13821 try { 13822 IBackupManager bm = IBackupManager.Stub.asInterface( 13823 ServiceManager.getService(Context.BACKUP_SERVICE)); 13824 bm.agentConnected(agentPackageName, agent); 13825 } catch (RemoteException e) { 13826 // can't happen; the backup manager service is local 13827 } catch (Exception e) { 13828 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13829 e.printStackTrace(); 13830 } finally { 13831 Binder.restoreCallingIdentity(oldIdent); 13832 } 13833 } 13834 13835 // done with this agent 13836 public void unbindBackupAgent(ApplicationInfo appInfo) { 13837 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13838 if (appInfo == null) { 13839 Slog.w(TAG, "unbind backup agent for null app"); 13840 return; 13841 } 13842 13843 synchronized(this) { 13844 try { 13845 if (mBackupAppName == null) { 13846 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13847 return; 13848 } 13849 13850 if (!mBackupAppName.equals(appInfo.packageName)) { 13851 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13852 return; 13853 } 13854 13855 // Not backing this app up any more; reset its OOM adjustment 13856 final ProcessRecord proc = mBackupTarget.app; 13857 updateOomAdjLocked(proc); 13858 13859 // If the app crashed during backup, 'thread' will be null here 13860 if (proc.thread != null) { 13861 try { 13862 proc.thread.scheduleDestroyBackupAgent(appInfo, 13863 compatibilityInfoForPackageLocked(appInfo)); 13864 } catch (Exception e) { 13865 Slog.e(TAG, "Exception when unbinding backup agent:"); 13866 e.printStackTrace(); 13867 } 13868 } 13869 } finally { 13870 mBackupTarget = null; 13871 mBackupAppName = null; 13872 } 13873 } 13874 } 13875 // ========================================================= 13876 // BROADCASTS 13877 // ========================================================= 13878 13879 private final List getStickiesLocked(String action, IntentFilter filter, 13880 List cur, int userId) { 13881 final ContentResolver resolver = mContext.getContentResolver(); 13882 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13883 if (stickies == null) { 13884 return cur; 13885 } 13886 final ArrayList<Intent> list = stickies.get(action); 13887 if (list == null) { 13888 return cur; 13889 } 13890 int N = list.size(); 13891 for (int i=0; i<N; i++) { 13892 Intent intent = list.get(i); 13893 if (filter.match(resolver, intent, true, TAG) >= 0) { 13894 if (cur == null) { 13895 cur = new ArrayList<Intent>(); 13896 } 13897 cur.add(intent); 13898 } 13899 } 13900 return cur; 13901 } 13902 13903 boolean isPendingBroadcastProcessLocked(int pid) { 13904 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13905 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13906 } 13907 13908 void skipPendingBroadcastLocked(int pid) { 13909 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13910 for (BroadcastQueue queue : mBroadcastQueues) { 13911 queue.skipPendingBroadcastLocked(pid); 13912 } 13913 } 13914 13915 // The app just attached; send any pending broadcasts that it should receive 13916 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13917 boolean didSomething = false; 13918 for (BroadcastQueue queue : mBroadcastQueues) { 13919 didSomething |= queue.sendPendingBroadcastsLocked(app); 13920 } 13921 return didSomething; 13922 } 13923 13924 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13925 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13926 enforceNotIsolatedCaller("registerReceiver"); 13927 int callingUid; 13928 int callingPid; 13929 synchronized(this) { 13930 ProcessRecord callerApp = null; 13931 if (caller != null) { 13932 callerApp = getRecordForAppLocked(caller); 13933 if (callerApp == null) { 13934 throw new SecurityException( 13935 "Unable to find app for caller " + caller 13936 + " (pid=" + Binder.getCallingPid() 13937 + ") when registering receiver " + receiver); 13938 } 13939 if (callerApp.info.uid != Process.SYSTEM_UID && 13940 !callerApp.pkgList.containsKey(callerPackage) && 13941 !"android".equals(callerPackage)) { 13942 throw new SecurityException("Given caller package " + callerPackage 13943 + " is not running in process " + callerApp); 13944 } 13945 callingUid = callerApp.info.uid; 13946 callingPid = callerApp.pid; 13947 } else { 13948 callerPackage = null; 13949 callingUid = Binder.getCallingUid(); 13950 callingPid = Binder.getCallingPid(); 13951 } 13952 13953 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13954 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 13955 13956 List allSticky = null; 13957 13958 // Look for any matching sticky broadcasts... 13959 Iterator actions = filter.actionsIterator(); 13960 if (actions != null) { 13961 while (actions.hasNext()) { 13962 String action = (String)actions.next(); 13963 allSticky = getStickiesLocked(action, filter, allSticky, 13964 UserHandle.USER_ALL); 13965 allSticky = getStickiesLocked(action, filter, allSticky, 13966 UserHandle.getUserId(callingUid)); 13967 } 13968 } else { 13969 allSticky = getStickiesLocked(null, filter, allSticky, 13970 UserHandle.USER_ALL); 13971 allSticky = getStickiesLocked(null, filter, allSticky, 13972 UserHandle.getUserId(callingUid)); 13973 } 13974 13975 // The first sticky in the list is returned directly back to 13976 // the client. 13977 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13978 13979 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13980 + ": " + sticky); 13981 13982 if (receiver == null) { 13983 return sticky; 13984 } 13985 13986 ReceiverList rl 13987 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13988 if (rl == null) { 13989 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13990 userId, receiver); 13991 if (rl.app != null) { 13992 rl.app.receivers.add(rl); 13993 } else { 13994 try { 13995 receiver.asBinder().linkToDeath(rl, 0); 13996 } catch (RemoteException e) { 13997 return sticky; 13998 } 13999 rl.linkedToDeath = true; 14000 } 14001 mRegisteredReceivers.put(receiver.asBinder(), rl); 14002 } else if (rl.uid != callingUid) { 14003 throw new IllegalArgumentException( 14004 "Receiver requested to register for uid " + callingUid 14005 + " was previously registered for uid " + rl.uid); 14006 } else if (rl.pid != callingPid) { 14007 throw new IllegalArgumentException( 14008 "Receiver requested to register for pid " + callingPid 14009 + " was previously registered for pid " + rl.pid); 14010 } else if (rl.userId != userId) { 14011 throw new IllegalArgumentException( 14012 "Receiver requested to register for user " + userId 14013 + " was previously registered for user " + rl.userId); 14014 } 14015 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14016 permission, callingUid, userId); 14017 rl.add(bf); 14018 if (!bf.debugCheck()) { 14019 Slog.w(TAG, "==> For Dynamic broadast"); 14020 } 14021 mReceiverResolver.addFilter(bf); 14022 14023 // Enqueue broadcasts for all existing stickies that match 14024 // this filter. 14025 if (allSticky != null) { 14026 ArrayList receivers = new ArrayList(); 14027 receivers.add(bf); 14028 14029 int N = allSticky.size(); 14030 for (int i=0; i<N; i++) { 14031 Intent intent = (Intent)allSticky.get(i); 14032 BroadcastQueue queue = broadcastQueueForIntent(intent); 14033 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14034 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14035 null, null, false, true, true, -1); 14036 queue.enqueueParallelBroadcastLocked(r); 14037 queue.scheduleBroadcastsLocked(); 14038 } 14039 } 14040 14041 return sticky; 14042 } 14043 } 14044 14045 public void unregisterReceiver(IIntentReceiver receiver) { 14046 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14047 14048 final long origId = Binder.clearCallingIdentity(); 14049 try { 14050 boolean doTrim = false; 14051 14052 synchronized(this) { 14053 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14054 if (rl != null) { 14055 if (rl.curBroadcast != null) { 14056 BroadcastRecord r = rl.curBroadcast; 14057 final boolean doNext = finishReceiverLocked( 14058 receiver.asBinder(), r.resultCode, r.resultData, 14059 r.resultExtras, r.resultAbort); 14060 if (doNext) { 14061 doTrim = true; 14062 r.queue.processNextBroadcast(false); 14063 } 14064 } 14065 14066 if (rl.app != null) { 14067 rl.app.receivers.remove(rl); 14068 } 14069 removeReceiverLocked(rl); 14070 if (rl.linkedToDeath) { 14071 rl.linkedToDeath = false; 14072 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14073 } 14074 } 14075 } 14076 14077 // If we actually concluded any broadcasts, we might now be able 14078 // to trim the recipients' apps from our working set 14079 if (doTrim) { 14080 trimApplications(); 14081 return; 14082 } 14083 14084 } finally { 14085 Binder.restoreCallingIdentity(origId); 14086 } 14087 } 14088 14089 void removeReceiverLocked(ReceiverList rl) { 14090 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14091 int N = rl.size(); 14092 for (int i=0; i<N; i++) { 14093 mReceiverResolver.removeFilter(rl.get(i)); 14094 } 14095 } 14096 14097 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14098 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14099 ProcessRecord r = mLruProcesses.get(i); 14100 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14101 try { 14102 r.thread.dispatchPackageBroadcast(cmd, packages); 14103 } catch (RemoteException ex) { 14104 } 14105 } 14106 } 14107 } 14108 14109 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14110 int[] users) { 14111 List<ResolveInfo> receivers = null; 14112 try { 14113 HashSet<ComponentName> singleUserReceivers = null; 14114 boolean scannedFirstReceivers = false; 14115 for (int user : users) { 14116 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14117 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14118 if (user != 0 && newReceivers != null) { 14119 // If this is not the primary user, we need to check for 14120 // any receivers that should be filtered out. 14121 for (int i=0; i<newReceivers.size(); i++) { 14122 ResolveInfo ri = newReceivers.get(i); 14123 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14124 newReceivers.remove(i); 14125 i--; 14126 } 14127 } 14128 } 14129 if (newReceivers != null && newReceivers.size() == 0) { 14130 newReceivers = null; 14131 } 14132 if (receivers == null) { 14133 receivers = newReceivers; 14134 } else if (newReceivers != null) { 14135 // We need to concatenate the additional receivers 14136 // found with what we have do far. This would be easy, 14137 // but we also need to de-dup any receivers that are 14138 // singleUser. 14139 if (!scannedFirstReceivers) { 14140 // Collect any single user receivers we had already retrieved. 14141 scannedFirstReceivers = true; 14142 for (int i=0; i<receivers.size(); i++) { 14143 ResolveInfo ri = receivers.get(i); 14144 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14145 ComponentName cn = new ComponentName( 14146 ri.activityInfo.packageName, ri.activityInfo.name); 14147 if (singleUserReceivers == null) { 14148 singleUserReceivers = new HashSet<ComponentName>(); 14149 } 14150 singleUserReceivers.add(cn); 14151 } 14152 } 14153 } 14154 // Add the new results to the existing results, tracking 14155 // and de-dupping single user receivers. 14156 for (int i=0; i<newReceivers.size(); i++) { 14157 ResolveInfo ri = newReceivers.get(i); 14158 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14159 ComponentName cn = new ComponentName( 14160 ri.activityInfo.packageName, ri.activityInfo.name); 14161 if (singleUserReceivers == null) { 14162 singleUserReceivers = new HashSet<ComponentName>(); 14163 } 14164 if (!singleUserReceivers.contains(cn)) { 14165 singleUserReceivers.add(cn); 14166 receivers.add(ri); 14167 } 14168 } else { 14169 receivers.add(ri); 14170 } 14171 } 14172 } 14173 } 14174 } catch (RemoteException ex) { 14175 // pm is in same process, this will never happen. 14176 } 14177 return receivers; 14178 } 14179 14180 private final int broadcastIntentLocked(ProcessRecord callerApp, 14181 String callerPackage, Intent intent, String resolvedType, 14182 IIntentReceiver resultTo, int resultCode, String resultData, 14183 Bundle map, String requiredPermission, int appOp, 14184 boolean ordered, boolean sticky, int callingPid, int callingUid, 14185 int userId) { 14186 intent = new Intent(intent); 14187 14188 // By default broadcasts do not go to stopped apps. 14189 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14190 14191 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14192 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14193 + " ordered=" + ordered + " userid=" + userId); 14194 if ((resultTo != null) && !ordered) { 14195 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14196 } 14197 14198 userId = handleIncomingUser(callingPid, callingUid, userId, 14199 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14200 14201 // Make sure that the user who is receiving this broadcast is started. 14202 // If not, we will just skip it. 14203 14204 14205 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14206 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14207 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14208 Slog.w(TAG, "Skipping broadcast of " + intent 14209 + ": user " + userId + " is stopped"); 14210 return ActivityManager.BROADCAST_SUCCESS; 14211 } 14212 } 14213 14214 /* 14215 * Prevent non-system code (defined here to be non-persistent 14216 * processes) from sending protected broadcasts. 14217 */ 14218 int callingAppId = UserHandle.getAppId(callingUid); 14219 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14220 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14221 || callingAppId == Process.NFC_UID || callingUid == 0) { 14222 // Always okay. 14223 } else if (callerApp == null || !callerApp.persistent) { 14224 try { 14225 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14226 intent.getAction())) { 14227 String msg = "Permission Denial: not allowed to send broadcast " 14228 + intent.getAction() + " from pid=" 14229 + callingPid + ", uid=" + callingUid; 14230 Slog.w(TAG, msg); 14231 throw new SecurityException(msg); 14232 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14233 // Special case for compatibility: we don't want apps to send this, 14234 // but historically it has not been protected and apps may be using it 14235 // to poke their own app widget. So, instead of making it protected, 14236 // just limit it to the caller. 14237 if (callerApp == null) { 14238 String msg = "Permission Denial: not allowed to send broadcast " 14239 + intent.getAction() + " from unknown caller."; 14240 Slog.w(TAG, msg); 14241 throw new SecurityException(msg); 14242 } else if (intent.getComponent() != null) { 14243 // They are good enough to send to an explicit component... verify 14244 // it is being sent to the calling app. 14245 if (!intent.getComponent().getPackageName().equals( 14246 callerApp.info.packageName)) { 14247 String msg = "Permission Denial: not allowed to send broadcast " 14248 + intent.getAction() + " to " 14249 + intent.getComponent().getPackageName() + " from " 14250 + callerApp.info.packageName; 14251 Slog.w(TAG, msg); 14252 throw new SecurityException(msg); 14253 } 14254 } else { 14255 // Limit broadcast to their own package. 14256 intent.setPackage(callerApp.info.packageName); 14257 } 14258 } 14259 } catch (RemoteException e) { 14260 Slog.w(TAG, "Remote exception", e); 14261 return ActivityManager.BROADCAST_SUCCESS; 14262 } 14263 } 14264 14265 // Handle special intents: if this broadcast is from the package 14266 // manager about a package being removed, we need to remove all of 14267 // its activities from the history stack. 14268 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14269 intent.getAction()); 14270 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14271 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14272 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14273 || uidRemoved) { 14274 if (checkComponentPermission( 14275 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14276 callingPid, callingUid, -1, true) 14277 == PackageManager.PERMISSION_GRANTED) { 14278 if (uidRemoved) { 14279 final Bundle intentExtras = intent.getExtras(); 14280 final int uid = intentExtras != null 14281 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14282 if (uid >= 0) { 14283 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14284 synchronized (bs) { 14285 bs.removeUidStatsLocked(uid); 14286 } 14287 mAppOpsService.uidRemoved(uid); 14288 } 14289 } else { 14290 // If resources are unavailable just force stop all 14291 // those packages and flush the attribute cache as well. 14292 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14293 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14294 if (list != null && (list.length > 0)) { 14295 for (String pkg : list) { 14296 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14297 "storage unmount"); 14298 } 14299 sendPackageBroadcastLocked( 14300 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14301 } 14302 } else { 14303 Uri data = intent.getData(); 14304 String ssp; 14305 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14306 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14307 intent.getAction()); 14308 boolean fullUninstall = removed && 14309 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14310 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14311 forceStopPackageLocked(ssp, UserHandle.getAppId( 14312 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14313 false, fullUninstall, userId, 14314 removed ? "pkg removed" : "pkg changed"); 14315 } 14316 if (removed) { 14317 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14318 new String[] {ssp}, userId); 14319 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14320 mAppOpsService.packageRemoved( 14321 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14322 14323 // Remove all permissions granted from/to this package 14324 removeUriPermissionsForPackageLocked(ssp, userId, true); 14325 } 14326 } 14327 } 14328 } 14329 } 14330 } else { 14331 String msg = "Permission Denial: " + intent.getAction() 14332 + " broadcast from " + callerPackage + " (pid=" + callingPid 14333 + ", uid=" + callingUid + ")" 14334 + " requires " 14335 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14336 Slog.w(TAG, msg); 14337 throw new SecurityException(msg); 14338 } 14339 14340 // Special case for adding a package: by default turn on compatibility 14341 // mode. 14342 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14343 Uri data = intent.getData(); 14344 String ssp; 14345 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14346 mCompatModePackages.handlePackageAddedLocked(ssp, 14347 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14348 } 14349 } 14350 14351 /* 14352 * If this is the time zone changed action, queue up a message that will reset the timezone 14353 * of all currently running processes. This message will get queued up before the broadcast 14354 * happens. 14355 */ 14356 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14357 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14358 } 14359 14360 /* 14361 * If the user set the time, let all running processes know. 14362 */ 14363 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14364 final int is24Hour = intent.getBooleanExtra( 14365 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14366 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14367 } 14368 14369 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14370 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14371 } 14372 14373 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14374 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14375 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14376 } 14377 14378 // Add to the sticky list if requested. 14379 if (sticky) { 14380 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14381 callingPid, callingUid) 14382 != PackageManager.PERMISSION_GRANTED) { 14383 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14384 + callingPid + ", uid=" + callingUid 14385 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14386 Slog.w(TAG, msg); 14387 throw new SecurityException(msg); 14388 } 14389 if (requiredPermission != null) { 14390 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14391 + " and enforce permission " + requiredPermission); 14392 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14393 } 14394 if (intent.getComponent() != null) { 14395 throw new SecurityException( 14396 "Sticky broadcasts can't target a specific component"); 14397 } 14398 // We use userId directly here, since the "all" target is maintained 14399 // as a separate set of sticky broadcasts. 14400 if (userId != UserHandle.USER_ALL) { 14401 // But first, if this is not a broadcast to all users, then 14402 // make sure it doesn't conflict with an existing broadcast to 14403 // all users. 14404 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14405 UserHandle.USER_ALL); 14406 if (stickies != null) { 14407 ArrayList<Intent> list = stickies.get(intent.getAction()); 14408 if (list != null) { 14409 int N = list.size(); 14410 int i; 14411 for (i=0; i<N; i++) { 14412 if (intent.filterEquals(list.get(i))) { 14413 throw new IllegalArgumentException( 14414 "Sticky broadcast " + intent + " for user " 14415 + userId + " conflicts with existing global broadcast"); 14416 } 14417 } 14418 } 14419 } 14420 } 14421 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14422 if (stickies == null) { 14423 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14424 mStickyBroadcasts.put(userId, stickies); 14425 } 14426 ArrayList<Intent> list = stickies.get(intent.getAction()); 14427 if (list == null) { 14428 list = new ArrayList<Intent>(); 14429 stickies.put(intent.getAction(), list); 14430 } 14431 int N = list.size(); 14432 int i; 14433 for (i=0; i<N; i++) { 14434 if (intent.filterEquals(list.get(i))) { 14435 // This sticky already exists, replace it. 14436 list.set(i, new Intent(intent)); 14437 break; 14438 } 14439 } 14440 if (i >= N) { 14441 list.add(new Intent(intent)); 14442 } 14443 } 14444 14445 int[] users; 14446 if (userId == UserHandle.USER_ALL) { 14447 // Caller wants broadcast to go to all started users. 14448 users = mStartedUserArray; 14449 } else { 14450 // Caller wants broadcast to go to one specific user. 14451 users = new int[] {userId}; 14452 } 14453 14454 // Figure out who all will receive this broadcast. 14455 List receivers = null; 14456 List<BroadcastFilter> registeredReceivers = null; 14457 // Need to resolve the intent to interested receivers... 14458 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14459 == 0) { 14460 receivers = collectReceiverComponents(intent, resolvedType, users); 14461 } 14462 if (intent.getComponent() == null) { 14463 registeredReceivers = mReceiverResolver.queryIntent(intent, 14464 resolvedType, false, userId); 14465 } 14466 14467 final boolean replacePending = 14468 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14469 14470 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14471 + " replacePending=" + replacePending); 14472 14473 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14474 if (!ordered && NR > 0) { 14475 // If we are not serializing this broadcast, then send the 14476 // registered receivers separately so they don't wait for the 14477 // components to be launched. 14478 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14479 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14480 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14481 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14482 ordered, sticky, false, userId); 14483 if (DEBUG_BROADCAST) Slog.v( 14484 TAG, "Enqueueing parallel broadcast " + r); 14485 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14486 if (!replaced) { 14487 queue.enqueueParallelBroadcastLocked(r); 14488 queue.scheduleBroadcastsLocked(); 14489 } 14490 registeredReceivers = null; 14491 NR = 0; 14492 } 14493 14494 // Merge into one list. 14495 int ir = 0; 14496 if (receivers != null) { 14497 // A special case for PACKAGE_ADDED: do not allow the package 14498 // being added to see this broadcast. This prevents them from 14499 // using this as a back door to get run as soon as they are 14500 // installed. Maybe in the future we want to have a special install 14501 // broadcast or such for apps, but we'd like to deliberately make 14502 // this decision. 14503 String skipPackages[] = null; 14504 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14505 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14506 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14507 Uri data = intent.getData(); 14508 if (data != null) { 14509 String pkgName = data.getSchemeSpecificPart(); 14510 if (pkgName != null) { 14511 skipPackages = new String[] { pkgName }; 14512 } 14513 } 14514 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14515 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14516 } 14517 if (skipPackages != null && (skipPackages.length > 0)) { 14518 for (String skipPackage : skipPackages) { 14519 if (skipPackage != null) { 14520 int NT = receivers.size(); 14521 for (int it=0; it<NT; it++) { 14522 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14523 if (curt.activityInfo.packageName.equals(skipPackage)) { 14524 receivers.remove(it); 14525 it--; 14526 NT--; 14527 } 14528 } 14529 } 14530 } 14531 } 14532 14533 int NT = receivers != null ? receivers.size() : 0; 14534 int it = 0; 14535 ResolveInfo curt = null; 14536 BroadcastFilter curr = null; 14537 while (it < NT && ir < NR) { 14538 if (curt == null) { 14539 curt = (ResolveInfo)receivers.get(it); 14540 } 14541 if (curr == null) { 14542 curr = registeredReceivers.get(ir); 14543 } 14544 if (curr.getPriority() >= curt.priority) { 14545 // Insert this broadcast record into the final list. 14546 receivers.add(it, curr); 14547 ir++; 14548 curr = null; 14549 it++; 14550 NT++; 14551 } else { 14552 // Skip to the next ResolveInfo in the final list. 14553 it++; 14554 curt = null; 14555 } 14556 } 14557 } 14558 while (ir < NR) { 14559 if (receivers == null) { 14560 receivers = new ArrayList(); 14561 } 14562 receivers.add(registeredReceivers.get(ir)); 14563 ir++; 14564 } 14565 14566 if ((receivers != null && receivers.size() > 0) 14567 || resultTo != null) { 14568 BroadcastQueue queue = broadcastQueueForIntent(intent); 14569 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14570 callerPackage, callingPid, callingUid, resolvedType, 14571 requiredPermission, appOp, receivers, resultTo, resultCode, 14572 resultData, map, ordered, sticky, false, userId); 14573 if (DEBUG_BROADCAST) Slog.v( 14574 TAG, "Enqueueing ordered broadcast " + r 14575 + ": prev had " + queue.mOrderedBroadcasts.size()); 14576 if (DEBUG_BROADCAST) { 14577 int seq = r.intent.getIntExtra("seq", -1); 14578 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14579 } 14580 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14581 if (!replaced) { 14582 queue.enqueueOrderedBroadcastLocked(r); 14583 queue.scheduleBroadcastsLocked(); 14584 } 14585 } 14586 14587 return ActivityManager.BROADCAST_SUCCESS; 14588 } 14589 14590 final Intent verifyBroadcastLocked(Intent intent) { 14591 // Refuse possible leaked file descriptors 14592 if (intent != null && intent.hasFileDescriptors() == true) { 14593 throw new IllegalArgumentException("File descriptors passed in Intent"); 14594 } 14595 14596 int flags = intent.getFlags(); 14597 14598 if (!mProcessesReady) { 14599 // if the caller really truly claims to know what they're doing, go 14600 // ahead and allow the broadcast without launching any receivers 14601 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14602 intent = new Intent(intent); 14603 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14604 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14605 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14606 + " before boot completion"); 14607 throw new IllegalStateException("Cannot broadcast before boot completed"); 14608 } 14609 } 14610 14611 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14612 throw new IllegalArgumentException( 14613 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14614 } 14615 14616 return intent; 14617 } 14618 14619 public final int broadcastIntent(IApplicationThread caller, 14620 Intent intent, String resolvedType, IIntentReceiver resultTo, 14621 int resultCode, String resultData, Bundle map, 14622 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14623 enforceNotIsolatedCaller("broadcastIntent"); 14624 synchronized(this) { 14625 intent = verifyBroadcastLocked(intent); 14626 14627 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14628 final int callingPid = Binder.getCallingPid(); 14629 final int callingUid = Binder.getCallingUid(); 14630 final long origId = Binder.clearCallingIdentity(); 14631 int res = broadcastIntentLocked(callerApp, 14632 callerApp != null ? callerApp.info.packageName : null, 14633 intent, resolvedType, resultTo, 14634 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14635 callingPid, callingUid, userId); 14636 Binder.restoreCallingIdentity(origId); 14637 return res; 14638 } 14639 } 14640 14641 int broadcastIntentInPackage(String packageName, int uid, 14642 Intent intent, String resolvedType, IIntentReceiver resultTo, 14643 int resultCode, String resultData, Bundle map, 14644 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14645 synchronized(this) { 14646 intent = verifyBroadcastLocked(intent); 14647 14648 final long origId = Binder.clearCallingIdentity(); 14649 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14650 resultTo, resultCode, resultData, map, requiredPermission, 14651 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14652 Binder.restoreCallingIdentity(origId); 14653 return res; 14654 } 14655 } 14656 14657 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14658 // Refuse possible leaked file descriptors 14659 if (intent != null && intent.hasFileDescriptors() == true) { 14660 throw new IllegalArgumentException("File descriptors passed in Intent"); 14661 } 14662 14663 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14664 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 14665 14666 synchronized(this) { 14667 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14668 != PackageManager.PERMISSION_GRANTED) { 14669 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14670 + Binder.getCallingPid() 14671 + ", uid=" + Binder.getCallingUid() 14672 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14673 Slog.w(TAG, msg); 14674 throw new SecurityException(msg); 14675 } 14676 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14677 if (stickies != null) { 14678 ArrayList<Intent> list = stickies.get(intent.getAction()); 14679 if (list != null) { 14680 int N = list.size(); 14681 int i; 14682 for (i=0; i<N; i++) { 14683 if (intent.filterEquals(list.get(i))) { 14684 list.remove(i); 14685 break; 14686 } 14687 } 14688 if (list.size() <= 0) { 14689 stickies.remove(intent.getAction()); 14690 } 14691 } 14692 if (stickies.size() <= 0) { 14693 mStickyBroadcasts.remove(userId); 14694 } 14695 } 14696 } 14697 } 14698 14699 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14700 String resultData, Bundle resultExtras, boolean resultAbort) { 14701 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14702 if (r == null) { 14703 Slog.w(TAG, "finishReceiver called but not found on queue"); 14704 return false; 14705 } 14706 14707 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14708 } 14709 14710 void backgroundServicesFinishedLocked(int userId) { 14711 for (BroadcastQueue queue : mBroadcastQueues) { 14712 queue.backgroundServicesFinishedLocked(userId); 14713 } 14714 } 14715 14716 public void finishReceiver(IBinder who, int resultCode, String resultData, 14717 Bundle resultExtras, boolean resultAbort) { 14718 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14719 14720 // Refuse possible leaked file descriptors 14721 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14722 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14723 } 14724 14725 final long origId = Binder.clearCallingIdentity(); 14726 try { 14727 boolean doNext = false; 14728 BroadcastRecord r; 14729 14730 synchronized(this) { 14731 r = broadcastRecordForReceiverLocked(who); 14732 if (r != null) { 14733 doNext = r.queue.finishReceiverLocked(r, resultCode, 14734 resultData, resultExtras, resultAbort, true); 14735 } 14736 } 14737 14738 if (doNext) { 14739 r.queue.processNextBroadcast(false); 14740 } 14741 trimApplications(); 14742 } finally { 14743 Binder.restoreCallingIdentity(origId); 14744 } 14745 } 14746 14747 // ========================================================= 14748 // INSTRUMENTATION 14749 // ========================================================= 14750 14751 public boolean startInstrumentation(ComponentName className, 14752 String profileFile, int flags, Bundle arguments, 14753 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14754 int userId, String abiOverride) { 14755 enforceNotIsolatedCaller("startInstrumentation"); 14756 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14757 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 14758 // Refuse possible leaked file descriptors 14759 if (arguments != null && arguments.hasFileDescriptors()) { 14760 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14761 } 14762 14763 synchronized(this) { 14764 InstrumentationInfo ii = null; 14765 ApplicationInfo ai = null; 14766 try { 14767 ii = mContext.getPackageManager().getInstrumentationInfo( 14768 className, STOCK_PM_FLAGS); 14769 ai = AppGlobals.getPackageManager().getApplicationInfo( 14770 ii.targetPackage, STOCK_PM_FLAGS, userId); 14771 } catch (PackageManager.NameNotFoundException e) { 14772 } catch (RemoteException e) { 14773 } 14774 if (ii == null) { 14775 reportStartInstrumentationFailure(watcher, className, 14776 "Unable to find instrumentation info for: " + className); 14777 return false; 14778 } 14779 if (ai == null) { 14780 reportStartInstrumentationFailure(watcher, className, 14781 "Unable to find instrumentation target package: " + ii.targetPackage); 14782 return false; 14783 } 14784 14785 int match = mContext.getPackageManager().checkSignatures( 14786 ii.targetPackage, ii.packageName); 14787 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14788 String msg = "Permission Denial: starting instrumentation " 14789 + className + " from pid=" 14790 + Binder.getCallingPid() 14791 + ", uid=" + Binder.getCallingPid() 14792 + " not allowed because package " + ii.packageName 14793 + " does not have a signature matching the target " 14794 + ii.targetPackage; 14795 reportStartInstrumentationFailure(watcher, className, msg); 14796 throw new SecurityException(msg); 14797 } 14798 14799 final long origId = Binder.clearCallingIdentity(); 14800 // Instrumentation can kill and relaunch even persistent processes 14801 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14802 "start instr"); 14803 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14804 app.instrumentationClass = className; 14805 app.instrumentationInfo = ai; 14806 app.instrumentationProfileFile = profileFile; 14807 app.instrumentationArguments = arguments; 14808 app.instrumentationWatcher = watcher; 14809 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14810 app.instrumentationResultClass = className; 14811 Binder.restoreCallingIdentity(origId); 14812 } 14813 14814 return true; 14815 } 14816 14817 /** 14818 * Report errors that occur while attempting to start Instrumentation. Always writes the 14819 * error to the logs, but if somebody is watching, send the report there too. This enables 14820 * the "am" command to report errors with more information. 14821 * 14822 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14823 * @param cn The component name of the instrumentation. 14824 * @param report The error report. 14825 */ 14826 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14827 ComponentName cn, String report) { 14828 Slog.w(TAG, report); 14829 try { 14830 if (watcher != null) { 14831 Bundle results = new Bundle(); 14832 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14833 results.putString("Error", report); 14834 watcher.instrumentationStatus(cn, -1, results); 14835 } 14836 } catch (RemoteException e) { 14837 Slog.w(TAG, e); 14838 } 14839 } 14840 14841 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14842 if (app.instrumentationWatcher != null) { 14843 try { 14844 // NOTE: IInstrumentationWatcher *must* be oneway here 14845 app.instrumentationWatcher.instrumentationFinished( 14846 app.instrumentationClass, 14847 resultCode, 14848 results); 14849 } catch (RemoteException e) { 14850 } 14851 } 14852 if (app.instrumentationUiAutomationConnection != null) { 14853 try { 14854 app.instrumentationUiAutomationConnection.shutdown(); 14855 } catch (RemoteException re) { 14856 /* ignore */ 14857 } 14858 // Only a UiAutomation can set this flag and now that 14859 // it is finished we make sure it is reset to its default. 14860 mUserIsMonkey = false; 14861 } 14862 app.instrumentationWatcher = null; 14863 app.instrumentationUiAutomationConnection = null; 14864 app.instrumentationClass = null; 14865 app.instrumentationInfo = null; 14866 app.instrumentationProfileFile = null; 14867 app.instrumentationArguments = null; 14868 14869 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14870 "finished inst"); 14871 } 14872 14873 public void finishInstrumentation(IApplicationThread target, 14874 int resultCode, Bundle results) { 14875 int userId = UserHandle.getCallingUserId(); 14876 // Refuse possible leaked file descriptors 14877 if (results != null && results.hasFileDescriptors()) { 14878 throw new IllegalArgumentException("File descriptors passed in Intent"); 14879 } 14880 14881 synchronized(this) { 14882 ProcessRecord app = getRecordForAppLocked(target); 14883 if (app == null) { 14884 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14885 return; 14886 } 14887 final long origId = Binder.clearCallingIdentity(); 14888 finishInstrumentationLocked(app, resultCode, results); 14889 Binder.restoreCallingIdentity(origId); 14890 } 14891 } 14892 14893 // ========================================================= 14894 // CONFIGURATION 14895 // ========================================================= 14896 14897 public ConfigurationInfo getDeviceConfigurationInfo() { 14898 ConfigurationInfo config = new ConfigurationInfo(); 14899 synchronized (this) { 14900 config.reqTouchScreen = mConfiguration.touchscreen; 14901 config.reqKeyboardType = mConfiguration.keyboard; 14902 config.reqNavigation = mConfiguration.navigation; 14903 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14904 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14905 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14906 } 14907 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14908 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14909 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14910 } 14911 config.reqGlEsVersion = GL_ES_VERSION; 14912 } 14913 return config; 14914 } 14915 14916 ActivityStack getFocusedStack() { 14917 return mStackSupervisor.getFocusedStack(); 14918 } 14919 14920 public Configuration getConfiguration() { 14921 Configuration ci; 14922 synchronized(this) { 14923 ci = new Configuration(mConfiguration); 14924 } 14925 return ci; 14926 } 14927 14928 public void updatePersistentConfiguration(Configuration values) { 14929 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14930 "updateConfiguration()"); 14931 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14932 "updateConfiguration()"); 14933 if (values == null) { 14934 throw new NullPointerException("Configuration must not be null"); 14935 } 14936 14937 synchronized(this) { 14938 final long origId = Binder.clearCallingIdentity(); 14939 updateConfigurationLocked(values, null, true, false); 14940 Binder.restoreCallingIdentity(origId); 14941 } 14942 } 14943 14944 public void updateConfiguration(Configuration values) { 14945 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14946 "updateConfiguration()"); 14947 14948 synchronized(this) { 14949 if (values == null && mWindowManager != null) { 14950 // sentinel: fetch the current configuration from the window manager 14951 values = mWindowManager.computeNewConfiguration(); 14952 } 14953 14954 if (mWindowManager != null) { 14955 mProcessList.applyDisplaySize(mWindowManager); 14956 } 14957 14958 final long origId = Binder.clearCallingIdentity(); 14959 if (values != null) { 14960 Settings.System.clearConfiguration(values); 14961 } 14962 updateConfigurationLocked(values, null, false, false); 14963 Binder.restoreCallingIdentity(origId); 14964 } 14965 } 14966 14967 /** 14968 * Do either or both things: (1) change the current configuration, and (2) 14969 * make sure the given activity is running with the (now) current 14970 * configuration. Returns true if the activity has been left running, or 14971 * false if <var>starting</var> is being destroyed to match the new 14972 * configuration. 14973 * @param persistent TODO 14974 */ 14975 boolean updateConfigurationLocked(Configuration values, 14976 ActivityRecord starting, boolean persistent, boolean initLocale) { 14977 int changes = 0; 14978 14979 if (values != null) { 14980 Configuration newConfig = new Configuration(mConfiguration); 14981 changes = newConfig.updateFrom(values); 14982 if (changes != 0) { 14983 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14984 Slog.i(TAG, "Updating configuration to: " + values); 14985 } 14986 14987 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14988 14989 if (values.locale != null && !initLocale) { 14990 saveLocaleLocked(values.locale, 14991 !values.locale.equals(mConfiguration.locale), 14992 values.userSetLocale); 14993 } 14994 14995 mConfigurationSeq++; 14996 if (mConfigurationSeq <= 0) { 14997 mConfigurationSeq = 1; 14998 } 14999 newConfig.seq = mConfigurationSeq; 15000 mConfiguration = newConfig; 15001 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15002 mUsageStatsService.noteStartConfig(newConfig); 15003 15004 final Configuration configCopy = new Configuration(mConfiguration); 15005 15006 // TODO: If our config changes, should we auto dismiss any currently 15007 // showing dialogs? 15008 mShowDialogs = shouldShowDialogs(newConfig); 15009 15010 AttributeCache ac = AttributeCache.instance(); 15011 if (ac != null) { 15012 ac.updateConfiguration(configCopy); 15013 } 15014 15015 // Make sure all resources in our process are updated 15016 // right now, so that anyone who is going to retrieve 15017 // resource values after we return will be sure to get 15018 // the new ones. This is especially important during 15019 // boot, where the first config change needs to guarantee 15020 // all resources have that config before following boot 15021 // code is executed. 15022 mSystemThread.applyConfigurationToResources(configCopy); 15023 15024 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15025 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15026 msg.obj = new Configuration(configCopy); 15027 mHandler.sendMessage(msg); 15028 } 15029 15030 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15031 ProcessRecord app = mLruProcesses.get(i); 15032 try { 15033 if (app.thread != null) { 15034 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15035 + app.processName + " new config " + mConfiguration); 15036 app.thread.scheduleConfigurationChanged(configCopy); 15037 } 15038 } catch (Exception e) { 15039 } 15040 } 15041 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15043 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15044 | Intent.FLAG_RECEIVER_FOREGROUND); 15045 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15046 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15047 Process.SYSTEM_UID, UserHandle.USER_ALL); 15048 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15049 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15050 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15051 broadcastIntentLocked(null, null, intent, 15052 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15053 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15054 } 15055 } 15056 } 15057 15058 boolean kept = true; 15059 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15060 // mainStack is null during startup. 15061 if (mainStack != null) { 15062 if (changes != 0 && starting == null) { 15063 // If the configuration changed, and the caller is not already 15064 // in the process of starting an activity, then find the top 15065 // activity to check if its configuration needs to change. 15066 starting = mainStack.topRunningActivityLocked(null); 15067 } 15068 15069 if (starting != null) { 15070 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15071 // And we need to make sure at this point that all other activities 15072 // are made visible with the correct configuration. 15073 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15074 } 15075 } 15076 15077 if (values != null && mWindowManager != null) { 15078 mWindowManager.setNewConfiguration(mConfiguration); 15079 } 15080 15081 return kept; 15082 } 15083 15084 /** 15085 * Decide based on the configuration whether we should shouw the ANR, 15086 * crash, etc dialogs. The idea is that if there is no affordnace to 15087 * press the on-screen buttons, we shouldn't show the dialog. 15088 * 15089 * A thought: SystemUI might also want to get told about this, the Power 15090 * dialog / global actions also might want different behaviors. 15091 */ 15092 private static final boolean shouldShowDialogs(Configuration config) { 15093 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15094 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15095 } 15096 15097 /** 15098 * Save the locale. You must be inside a synchronized (this) block. 15099 */ 15100 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15101 if(isDiff) { 15102 SystemProperties.set("user.language", l.getLanguage()); 15103 SystemProperties.set("user.region", l.getCountry()); 15104 } 15105 15106 if(isPersist) { 15107 SystemProperties.set("persist.sys.language", l.getLanguage()); 15108 SystemProperties.set("persist.sys.country", l.getCountry()); 15109 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15110 } 15111 } 15112 15113 @Override 15114 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15115 ActivityRecord srec = ActivityRecord.forToken(token); 15116 return srec != null && srec.task.affinity != null && 15117 srec.task.affinity.equals(destAffinity); 15118 } 15119 15120 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15121 Intent resultData) { 15122 15123 synchronized (this) { 15124 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15125 if (stack != null) { 15126 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15127 } 15128 return false; 15129 } 15130 } 15131 15132 public int getLaunchedFromUid(IBinder activityToken) { 15133 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15134 if (srec == null) { 15135 return -1; 15136 } 15137 return srec.launchedFromUid; 15138 } 15139 15140 public String getLaunchedFromPackage(IBinder activityToken) { 15141 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15142 if (srec == null) { 15143 return null; 15144 } 15145 return srec.launchedFromPackage; 15146 } 15147 15148 // ========================================================= 15149 // LIFETIME MANAGEMENT 15150 // ========================================================= 15151 15152 // Returns which broadcast queue the app is the current [or imminent] receiver 15153 // on, or 'null' if the app is not an active broadcast recipient. 15154 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15155 BroadcastRecord r = app.curReceiver; 15156 if (r != null) { 15157 return r.queue; 15158 } 15159 15160 // It's not the current receiver, but it might be starting up to become one 15161 synchronized (this) { 15162 for (BroadcastQueue queue : mBroadcastQueues) { 15163 r = queue.mPendingBroadcast; 15164 if (r != null && r.curApp == app) { 15165 // found it; report which queue it's in 15166 return queue; 15167 } 15168 } 15169 } 15170 15171 return null; 15172 } 15173 15174 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15175 boolean doingAll, long now) { 15176 if (mAdjSeq == app.adjSeq) { 15177 // This adjustment has already been computed. 15178 return app.curRawAdj; 15179 } 15180 15181 if (app.thread == null) { 15182 app.adjSeq = mAdjSeq; 15183 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15184 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15185 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15186 } 15187 15188 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15189 app.adjSource = null; 15190 app.adjTarget = null; 15191 app.empty = false; 15192 app.cached = false; 15193 15194 final int activitiesSize = app.activities.size(); 15195 15196 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15197 // The max adjustment doesn't allow this app to be anything 15198 // below foreground, so it is not worth doing work for it. 15199 app.adjType = "fixed"; 15200 app.adjSeq = mAdjSeq; 15201 app.curRawAdj = app.maxAdj; 15202 app.foregroundActivities = false; 15203 app.keeping = true; 15204 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15205 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15206 // System processes can do UI, and when they do we want to have 15207 // them trim their memory after the user leaves the UI. To 15208 // facilitate this, here we need to determine whether or not it 15209 // is currently showing UI. 15210 app.systemNoUi = true; 15211 if (app == TOP_APP) { 15212 app.systemNoUi = false; 15213 } else if (activitiesSize > 0) { 15214 for (int j = 0; j < activitiesSize; j++) { 15215 final ActivityRecord r = app.activities.get(j); 15216 if (r.visible) { 15217 app.systemNoUi = false; 15218 } 15219 } 15220 } 15221 if (!app.systemNoUi) { 15222 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15223 } 15224 return (app.curAdj=app.maxAdj); 15225 } 15226 15227 app.keeping = false; 15228 app.systemNoUi = false; 15229 15230 // Determine the importance of the process, starting with most 15231 // important to least, and assign an appropriate OOM adjustment. 15232 int adj; 15233 int schedGroup; 15234 int procState; 15235 boolean foregroundActivities = false; 15236 BroadcastQueue queue; 15237 if (app == TOP_APP) { 15238 // The last app on the list is the foreground app. 15239 adj = ProcessList.FOREGROUND_APP_ADJ; 15240 schedGroup = Process.THREAD_GROUP_DEFAULT; 15241 app.adjType = "top-activity"; 15242 foregroundActivities = true; 15243 procState = ActivityManager.PROCESS_STATE_TOP; 15244 } else if (app.instrumentationClass != null) { 15245 // Don't want to kill running instrumentation. 15246 adj = ProcessList.FOREGROUND_APP_ADJ; 15247 schedGroup = Process.THREAD_GROUP_DEFAULT; 15248 app.adjType = "instrumentation"; 15249 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15250 } else if ((queue = isReceivingBroadcast(app)) != null) { 15251 // An app that is currently receiving a broadcast also 15252 // counts as being in the foreground for OOM killer purposes. 15253 // It's placed in a sched group based on the nature of the 15254 // broadcast as reflected by which queue it's active in. 15255 adj = ProcessList.FOREGROUND_APP_ADJ; 15256 schedGroup = (queue == mFgBroadcastQueue) 15257 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15258 app.adjType = "broadcast"; 15259 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15260 } else if (app.executingServices.size() > 0) { 15261 // An app that is currently executing a service callback also 15262 // counts as being in the foreground. 15263 adj = ProcessList.FOREGROUND_APP_ADJ; 15264 schedGroup = app.execServicesFg ? 15265 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15266 app.adjType = "exec-service"; 15267 procState = ActivityManager.PROCESS_STATE_SERVICE; 15268 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15269 } else { 15270 // As far as we know the process is empty. We may change our mind later. 15271 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15272 // At this point we don't actually know the adjustment. Use the cached adj 15273 // value that the caller wants us to. 15274 adj = cachedAdj; 15275 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15276 app.cached = true; 15277 app.empty = true; 15278 app.adjType = "cch-empty"; 15279 } 15280 15281 // Examine all activities if not already foreground. 15282 if (!foregroundActivities && activitiesSize > 0) { 15283 for (int j = 0; j < activitiesSize; j++) { 15284 final ActivityRecord r = app.activities.get(j); 15285 if (r.app != app) { 15286 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15287 + app + "?!?"); 15288 continue; 15289 } 15290 if (r.visible) { 15291 // App has a visible activity; only upgrade adjustment. 15292 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15293 adj = ProcessList.VISIBLE_APP_ADJ; 15294 app.adjType = "visible"; 15295 } 15296 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15297 procState = ActivityManager.PROCESS_STATE_TOP; 15298 } 15299 schedGroup = Process.THREAD_GROUP_DEFAULT; 15300 app.cached = false; 15301 app.empty = false; 15302 foregroundActivities = true; 15303 break; 15304 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15305 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15306 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15307 app.adjType = "pausing"; 15308 } 15309 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15310 procState = ActivityManager.PROCESS_STATE_TOP; 15311 } 15312 schedGroup = Process.THREAD_GROUP_DEFAULT; 15313 app.cached = false; 15314 app.empty = false; 15315 foregroundActivities = true; 15316 } else if (r.state == ActivityState.STOPPING) { 15317 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15318 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15319 app.adjType = "stopping"; 15320 } 15321 // For the process state, we will at this point consider the 15322 // process to be cached. It will be cached either as an activity 15323 // or empty depending on whether the activity is finishing. We do 15324 // this so that we can treat the process as cached for purposes of 15325 // memory trimming (determing current memory level, trim command to 15326 // send to process) since there can be an arbitrary number of stopping 15327 // processes and they should soon all go into the cached state. 15328 if (!r.finishing) { 15329 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15330 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15331 } 15332 } 15333 app.cached = false; 15334 app.empty = false; 15335 foregroundActivities = true; 15336 } else { 15337 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15338 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15339 app.adjType = "cch-act"; 15340 } 15341 } 15342 } 15343 } 15344 15345 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15346 if (app.foregroundServices) { 15347 // The user is aware of this app, so make it visible. 15348 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15349 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15350 app.cached = false; 15351 app.adjType = "fg-service"; 15352 schedGroup = Process.THREAD_GROUP_DEFAULT; 15353 } else if (app.forcingToForeground != null) { 15354 // The user is aware of this app, so make it visible. 15355 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15356 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15357 app.cached = false; 15358 app.adjType = "force-fg"; 15359 app.adjSource = app.forcingToForeground; 15360 schedGroup = Process.THREAD_GROUP_DEFAULT; 15361 } 15362 } 15363 15364 if (app == mHeavyWeightProcess) { 15365 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15366 // We don't want to kill the current heavy-weight process. 15367 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15368 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15369 app.cached = false; 15370 app.adjType = "heavy"; 15371 } 15372 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15373 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15374 } 15375 } 15376 15377 if (app == mHomeProcess) { 15378 if (adj > ProcessList.HOME_APP_ADJ) { 15379 // This process is hosting what we currently consider to be the 15380 // home app, so we don't want to let it go into the background. 15381 adj = ProcessList.HOME_APP_ADJ; 15382 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15383 app.cached = false; 15384 app.adjType = "home"; 15385 } 15386 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15387 procState = ActivityManager.PROCESS_STATE_HOME; 15388 } 15389 } 15390 15391 if (app == mPreviousProcess && app.activities.size() > 0) { 15392 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15393 // This was the previous process that showed UI to the user. 15394 // We want to try to keep it around more aggressively, to give 15395 // a good experience around switching between two apps. 15396 adj = ProcessList.PREVIOUS_APP_ADJ; 15397 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15398 app.cached = false; 15399 app.adjType = "previous"; 15400 } 15401 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15402 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15403 } 15404 } 15405 15406 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15407 + " reason=" + app.adjType); 15408 15409 // By default, we use the computed adjustment. It may be changed if 15410 // there are applications dependent on our services or providers, but 15411 // this gives us a baseline and makes sure we don't get into an 15412 // infinite recursion. 15413 app.adjSeq = mAdjSeq; 15414 app.curRawAdj = adj; 15415 app.hasStartedServices = false; 15416 15417 if (mBackupTarget != null && app == mBackupTarget.app) { 15418 // If possible we want to avoid killing apps while they're being backed up 15419 if (adj > ProcessList.BACKUP_APP_ADJ) { 15420 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15421 adj = ProcessList.BACKUP_APP_ADJ; 15422 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15423 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15424 } 15425 app.adjType = "backup"; 15426 app.cached = false; 15427 } 15428 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15429 procState = ActivityManager.PROCESS_STATE_BACKUP; 15430 } 15431 } 15432 15433 boolean mayBeTop = false; 15434 15435 for (int is = app.services.size()-1; 15436 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15437 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15438 || procState > ActivityManager.PROCESS_STATE_TOP); 15439 is--) { 15440 ServiceRecord s = app.services.valueAt(is); 15441 if (s.startRequested) { 15442 app.hasStartedServices = true; 15443 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15444 procState = ActivityManager.PROCESS_STATE_SERVICE; 15445 } 15446 if (app.hasShownUi && app != mHomeProcess) { 15447 // If this process has shown some UI, let it immediately 15448 // go to the LRU list because it may be pretty heavy with 15449 // UI stuff. We'll tag it with a label just to help 15450 // debug and understand what is going on. 15451 if (adj > ProcessList.SERVICE_ADJ) { 15452 app.adjType = "cch-started-ui-services"; 15453 } 15454 } else { 15455 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15456 // This service has seen some activity within 15457 // recent memory, so we will keep its process ahead 15458 // of the background processes. 15459 if (adj > ProcessList.SERVICE_ADJ) { 15460 adj = ProcessList.SERVICE_ADJ; 15461 app.adjType = "started-services"; 15462 app.cached = false; 15463 } 15464 } 15465 // If we have let the service slide into the background 15466 // state, still have some text describing what it is doing 15467 // even though the service no longer has an impact. 15468 if (adj > ProcessList.SERVICE_ADJ) { 15469 app.adjType = "cch-started-services"; 15470 } 15471 } 15472 // Don't kill this process because it is doing work; it 15473 // has said it is doing work. 15474 app.keeping = true; 15475 } 15476 for (int conni = s.connections.size()-1; 15477 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15478 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15479 || procState > ActivityManager.PROCESS_STATE_TOP); 15480 conni--) { 15481 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15482 for (int i = 0; 15483 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15484 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15485 || procState > ActivityManager.PROCESS_STATE_TOP); 15486 i++) { 15487 // XXX should compute this based on the max of 15488 // all connected clients. 15489 ConnectionRecord cr = clist.get(i); 15490 if (cr.binding.client == app) { 15491 // Binding to ourself is not interesting. 15492 continue; 15493 } 15494 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15495 ProcessRecord client = cr.binding.client; 15496 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15497 TOP_APP, doingAll, now); 15498 int clientProcState = client.curProcState; 15499 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15500 // If the other app is cached for any reason, for purposes here 15501 // we are going to consider it empty. The specific cached state 15502 // doesn't propagate except under certain conditions. 15503 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15504 } 15505 String adjType = null; 15506 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15507 // Not doing bind OOM management, so treat 15508 // this guy more like a started service. 15509 if (app.hasShownUi && app != mHomeProcess) { 15510 // If this process has shown some UI, let it immediately 15511 // go to the LRU list because it may be pretty heavy with 15512 // UI stuff. We'll tag it with a label just to help 15513 // debug and understand what is going on. 15514 if (adj > clientAdj) { 15515 adjType = "cch-bound-ui-services"; 15516 } 15517 app.cached = false; 15518 clientAdj = adj; 15519 clientProcState = procState; 15520 } else { 15521 if (now >= (s.lastActivity 15522 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15523 // This service has not seen activity within 15524 // recent memory, so allow it to drop to the 15525 // LRU list if there is no other reason to keep 15526 // it around. We'll also tag it with a label just 15527 // to help debug and undertand what is going on. 15528 if (adj > clientAdj) { 15529 adjType = "cch-bound-services"; 15530 } 15531 clientAdj = adj; 15532 } 15533 } 15534 } 15535 if (adj > clientAdj) { 15536 // If this process has recently shown UI, and 15537 // the process that is binding to it is less 15538 // important than being visible, then we don't 15539 // care about the binding as much as we care 15540 // about letting this process get into the LRU 15541 // list to be killed and restarted if needed for 15542 // memory. 15543 if (app.hasShownUi && app != mHomeProcess 15544 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15545 adjType = "cch-bound-ui-services"; 15546 } else { 15547 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15548 |Context.BIND_IMPORTANT)) != 0) { 15549 adj = clientAdj; 15550 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15551 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15552 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15553 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15554 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15555 adj = clientAdj; 15556 } else { 15557 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15558 adj = ProcessList.VISIBLE_APP_ADJ; 15559 } 15560 } 15561 if (!client.cached) { 15562 app.cached = false; 15563 } 15564 if (client.keeping) { 15565 app.keeping = true; 15566 } 15567 adjType = "service"; 15568 } 15569 } 15570 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15571 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15572 schedGroup = Process.THREAD_GROUP_DEFAULT; 15573 } 15574 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15575 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15576 // Special handling of clients who are in the top state. 15577 // We *may* want to consider this process to be in the 15578 // top state as well, but only if there is not another 15579 // reason for it to be running. Being on the top is a 15580 // special state, meaning you are specifically running 15581 // for the current top app. If the process is already 15582 // running in the background for some other reason, it 15583 // is more important to continue considering it to be 15584 // in the background state. 15585 mayBeTop = true; 15586 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15587 } else { 15588 // Special handling for above-top states (persistent 15589 // processes). These should not bring the current process 15590 // into the top state, since they are not on top. Instead 15591 // give them the best state after that. 15592 clientProcState = 15593 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15594 } 15595 } 15596 } else { 15597 if (clientProcState < 15598 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15599 clientProcState = 15600 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15601 } 15602 } 15603 if (procState > clientProcState) { 15604 procState = clientProcState; 15605 } 15606 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15607 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15608 app.pendingUiClean = true; 15609 } 15610 if (adjType != null) { 15611 app.adjType = adjType; 15612 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15613 .REASON_SERVICE_IN_USE; 15614 app.adjSource = cr.binding.client; 15615 app.adjSourceOom = clientAdj; 15616 app.adjTarget = s.name; 15617 } 15618 } 15619 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15620 app.treatLikeActivity = true; 15621 } 15622 final ActivityRecord a = cr.activity; 15623 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15624 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15625 (a.visible || a.state == ActivityState.RESUMED 15626 || a.state == ActivityState.PAUSING)) { 15627 adj = ProcessList.FOREGROUND_APP_ADJ; 15628 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15629 schedGroup = Process.THREAD_GROUP_DEFAULT; 15630 } 15631 app.cached = false; 15632 app.adjType = "service"; 15633 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15634 .REASON_SERVICE_IN_USE; 15635 app.adjSource = a; 15636 app.adjSourceOom = adj; 15637 app.adjTarget = s.name; 15638 } 15639 } 15640 } 15641 } 15642 } 15643 15644 for (int provi = app.pubProviders.size()-1; 15645 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15646 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15647 || procState > ActivityManager.PROCESS_STATE_TOP); 15648 provi--) { 15649 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15650 for (int i = cpr.connections.size()-1; 15651 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15652 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15653 || procState > ActivityManager.PROCESS_STATE_TOP); 15654 i--) { 15655 ContentProviderConnection conn = cpr.connections.get(i); 15656 ProcessRecord client = conn.client; 15657 if (client == app) { 15658 // Being our own client is not interesting. 15659 continue; 15660 } 15661 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15662 int clientProcState = client.curProcState; 15663 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15664 // If the other app is cached for any reason, for purposes here 15665 // we are going to consider it empty. 15666 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15667 } 15668 if (adj > clientAdj) { 15669 if (app.hasShownUi && app != mHomeProcess 15670 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15671 app.adjType = "cch-ui-provider"; 15672 } else { 15673 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15674 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15675 app.adjType = "provider"; 15676 } 15677 app.cached &= client.cached; 15678 app.keeping |= client.keeping; 15679 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15680 .REASON_PROVIDER_IN_USE; 15681 app.adjSource = client; 15682 app.adjSourceOom = clientAdj; 15683 app.adjTarget = cpr.name; 15684 } 15685 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15686 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15687 // Special handling of clients who are in the top state. 15688 // We *may* want to consider this process to be in the 15689 // top state as well, but only if there is not another 15690 // reason for it to be running. Being on the top is a 15691 // special state, meaning you are specifically running 15692 // for the current top app. If the process is already 15693 // running in the background for some other reason, it 15694 // is more important to continue considering it to be 15695 // in the background state. 15696 mayBeTop = true; 15697 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15698 } else { 15699 // Special handling for above-top states (persistent 15700 // processes). These should not bring the current process 15701 // into the top state, since they are not on top. Instead 15702 // give them the best state after that. 15703 clientProcState = 15704 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15705 } 15706 } 15707 if (procState > clientProcState) { 15708 procState = clientProcState; 15709 } 15710 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15711 schedGroup = Process.THREAD_GROUP_DEFAULT; 15712 } 15713 } 15714 // If the provider has external (non-framework) process 15715 // dependencies, ensure that its adjustment is at least 15716 // FOREGROUND_APP_ADJ. 15717 if (cpr.hasExternalProcessHandles()) { 15718 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15719 adj = ProcessList.FOREGROUND_APP_ADJ; 15720 schedGroup = Process.THREAD_GROUP_DEFAULT; 15721 app.cached = false; 15722 app.keeping = true; 15723 app.adjType = "provider"; 15724 app.adjTarget = cpr.name; 15725 } 15726 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15727 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15728 } 15729 } 15730 } 15731 15732 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15733 // A client of one of our services or providers is in the top state. We 15734 // *may* want to be in the top state, but not if we are already running in 15735 // the background for some other reason. For the decision here, we are going 15736 // to pick out a few specific states that we want to remain in when a client 15737 // is top (states that tend to be longer-term) and otherwise allow it to go 15738 // to the top state. 15739 switch (procState) { 15740 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15741 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15742 case ActivityManager.PROCESS_STATE_SERVICE: 15743 // These all are longer-term states, so pull them up to the top 15744 // of the background states, but not all the way to the top state. 15745 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15746 break; 15747 default: 15748 // Otherwise, top is a better choice, so take it. 15749 procState = ActivityManager.PROCESS_STATE_TOP; 15750 break; 15751 } 15752 } 15753 15754 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15755 if (app.hasClientActivities) { 15756 // This is a cached process, but with client activities. Mark it so. 15757 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15758 app.adjType = "cch-client-act"; 15759 } else if (app.treatLikeActivity) { 15760 // This is a cached process, but somebody wants us to treat it like it has 15761 // an activity, okay! 15762 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15763 app.adjType = "cch-as-act"; 15764 } 15765 } 15766 15767 if (adj == ProcessList.SERVICE_ADJ) { 15768 if (doingAll) { 15769 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15770 mNewNumServiceProcs++; 15771 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15772 if (!app.serviceb) { 15773 // This service isn't far enough down on the LRU list to 15774 // normally be a B service, but if we are low on RAM and it 15775 // is large we want to force it down since we would prefer to 15776 // keep launcher over it. 15777 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15778 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15779 app.serviceHighRam = true; 15780 app.serviceb = true; 15781 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15782 } else { 15783 mNewNumAServiceProcs++; 15784 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15785 } 15786 } else { 15787 app.serviceHighRam = false; 15788 } 15789 } 15790 if (app.serviceb) { 15791 adj = ProcessList.SERVICE_B_ADJ; 15792 } 15793 } 15794 15795 app.curRawAdj = adj; 15796 15797 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15798 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15799 if (adj > app.maxAdj) { 15800 adj = app.maxAdj; 15801 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15802 schedGroup = Process.THREAD_GROUP_DEFAULT; 15803 } 15804 } 15805 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15806 app.keeping = true; 15807 } 15808 15809 // Do final modification to adj. Everything we do between here and applying 15810 // the final setAdj must be done in this function, because we will also use 15811 // it when computing the final cached adj later. Note that we don't need to 15812 // worry about this for max adj above, since max adj will always be used to 15813 // keep it out of the cached vaues. 15814 app.curAdj = app.modifyRawOomAdj(adj); 15815 app.curSchedGroup = schedGroup; 15816 app.curProcState = procState; 15817 app.foregroundActivities = foregroundActivities; 15818 15819 return app.curRawAdj; 15820 } 15821 15822 /** 15823 * Schedule PSS collection of a process. 15824 */ 15825 void requestPssLocked(ProcessRecord proc, int procState) { 15826 if (mPendingPssProcesses.contains(proc)) { 15827 return; 15828 } 15829 if (mPendingPssProcesses.size() == 0) { 15830 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15831 } 15832 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15833 proc.pssProcState = procState; 15834 mPendingPssProcesses.add(proc); 15835 } 15836 15837 /** 15838 * Schedule PSS collection of all processes. 15839 */ 15840 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15841 if (!always) { 15842 if (now < (mLastFullPssTime + 15843 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15844 return; 15845 } 15846 } 15847 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15848 mLastFullPssTime = now; 15849 mFullPssPending = true; 15850 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15851 mPendingPssProcesses.clear(); 15852 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15853 ProcessRecord app = mLruProcesses.get(i); 15854 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15855 app.pssProcState = app.setProcState; 15856 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15857 isSleeping(), now); 15858 mPendingPssProcesses.add(app); 15859 } 15860 } 15861 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15862 } 15863 15864 /** 15865 * Ask a given process to GC right now. 15866 */ 15867 final void performAppGcLocked(ProcessRecord app) { 15868 try { 15869 app.lastRequestedGc = SystemClock.uptimeMillis(); 15870 if (app.thread != null) { 15871 if (app.reportLowMemory) { 15872 app.reportLowMemory = false; 15873 app.thread.scheduleLowMemory(); 15874 } else { 15875 app.thread.processInBackground(); 15876 } 15877 } 15878 } catch (Exception e) { 15879 // whatever. 15880 } 15881 } 15882 15883 /** 15884 * Returns true if things are idle enough to perform GCs. 15885 */ 15886 private final boolean canGcNowLocked() { 15887 boolean processingBroadcasts = false; 15888 for (BroadcastQueue q : mBroadcastQueues) { 15889 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15890 processingBroadcasts = true; 15891 } 15892 } 15893 return !processingBroadcasts 15894 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15895 } 15896 15897 /** 15898 * Perform GCs on all processes that are waiting for it, but only 15899 * if things are idle. 15900 */ 15901 final void performAppGcsLocked() { 15902 final int N = mProcessesToGc.size(); 15903 if (N <= 0) { 15904 return; 15905 } 15906 if (canGcNowLocked()) { 15907 while (mProcessesToGc.size() > 0) { 15908 ProcessRecord proc = mProcessesToGc.remove(0); 15909 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15910 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15911 <= SystemClock.uptimeMillis()) { 15912 // To avoid spamming the system, we will GC processes one 15913 // at a time, waiting a few seconds between each. 15914 performAppGcLocked(proc); 15915 scheduleAppGcsLocked(); 15916 return; 15917 } else { 15918 // It hasn't been long enough since we last GCed this 15919 // process... put it in the list to wait for its time. 15920 addProcessToGcListLocked(proc); 15921 break; 15922 } 15923 } 15924 } 15925 15926 scheduleAppGcsLocked(); 15927 } 15928 } 15929 15930 /** 15931 * If all looks good, perform GCs on all processes waiting for them. 15932 */ 15933 final void performAppGcsIfAppropriateLocked() { 15934 if (canGcNowLocked()) { 15935 performAppGcsLocked(); 15936 return; 15937 } 15938 // Still not idle, wait some more. 15939 scheduleAppGcsLocked(); 15940 } 15941 15942 /** 15943 * Schedule the execution of all pending app GCs. 15944 */ 15945 final void scheduleAppGcsLocked() { 15946 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15947 15948 if (mProcessesToGc.size() > 0) { 15949 // Schedule a GC for the time to the next process. 15950 ProcessRecord proc = mProcessesToGc.get(0); 15951 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15952 15953 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15954 long now = SystemClock.uptimeMillis(); 15955 if (when < (now+GC_TIMEOUT)) { 15956 when = now + GC_TIMEOUT; 15957 } 15958 mHandler.sendMessageAtTime(msg, when); 15959 } 15960 } 15961 15962 /** 15963 * Add a process to the array of processes waiting to be GCed. Keeps the 15964 * list in sorted order by the last GC time. The process can't already be 15965 * on the list. 15966 */ 15967 final void addProcessToGcListLocked(ProcessRecord proc) { 15968 boolean added = false; 15969 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15970 if (mProcessesToGc.get(i).lastRequestedGc < 15971 proc.lastRequestedGc) { 15972 added = true; 15973 mProcessesToGc.add(i+1, proc); 15974 break; 15975 } 15976 } 15977 if (!added) { 15978 mProcessesToGc.add(0, proc); 15979 } 15980 } 15981 15982 /** 15983 * Set up to ask a process to GC itself. This will either do it 15984 * immediately, or put it on the list of processes to gc the next 15985 * time things are idle. 15986 */ 15987 final void scheduleAppGcLocked(ProcessRecord app) { 15988 long now = SystemClock.uptimeMillis(); 15989 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15990 return; 15991 } 15992 if (!mProcessesToGc.contains(app)) { 15993 addProcessToGcListLocked(app); 15994 scheduleAppGcsLocked(); 15995 } 15996 } 15997 15998 final void checkExcessivePowerUsageLocked(boolean doKills) { 15999 updateCpuStatsNow(); 16000 16001 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16002 boolean doWakeKills = doKills; 16003 boolean doCpuKills = doKills; 16004 if (mLastPowerCheckRealtime == 0) { 16005 doWakeKills = false; 16006 } 16007 if (mLastPowerCheckUptime == 0) { 16008 doCpuKills = false; 16009 } 16010 if (stats.isScreenOn()) { 16011 doWakeKills = false; 16012 } 16013 final long curRealtime = SystemClock.elapsedRealtime(); 16014 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16015 final long curUptime = SystemClock.uptimeMillis(); 16016 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16017 mLastPowerCheckRealtime = curRealtime; 16018 mLastPowerCheckUptime = curUptime; 16019 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16020 doWakeKills = false; 16021 } 16022 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16023 doCpuKills = false; 16024 } 16025 int i = mLruProcesses.size(); 16026 while (i > 0) { 16027 i--; 16028 ProcessRecord app = mLruProcesses.get(i); 16029 if (!app.keeping) { 16030 long wtime; 16031 synchronized (stats) { 16032 wtime = stats.getProcessWakeTime(app.info.uid, 16033 app.pid, curRealtime); 16034 } 16035 long wtimeUsed = wtime - app.lastWakeTime; 16036 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16037 if (DEBUG_POWER) { 16038 StringBuilder sb = new StringBuilder(128); 16039 sb.append("Wake for "); 16040 app.toShortString(sb); 16041 sb.append(": over "); 16042 TimeUtils.formatDuration(realtimeSince, sb); 16043 sb.append(" used "); 16044 TimeUtils.formatDuration(wtimeUsed, sb); 16045 sb.append(" ("); 16046 sb.append((wtimeUsed*100)/realtimeSince); 16047 sb.append("%)"); 16048 Slog.i(TAG, sb.toString()); 16049 sb.setLength(0); 16050 sb.append("CPU for "); 16051 app.toShortString(sb); 16052 sb.append(": over "); 16053 TimeUtils.formatDuration(uptimeSince, sb); 16054 sb.append(" used "); 16055 TimeUtils.formatDuration(cputimeUsed, sb); 16056 sb.append(" ("); 16057 sb.append((cputimeUsed*100)/uptimeSince); 16058 sb.append("%)"); 16059 Slog.i(TAG, sb.toString()); 16060 } 16061 // If a process has held a wake lock for more 16062 // than 50% of the time during this period, 16063 // that sounds bad. Kill! 16064 if (doWakeKills && realtimeSince > 0 16065 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16066 synchronized (stats) { 16067 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16068 realtimeSince, wtimeUsed); 16069 } 16070 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16071 + " during " + realtimeSince); 16072 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16073 } else if (doCpuKills && uptimeSince > 0 16074 && ((cputimeUsed*100)/uptimeSince) >= 50) { 16075 synchronized (stats) { 16076 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16077 uptimeSince, cputimeUsed); 16078 } 16079 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16080 + " during " + uptimeSince); 16081 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16082 } else { 16083 app.lastWakeTime = wtime; 16084 app.lastCpuTime = app.curCpuTime; 16085 } 16086 } 16087 } 16088 } 16089 16090 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 16091 ProcessRecord TOP_APP, boolean doingAll, long now) { 16092 boolean success = true; 16093 16094 if (app.curRawAdj != app.setRawAdj) { 16095 if (wasKeeping && !app.keeping) { 16096 // This app is no longer something we want to keep. Note 16097 // its current wake lock time to later know to kill it if 16098 // it is not behaving well. 16099 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16100 synchronized (stats) { 16101 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16102 app.pid, SystemClock.elapsedRealtime()); 16103 } 16104 app.lastCpuTime = app.curCpuTime; 16105 } 16106 16107 app.setRawAdj = app.curRawAdj; 16108 } 16109 16110 int changes = 0; 16111 16112 if (app.curAdj != app.setAdj) { 16113 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16114 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16115 TAG, "Set " + app.pid + " " + app.processName + 16116 " adj " + app.curAdj + ": " + app.adjType); 16117 app.setAdj = app.curAdj; 16118 } 16119 16120 if (app.setSchedGroup != app.curSchedGroup) { 16121 app.setSchedGroup = app.curSchedGroup; 16122 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16123 "Setting process group of " + app.processName 16124 + " to " + app.curSchedGroup); 16125 if (app.waitingToKill != null && 16126 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16127 killUnneededProcessLocked(app, app.waitingToKill); 16128 success = false; 16129 } else { 16130 if (true) { 16131 long oldId = Binder.clearCallingIdentity(); 16132 try { 16133 Process.setProcessGroup(app.pid, app.curSchedGroup); 16134 } catch (Exception e) { 16135 Slog.w(TAG, "Failed setting process group of " + app.pid 16136 + " to " + app.curSchedGroup); 16137 e.printStackTrace(); 16138 } finally { 16139 Binder.restoreCallingIdentity(oldId); 16140 } 16141 } else { 16142 if (app.thread != null) { 16143 try { 16144 app.thread.setSchedulingGroup(app.curSchedGroup); 16145 } catch (RemoteException e) { 16146 } 16147 } 16148 } 16149 Process.setSwappiness(app.pid, 16150 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16151 } 16152 } 16153 if (app.repForegroundActivities != app.foregroundActivities) { 16154 app.repForegroundActivities = app.foregroundActivities; 16155 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16156 } 16157 if (app.repProcState != app.curProcState) { 16158 app.repProcState = app.curProcState; 16159 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16160 if (app.thread != null) { 16161 try { 16162 if (false) { 16163 //RuntimeException h = new RuntimeException("here"); 16164 Slog.i(TAG, "Sending new process state " + app.repProcState 16165 + " to " + app /*, h*/); 16166 } 16167 app.thread.setProcessState(app.repProcState); 16168 } catch (RemoteException e) { 16169 } 16170 } 16171 } 16172 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16173 app.setProcState)) { 16174 app.lastStateTime = now; 16175 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16176 isSleeping(), now); 16177 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16178 + ProcessList.makeProcStateString(app.setProcState) + " to " 16179 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16180 + (app.nextPssTime-now) + ": " + app); 16181 } else { 16182 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16183 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16184 requestPssLocked(app, app.setProcState); 16185 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16186 isSleeping(), now); 16187 } else if (false && DEBUG_PSS) { 16188 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16189 } 16190 } 16191 if (app.setProcState != app.curProcState) { 16192 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16193 "Proc state change of " + app.processName 16194 + " to " + app.curProcState); 16195 app.setProcState = app.curProcState; 16196 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16197 app.notCachedSinceIdle = false; 16198 } 16199 if (!doingAll) { 16200 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16201 } else { 16202 app.procStateChanged = true; 16203 } 16204 } 16205 16206 if (changes != 0) { 16207 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16208 int i = mPendingProcessChanges.size()-1; 16209 ProcessChangeItem item = null; 16210 while (i >= 0) { 16211 item = mPendingProcessChanges.get(i); 16212 if (item.pid == app.pid) { 16213 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16214 break; 16215 } 16216 i--; 16217 } 16218 if (i < 0) { 16219 // No existing item in pending changes; need a new one. 16220 final int NA = mAvailProcessChanges.size(); 16221 if (NA > 0) { 16222 item = mAvailProcessChanges.remove(NA-1); 16223 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16224 } else { 16225 item = new ProcessChangeItem(); 16226 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16227 } 16228 item.changes = 0; 16229 item.pid = app.pid; 16230 item.uid = app.info.uid; 16231 if (mPendingProcessChanges.size() == 0) { 16232 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16233 "*** Enqueueing dispatch processes changed!"); 16234 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16235 } 16236 mPendingProcessChanges.add(item); 16237 } 16238 item.changes |= changes; 16239 item.processState = app.repProcState; 16240 item.foregroundActivities = app.repForegroundActivities; 16241 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16242 + Integer.toHexString(System.identityHashCode(item)) 16243 + " " + app.toShortString() + ": changes=" + item.changes 16244 + " procState=" + item.processState 16245 + " foreground=" + item.foregroundActivities 16246 + " type=" + app.adjType + " source=" + app.adjSource 16247 + " target=" + app.adjTarget); 16248 } 16249 16250 return success; 16251 } 16252 16253 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16254 if (proc.thread != null) { 16255 if (proc.baseProcessTracker != null) { 16256 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16257 } 16258 if (proc.repProcState >= 0) { 16259 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16260 proc.repProcState); 16261 } 16262 } 16263 } 16264 16265 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16266 ProcessRecord TOP_APP, boolean doingAll, long now) { 16267 if (app.thread == null) { 16268 return false; 16269 } 16270 16271 final boolean wasKeeping = app.keeping; 16272 16273 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16274 16275 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16276 } 16277 16278 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16279 boolean oomAdj) { 16280 if (isForeground != proc.foregroundServices) { 16281 proc.foregroundServices = isForeground; 16282 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16283 proc.info.uid); 16284 if (isForeground) { 16285 if (curProcs == null) { 16286 curProcs = new ArrayList<ProcessRecord>(); 16287 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16288 } 16289 if (!curProcs.contains(proc)) { 16290 curProcs.add(proc); 16291 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16292 proc.info.packageName, proc.info.uid); 16293 } 16294 } else { 16295 if (curProcs != null) { 16296 if (curProcs.remove(proc)) { 16297 mBatteryStatsService.noteEvent( 16298 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16299 proc.info.packageName, proc.info.uid); 16300 if (curProcs.size() <= 0) { 16301 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16302 } 16303 } 16304 } 16305 } 16306 if (oomAdj) { 16307 updateOomAdjLocked(); 16308 } 16309 } 16310 } 16311 16312 private final ActivityRecord resumedAppLocked() { 16313 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16314 String pkg; 16315 int uid; 16316 if (act != null) { 16317 pkg = act.packageName; 16318 uid = act.info.applicationInfo.uid; 16319 } else { 16320 pkg = null; 16321 uid = -1; 16322 } 16323 // Has the UID or resumed package name changed? 16324 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16325 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16326 if (mCurResumedPackage != null) { 16327 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16328 mCurResumedPackage, mCurResumedUid); 16329 } 16330 mCurResumedPackage = pkg; 16331 mCurResumedUid = uid; 16332 if (mCurResumedPackage != null) { 16333 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16334 mCurResumedPackage, mCurResumedUid); 16335 } 16336 } 16337 return act; 16338 } 16339 16340 final boolean updateOomAdjLocked(ProcessRecord app) { 16341 final ActivityRecord TOP_ACT = resumedAppLocked(); 16342 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16343 final boolean wasCached = app.cached; 16344 16345 mAdjSeq++; 16346 16347 // This is the desired cached adjusment we want to tell it to use. 16348 // If our app is currently cached, we know it, and that is it. Otherwise, 16349 // we don't know it yet, and it needs to now be cached we will then 16350 // need to do a complete oom adj. 16351 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16352 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16353 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16354 SystemClock.uptimeMillis()); 16355 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16356 // Changed to/from cached state, so apps after it in the LRU 16357 // list may also be changed. 16358 updateOomAdjLocked(); 16359 } 16360 return success; 16361 } 16362 16363 final void updateOomAdjLocked() { 16364 final ActivityRecord TOP_ACT = resumedAppLocked(); 16365 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16366 final long now = SystemClock.uptimeMillis(); 16367 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16368 final int N = mLruProcesses.size(); 16369 16370 if (false) { 16371 RuntimeException e = new RuntimeException(); 16372 e.fillInStackTrace(); 16373 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16374 } 16375 16376 mAdjSeq++; 16377 mNewNumServiceProcs = 0; 16378 mNewNumAServiceProcs = 0; 16379 16380 final int emptyProcessLimit; 16381 final int cachedProcessLimit; 16382 if (mProcessLimit <= 0) { 16383 emptyProcessLimit = cachedProcessLimit = 0; 16384 } else if (mProcessLimit == 1) { 16385 emptyProcessLimit = 1; 16386 cachedProcessLimit = 0; 16387 } else { 16388 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16389 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16390 } 16391 16392 // Let's determine how many processes we have running vs. 16393 // how many slots we have for background processes; we may want 16394 // to put multiple processes in a slot of there are enough of 16395 // them. 16396 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16397 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16398 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16399 if (numEmptyProcs > cachedProcessLimit) { 16400 // If there are more empty processes than our limit on cached 16401 // processes, then use the cached process limit for the factor. 16402 // This ensures that the really old empty processes get pushed 16403 // down to the bottom, so if we are running low on memory we will 16404 // have a better chance at keeping around more cached processes 16405 // instead of a gazillion empty processes. 16406 numEmptyProcs = cachedProcessLimit; 16407 } 16408 int emptyFactor = numEmptyProcs/numSlots; 16409 if (emptyFactor < 1) emptyFactor = 1; 16410 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16411 if (cachedFactor < 1) cachedFactor = 1; 16412 int stepCached = 0; 16413 int stepEmpty = 0; 16414 int numCached = 0; 16415 int numEmpty = 0; 16416 int numTrimming = 0; 16417 16418 mNumNonCachedProcs = 0; 16419 mNumCachedHiddenProcs = 0; 16420 16421 // First update the OOM adjustment for each of the 16422 // application processes based on their current state. 16423 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16424 int nextCachedAdj = curCachedAdj+1; 16425 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16426 int nextEmptyAdj = curEmptyAdj+2; 16427 for (int i=N-1; i>=0; i--) { 16428 ProcessRecord app = mLruProcesses.get(i); 16429 if (!app.killedByAm && app.thread != null) { 16430 app.procStateChanged = false; 16431 final boolean wasKeeping = app.keeping; 16432 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16433 16434 // If we haven't yet assigned the final cached adj 16435 // to the process, do that now. 16436 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16437 switch (app.curProcState) { 16438 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16439 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16440 // This process is a cached process holding activities... 16441 // assign it the next cached value for that type, and then 16442 // step that cached level. 16443 app.curRawAdj = curCachedAdj; 16444 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16445 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16446 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16447 + ")"); 16448 if (curCachedAdj != nextCachedAdj) { 16449 stepCached++; 16450 if (stepCached >= cachedFactor) { 16451 stepCached = 0; 16452 curCachedAdj = nextCachedAdj; 16453 nextCachedAdj += 2; 16454 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16455 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16456 } 16457 } 16458 } 16459 break; 16460 default: 16461 // For everything else, assign next empty cached process 16462 // level and bump that up. Note that this means that 16463 // long-running services that have dropped down to the 16464 // cached level will be treated as empty (since their process 16465 // state is still as a service), which is what we want. 16466 app.curRawAdj = curEmptyAdj; 16467 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16468 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16469 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16470 + ")"); 16471 if (curEmptyAdj != nextEmptyAdj) { 16472 stepEmpty++; 16473 if (stepEmpty >= emptyFactor) { 16474 stepEmpty = 0; 16475 curEmptyAdj = nextEmptyAdj; 16476 nextEmptyAdj += 2; 16477 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16478 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16479 } 16480 } 16481 } 16482 break; 16483 } 16484 } 16485 16486 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16487 16488 // Count the number of process types. 16489 switch (app.curProcState) { 16490 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16491 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16492 mNumCachedHiddenProcs++; 16493 numCached++; 16494 if (numCached > cachedProcessLimit) { 16495 killUnneededProcessLocked(app, "cached #" + numCached); 16496 } 16497 break; 16498 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16499 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16500 && app.lastActivityTime < oldTime) { 16501 killUnneededProcessLocked(app, "empty for " 16502 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16503 / 1000) + "s"); 16504 } else { 16505 numEmpty++; 16506 if (numEmpty > emptyProcessLimit) { 16507 killUnneededProcessLocked(app, "empty #" + numEmpty); 16508 } 16509 } 16510 break; 16511 default: 16512 mNumNonCachedProcs++; 16513 break; 16514 } 16515 16516 if (app.isolated && app.services.size() <= 0) { 16517 // If this is an isolated process, and there are no 16518 // services running in it, then the process is no longer 16519 // needed. We agressively kill these because we can by 16520 // definition not re-use the same process again, and it is 16521 // good to avoid having whatever code was running in them 16522 // left sitting around after no longer needed. 16523 killUnneededProcessLocked(app, "isolated not needed"); 16524 } 16525 16526 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16527 && !app.killedByAm) { 16528 numTrimming++; 16529 } 16530 } 16531 } 16532 16533 mNumServiceProcs = mNewNumServiceProcs; 16534 16535 // Now determine the memory trimming level of background processes. 16536 // Unfortunately we need to start at the back of the list to do this 16537 // properly. We only do this if the number of background apps we 16538 // are managing to keep around is less than half the maximum we desire; 16539 // if we are keeping a good number around, we'll let them use whatever 16540 // memory they want. 16541 final int numCachedAndEmpty = numCached + numEmpty; 16542 int memFactor; 16543 if (numCached <= ProcessList.TRIM_CACHED_APPS 16544 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16545 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16546 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16547 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16548 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16549 } else { 16550 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16551 } 16552 } else { 16553 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16554 } 16555 // We always allow the memory level to go up (better). We only allow it to go 16556 // down if we are in a state where that is allowed, *and* the total number of processes 16557 // has gone down since last time. 16558 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16559 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16560 + " last=" + mLastNumProcesses); 16561 if (memFactor > mLastMemoryLevel) { 16562 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16563 memFactor = mLastMemoryLevel; 16564 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16565 } 16566 } 16567 mLastMemoryLevel = memFactor; 16568 mLastNumProcesses = mLruProcesses.size(); 16569 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16570 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16571 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16572 if (mLowRamStartTime == 0) { 16573 mLowRamStartTime = now; 16574 } 16575 int step = 0; 16576 int fgTrimLevel; 16577 switch (memFactor) { 16578 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16579 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16580 break; 16581 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16582 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16583 break; 16584 default: 16585 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16586 break; 16587 } 16588 int factor = numTrimming/3; 16589 int minFactor = 2; 16590 if (mHomeProcess != null) minFactor++; 16591 if (mPreviousProcess != null) minFactor++; 16592 if (factor < minFactor) factor = minFactor; 16593 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16594 for (int i=N-1; i>=0; i--) { 16595 ProcessRecord app = mLruProcesses.get(i); 16596 if (allChanged || app.procStateChanged) { 16597 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16598 app.procStateChanged = false; 16599 } 16600 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16601 && !app.killedByAm) { 16602 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16603 try { 16604 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16605 "Trimming memory of " + app.processName 16606 + " to " + curLevel); 16607 app.thread.scheduleTrimMemory(curLevel); 16608 } catch (RemoteException e) { 16609 } 16610 if (false) { 16611 // For now we won't do this; our memory trimming seems 16612 // to be good enough at this point that destroying 16613 // activities causes more harm than good. 16614 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16615 && app != mHomeProcess && app != mPreviousProcess) { 16616 // Need to do this on its own message because the stack may not 16617 // be in a consistent state at this point. 16618 // For these apps we will also finish their activities 16619 // to help them free memory. 16620 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16621 } 16622 } 16623 } 16624 app.trimMemoryLevel = curLevel; 16625 step++; 16626 if (step >= factor) { 16627 step = 0; 16628 switch (curLevel) { 16629 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16630 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16631 break; 16632 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16633 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16634 break; 16635 } 16636 } 16637 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16638 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16639 && app.thread != null) { 16640 try { 16641 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16642 "Trimming memory of heavy-weight " + app.processName 16643 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16644 app.thread.scheduleTrimMemory( 16645 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16646 } catch (RemoteException e) { 16647 } 16648 } 16649 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16650 } else { 16651 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16652 || app.systemNoUi) && app.pendingUiClean) { 16653 // If this application is now in the background and it 16654 // had done UI, then give it the special trim level to 16655 // have it free UI resources. 16656 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16657 if (app.trimMemoryLevel < level && app.thread != null) { 16658 try { 16659 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16660 "Trimming memory of bg-ui " + app.processName 16661 + " to " + level); 16662 app.thread.scheduleTrimMemory(level); 16663 } catch (RemoteException e) { 16664 } 16665 } 16666 app.pendingUiClean = false; 16667 } 16668 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16669 try { 16670 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16671 "Trimming memory of fg " + app.processName 16672 + " to " + fgTrimLevel); 16673 app.thread.scheduleTrimMemory(fgTrimLevel); 16674 } catch (RemoteException e) { 16675 } 16676 } 16677 app.trimMemoryLevel = fgTrimLevel; 16678 } 16679 } 16680 } else { 16681 if (mLowRamStartTime != 0) { 16682 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16683 mLowRamStartTime = 0; 16684 } 16685 for (int i=N-1; i>=0; i--) { 16686 ProcessRecord app = mLruProcesses.get(i); 16687 if (allChanged || app.procStateChanged) { 16688 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16689 app.procStateChanged = false; 16690 } 16691 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16692 || app.systemNoUi) && app.pendingUiClean) { 16693 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16694 && app.thread != null) { 16695 try { 16696 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16697 "Trimming memory of ui hidden " + app.processName 16698 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16699 app.thread.scheduleTrimMemory( 16700 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16701 } catch (RemoteException e) { 16702 } 16703 } 16704 app.pendingUiClean = false; 16705 } 16706 app.trimMemoryLevel = 0; 16707 } 16708 } 16709 16710 if (mAlwaysFinishActivities) { 16711 // Need to do this on its own message because the stack may not 16712 // be in a consistent state at this point. 16713 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16714 } 16715 16716 if (allChanged) { 16717 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16718 } 16719 16720 if (mProcessStats.shouldWriteNowLocked(now)) { 16721 mHandler.post(new Runnable() { 16722 @Override public void run() { 16723 synchronized (ActivityManagerService.this) { 16724 mProcessStats.writeStateAsyncLocked(); 16725 } 16726 } 16727 }); 16728 } 16729 16730 if (DEBUG_OOM_ADJ) { 16731 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16732 } 16733 } 16734 16735 final void trimApplications() { 16736 synchronized (this) { 16737 int i; 16738 16739 // First remove any unused application processes whose package 16740 // has been removed. 16741 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16742 final ProcessRecord app = mRemovedProcesses.get(i); 16743 if (app.activities.size() == 0 16744 && app.curReceiver == null && app.services.size() == 0) { 16745 Slog.i( 16746 TAG, "Exiting empty application process " 16747 + app.processName + " (" 16748 + (app.thread != null ? app.thread.asBinder() : null) 16749 + ")\n"); 16750 if (app.pid > 0 && app.pid != MY_PID) { 16751 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16752 app.processName, app.setAdj, "empty"); 16753 app.killedByAm = true; 16754 Process.killProcessQuiet(app.pid); 16755 Process.killProcessGroup(app.info.uid, app.pid); 16756 } else { 16757 try { 16758 app.thread.scheduleExit(); 16759 } catch (Exception e) { 16760 // Ignore exceptions. 16761 } 16762 } 16763 cleanUpApplicationRecordLocked(app, false, true, -1); 16764 mRemovedProcesses.remove(i); 16765 16766 if (app.persistent) { 16767 addAppLocked(app.info, false, null /* ABI override */); 16768 } 16769 } 16770 } 16771 16772 // Now update the oom adj for all processes. 16773 updateOomAdjLocked(); 16774 } 16775 } 16776 16777 /** This method sends the specified signal to each of the persistent apps */ 16778 public void signalPersistentProcesses(int sig) throws RemoteException { 16779 if (sig != Process.SIGNAL_USR1) { 16780 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16781 } 16782 16783 synchronized (this) { 16784 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16785 != PackageManager.PERMISSION_GRANTED) { 16786 throw new SecurityException("Requires permission " 16787 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16788 } 16789 16790 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16791 ProcessRecord r = mLruProcesses.get(i); 16792 if (r.thread != null && r.persistent) { 16793 Process.sendSignal(r.pid, sig); 16794 } 16795 } 16796 } 16797 } 16798 16799 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16800 if (proc == null || proc == mProfileProc) { 16801 proc = mProfileProc; 16802 path = mProfileFile; 16803 profileType = mProfileType; 16804 clearProfilerLocked(); 16805 } 16806 if (proc == null) { 16807 return; 16808 } 16809 try { 16810 proc.thread.profilerControl(false, path, null, profileType); 16811 } catch (RemoteException e) { 16812 throw new IllegalStateException("Process disappeared"); 16813 } 16814 } 16815 16816 private void clearProfilerLocked() { 16817 if (mProfileFd != null) { 16818 try { 16819 mProfileFd.close(); 16820 } catch (IOException e) { 16821 } 16822 } 16823 mProfileApp = null; 16824 mProfileProc = null; 16825 mProfileFile = null; 16826 mProfileType = 0; 16827 mAutoStopProfiler = false; 16828 } 16829 16830 public boolean profileControl(String process, int userId, boolean start, 16831 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16832 16833 try { 16834 synchronized (this) { 16835 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16836 // its own permission. 16837 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16838 != PackageManager.PERMISSION_GRANTED) { 16839 throw new SecurityException("Requires permission " 16840 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16841 } 16842 16843 if (start && fd == null) { 16844 throw new IllegalArgumentException("null fd"); 16845 } 16846 16847 ProcessRecord proc = null; 16848 if (process != null) { 16849 proc = findProcessLocked(process, userId, "profileControl"); 16850 } 16851 16852 if (start && (proc == null || proc.thread == null)) { 16853 throw new IllegalArgumentException("Unknown process: " + process); 16854 } 16855 16856 if (start) { 16857 stopProfilerLocked(null, null, 0); 16858 setProfileApp(proc.info, proc.processName, path, fd, false); 16859 mProfileProc = proc; 16860 mProfileType = profileType; 16861 try { 16862 fd = fd.dup(); 16863 } catch (IOException e) { 16864 fd = null; 16865 } 16866 proc.thread.profilerControl(start, path, fd, profileType); 16867 fd = null; 16868 mProfileFd = null; 16869 } else { 16870 stopProfilerLocked(proc, path, profileType); 16871 if (fd != null) { 16872 try { 16873 fd.close(); 16874 } catch (IOException e) { 16875 } 16876 } 16877 } 16878 16879 return true; 16880 } 16881 } catch (RemoteException e) { 16882 throw new IllegalStateException("Process disappeared"); 16883 } finally { 16884 if (fd != null) { 16885 try { 16886 fd.close(); 16887 } catch (IOException e) { 16888 } 16889 } 16890 } 16891 } 16892 16893 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16894 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16895 userId, true, ALLOW_FULL_ONLY, callName, null); 16896 ProcessRecord proc = null; 16897 try { 16898 int pid = Integer.parseInt(process); 16899 synchronized (mPidsSelfLocked) { 16900 proc = mPidsSelfLocked.get(pid); 16901 } 16902 } catch (NumberFormatException e) { 16903 } 16904 16905 if (proc == null) { 16906 ArrayMap<String, SparseArray<ProcessRecord>> all 16907 = mProcessNames.getMap(); 16908 SparseArray<ProcessRecord> procs = all.get(process); 16909 if (procs != null && procs.size() > 0) { 16910 proc = procs.valueAt(0); 16911 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16912 for (int i=1; i<procs.size(); i++) { 16913 ProcessRecord thisProc = procs.valueAt(i); 16914 if (thisProc.userId == userId) { 16915 proc = thisProc; 16916 break; 16917 } 16918 } 16919 } 16920 } 16921 } 16922 16923 return proc; 16924 } 16925 16926 public boolean dumpHeap(String process, int userId, boolean managed, 16927 String path, ParcelFileDescriptor fd) throws RemoteException { 16928 16929 try { 16930 synchronized (this) { 16931 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16932 // its own permission (same as profileControl). 16933 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16934 != PackageManager.PERMISSION_GRANTED) { 16935 throw new SecurityException("Requires permission " 16936 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16937 } 16938 16939 if (fd == null) { 16940 throw new IllegalArgumentException("null fd"); 16941 } 16942 16943 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16944 if (proc == null || proc.thread == null) { 16945 throw new IllegalArgumentException("Unknown process: " + process); 16946 } 16947 16948 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16949 if (!isDebuggable) { 16950 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16951 throw new SecurityException("Process not debuggable: " + proc); 16952 } 16953 } 16954 16955 proc.thread.dumpHeap(managed, path, fd); 16956 fd = null; 16957 return true; 16958 } 16959 } catch (RemoteException e) { 16960 throw new IllegalStateException("Process disappeared"); 16961 } finally { 16962 if (fd != null) { 16963 try { 16964 fd.close(); 16965 } catch (IOException e) { 16966 } 16967 } 16968 } 16969 } 16970 16971 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16972 public void monitor() { 16973 synchronized (this) { } 16974 } 16975 16976 void onCoreSettingsChange(Bundle settings) { 16977 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16978 ProcessRecord processRecord = mLruProcesses.get(i); 16979 try { 16980 if (processRecord.thread != null) { 16981 processRecord.thread.setCoreSettings(settings); 16982 } 16983 } catch (RemoteException re) { 16984 /* ignore */ 16985 } 16986 } 16987 } 16988 16989 // Multi-user methods 16990 16991 /** 16992 * Start user, if its not already running, but don't bring it to foreground. 16993 */ 16994 @Override 16995 public boolean startUserInBackground(final int userId) { 16996 return startUser(userId, /* foreground */ false); 16997 } 16998 16999 /** 17000 * Refreshes the list of users related to the current user when either a 17001 * user switch happens or when a new related user is started in the 17002 * background. 17003 */ 17004 private void updateCurrentProfileIdsLocked() { 17005 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17006 mCurrentUserId, false /* enabledOnly */); 17007 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17008 for (int i = 0; i < currentProfileIds.length; i++) { 17009 currentProfileIds[i] = profiles.get(i).id; 17010 } 17011 mCurrentProfileIds = currentProfileIds; 17012 17013 synchronized (mUserProfileGroupIdsSelfLocked) { 17014 mUserProfileGroupIdsSelfLocked.clear(); 17015 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17016 for (int i = 0; i < users.size(); i++) { 17017 UserInfo user = users.get(i); 17018 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17019 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17020 } 17021 } 17022 } 17023 } 17024 17025 private Set getProfileIdsLocked(int userId) { 17026 Set userIds = new HashSet<Integer>(); 17027 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17028 userId, false /* enabledOnly */); 17029 for (UserInfo user : profiles) { 17030 userIds.add(Integer.valueOf(user.id)); 17031 } 17032 return userIds; 17033 } 17034 17035 @Override 17036 public boolean switchUser(final int userId) { 17037 return startUser(userId, /* foregound */ true); 17038 } 17039 17040 private boolean startUser(final int userId, boolean foreground) { 17041 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17042 != PackageManager.PERMISSION_GRANTED) { 17043 String msg = "Permission Denial: switchUser() from pid=" 17044 + Binder.getCallingPid() 17045 + ", uid=" + Binder.getCallingUid() 17046 + " requires " + INTERACT_ACROSS_USERS_FULL; 17047 Slog.w(TAG, msg); 17048 throw new SecurityException(msg); 17049 } 17050 17051 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17052 17053 final long ident = Binder.clearCallingIdentity(); 17054 try { 17055 synchronized (this) { 17056 final int oldUserId = mCurrentUserId; 17057 if (oldUserId == userId) { 17058 return true; 17059 } 17060 17061 mStackSupervisor.setLockTaskModeLocked(null, false); 17062 17063 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17064 if (userInfo == null) { 17065 Slog.w(TAG, "No user info for user #" + userId); 17066 return false; 17067 } 17068 17069 if (foreground) { 17070 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17071 R.anim.screen_user_enter); 17072 } 17073 17074 boolean needStart = false; 17075 17076 // If the user we are switching to is not currently started, then 17077 // we need to start it now. 17078 if (mStartedUsers.get(userId) == null) { 17079 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17080 updateStartedUserArrayLocked(); 17081 needStart = true; 17082 } 17083 17084 final Integer userIdInt = Integer.valueOf(userId); 17085 mUserLru.remove(userIdInt); 17086 mUserLru.add(userIdInt); 17087 17088 if (foreground) { 17089 mCurrentUserId = userId; 17090 updateCurrentProfileIdsLocked(); 17091 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17092 // Once the internal notion of the active user has switched, we lock the device 17093 // with the option to show the user switcher on the keyguard. 17094 mWindowManager.lockNow(null); 17095 } else { 17096 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17097 updateCurrentProfileIdsLocked(); 17098 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17099 mUserLru.remove(currentUserIdInt); 17100 mUserLru.add(currentUserIdInt); 17101 } 17102 17103 final UserStartedState uss = mStartedUsers.get(userId); 17104 17105 // Make sure user is in the started state. If it is currently 17106 // stopping, we need to knock that off. 17107 if (uss.mState == UserStartedState.STATE_STOPPING) { 17108 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17109 // so we can just fairly silently bring the user back from 17110 // the almost-dead. 17111 uss.mState = UserStartedState.STATE_RUNNING; 17112 updateStartedUserArrayLocked(); 17113 needStart = true; 17114 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17115 // This means ACTION_SHUTDOWN has been sent, so we will 17116 // need to treat this as a new boot of the user. 17117 uss.mState = UserStartedState.STATE_BOOTING; 17118 updateStartedUserArrayLocked(); 17119 needStart = true; 17120 } 17121 17122 if (uss.mState == UserStartedState.STATE_BOOTING) { 17123 // Booting up a new user, need to tell system services about it. 17124 // Note that this is on the same handler as scheduling of broadcasts, 17125 // which is important because it needs to go first. 17126 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 17127 } 17128 17129 if (foreground) { 17130 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 17131 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17132 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17133 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17134 oldUserId, userId, uss)); 17135 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17136 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17137 } 17138 17139 if (needStart) { 17140 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17141 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17142 | Intent.FLAG_RECEIVER_FOREGROUND); 17143 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17144 broadcastIntentLocked(null, null, intent, 17145 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17146 false, false, MY_PID, Process.SYSTEM_UID, userId); 17147 } 17148 17149 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17150 if (userId != UserHandle.USER_OWNER) { 17151 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17152 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17153 broadcastIntentLocked(null, null, intent, null, 17154 new IIntentReceiver.Stub() { 17155 public void performReceive(Intent intent, int resultCode, 17156 String data, Bundle extras, boolean ordered, 17157 boolean sticky, int sendingUser) { 17158 userInitialized(uss, userId); 17159 } 17160 }, 0, null, null, null, AppOpsManager.OP_NONE, 17161 true, false, MY_PID, Process.SYSTEM_UID, 17162 userId); 17163 uss.initializing = true; 17164 } else { 17165 getUserManagerLocked().makeInitialized(userInfo.id); 17166 } 17167 } 17168 17169 if (foreground) { 17170 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17171 if (homeInFront) { 17172 startHomeActivityLocked(userId); 17173 } else { 17174 mStackSupervisor.resumeTopActivitiesLocked(); 17175 } 17176 EventLogTags.writeAmSwitchUser(userId); 17177 getUserManagerLocked().userForeground(userId); 17178 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17179 } else { 17180 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17181 } 17182 17183 if (needStart) { 17184 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17185 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17186 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17187 broadcastIntentLocked(null, null, intent, 17188 null, new IIntentReceiver.Stub() { 17189 @Override 17190 public void performReceive(Intent intent, int resultCode, String data, 17191 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17192 throws RemoteException { 17193 } 17194 }, 0, null, null, 17195 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17196 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17197 } 17198 } 17199 } finally { 17200 Binder.restoreCallingIdentity(ident); 17201 } 17202 17203 return true; 17204 } 17205 17206 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17207 long ident = Binder.clearCallingIdentity(); 17208 try { 17209 Intent intent; 17210 if (oldUserId >= 0) { 17211 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17212 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17213 int count = profiles.size(); 17214 for (int i = 0; i < count; i++) { 17215 int profileUserId = profiles.get(i).id; 17216 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17217 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17218 | Intent.FLAG_RECEIVER_FOREGROUND); 17219 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17220 broadcastIntentLocked(null, null, intent, 17221 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17222 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17223 } 17224 } 17225 if (newUserId >= 0) { 17226 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17227 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17228 int count = profiles.size(); 17229 for (int i = 0; i < count; i++) { 17230 int profileUserId = profiles.get(i).id; 17231 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17232 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17233 | Intent.FLAG_RECEIVER_FOREGROUND); 17234 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17235 broadcastIntentLocked(null, null, intent, 17236 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17237 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17238 } 17239 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17241 | Intent.FLAG_RECEIVER_FOREGROUND); 17242 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17243 broadcastIntentLocked(null, null, intent, 17244 null, null, 0, null, null, 17245 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17246 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17247 } 17248 } finally { 17249 Binder.restoreCallingIdentity(ident); 17250 } 17251 } 17252 17253 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17254 final int newUserId) { 17255 final int N = mUserSwitchObservers.beginBroadcast(); 17256 if (N > 0) { 17257 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17258 int mCount = 0; 17259 @Override 17260 public void sendResult(Bundle data) throws RemoteException { 17261 synchronized (ActivityManagerService.this) { 17262 if (mCurUserSwitchCallback == this) { 17263 mCount++; 17264 if (mCount == N) { 17265 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17266 } 17267 } 17268 } 17269 } 17270 }; 17271 synchronized (this) { 17272 uss.switching = true; 17273 mCurUserSwitchCallback = callback; 17274 } 17275 for (int i=0; i<N; i++) { 17276 try { 17277 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17278 newUserId, callback); 17279 } catch (RemoteException e) { 17280 } 17281 } 17282 } else { 17283 synchronized (this) { 17284 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17285 } 17286 } 17287 mUserSwitchObservers.finishBroadcast(); 17288 } 17289 17290 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17291 synchronized (this) { 17292 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17293 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17294 } 17295 } 17296 17297 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17298 mCurUserSwitchCallback = null; 17299 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17300 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17301 oldUserId, newUserId, uss)); 17302 } 17303 17304 void userInitialized(UserStartedState uss, int newUserId) { 17305 completeSwitchAndInitalize(uss, newUserId, true, false); 17306 } 17307 17308 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17309 completeSwitchAndInitalize(uss, newUserId, false, true); 17310 } 17311 17312 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17313 boolean clearInitializing, boolean clearSwitching) { 17314 boolean unfrozen = false; 17315 synchronized (this) { 17316 if (clearInitializing) { 17317 uss.initializing = false; 17318 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17319 } 17320 if (clearSwitching) { 17321 uss.switching = false; 17322 } 17323 if (!uss.switching && !uss.initializing) { 17324 mWindowManager.stopFreezingScreen(); 17325 unfrozen = true; 17326 } 17327 } 17328 if (unfrozen) { 17329 final int N = mUserSwitchObservers.beginBroadcast(); 17330 for (int i=0; i<N; i++) { 17331 try { 17332 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17333 } catch (RemoteException e) { 17334 } 17335 } 17336 mUserSwitchObservers.finishBroadcast(); 17337 } 17338 } 17339 17340 void scheduleStartProfilesLocked() { 17341 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17342 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17343 DateUtils.SECOND_IN_MILLIS); 17344 } 17345 } 17346 17347 void startProfilesLocked() { 17348 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17349 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17350 mCurrentUserId, false /* enabledOnly */); 17351 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17352 for (UserInfo user : profiles) { 17353 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17354 && user.id != mCurrentUserId) { 17355 toStart.add(user); 17356 } 17357 } 17358 final int n = toStart.size(); 17359 int i = 0; 17360 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17361 startUserInBackground(toStart.get(i).id); 17362 } 17363 if (i < n) { 17364 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17365 } 17366 } 17367 17368 void finishUserBoot(UserStartedState uss) { 17369 synchronized (this) { 17370 if (uss.mState == UserStartedState.STATE_BOOTING 17371 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17372 uss.mState = UserStartedState.STATE_RUNNING; 17373 final int userId = uss.mHandle.getIdentifier(); 17374 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17375 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17376 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17377 broadcastIntentLocked(null, null, intent, 17378 null, null, 0, null, null, 17379 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17380 true, false, MY_PID, Process.SYSTEM_UID, userId); 17381 } 17382 } 17383 } 17384 17385 void finishUserSwitch(UserStartedState uss) { 17386 synchronized (this) { 17387 finishUserBoot(uss); 17388 17389 startProfilesLocked(); 17390 17391 int num = mUserLru.size(); 17392 int i = 0; 17393 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17394 Integer oldUserId = mUserLru.get(i); 17395 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17396 if (oldUss == null) { 17397 // Shouldn't happen, but be sane if it does. 17398 mUserLru.remove(i); 17399 num--; 17400 continue; 17401 } 17402 if (oldUss.mState == UserStartedState.STATE_STOPPING 17403 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17404 // This user is already stopping, doesn't count. 17405 num--; 17406 i++; 17407 continue; 17408 } 17409 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17410 // Owner and current can't be stopped, but count as running. 17411 i++; 17412 continue; 17413 } 17414 // This is a user to be stopped. 17415 stopUserLocked(oldUserId, null); 17416 num--; 17417 i++; 17418 } 17419 } 17420 } 17421 17422 @Override 17423 public int stopUser(final int userId, final IStopUserCallback callback) { 17424 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17425 != PackageManager.PERMISSION_GRANTED) { 17426 String msg = "Permission Denial: switchUser() from pid=" 17427 + Binder.getCallingPid() 17428 + ", uid=" + Binder.getCallingUid() 17429 + " requires " + INTERACT_ACROSS_USERS_FULL; 17430 Slog.w(TAG, msg); 17431 throw new SecurityException(msg); 17432 } 17433 if (userId <= 0) { 17434 throw new IllegalArgumentException("Can't stop primary user " + userId); 17435 } 17436 synchronized (this) { 17437 return stopUserLocked(userId, callback); 17438 } 17439 } 17440 17441 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17442 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17443 if (mCurrentUserId == userId) { 17444 return ActivityManager.USER_OP_IS_CURRENT; 17445 } 17446 17447 final UserStartedState uss = mStartedUsers.get(userId); 17448 if (uss == null) { 17449 // User is not started, nothing to do... but we do need to 17450 // callback if requested. 17451 if (callback != null) { 17452 mHandler.post(new Runnable() { 17453 @Override 17454 public void run() { 17455 try { 17456 callback.userStopped(userId); 17457 } catch (RemoteException e) { 17458 } 17459 } 17460 }); 17461 } 17462 return ActivityManager.USER_OP_SUCCESS; 17463 } 17464 17465 if (callback != null) { 17466 uss.mStopCallbacks.add(callback); 17467 } 17468 17469 if (uss.mState != UserStartedState.STATE_STOPPING 17470 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17471 uss.mState = UserStartedState.STATE_STOPPING; 17472 updateStartedUserArrayLocked(); 17473 17474 long ident = Binder.clearCallingIdentity(); 17475 try { 17476 // We are going to broadcast ACTION_USER_STOPPING and then 17477 // once that is done send a final ACTION_SHUTDOWN and then 17478 // stop the user. 17479 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17480 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17481 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17482 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17483 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17484 // This is the result receiver for the final shutdown broadcast. 17485 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17486 @Override 17487 public void performReceive(Intent intent, int resultCode, String data, 17488 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17489 finishUserStop(uss); 17490 } 17491 }; 17492 // This is the result receiver for the initial stopping broadcast. 17493 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17494 @Override 17495 public void performReceive(Intent intent, int resultCode, String data, 17496 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17497 // On to the next. 17498 synchronized (ActivityManagerService.this) { 17499 if (uss.mState != UserStartedState.STATE_STOPPING) { 17500 // Whoops, we are being started back up. Abort, abort! 17501 return; 17502 } 17503 uss.mState = UserStartedState.STATE_SHUTDOWN; 17504 } 17505 mSystemServiceManager.stopUser(userId); 17506 broadcastIntentLocked(null, null, shutdownIntent, 17507 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17508 true, false, MY_PID, Process.SYSTEM_UID, userId); 17509 } 17510 }; 17511 // Kick things off. 17512 broadcastIntentLocked(null, null, stoppingIntent, 17513 null, stoppingReceiver, 0, null, null, 17514 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17515 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17516 } finally { 17517 Binder.restoreCallingIdentity(ident); 17518 } 17519 } 17520 17521 return ActivityManager.USER_OP_SUCCESS; 17522 } 17523 17524 void finishUserStop(UserStartedState uss) { 17525 final int userId = uss.mHandle.getIdentifier(); 17526 boolean stopped; 17527 ArrayList<IStopUserCallback> callbacks; 17528 synchronized (this) { 17529 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17530 if (mStartedUsers.get(userId) != uss) { 17531 stopped = false; 17532 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17533 stopped = false; 17534 } else { 17535 stopped = true; 17536 // User can no longer run. 17537 mStartedUsers.remove(userId); 17538 mUserLru.remove(Integer.valueOf(userId)); 17539 updateStartedUserArrayLocked(); 17540 17541 // Clean up all state and processes associated with the user. 17542 // Kill all the processes for the user. 17543 forceStopUserLocked(userId, "finish user"); 17544 } 17545 } 17546 17547 for (int i=0; i<callbacks.size(); i++) { 17548 try { 17549 if (stopped) callbacks.get(i).userStopped(userId); 17550 else callbacks.get(i).userStopAborted(userId); 17551 } catch (RemoteException e) { 17552 } 17553 } 17554 17555 if (stopped) { 17556 mSystemServiceManager.cleanupUser(userId); 17557 synchronized (this) { 17558 mStackSupervisor.removeUserLocked(userId); 17559 } 17560 } 17561 } 17562 17563 @Override 17564 public UserInfo getCurrentUser() { 17565 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 17566 != PackageManager.PERMISSION_GRANTED) && ( 17567 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17568 != PackageManager.PERMISSION_GRANTED)) { 17569 String msg = "Permission Denial: getCurrentUser() from pid=" 17570 + Binder.getCallingPid() 17571 + ", uid=" + Binder.getCallingUid() 17572 + " requires " + INTERACT_ACROSS_USERS; 17573 Slog.w(TAG, msg); 17574 throw new SecurityException(msg); 17575 } 17576 synchronized (this) { 17577 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17578 } 17579 } 17580 17581 int getCurrentUserIdLocked() { 17582 return mCurrentUserId; 17583 } 17584 17585 @Override 17586 public boolean isUserRunning(int userId, boolean orStopped) { 17587 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17588 != PackageManager.PERMISSION_GRANTED) { 17589 String msg = "Permission Denial: isUserRunning() from pid=" 17590 + Binder.getCallingPid() 17591 + ", uid=" + Binder.getCallingUid() 17592 + " requires " + INTERACT_ACROSS_USERS; 17593 Slog.w(TAG, msg); 17594 throw new SecurityException(msg); 17595 } 17596 synchronized (this) { 17597 return isUserRunningLocked(userId, orStopped); 17598 } 17599 } 17600 17601 boolean isUserRunningLocked(int userId, boolean orStopped) { 17602 UserStartedState state = mStartedUsers.get(userId); 17603 if (state == null) { 17604 return false; 17605 } 17606 if (orStopped) { 17607 return true; 17608 } 17609 return state.mState != UserStartedState.STATE_STOPPING 17610 && state.mState != UserStartedState.STATE_SHUTDOWN; 17611 } 17612 17613 @Override 17614 public int[] getRunningUserIds() { 17615 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17616 != PackageManager.PERMISSION_GRANTED) { 17617 String msg = "Permission Denial: isUserRunning() from pid=" 17618 + Binder.getCallingPid() 17619 + ", uid=" + Binder.getCallingUid() 17620 + " requires " + INTERACT_ACROSS_USERS; 17621 Slog.w(TAG, msg); 17622 throw new SecurityException(msg); 17623 } 17624 synchronized (this) { 17625 return mStartedUserArray; 17626 } 17627 } 17628 17629 private void updateStartedUserArrayLocked() { 17630 int num = 0; 17631 for (int i=0; i<mStartedUsers.size(); i++) { 17632 UserStartedState uss = mStartedUsers.valueAt(i); 17633 // This list does not include stopping users. 17634 if (uss.mState != UserStartedState.STATE_STOPPING 17635 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17636 num++; 17637 } 17638 } 17639 mStartedUserArray = new int[num]; 17640 num = 0; 17641 for (int i=0; i<mStartedUsers.size(); i++) { 17642 UserStartedState uss = mStartedUsers.valueAt(i); 17643 if (uss.mState != UserStartedState.STATE_STOPPING 17644 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17645 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17646 num++; 17647 } 17648 } 17649 } 17650 17651 @Override 17652 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17653 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17654 != PackageManager.PERMISSION_GRANTED) { 17655 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17656 + Binder.getCallingPid() 17657 + ", uid=" + Binder.getCallingUid() 17658 + " requires " + INTERACT_ACROSS_USERS_FULL; 17659 Slog.w(TAG, msg); 17660 throw new SecurityException(msg); 17661 } 17662 17663 mUserSwitchObservers.register(observer); 17664 } 17665 17666 @Override 17667 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17668 mUserSwitchObservers.unregister(observer); 17669 } 17670 17671 private boolean userExists(int userId) { 17672 if (userId == 0) { 17673 return true; 17674 } 17675 UserManagerService ums = getUserManagerLocked(); 17676 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17677 } 17678 17679 int[] getUsersLocked() { 17680 UserManagerService ums = getUserManagerLocked(); 17681 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17682 } 17683 17684 UserManagerService getUserManagerLocked() { 17685 if (mUserManager == null) { 17686 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17687 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17688 } 17689 return mUserManager; 17690 } 17691 17692 private int applyUserId(int uid, int userId) { 17693 return UserHandle.getUid(userId, uid); 17694 } 17695 17696 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17697 if (info == null) return null; 17698 ApplicationInfo newInfo = new ApplicationInfo(info); 17699 newInfo.uid = applyUserId(info.uid, userId); 17700 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17701 + info.packageName; 17702 return newInfo; 17703 } 17704 17705 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17706 if (aInfo == null 17707 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17708 return aInfo; 17709 } 17710 17711 ActivityInfo info = new ActivityInfo(aInfo); 17712 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17713 return info; 17714 } 17715 17716 private final class LocalService extends ActivityManagerInternal { 17717 @Override 17718 public void goingToSleep() { 17719 ActivityManagerService.this.goingToSleep(); 17720 } 17721 17722 @Override 17723 public void wakingUp() { 17724 ActivityManagerService.this.wakingUp(); 17725 } 17726 } 17727 17728 /** 17729 * An implementation of IAppTask, that allows an app to manage its own tasks via 17730 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17731 * only the process that calls getAppTasks() can call the AppTask methods. 17732 */ 17733 class AppTaskImpl extends IAppTask.Stub { 17734 private int mTaskId; 17735 private int mCallingUid; 17736 17737 public AppTaskImpl(int taskId, int callingUid) { 17738 mTaskId = taskId; 17739 mCallingUid = callingUid; 17740 } 17741 17742 @Override 17743 public void finishAndRemoveTask() { 17744 // Ensure that we are called from the same process that created this AppTask 17745 if (mCallingUid != Binder.getCallingUid()) { 17746 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17747 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17748 return; 17749 } 17750 17751 synchronized (ActivityManagerService.this) { 17752 long origId = Binder.clearCallingIdentity(); 17753 try { 17754 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17755 if (tr != null) { 17756 // Only kill the process if we are not a new document 17757 int flags = tr.getBaseIntent().getFlags(); 17758 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17759 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17760 removeTaskByIdLocked(mTaskId, 17761 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17762 } 17763 } finally { 17764 Binder.restoreCallingIdentity(origId); 17765 } 17766 } 17767 } 17768 17769 @Override 17770 public ActivityManager.RecentTaskInfo getTaskInfo() { 17771 // Ensure that we are called from the same process that created this AppTask 17772 if (mCallingUid != Binder.getCallingUid()) { 17773 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17774 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17775 return null; 17776 } 17777 17778 synchronized (ActivityManagerService.this) { 17779 long origId = Binder.clearCallingIdentity(); 17780 try { 17781 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17782 if (tr != null) { 17783 return createRecentTaskInfoFromTaskRecord(tr); 17784 } 17785 } finally { 17786 Binder.restoreCallingIdentity(origId); 17787 } 17788 return null; 17789 } 17790 } 17791 } 17792} 17793