ActivityManagerService.java revision 422570ea3fe5bf6c4dbc4d96cf47734252ffe703
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.IActivityContainer; 37import android.app.IActivityContainerCallback; 38import android.app.IAppTask; 39import android.app.admin.DevicePolicyManager; 40import android.app.usage.UsageStats; 41import android.app.usage.UsageStatsManagerInternal; 42import android.appwidget.AppWidgetManager; 43import android.graphics.Rect; 44import android.os.BatteryStats; 45import android.os.PersistableBundle; 46import android.service.voice.IVoiceInteractionSession; 47import android.util.ArrayMap; 48import android.util.ArraySet; 49import android.util.SparseIntArray; 50 51import com.android.internal.R; 52import com.android.internal.annotations.GuardedBy; 53import com.android.internal.app.IAppOpsService; 54import com.android.internal.app.IVoiceInteractor; 55import com.android.internal.app.ProcessMap; 56import com.android.internal.app.ProcessStats; 57import com.android.internal.content.PackageMonitor; 58import com.android.internal.os.BackgroundThread; 59import com.android.internal.os.BatteryStatsImpl; 60import com.android.internal.os.ProcessCpuTracker; 61import com.android.internal.os.TransferPipe; 62import com.android.internal.os.Zygote; 63import com.android.internal.util.FastPrintWriter; 64import com.android.internal.util.FastXmlSerializer; 65import com.android.internal.util.MemInfoReader; 66import com.android.internal.util.Preconditions; 67import com.android.server.AppOpsService; 68import com.android.server.AttributeCache; 69import com.android.server.IntentResolver; 70import com.android.server.LocalServices; 71import com.android.server.ServiceThread; 72import com.android.server.SystemService; 73import com.android.server.SystemServiceManager; 74import com.android.server.Watchdog; 75import com.android.server.am.ActivityStack.ActivityState; 76import com.android.server.firewall.IntentFirewall; 77import com.android.server.pm.UserManagerService; 78import com.android.server.wm.AppTransition; 79import com.android.server.wm.WindowManagerService; 80import com.google.android.collect.Lists; 81import com.google.android.collect.Maps; 82 83import libcore.io.IoUtils; 84 85import org.xmlpull.v1.XmlPullParser; 86import org.xmlpull.v1.XmlPullParserException; 87import org.xmlpull.v1.XmlSerializer; 88 89import android.app.Activity; 90import android.app.ActivityManager; 91import android.app.ActivityManager.RunningTaskInfo; 92import android.app.ActivityManager.StackInfo; 93import android.app.ActivityManagerInternal; 94import android.app.ActivityManagerNative; 95import android.app.ActivityOptions; 96import android.app.ActivityThread; 97import android.app.AlertDialog; 98import android.app.AppGlobals; 99import android.app.ApplicationErrorReport; 100import android.app.Dialog; 101import android.app.IActivityController; 102import android.app.IApplicationThread; 103import android.app.IInstrumentationWatcher; 104import android.app.INotificationManager; 105import android.app.IProcessObserver; 106import android.app.IServiceConnection; 107import android.app.IStopUserCallback; 108import android.app.IUiAutomationConnection; 109import android.app.IUserSwitchObserver; 110import android.app.Instrumentation; 111import android.app.Notification; 112import android.app.NotificationManager; 113import android.app.PendingIntent; 114import android.app.backup.IBackupManager; 115import android.content.ActivityNotFoundException; 116import android.content.BroadcastReceiver; 117import android.content.ClipData; 118import android.content.ComponentCallbacks2; 119import android.content.ComponentName; 120import android.content.ContentProvider; 121import android.content.ContentResolver; 122import android.content.Context; 123import android.content.DialogInterface; 124import android.content.IContentProvider; 125import android.content.IIntentReceiver; 126import android.content.IIntentSender; 127import android.content.Intent; 128import android.content.IntentFilter; 129import android.content.IntentSender; 130import android.content.pm.ActivityInfo; 131import android.content.pm.ApplicationInfo; 132import android.content.pm.ConfigurationInfo; 133import android.content.pm.IPackageDataObserver; 134import android.content.pm.IPackageManager; 135import android.content.pm.InstrumentationInfo; 136import android.content.pm.PackageInfo; 137import android.content.pm.PackageManager; 138import android.content.pm.ParceledListSlice; 139import android.content.pm.UserInfo; 140import android.content.pm.PackageManager.NameNotFoundException; 141import android.content.pm.PathPermission; 142import android.content.pm.ProviderInfo; 143import android.content.pm.ResolveInfo; 144import android.content.pm.ServiceInfo; 145import android.content.res.CompatibilityInfo; 146import android.content.res.Configuration; 147import android.net.Proxy; 148import android.net.ProxyInfo; 149import android.net.Uri; 150import android.os.Binder; 151import android.os.Build; 152import android.os.Bundle; 153import android.os.Debug; 154import android.os.DropBoxManager; 155import android.os.Environment; 156import android.os.FactoryTest; 157import android.os.FileObserver; 158import android.os.FileUtils; 159import android.os.Handler; 160import android.os.IBinder; 161import android.os.IPermissionController; 162import android.os.IRemoteCallback; 163import android.os.IUserManager; 164import android.os.Looper; 165import android.os.Message; 166import android.os.Parcel; 167import android.os.ParcelFileDescriptor; 168import android.os.Process; 169import android.os.RemoteCallbackList; 170import android.os.RemoteException; 171import android.os.SELinux; 172import android.os.ServiceManager; 173import android.os.StrictMode; 174import android.os.SystemClock; 175import android.os.SystemProperties; 176import android.os.UpdateLock; 177import android.os.UserHandle; 178import android.provider.Settings; 179import android.text.format.DateUtils; 180import android.text.format.Time; 181import android.util.AtomicFile; 182import android.util.EventLog; 183import android.util.Log; 184import android.util.Pair; 185import android.util.PrintWriterPrinter; 186import android.util.Slog; 187import android.util.SparseArray; 188import android.util.TimeUtils; 189import android.util.Xml; 190import android.view.Gravity; 191import android.view.LayoutInflater; 192import android.view.View; 193import android.view.WindowManager; 194 195import java.io.BufferedInputStream; 196import java.io.BufferedOutputStream; 197import java.io.DataInputStream; 198import java.io.DataOutputStream; 199import java.io.File; 200import java.io.FileDescriptor; 201import java.io.FileInputStream; 202import java.io.FileNotFoundException; 203import java.io.FileOutputStream; 204import java.io.IOException; 205import java.io.InputStreamReader; 206import java.io.PrintWriter; 207import java.io.StringWriter; 208import java.lang.ref.WeakReference; 209import java.util.ArrayList; 210import java.util.Arrays; 211import java.util.Collections; 212import java.util.Comparator; 213import java.util.HashMap; 214import java.util.HashSet; 215import java.util.Iterator; 216import java.util.List; 217import java.util.Locale; 218import java.util.Map; 219import java.util.Set; 220import java.util.concurrent.atomic.AtomicBoolean; 221import java.util.concurrent.atomic.AtomicLong; 222 223public final class ActivityManagerService extends ActivityManagerNative 224 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 225 226 private static final String USER_DATA_DIR = "/data/user/"; 227 // File that stores last updated system version and called preboot receivers 228 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 229 230 static final String TAG = "ActivityManager"; 231 static final String TAG_MU = "ActivityManagerServiceMU"; 232 static final boolean DEBUG = false; 233 static final boolean localLOGV = DEBUG; 234 static final boolean DEBUG_BACKUP = localLOGV || false; 235 static final boolean DEBUG_BROADCAST = localLOGV || false; 236 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 237 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 238 static final boolean DEBUG_CLEANUP = localLOGV || false; 239 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 240 static final boolean DEBUG_FOCUS = false; 241 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 242 static final boolean DEBUG_MU = localLOGV || false; 243 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 244 static final boolean DEBUG_LRU = localLOGV || false; 245 static final boolean DEBUG_PAUSE = localLOGV || false; 246 static final boolean DEBUG_POWER = localLOGV || false; 247 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 248 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 249 static final boolean DEBUG_PROCESSES = localLOGV || false; 250 static final boolean DEBUG_PROVIDER = localLOGV || false; 251 static final boolean DEBUG_RESULTS = localLOGV || false; 252 static final boolean DEBUG_SERVICE = localLOGV || false; 253 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 254 static final boolean DEBUG_STACK = localLOGV || false; 255 static final boolean DEBUG_SWITCH = localLOGV || false; 256 static final boolean DEBUG_TASKS = localLOGV || false; 257 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 258 static final boolean DEBUG_TRANSITION = localLOGV || false; 259 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 260 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 261 static final boolean DEBUG_VISBILITY = localLOGV || false; 262 static final boolean DEBUG_PSS = localLOGV || false; 263 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 264 static final boolean VALIDATE_TOKENS = false; 265 static final boolean SHOW_ACTIVITY_START_TIME = true; 266 267 // Control over CPU and battery monitoring. 268 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 269 static final boolean MONITOR_CPU_USAGE = true; 270 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 271 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 272 static final boolean MONITOR_THREAD_CPU_USAGE = false; 273 274 // The flags that are set for all calls we make to the package manager. 275 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 276 277 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 278 279 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 280 281 // Maximum number of recent tasks that we can remember. 282 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 283 284 // Maximum number recent bitmaps to keep in memory. 285 static final int MAX_RECENT_BITMAPS = 5; 286 287 // Amount of time after a call to stopAppSwitches() during which we will 288 // prevent further untrusted switches from happening. 289 static final long APP_SWITCH_DELAY_TIME = 5*1000; 290 291 // How long we wait for a launched process to attach to the activity manager 292 // before we decide it's never going to come up for real. 293 static final int PROC_START_TIMEOUT = 10*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real, when the process was 297 // started with a wrapper for instrumentation (such as Valgrind) because it 298 // could take much longer than usual. 299 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 300 301 // How long to wait after going idle before forcing apps to GC. 302 static final int GC_TIMEOUT = 5*1000; 303 304 // The minimum amount of time between successive GC requests for a process. 305 static final int GC_MIN_INTERVAL = 60*1000; 306 307 // The minimum amount of time between successive PSS requests for a process. 308 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process 311 // when the request is due to the memory state being lowered. 312 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 313 314 // The rate at which we check for apps using excessive power -- 15 mins. 315 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 316 317 // The minimum sample duration we will allow before deciding we have 318 // enough data on wake locks to start killing things. 319 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on CPU usage to start killing things. 323 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // How long we allow a receiver to run before giving up on it. 326 static final int BROADCAST_FG_TIMEOUT = 10*1000; 327 static final int BROADCAST_BG_TIMEOUT = 60*1000; 328 329 // How long we wait until we timeout on key dispatching. 330 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 331 332 // How long we wait until we timeout on key dispatching during instrumentation. 333 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 334 335 // Amount of time we wait for observers to handle a user switch before 336 // giving up on them and unfreezing the screen. 337 static final int USER_SWITCH_TIMEOUT = 2*1000; 338 339 // Maximum number of users we allow to be running at a time. 340 static final int MAX_RUNNING_USERS = 3; 341 342 // How long to wait in getAssistContextExtras for the activity and foreground services 343 // to respond with the result. 344 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 345 346 // Maximum number of persisted Uri grants a package is allowed 347 static final int MAX_PERSISTED_URI_GRANTS = 128; 348 349 static final int MY_PID = Process.myPid(); 350 351 static final String[] EMPTY_STRING_ARRAY = new String[0]; 352 353 // How many bytes to write into the dropbox log before truncating 354 static final int DROPBOX_MAX_SIZE = 256 * 1024; 355 356 // Access modes for handleIncomingUser. 357 static final int ALLOW_NON_FULL = 0; 358 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 359 static final int ALLOW_FULL_ONLY = 2; 360 361 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 362 363 /** All system services */ 364 SystemServiceManager mSystemServiceManager; 365 366 /** Run all ActivityStacks through this */ 367 ActivityStackSupervisor mStackSupervisor; 368 369 public IntentFirewall mIntentFirewall; 370 371 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 372 // default actuion automatically. Important for devices without direct input 373 // devices. 374 private boolean mShowDialogs = true; 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 ArrayList<TaskRecord> mRecentTasks; 411 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 412 413 public class PendingAssistExtras extends Binder implements Runnable { 414 public final ActivityRecord activity; 415 public boolean haveResult = false; 416 public Bundle result = null; 417 public PendingAssistExtras(ActivityRecord _activity) { 418 activity = _activity; 419 } 420 @Override 421 public void run() { 422 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 423 synchronized (this) { 424 haveResult = true; 425 notifyAll(); 426 } 427 } 428 } 429 430 final ArrayList<PendingAssistExtras> mPendingAssistExtras 431 = new ArrayList<PendingAssistExtras>(); 432 433 /** 434 * Process management. 435 */ 436 final ProcessList mProcessList = new ProcessList(); 437 438 /** 439 * All of the applications we currently have running organized by name. 440 * The keys are strings of the application package name (as 441 * returned by the package manager), and the keys are ApplicationRecord 442 * objects. 443 */ 444 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 445 446 /** 447 * Tracking long-term execution of processes to look for abuse and other 448 * bad app behavior. 449 */ 450 final ProcessStatsService mProcessStats; 451 452 /** 453 * The currently running isolated processes. 454 */ 455 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 456 457 /** 458 * Counter for assigning isolated process uids, to avoid frequently reusing the 459 * same ones. 460 */ 461 int mNextIsolatedProcessUid = 0; 462 463 /** 464 * The currently running heavy-weight process, if any. 465 */ 466 ProcessRecord mHeavyWeightProcess = null; 467 468 /** 469 * The last time that various processes have crashed. 470 */ 471 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 472 473 /** 474 * Information about a process that is currently marked as bad. 475 */ 476 static final class BadProcessInfo { 477 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 478 this.time = time; 479 this.shortMsg = shortMsg; 480 this.longMsg = longMsg; 481 this.stack = stack; 482 } 483 484 final long time; 485 final String shortMsg; 486 final String longMsg; 487 final String stack; 488 } 489 490 /** 491 * Set of applications that we consider to be bad, and will reject 492 * incoming broadcasts from (which the user has no control over). 493 * Processes are added to this set when they have crashed twice within 494 * a minimum amount of time; they are removed from it when they are 495 * later restarted (hopefully due to some user action). The value is the 496 * time it was added to the list. 497 */ 498 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 499 500 /** 501 * All of the processes we currently have running organized by pid. 502 * The keys are the pid running the application. 503 * 504 * <p>NOTE: This object is protected by its own lock, NOT the global 505 * activity manager lock! 506 */ 507 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 508 509 /** 510 * All of the processes that have been forced to be foreground. The key 511 * is the pid of the caller who requested it (we hold a death 512 * link on it). 513 */ 514 abstract class ForegroundToken implements IBinder.DeathRecipient { 515 int pid; 516 IBinder token; 517 } 518 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 519 520 /** 521 * List of records for processes that someone had tried to start before the 522 * system was ready. We don't start them at that point, but ensure they 523 * are started by the time booting is complete. 524 */ 525 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 526 527 /** 528 * List of persistent applications that are in the process 529 * of being started. 530 */ 531 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 532 533 /** 534 * Processes that are being forcibly torn down. 535 */ 536 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * List of running applications, sorted by recent usage. 540 * The first entry in the list is the least recently used. 541 */ 542 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 543 544 /** 545 * Where in mLruProcesses that the processes hosting activities start. 546 */ 547 int mLruProcessActivityStart = 0; 548 549 /** 550 * Where in mLruProcesses that the processes hosting services start. 551 * This is after (lower index) than mLruProcessesActivityStart. 552 */ 553 int mLruProcessServiceStart = 0; 554 555 /** 556 * List of processes that should gc as soon as things are idle. 557 */ 558 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 559 560 /** 561 * Processes we want to collect PSS data from. 562 */ 563 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Last time we requested PSS data of all processes. 567 */ 568 long mLastFullPssTime = SystemClock.uptimeMillis(); 569 570 /** 571 * If set, the next time we collect PSS data we should do a full collection 572 * with data from native processes and the kernel. 573 */ 574 boolean mFullPssPending = false; 575 576 /** 577 * This is the process holding what we currently consider to be 578 * the "home" activity. 579 */ 580 ProcessRecord mHomeProcess; 581 582 /** 583 * This is the process holding the activity the user last visited that 584 * is in a different process from the one they are currently in. 585 */ 586 ProcessRecord mPreviousProcess; 587 588 /** 589 * The time at which the previous process was last visible. 590 */ 591 long mPreviousProcessVisibleTime; 592 593 /** 594 * Which uses have been started, so are allowed to run code. 595 */ 596 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 597 598 /** 599 * LRU list of history of current users. Most recently current is at the end. 600 */ 601 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 602 603 /** 604 * Constant array of the users that are currently started. 605 */ 606 int[] mStartedUserArray = new int[] { 0 }; 607 608 /** 609 * Registered observers of the user switching mechanics. 610 */ 611 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 612 = new RemoteCallbackList<IUserSwitchObserver>(); 613 614 /** 615 * Currently active user switch. 616 */ 617 Object mCurUserSwitchCallback; 618 619 /** 620 * Packages that the user has asked to have run in screen size 621 * compatibility mode instead of filling the screen. 622 */ 623 final CompatModePackages mCompatModePackages; 624 625 /** 626 * Set of IntentSenderRecord objects that are currently active. 627 */ 628 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 629 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 630 631 /** 632 * Fingerprints (hashCode()) of stack traces that we've 633 * already logged DropBox entries for. Guarded by itself. If 634 * something (rogue user app) forces this over 635 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 636 */ 637 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 638 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 639 640 /** 641 * Strict Mode background batched logging state. 642 * 643 * The string buffer is guarded by itself, and its lock is also 644 * used to determine if another batched write is already 645 * in-flight. 646 */ 647 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 648 649 /** 650 * Keeps track of all IIntentReceivers that have been registered for 651 * broadcasts. Hash keys are the receiver IBinder, hash value is 652 * a ReceiverList. 653 */ 654 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 655 new HashMap<IBinder, ReceiverList>(); 656 657 /** 658 * Resolver for broadcast intents to registered receivers. 659 * Holds BroadcastFilter (subclass of IntentFilter). 660 */ 661 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 662 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 663 @Override 664 protected boolean allowFilterResult( 665 BroadcastFilter filter, List<BroadcastFilter> dest) { 666 IBinder target = filter.receiverList.receiver.asBinder(); 667 for (int i=dest.size()-1; i>=0; i--) { 668 if (dest.get(i).receiverList.receiver.asBinder() == target) { 669 return false; 670 } 671 } 672 return true; 673 } 674 675 @Override 676 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 677 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 678 || userId == filter.owningUserId) { 679 return super.newResult(filter, match, userId); 680 } 681 return null; 682 } 683 684 @Override 685 protected BroadcastFilter[] newArray(int size) { 686 return new BroadcastFilter[size]; 687 } 688 689 @Override 690 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 691 return packageName.equals(filter.packageName); 692 } 693 }; 694 695 /** 696 * State of all active sticky broadcasts per user. Keys are the action of the 697 * sticky Intent, values are an ArrayList of all broadcasted intents with 698 * that action (which should usually be one). The SparseArray is keyed 699 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 700 * for stickies that are sent to all users. 701 */ 702 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 703 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 704 705 final ActiveServices mServices; 706 707 /** 708 * Backup/restore process management 709 */ 710 String mBackupAppName = null; 711 BackupRecord mBackupTarget = null; 712 713 final ProviderMap mProviderMap; 714 715 /** 716 * List of content providers who have clients waiting for them. The 717 * application is currently being launched and the provider will be 718 * removed from this list once it is published. 719 */ 720 final ArrayList<ContentProviderRecord> mLaunchingProviders 721 = new ArrayList<ContentProviderRecord>(); 722 723 /** 724 * File storing persisted {@link #mGrantedUriPermissions}. 725 */ 726 private final AtomicFile mGrantFile; 727 728 /** XML constants used in {@link #mGrantFile} */ 729 private static final String TAG_URI_GRANTS = "uri-grants"; 730 private static final String TAG_URI_GRANT = "uri-grant"; 731 private static final String ATTR_USER_HANDLE = "userHandle"; 732 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 733 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 734 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 735 private static final String ATTR_TARGET_PKG = "targetPkg"; 736 private static final String ATTR_URI = "uri"; 737 private static final String ATTR_MODE_FLAGS = "modeFlags"; 738 private static final String ATTR_CREATED_TIME = "createdTime"; 739 private static final String ATTR_PREFIX = "prefix"; 740 741 /** 742 * Global set of specific {@link Uri} permissions that have been granted. 743 * This optimized lookup structure maps from {@link UriPermission#targetUid} 744 * to {@link UriPermission#uri} to {@link UriPermission}. 745 */ 746 @GuardedBy("this") 747 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 748 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 749 750 public static class GrantUri { 751 public final int sourceUserId; 752 public final Uri uri; 753 public boolean prefix; 754 755 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 756 this.sourceUserId = sourceUserId; 757 this.uri = uri; 758 this.prefix = prefix; 759 } 760 761 @Override 762 public int hashCode() { 763 return toString().hashCode(); 764 } 765 766 @Override 767 public boolean equals(Object o) { 768 if (o instanceof GrantUri) { 769 GrantUri other = (GrantUri) o; 770 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 771 && prefix == other.prefix; 772 } 773 return false; 774 } 775 776 @Override 777 public String toString() { 778 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 779 if (prefix) result += " [prefix]"; 780 return result; 781 } 782 783 public String toSafeString() { 784 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 785 if (prefix) result += " [prefix]"; 786 return result; 787 } 788 789 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 790 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 791 ContentProvider.getUriWithoutUserId(uri), false); 792 } 793 } 794 795 CoreSettingsObserver mCoreSettingsObserver; 796 797 /** 798 * Thread-local storage used to carry caller permissions over through 799 * indirect content-provider access. 800 */ 801 private class Identity { 802 public int pid; 803 public int uid; 804 805 Identity(int _pid, int _uid) { 806 pid = _pid; 807 uid = _uid; 808 } 809 } 810 811 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 812 813 /** 814 * All information we have collected about the runtime performance of 815 * any user id that can impact battery performance. 816 */ 817 final BatteryStatsService mBatteryStatsService; 818 819 /** 820 * Information about component usage 821 */ 822 UsageStatsManagerInternal mUsageStatsService; 823 824 /** 825 * Information about and control over application operations 826 */ 827 final AppOpsService mAppOpsService; 828 829 /** 830 * Save recent tasks information across reboots. 831 */ 832 final TaskPersister mTaskPersister; 833 834 /** 835 * Current configuration information. HistoryRecord objects are given 836 * a reference to this object to indicate which configuration they are 837 * currently running in, so this object must be kept immutable. 838 */ 839 Configuration mConfiguration = new Configuration(); 840 841 /** 842 * Current sequencing integer of the configuration, for skipping old 843 * configurations. 844 */ 845 int mConfigurationSeq = 0; 846 847 /** 848 * Hardware-reported OpenGLES version. 849 */ 850 final int GL_ES_VERSION; 851 852 /** 853 * List of initialization arguments to pass to all processes when binding applications to them. 854 * For example, references to the commonly used services. 855 */ 856 HashMap<String, IBinder> mAppBindArgs; 857 858 /** 859 * Temporary to avoid allocations. Protected by main lock. 860 */ 861 final StringBuilder mStringBuilder = new StringBuilder(256); 862 863 /** 864 * Used to control how we initialize the service. 865 */ 866 ComponentName mTopComponent; 867 String mTopAction = Intent.ACTION_MAIN; 868 String mTopData; 869 boolean mProcessesReady = false; 870 boolean mSystemReady = false; 871 boolean mBooting = false; 872 boolean mWaitingUpdate = false; 873 boolean mDidUpdate = false; 874 boolean mOnBattery = false; 875 boolean mLaunchWarningShown = false; 876 877 Context mContext; 878 879 int mFactoryTest; 880 881 boolean mCheckedForSetup; 882 883 /** 884 * The time at which we will allow normal application switches again, 885 * after a call to {@link #stopAppSwitches()}. 886 */ 887 long mAppSwitchesAllowedTime; 888 889 /** 890 * This is set to true after the first switch after mAppSwitchesAllowedTime 891 * is set; any switches after that will clear the time. 892 */ 893 boolean mDidAppSwitch; 894 895 /** 896 * Last time (in realtime) at which we checked for power usage. 897 */ 898 long mLastPowerCheckRealtime; 899 900 /** 901 * Last time (in uptime) at which we checked for power usage. 902 */ 903 long mLastPowerCheckUptime; 904 905 /** 906 * Set while we are wanting to sleep, to prevent any 907 * activities from being started/resumed. 908 */ 909 private boolean mSleeping = false; 910 911 /** 912 * Set while we are running a voice interaction. This overrides 913 * sleeping while it is active. 914 */ 915 private boolean mRunningVoice = false; 916 917 /** 918 * State of external calls telling us if the device is asleep. 919 */ 920 private boolean mWentToSleep = false; 921 922 /** 923 * State of external call telling us if the lock screen is shown. 924 */ 925 private boolean mLockScreenShown = false; 926 927 /** 928 * Set if we are shutting down the system, similar to sleeping. 929 */ 930 boolean mShuttingDown = false; 931 932 /** 933 * Current sequence id for oom_adj computation traversal. 934 */ 935 int mAdjSeq = 0; 936 937 /** 938 * Current sequence id for process LRU updating. 939 */ 940 int mLruSeq = 0; 941 942 /** 943 * Keep track of the non-cached/empty process we last found, to help 944 * determine how to distribute cached/empty processes next time. 945 */ 946 int mNumNonCachedProcs = 0; 947 948 /** 949 * Keep track of the number of cached hidden procs, to balance oom adj 950 * distribution between those and empty procs. 951 */ 952 int mNumCachedHiddenProcs = 0; 953 954 /** 955 * Keep track of the number of service processes we last found, to 956 * determine on the next iteration which should be B services. 957 */ 958 int mNumServiceProcs = 0; 959 int mNewNumAServiceProcs = 0; 960 int mNewNumServiceProcs = 0; 961 962 /** 963 * Allow the current computed overall memory level of the system to go down? 964 * This is set to false when we are killing processes for reasons other than 965 * memory management, so that the now smaller process list will not be taken as 966 * an indication that memory is tighter. 967 */ 968 boolean mAllowLowerMemLevel = false; 969 970 /** 971 * The last computed memory level, for holding when we are in a state that 972 * processes are going away for other reasons. 973 */ 974 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 975 976 /** 977 * The last total number of process we have, to determine if changes actually look 978 * like a shrinking number of process due to lower RAM. 979 */ 980 int mLastNumProcesses; 981 982 /** 983 * The uptime of the last time we performed idle maintenance. 984 */ 985 long mLastIdleTime = SystemClock.uptimeMillis(); 986 987 /** 988 * Total time spent with RAM that has been added in the past since the last idle time. 989 */ 990 long mLowRamTimeSinceLastIdle = 0; 991 992 /** 993 * If RAM is currently low, when that horrible situation started. 994 */ 995 long mLowRamStartTime = 0; 996 997 /** 998 * For reporting to battery stats the current top application. 999 */ 1000 private String mCurResumedPackage = null; 1001 private int mCurResumedUid = -1; 1002 1003 /** 1004 * For reporting to battery stats the apps currently running foreground 1005 * service. The ProcessMap is package/uid tuples; each of these contain 1006 * an array of the currently foreground processes. 1007 */ 1008 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1009 = new ProcessMap<ArrayList<ProcessRecord>>(); 1010 1011 /** 1012 * This is set if we had to do a delayed dexopt of an app before launching 1013 * it, to increase the ANR timeouts in that case. 1014 */ 1015 boolean mDidDexOpt; 1016 1017 /** 1018 * Set if the systemServer made a call to enterSafeMode. 1019 */ 1020 boolean mSafeMode; 1021 1022 String mDebugApp = null; 1023 boolean mWaitForDebugger = false; 1024 boolean mDebugTransient = false; 1025 String mOrigDebugApp = null; 1026 boolean mOrigWaitForDebugger = false; 1027 boolean mAlwaysFinishActivities = false; 1028 IActivityController mController = null; 1029 String mProfileApp = null; 1030 ProcessRecord mProfileProc = null; 1031 String mProfileFile; 1032 ParcelFileDescriptor mProfileFd; 1033 int mProfileType = 0; 1034 boolean mAutoStopProfiler = false; 1035 String mOpenGlTraceApp = null; 1036 1037 static class ProcessChangeItem { 1038 static final int CHANGE_ACTIVITIES = 1<<0; 1039 static final int CHANGE_PROCESS_STATE = 1<<1; 1040 int changes; 1041 int uid; 1042 int pid; 1043 int processState; 1044 boolean foregroundActivities; 1045 } 1046 1047 final RemoteCallbackList<IProcessObserver> mProcessObservers 1048 = new RemoteCallbackList<IProcessObserver>(); 1049 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1050 1051 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1052 = new ArrayList<ProcessChangeItem>(); 1053 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1054 = new ArrayList<ProcessChangeItem>(); 1055 1056 /** 1057 * Runtime CPU use collection thread. This object's lock is used to 1058 * protect all related state. 1059 */ 1060 final Thread mProcessCpuThread; 1061 1062 /** 1063 * Used to collect process stats when showing not responding dialog. 1064 * Protected by mProcessCpuThread. 1065 */ 1066 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1067 MONITOR_THREAD_CPU_USAGE); 1068 final AtomicLong mLastCpuTime = new AtomicLong(0); 1069 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1070 1071 long mLastWriteTime = 0; 1072 1073 /** 1074 * Used to retain an update lock when the foreground activity is in 1075 * immersive mode. 1076 */ 1077 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1078 1079 /** 1080 * Set to true after the system has finished booting. 1081 */ 1082 boolean mBooted = false; 1083 1084 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1085 int mProcessLimitOverride = -1; 1086 1087 WindowManagerService mWindowManager; 1088 1089 final ActivityThread mSystemThread; 1090 1091 int mCurrentUserId = 0; 1092 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1093 1094 /** 1095 * Mapping from each known user ID to the profile group ID it is associated with. 1096 */ 1097 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1098 1099 private UserManagerService mUserManager; 1100 1101 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1102 final ProcessRecord mApp; 1103 final int mPid; 1104 final IApplicationThread mAppThread; 1105 1106 AppDeathRecipient(ProcessRecord app, int pid, 1107 IApplicationThread thread) { 1108 if (localLOGV) Slog.v( 1109 TAG, "New death recipient " + this 1110 + " for thread " + thread.asBinder()); 1111 mApp = app; 1112 mPid = pid; 1113 mAppThread = thread; 1114 } 1115 1116 @Override 1117 public void binderDied() { 1118 if (localLOGV) Slog.v( 1119 TAG, "Death received in " + this 1120 + " for thread " + mAppThread.asBinder()); 1121 synchronized(ActivityManagerService.this) { 1122 appDiedLocked(mApp, mPid, mAppThread); 1123 } 1124 } 1125 } 1126 1127 static final int SHOW_ERROR_MSG = 1; 1128 static final int SHOW_NOT_RESPONDING_MSG = 2; 1129 static final int SHOW_FACTORY_ERROR_MSG = 3; 1130 static final int UPDATE_CONFIGURATION_MSG = 4; 1131 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1132 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1133 static final int SERVICE_TIMEOUT_MSG = 12; 1134 static final int UPDATE_TIME_ZONE = 13; 1135 static final int SHOW_UID_ERROR_MSG = 14; 1136 static final int IM_FEELING_LUCKY_MSG = 15; 1137 static final int PROC_START_TIMEOUT_MSG = 20; 1138 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1139 static final int KILL_APPLICATION_MSG = 22; 1140 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1141 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1142 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1143 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1144 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1145 static final int CLEAR_DNS_CACHE_MSG = 28; 1146 static final int UPDATE_HTTP_PROXY_MSG = 29; 1147 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1148 static final int DISPATCH_PROCESSES_CHANGED = 31; 1149 static final int DISPATCH_PROCESS_DIED = 32; 1150 static final int REPORT_MEM_USAGE_MSG = 33; 1151 static final int REPORT_USER_SWITCH_MSG = 34; 1152 static final int CONTINUE_USER_SWITCH_MSG = 35; 1153 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1154 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1155 static final int PERSIST_URI_GRANTS_MSG = 38; 1156 static final int REQUEST_ALL_PSS_MSG = 39; 1157 static final int START_PROFILES_MSG = 40; 1158 static final int UPDATE_TIME = 41; 1159 static final int SYSTEM_USER_START_MSG = 42; 1160 static final int SYSTEM_USER_CURRENT_MSG = 43; 1161 1162 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1163 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1164 static final int FIRST_COMPAT_MODE_MSG = 300; 1165 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1166 1167 AlertDialog mUidAlert; 1168 CompatModeDialog mCompatModeDialog; 1169 long mLastMemUsageReportTime = 0; 1170 1171 private LockToAppRequestDialog mLockToAppRequest; 1172 1173 /** 1174 * Flag whether the current user is a "monkey", i.e. whether 1175 * the UI is driven by a UI automation tool. 1176 */ 1177 private boolean mUserIsMonkey; 1178 1179 /** Flag whether the device has a recents UI */ 1180 final boolean mHasRecents; 1181 1182 final ServiceThread mHandlerThread; 1183 final MainHandler mHandler; 1184 1185 final class MainHandler extends Handler { 1186 public MainHandler(Looper looper) { 1187 super(looper, null, true); 1188 } 1189 1190 @Override 1191 public void handleMessage(Message msg) { 1192 switch (msg.what) { 1193 case SHOW_ERROR_MSG: { 1194 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1195 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1196 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1197 synchronized (ActivityManagerService.this) { 1198 ProcessRecord proc = (ProcessRecord)data.get("app"); 1199 AppErrorResult res = (AppErrorResult) data.get("result"); 1200 if (proc != null && proc.crashDialog != null) { 1201 Slog.e(TAG, "App already has crash dialog: " + proc); 1202 if (res != null) { 1203 res.set(0); 1204 } 1205 return; 1206 } 1207 if (!showBackground && UserHandle.getAppId(proc.uid) 1208 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1209 && proc.pid != MY_PID) { 1210 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1211 if (res != null) { 1212 res.set(0); 1213 } 1214 return; 1215 } 1216 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1217 Dialog d = new AppErrorDialog(mContext, 1218 ActivityManagerService.this, res, proc); 1219 d.show(); 1220 proc.crashDialog = d; 1221 } else { 1222 // The device is asleep, so just pretend that the user 1223 // saw a crash dialog and hit "force quit". 1224 if (res != null) { 1225 res.set(0); 1226 } 1227 } 1228 } 1229 1230 ensureBootCompleted(); 1231 } break; 1232 case SHOW_NOT_RESPONDING_MSG: { 1233 synchronized (ActivityManagerService.this) { 1234 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1235 ProcessRecord proc = (ProcessRecord)data.get("app"); 1236 if (proc != null && proc.anrDialog != null) { 1237 Slog.e(TAG, "App already has anr dialog: " + proc); 1238 return; 1239 } 1240 1241 Intent intent = new Intent("android.intent.action.ANR"); 1242 if (!mProcessesReady) { 1243 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1244 | Intent.FLAG_RECEIVER_FOREGROUND); 1245 } 1246 broadcastIntentLocked(null, null, intent, 1247 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1248 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1249 1250 if (mShowDialogs) { 1251 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1252 mContext, proc, (ActivityRecord)data.get("activity"), 1253 msg.arg1 != 0); 1254 d.show(); 1255 proc.anrDialog = d; 1256 } else { 1257 // Just kill the app if there is no dialog to be shown. 1258 killAppAtUsersRequest(proc, null); 1259 } 1260 } 1261 1262 ensureBootCompleted(); 1263 } break; 1264 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1265 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1266 synchronized (ActivityManagerService.this) { 1267 ProcessRecord proc = (ProcessRecord) data.get("app"); 1268 if (proc == null) { 1269 Slog.e(TAG, "App not found when showing strict mode dialog."); 1270 break; 1271 } 1272 if (proc.crashDialog != null) { 1273 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1274 return; 1275 } 1276 AppErrorResult res = (AppErrorResult) data.get("result"); 1277 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1278 Dialog d = new StrictModeViolationDialog(mContext, 1279 ActivityManagerService.this, res, proc); 1280 d.show(); 1281 proc.crashDialog = d; 1282 } else { 1283 // The device is asleep, so just pretend that the user 1284 // saw a crash dialog and hit "force quit". 1285 res.set(0); 1286 } 1287 } 1288 ensureBootCompleted(); 1289 } break; 1290 case SHOW_FACTORY_ERROR_MSG: { 1291 Dialog d = new FactoryErrorDialog( 1292 mContext, msg.getData().getCharSequence("msg")); 1293 d.show(); 1294 ensureBootCompleted(); 1295 } break; 1296 case UPDATE_CONFIGURATION_MSG: { 1297 final ContentResolver resolver = mContext.getContentResolver(); 1298 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1299 } break; 1300 case GC_BACKGROUND_PROCESSES_MSG: { 1301 synchronized (ActivityManagerService.this) { 1302 performAppGcsIfAppropriateLocked(); 1303 } 1304 } break; 1305 case WAIT_FOR_DEBUGGER_MSG: { 1306 synchronized (ActivityManagerService.this) { 1307 ProcessRecord app = (ProcessRecord)msg.obj; 1308 if (msg.arg1 != 0) { 1309 if (!app.waitedForDebugger) { 1310 Dialog d = new AppWaitingForDebuggerDialog( 1311 ActivityManagerService.this, 1312 mContext, app); 1313 app.waitDialog = d; 1314 app.waitedForDebugger = true; 1315 d.show(); 1316 } 1317 } else { 1318 if (app.waitDialog != null) { 1319 app.waitDialog.dismiss(); 1320 app.waitDialog = null; 1321 } 1322 } 1323 } 1324 } break; 1325 case SERVICE_TIMEOUT_MSG: { 1326 if (mDidDexOpt) { 1327 mDidDexOpt = false; 1328 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1329 nmsg.obj = msg.obj; 1330 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1331 return; 1332 } 1333 mServices.serviceTimeout((ProcessRecord)msg.obj); 1334 } break; 1335 case UPDATE_TIME_ZONE: { 1336 synchronized (ActivityManagerService.this) { 1337 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1338 ProcessRecord r = mLruProcesses.get(i); 1339 if (r.thread != null) { 1340 try { 1341 r.thread.updateTimeZone(); 1342 } catch (RemoteException ex) { 1343 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1344 } 1345 } 1346 } 1347 } 1348 } break; 1349 case CLEAR_DNS_CACHE_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1352 ProcessRecord r = mLruProcesses.get(i); 1353 if (r.thread != null) { 1354 try { 1355 r.thread.clearDnsCache(); 1356 } catch (RemoteException ex) { 1357 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1358 } 1359 } 1360 } 1361 } 1362 } break; 1363 case UPDATE_HTTP_PROXY_MSG: { 1364 ProxyInfo proxy = (ProxyInfo)msg.obj; 1365 String host = ""; 1366 String port = ""; 1367 String exclList = ""; 1368 Uri pacFileUrl = Uri.EMPTY; 1369 if (proxy != null) { 1370 host = proxy.getHost(); 1371 port = Integer.toString(proxy.getPort()); 1372 exclList = proxy.getExclusionListAsString(); 1373 pacFileUrl = proxy.getPacFileUrl(); 1374 } 1375 synchronized (ActivityManagerService.this) { 1376 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1377 ProcessRecord r = mLruProcesses.get(i); 1378 if (r.thread != null) { 1379 try { 1380 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1381 } catch (RemoteException ex) { 1382 Slog.w(TAG, "Failed to update http proxy for: " + 1383 r.info.processName); 1384 } 1385 } 1386 } 1387 } 1388 } break; 1389 case SHOW_UID_ERROR_MSG: { 1390 String title = "System UIDs Inconsistent"; 1391 String text = "UIDs on the system are inconsistent, you need to wipe your" 1392 + " data partition or your device will be unstable."; 1393 Log.e(TAG, title + ": " + text); 1394 if (mShowDialogs) { 1395 // XXX This is a temporary dialog, no need to localize. 1396 AlertDialog d = new BaseErrorDialog(mContext); 1397 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1398 d.setCancelable(false); 1399 d.setTitle(title); 1400 d.setMessage(text); 1401 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1402 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1403 mUidAlert = d; 1404 d.show(); 1405 } 1406 } break; 1407 case IM_FEELING_LUCKY_MSG: { 1408 if (mUidAlert != null) { 1409 mUidAlert.dismiss(); 1410 mUidAlert = null; 1411 } 1412 } break; 1413 case PROC_START_TIMEOUT_MSG: { 1414 if (mDidDexOpt) { 1415 mDidDexOpt = false; 1416 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1417 nmsg.obj = msg.obj; 1418 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1419 return; 1420 } 1421 ProcessRecord app = (ProcessRecord)msg.obj; 1422 synchronized (ActivityManagerService.this) { 1423 processStartTimedOutLocked(app); 1424 } 1425 } break; 1426 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1427 synchronized (ActivityManagerService.this) { 1428 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1429 } 1430 } break; 1431 case KILL_APPLICATION_MSG: { 1432 synchronized (ActivityManagerService.this) { 1433 int appid = msg.arg1; 1434 boolean restart = (msg.arg2 == 1); 1435 Bundle bundle = (Bundle)msg.obj; 1436 String pkg = bundle.getString("pkg"); 1437 String reason = bundle.getString("reason"); 1438 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1439 false, UserHandle.USER_ALL, reason); 1440 } 1441 } break; 1442 case FINALIZE_PENDING_INTENT_MSG: { 1443 ((PendingIntentRecord)msg.obj).completeFinalize(); 1444 } break; 1445 case POST_HEAVY_NOTIFICATION_MSG: { 1446 INotificationManager inm = NotificationManager.getService(); 1447 if (inm == null) { 1448 return; 1449 } 1450 1451 ActivityRecord root = (ActivityRecord)msg.obj; 1452 ProcessRecord process = root.app; 1453 if (process == null) { 1454 return; 1455 } 1456 1457 try { 1458 Context context = mContext.createPackageContext(process.info.packageName, 0); 1459 String text = mContext.getString(R.string.heavy_weight_notification, 1460 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1461 Notification notification = new Notification(); 1462 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1463 notification.when = 0; 1464 notification.flags = Notification.FLAG_ONGOING_EVENT; 1465 notification.tickerText = text; 1466 notification.defaults = 0; // please be quiet 1467 notification.sound = null; 1468 notification.vibrate = null; 1469 notification.setLatestEventInfo(context, text, 1470 mContext.getText(R.string.heavy_weight_notification_detail), 1471 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1472 PendingIntent.FLAG_CANCEL_CURRENT, null, 1473 new UserHandle(root.userId))); 1474 1475 try { 1476 int[] outId = new int[1]; 1477 inm.enqueueNotificationWithTag("android", "android", null, 1478 R.string.heavy_weight_notification, 1479 notification, outId, root.userId); 1480 } catch (RuntimeException e) { 1481 Slog.w(ActivityManagerService.TAG, 1482 "Error showing notification for heavy-weight app", e); 1483 } catch (RemoteException e) { 1484 } 1485 } catch (NameNotFoundException e) { 1486 Slog.w(TAG, "Unable to create context for heavy notification", e); 1487 } 1488 } break; 1489 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1490 INotificationManager inm = NotificationManager.getService(); 1491 if (inm == null) { 1492 return; 1493 } 1494 try { 1495 inm.cancelNotificationWithTag("android", null, 1496 R.string.heavy_weight_notification, msg.arg1); 1497 } catch (RuntimeException e) { 1498 Slog.w(ActivityManagerService.TAG, 1499 "Error canceling notification for service", e); 1500 } catch (RemoteException e) { 1501 } 1502 } break; 1503 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1504 synchronized (ActivityManagerService.this) { 1505 checkExcessivePowerUsageLocked(true); 1506 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1507 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1508 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1509 } 1510 } break; 1511 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1512 synchronized (ActivityManagerService.this) { 1513 ActivityRecord ar = (ActivityRecord)msg.obj; 1514 if (mCompatModeDialog != null) { 1515 if (mCompatModeDialog.mAppInfo.packageName.equals( 1516 ar.info.applicationInfo.packageName)) { 1517 return; 1518 } 1519 mCompatModeDialog.dismiss(); 1520 mCompatModeDialog = null; 1521 } 1522 if (ar != null && false) { 1523 if (mCompatModePackages.getPackageAskCompatModeLocked( 1524 ar.packageName)) { 1525 int mode = mCompatModePackages.computeCompatModeLocked( 1526 ar.info.applicationInfo); 1527 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1528 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1529 mCompatModeDialog = new CompatModeDialog( 1530 ActivityManagerService.this, mContext, 1531 ar.info.applicationInfo); 1532 mCompatModeDialog.show(); 1533 } 1534 } 1535 } 1536 } 1537 break; 1538 } 1539 case DISPATCH_PROCESSES_CHANGED: { 1540 dispatchProcessesChanged(); 1541 break; 1542 } 1543 case DISPATCH_PROCESS_DIED: { 1544 final int pid = msg.arg1; 1545 final int uid = msg.arg2; 1546 dispatchProcessDied(pid, uid); 1547 break; 1548 } 1549 case REPORT_MEM_USAGE_MSG: { 1550 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1551 Thread thread = new Thread() { 1552 @Override public void run() { 1553 final SparseArray<ProcessMemInfo> infoMap 1554 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1555 for (int i=0, N=memInfos.size(); i<N; i++) { 1556 ProcessMemInfo mi = memInfos.get(i); 1557 infoMap.put(mi.pid, mi); 1558 } 1559 updateCpuStatsNow(); 1560 synchronized (mProcessCpuThread) { 1561 final int N = mProcessCpuTracker.countStats(); 1562 for (int i=0; i<N; i++) { 1563 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1564 if (st.vsize > 0) { 1565 long pss = Debug.getPss(st.pid, null); 1566 if (pss > 0) { 1567 if (infoMap.indexOfKey(st.pid) < 0) { 1568 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1569 ProcessList.NATIVE_ADJ, -1, "native", null); 1570 mi.pss = pss; 1571 memInfos.add(mi); 1572 } 1573 } 1574 } 1575 } 1576 } 1577 1578 long totalPss = 0; 1579 for (int i=0, N=memInfos.size(); i<N; i++) { 1580 ProcessMemInfo mi = memInfos.get(i); 1581 if (mi.pss == 0) { 1582 mi.pss = Debug.getPss(mi.pid, null); 1583 } 1584 totalPss += mi.pss; 1585 } 1586 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1587 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1588 if (lhs.oomAdj != rhs.oomAdj) { 1589 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1590 } 1591 if (lhs.pss != rhs.pss) { 1592 return lhs.pss < rhs.pss ? 1 : -1; 1593 } 1594 return 0; 1595 } 1596 }); 1597 1598 StringBuilder tag = new StringBuilder(128); 1599 StringBuilder stack = new StringBuilder(128); 1600 tag.append("Low on memory -- "); 1601 appendMemBucket(tag, totalPss, "total", false); 1602 appendMemBucket(stack, totalPss, "total", true); 1603 1604 StringBuilder logBuilder = new StringBuilder(1024); 1605 logBuilder.append("Low on memory:\n"); 1606 1607 boolean firstLine = true; 1608 int lastOomAdj = Integer.MIN_VALUE; 1609 for (int i=0, N=memInfos.size(); i<N; i++) { 1610 ProcessMemInfo mi = memInfos.get(i); 1611 1612 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1613 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1614 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1615 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1616 if (lastOomAdj != mi.oomAdj) { 1617 lastOomAdj = mi.oomAdj; 1618 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1619 tag.append(" / "); 1620 } 1621 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1622 if (firstLine) { 1623 stack.append(":"); 1624 firstLine = false; 1625 } 1626 stack.append("\n\t at "); 1627 } else { 1628 stack.append("$"); 1629 } 1630 } else { 1631 tag.append(" "); 1632 stack.append("$"); 1633 } 1634 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1635 appendMemBucket(tag, mi.pss, mi.name, false); 1636 } 1637 appendMemBucket(stack, mi.pss, mi.name, true); 1638 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1639 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1640 stack.append("("); 1641 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1642 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1643 stack.append(DUMP_MEM_OOM_LABEL[k]); 1644 stack.append(":"); 1645 stack.append(DUMP_MEM_OOM_ADJ[k]); 1646 } 1647 } 1648 stack.append(")"); 1649 } 1650 } 1651 1652 logBuilder.append(" "); 1653 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1654 logBuilder.append(' '); 1655 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1656 logBuilder.append(' '); 1657 ProcessList.appendRamKb(logBuilder, mi.pss); 1658 logBuilder.append(" kB: "); 1659 logBuilder.append(mi.name); 1660 logBuilder.append(" ("); 1661 logBuilder.append(mi.pid); 1662 logBuilder.append(") "); 1663 logBuilder.append(mi.adjType); 1664 logBuilder.append('\n'); 1665 if (mi.adjReason != null) { 1666 logBuilder.append(" "); 1667 logBuilder.append(mi.adjReason); 1668 logBuilder.append('\n'); 1669 } 1670 } 1671 1672 logBuilder.append(" "); 1673 ProcessList.appendRamKb(logBuilder, totalPss); 1674 logBuilder.append(" kB: TOTAL\n"); 1675 1676 long[] infos = new long[Debug.MEMINFO_COUNT]; 1677 Debug.getMemInfo(infos); 1678 logBuilder.append(" MemInfo: "); 1679 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1680 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1681 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1682 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1683 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1684 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1685 logBuilder.append(" ZRAM: "); 1686 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1687 logBuilder.append(" kB RAM, "); 1688 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1689 logBuilder.append(" kB swap total, "); 1690 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1691 logBuilder.append(" kB swap free\n"); 1692 } 1693 Slog.i(TAG, logBuilder.toString()); 1694 1695 StringBuilder dropBuilder = new StringBuilder(1024); 1696 /* 1697 StringWriter oomSw = new StringWriter(); 1698 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1699 StringWriter catSw = new StringWriter(); 1700 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1701 String[] emptyArgs = new String[] { }; 1702 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1703 oomPw.flush(); 1704 String oomString = oomSw.toString(); 1705 */ 1706 dropBuilder.append(stack); 1707 dropBuilder.append('\n'); 1708 dropBuilder.append('\n'); 1709 dropBuilder.append(logBuilder); 1710 dropBuilder.append('\n'); 1711 /* 1712 dropBuilder.append(oomString); 1713 dropBuilder.append('\n'); 1714 */ 1715 StringWriter catSw = new StringWriter(); 1716 synchronized (ActivityManagerService.this) { 1717 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1718 String[] emptyArgs = new String[] { }; 1719 catPw.println(); 1720 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1721 catPw.println(); 1722 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1723 false, false, null); 1724 catPw.println(); 1725 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1726 catPw.flush(); 1727 } 1728 dropBuilder.append(catSw.toString()); 1729 addErrorToDropBox("lowmem", null, "system_server", null, 1730 null, tag.toString(), dropBuilder.toString(), null, null); 1731 //Slog.i(TAG, "Sent to dropbox:"); 1732 //Slog.i(TAG, dropBuilder.toString()); 1733 synchronized (ActivityManagerService.this) { 1734 long now = SystemClock.uptimeMillis(); 1735 if (mLastMemUsageReportTime < now) { 1736 mLastMemUsageReportTime = now; 1737 } 1738 } 1739 } 1740 }; 1741 thread.start(); 1742 break; 1743 } 1744 case REPORT_USER_SWITCH_MSG: { 1745 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1746 break; 1747 } 1748 case CONTINUE_USER_SWITCH_MSG: { 1749 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1750 break; 1751 } 1752 case USER_SWITCH_TIMEOUT_MSG: { 1753 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1754 break; 1755 } 1756 case IMMERSIVE_MODE_LOCK_MSG: { 1757 final boolean nextState = (msg.arg1 != 0); 1758 if (mUpdateLock.isHeld() != nextState) { 1759 if (DEBUG_IMMERSIVE) { 1760 final ActivityRecord r = (ActivityRecord) msg.obj; 1761 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1762 } 1763 if (nextState) { 1764 mUpdateLock.acquire(); 1765 } else { 1766 mUpdateLock.release(); 1767 } 1768 } 1769 break; 1770 } 1771 case PERSIST_URI_GRANTS_MSG: { 1772 writeGrantedUriPermissions(); 1773 break; 1774 } 1775 case REQUEST_ALL_PSS_MSG: { 1776 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1777 break; 1778 } 1779 case START_PROFILES_MSG: { 1780 synchronized (ActivityManagerService.this) { 1781 startProfilesLocked(); 1782 } 1783 break; 1784 } 1785 case UPDATE_TIME: { 1786 synchronized (ActivityManagerService.this) { 1787 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1788 ProcessRecord r = mLruProcesses.get(i); 1789 if (r.thread != null) { 1790 try { 1791 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1792 } catch (RemoteException ex) { 1793 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1794 } 1795 } 1796 } 1797 } 1798 break; 1799 } 1800 case SYSTEM_USER_START_MSG: { 1801 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1802 Integer.toString(msg.arg1), msg.arg1); 1803 mSystemServiceManager.startUser(msg.arg1); 1804 break; 1805 } 1806 case SYSTEM_USER_CURRENT_MSG: { 1807 mBatteryStatsService.noteEvent( 1808 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1809 Integer.toString(msg.arg2), msg.arg2); 1810 mBatteryStatsService.noteEvent( 1811 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1812 Integer.toString(msg.arg1), msg.arg1); 1813 mSystemServiceManager.switchUser(msg.arg1); 1814 break; 1815 } 1816 } 1817 } 1818 }; 1819 1820 static final int COLLECT_PSS_BG_MSG = 1; 1821 1822 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1823 @Override 1824 public void handleMessage(Message msg) { 1825 switch (msg.what) { 1826 case COLLECT_PSS_BG_MSG: { 1827 long start = SystemClock.uptimeMillis(); 1828 MemInfoReader memInfo = null; 1829 synchronized (ActivityManagerService.this) { 1830 if (mFullPssPending) { 1831 mFullPssPending = false; 1832 memInfo = new MemInfoReader(); 1833 } 1834 } 1835 if (memInfo != null) { 1836 updateCpuStatsNow(); 1837 long nativeTotalPss = 0; 1838 synchronized (mProcessCpuThread) { 1839 final int N = mProcessCpuTracker.countStats(); 1840 for (int j=0; j<N; j++) { 1841 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1842 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1843 // This is definitely an application process; skip it. 1844 continue; 1845 } 1846 synchronized (mPidsSelfLocked) { 1847 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1848 // This is one of our own processes; skip it. 1849 continue; 1850 } 1851 } 1852 nativeTotalPss += Debug.getPss(st.pid, null); 1853 } 1854 } 1855 memInfo.readMemInfo(); 1856 synchronized (this) { 1857 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1858 + (SystemClock.uptimeMillis()-start) + "ms"); 1859 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1860 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1861 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1862 +memInfo.getSlabSizeKb(), 1863 nativeTotalPss); 1864 } 1865 } 1866 1867 int i=0, num=0; 1868 long[] tmp = new long[1]; 1869 do { 1870 ProcessRecord proc; 1871 int procState; 1872 int pid; 1873 synchronized (ActivityManagerService.this) { 1874 if (i >= mPendingPssProcesses.size()) { 1875 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1876 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1877 mPendingPssProcesses.clear(); 1878 return; 1879 } 1880 proc = mPendingPssProcesses.get(i); 1881 procState = proc.pssProcState; 1882 if (proc.thread != null && procState == proc.setProcState) { 1883 pid = proc.pid; 1884 } else { 1885 proc = null; 1886 pid = 0; 1887 } 1888 i++; 1889 } 1890 if (proc != null) { 1891 long pss = Debug.getPss(pid, tmp); 1892 synchronized (ActivityManagerService.this) { 1893 if (proc.thread != null && proc.setProcState == procState 1894 && proc.pid == pid) { 1895 num++; 1896 proc.lastPssTime = SystemClock.uptimeMillis(); 1897 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1898 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1899 + ": " + pss + " lastPss=" + proc.lastPss 1900 + " state=" + ProcessList.makeProcStateString(procState)); 1901 if (proc.initialIdlePss == 0) { 1902 proc.initialIdlePss = pss; 1903 } 1904 proc.lastPss = pss; 1905 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1906 proc.lastCachedPss = pss; 1907 } 1908 } 1909 } 1910 } 1911 } while (true); 1912 } 1913 } 1914 } 1915 }; 1916 1917 /** 1918 * Monitor for package changes and update our internal state. 1919 */ 1920 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1921 @Override 1922 public void onPackageRemoved(String packageName, int uid) { 1923 // Remove all tasks with activities in the specified package from the list of recent tasks 1924 synchronized (ActivityManagerService.this) { 1925 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1926 TaskRecord tr = mRecentTasks.get(i); 1927 ComponentName cn = tr.intent.getComponent(); 1928 if (cn != null && cn.getPackageName().equals(packageName)) { 1929 // If the package name matches, remove the task and kill the process 1930 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1931 } 1932 } 1933 } 1934 } 1935 1936 @Override 1937 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1938 onPackageModified(packageName); 1939 return true; 1940 } 1941 1942 @Override 1943 public void onPackageModified(String packageName) { 1944 final PackageManager pm = mContext.getPackageManager(); 1945 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1946 new ArrayList<Pair<Intent, Integer>>(); 1947 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1948 // Copy the list of recent tasks so that we don't hold onto the lock on 1949 // ActivityManagerService for long periods while checking if components exist. 1950 synchronized (ActivityManagerService.this) { 1951 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1952 TaskRecord tr = mRecentTasks.get(i); 1953 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1954 } 1955 } 1956 // Check the recent tasks and filter out all tasks with components that no longer exist. 1957 Intent tmpI = new Intent(); 1958 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1959 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1960 ComponentName cn = p.first.getComponent(); 1961 if (cn != null && cn.getPackageName().equals(packageName)) { 1962 try { 1963 // Add the task to the list to remove if the component no longer exists 1964 tmpI.setComponent(cn); 1965 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1966 tasksToRemove.add(p.second); 1967 } 1968 } catch (Exception e) {} 1969 } 1970 } 1971 // Prune all the tasks with removed components from the list of recent tasks 1972 synchronized (ActivityManagerService.this) { 1973 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1974 // Remove the task but don't kill the process (since other components in that 1975 // package may still be running and in the background) 1976 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1977 } 1978 } 1979 } 1980 1981 @Override 1982 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1983 // Force stop the specified packages 1984 if (packages != null) { 1985 for (String pkg : packages) { 1986 synchronized (ActivityManagerService.this) { 1987 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1988 "finished booting")) { 1989 return true; 1990 } 1991 } 1992 } 1993 } 1994 return false; 1995 } 1996 }; 1997 1998 public void setSystemProcess() { 1999 try { 2000 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2001 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2002 ServiceManager.addService("meminfo", new MemBinder(this)); 2003 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2004 ServiceManager.addService("dbinfo", new DbBinder(this)); 2005 if (MONITOR_CPU_USAGE) { 2006 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2007 } 2008 ServiceManager.addService("permission", new PermissionController(this)); 2009 2010 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2011 "android", STOCK_PM_FLAGS); 2012 mSystemThread.installSystemApplicationInfo(info); 2013 2014 synchronized (this) { 2015 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2016 app.persistent = true; 2017 app.pid = MY_PID; 2018 app.maxAdj = ProcessList.SYSTEM_ADJ; 2019 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2020 mProcessNames.put(app.processName, app.uid, app); 2021 synchronized (mPidsSelfLocked) { 2022 mPidsSelfLocked.put(app.pid, app); 2023 } 2024 updateLruProcessLocked(app, false, null); 2025 updateOomAdjLocked(); 2026 } 2027 } catch (PackageManager.NameNotFoundException e) { 2028 throw new RuntimeException( 2029 "Unable to find android system package", e); 2030 } 2031 } 2032 2033 public void setWindowManager(WindowManagerService wm) { 2034 mWindowManager = wm; 2035 mStackSupervisor.setWindowManager(wm); 2036 } 2037 2038 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2039 mUsageStatsService = usageStatsManager; 2040 } 2041 2042 public void startObservingNativeCrashes() { 2043 final NativeCrashListener ncl = new NativeCrashListener(this); 2044 ncl.start(); 2045 } 2046 2047 public IAppOpsService getAppOpsService() { 2048 return mAppOpsService; 2049 } 2050 2051 static class MemBinder extends Binder { 2052 ActivityManagerService mActivityManagerService; 2053 MemBinder(ActivityManagerService activityManagerService) { 2054 mActivityManagerService = activityManagerService; 2055 } 2056 2057 @Override 2058 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2059 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2060 != PackageManager.PERMISSION_GRANTED) { 2061 pw.println("Permission Denial: can't dump meminfo from from pid=" 2062 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2063 + " without permission " + android.Manifest.permission.DUMP); 2064 return; 2065 } 2066 2067 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2068 } 2069 } 2070 2071 static class GraphicsBinder extends Binder { 2072 ActivityManagerService mActivityManagerService; 2073 GraphicsBinder(ActivityManagerService activityManagerService) { 2074 mActivityManagerService = activityManagerService; 2075 } 2076 2077 @Override 2078 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2079 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2080 != PackageManager.PERMISSION_GRANTED) { 2081 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2082 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2083 + " without permission " + android.Manifest.permission.DUMP); 2084 return; 2085 } 2086 2087 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2088 } 2089 } 2090 2091 static class DbBinder extends Binder { 2092 ActivityManagerService mActivityManagerService; 2093 DbBinder(ActivityManagerService activityManagerService) { 2094 mActivityManagerService = activityManagerService; 2095 } 2096 2097 @Override 2098 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2099 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2100 != PackageManager.PERMISSION_GRANTED) { 2101 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2102 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2103 + " without permission " + android.Manifest.permission.DUMP); 2104 return; 2105 } 2106 2107 mActivityManagerService.dumpDbInfo(fd, pw, args); 2108 } 2109 } 2110 2111 static class CpuBinder extends Binder { 2112 ActivityManagerService mActivityManagerService; 2113 CpuBinder(ActivityManagerService activityManagerService) { 2114 mActivityManagerService = activityManagerService; 2115 } 2116 2117 @Override 2118 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2119 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2120 != PackageManager.PERMISSION_GRANTED) { 2121 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2122 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2123 + " without permission " + android.Manifest.permission.DUMP); 2124 return; 2125 } 2126 2127 synchronized (mActivityManagerService.mProcessCpuThread) { 2128 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2129 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2130 SystemClock.uptimeMillis())); 2131 } 2132 } 2133 } 2134 2135 public static final class Lifecycle extends SystemService { 2136 private final ActivityManagerService mService; 2137 2138 public Lifecycle(Context context) { 2139 super(context); 2140 mService = new ActivityManagerService(context); 2141 } 2142 2143 @Override 2144 public void onStart() { 2145 mService.start(); 2146 } 2147 2148 public ActivityManagerService getService() { 2149 return mService; 2150 } 2151 } 2152 2153 // Note: This method is invoked on the main thread but may need to attach various 2154 // handlers to other threads. So take care to be explicit about the looper. 2155 public ActivityManagerService(Context systemContext) { 2156 mContext = systemContext; 2157 mFactoryTest = FactoryTest.getMode(); 2158 mSystemThread = ActivityThread.currentActivityThread(); 2159 2160 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2161 2162 mHandlerThread = new ServiceThread(TAG, 2163 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2164 mHandlerThread.start(); 2165 mHandler = new MainHandler(mHandlerThread.getLooper()); 2166 2167 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2168 "foreground", BROADCAST_FG_TIMEOUT, false); 2169 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2170 "background", BROADCAST_BG_TIMEOUT, true); 2171 mBroadcastQueues[0] = mFgBroadcastQueue; 2172 mBroadcastQueues[1] = mBgBroadcastQueue; 2173 2174 mServices = new ActiveServices(this); 2175 mProviderMap = new ProviderMap(this); 2176 2177 // TODO: Move creation of battery stats service outside of activity manager service. 2178 File dataDir = Environment.getDataDirectory(); 2179 File systemDir = new File(dataDir, "system"); 2180 systemDir.mkdirs(); 2181 mBatteryStatsService = new BatteryStatsService(new File( 2182 systemDir, "batterystats.bin").toString(), mHandler); 2183 mBatteryStatsService.getActiveStatistics().readLocked(); 2184 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2185 mOnBattery = DEBUG_POWER ? true 2186 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2187 mBatteryStatsService.getActiveStatistics().setCallback(this); 2188 2189 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2190 2191 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2192 2193 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2194 2195 // User 0 is the first and only user that runs at boot. 2196 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2197 mUserLru.add(Integer.valueOf(0)); 2198 updateStartedUserArrayLocked(); 2199 2200 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2201 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2202 2203 mConfiguration.setToDefaults(); 2204 mConfiguration.setLocale(Locale.getDefault()); 2205 2206 mConfigurationSeq = mConfiguration.seq = 1; 2207 mProcessCpuTracker.init(); 2208 2209 mHasRecents = mContext.getResources().getBoolean( 2210 com.android.internal.R.bool.config_hasRecents); 2211 2212 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2213 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2214 mStackSupervisor = new ActivityStackSupervisor(this); 2215 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2216 2217 mProcessCpuThread = new Thread("CpuTracker") { 2218 @Override 2219 public void run() { 2220 while (true) { 2221 try { 2222 try { 2223 synchronized(this) { 2224 final long now = SystemClock.uptimeMillis(); 2225 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2226 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2227 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2228 // + ", write delay=" + nextWriteDelay); 2229 if (nextWriteDelay < nextCpuDelay) { 2230 nextCpuDelay = nextWriteDelay; 2231 } 2232 if (nextCpuDelay > 0) { 2233 mProcessCpuMutexFree.set(true); 2234 this.wait(nextCpuDelay); 2235 } 2236 } 2237 } catch (InterruptedException e) { 2238 } 2239 updateCpuStatsNow(); 2240 } catch (Exception e) { 2241 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2242 } 2243 } 2244 } 2245 }; 2246 2247 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2248 2249 Watchdog.getInstance().addMonitor(this); 2250 Watchdog.getInstance().addThread(mHandler); 2251 } 2252 2253 public void setSystemServiceManager(SystemServiceManager mgr) { 2254 mSystemServiceManager = mgr; 2255 } 2256 2257 private void start() { 2258 Process.removeAllProcessGroups(); 2259 mProcessCpuThread.start(); 2260 2261 mBatteryStatsService.publish(mContext); 2262 mAppOpsService.publish(mContext); 2263 Slog.d("AppOps", "AppOpsService published"); 2264 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2265 } 2266 2267 public void initPowerManagement() { 2268 mStackSupervisor.initPowerManagement(); 2269 mBatteryStatsService.initPowerManagement(); 2270 } 2271 2272 @Override 2273 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2274 throws RemoteException { 2275 if (code == SYSPROPS_TRANSACTION) { 2276 // We need to tell all apps about the system property change. 2277 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2278 synchronized(this) { 2279 final int NP = mProcessNames.getMap().size(); 2280 for (int ip=0; ip<NP; ip++) { 2281 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2282 final int NA = apps.size(); 2283 for (int ia=0; ia<NA; ia++) { 2284 ProcessRecord app = apps.valueAt(ia); 2285 if (app.thread != null) { 2286 procs.add(app.thread.asBinder()); 2287 } 2288 } 2289 } 2290 } 2291 2292 int N = procs.size(); 2293 for (int i=0; i<N; i++) { 2294 Parcel data2 = Parcel.obtain(); 2295 try { 2296 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2297 } catch (RemoteException e) { 2298 } 2299 data2.recycle(); 2300 } 2301 } 2302 try { 2303 return super.onTransact(code, data, reply, flags); 2304 } catch (RuntimeException e) { 2305 // The activity manager only throws security exceptions, so let's 2306 // log all others. 2307 if (!(e instanceof SecurityException)) { 2308 Slog.wtf(TAG, "Activity Manager Crash", e); 2309 } 2310 throw e; 2311 } 2312 } 2313 2314 void updateCpuStats() { 2315 final long now = SystemClock.uptimeMillis(); 2316 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2317 return; 2318 } 2319 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2320 synchronized (mProcessCpuThread) { 2321 mProcessCpuThread.notify(); 2322 } 2323 } 2324 } 2325 2326 void updateCpuStatsNow() { 2327 synchronized (mProcessCpuThread) { 2328 mProcessCpuMutexFree.set(false); 2329 final long now = SystemClock.uptimeMillis(); 2330 boolean haveNewCpuStats = false; 2331 2332 if (MONITOR_CPU_USAGE && 2333 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2334 mLastCpuTime.set(now); 2335 haveNewCpuStats = true; 2336 mProcessCpuTracker.update(); 2337 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2338 //Slog.i(TAG, "Total CPU usage: " 2339 // + mProcessCpu.getTotalCpuPercent() + "%"); 2340 2341 // Slog the cpu usage if the property is set. 2342 if ("true".equals(SystemProperties.get("events.cpu"))) { 2343 int user = mProcessCpuTracker.getLastUserTime(); 2344 int system = mProcessCpuTracker.getLastSystemTime(); 2345 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2346 int irq = mProcessCpuTracker.getLastIrqTime(); 2347 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2348 int idle = mProcessCpuTracker.getLastIdleTime(); 2349 2350 int total = user + system + iowait + irq + softIrq + idle; 2351 if (total == 0) total = 1; 2352 2353 EventLog.writeEvent(EventLogTags.CPU, 2354 ((user+system+iowait+irq+softIrq) * 100) / total, 2355 (user * 100) / total, 2356 (system * 100) / total, 2357 (iowait * 100) / total, 2358 (irq * 100) / total, 2359 (softIrq * 100) / total); 2360 } 2361 } 2362 2363 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2364 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2365 synchronized(bstats) { 2366 synchronized(mPidsSelfLocked) { 2367 if (haveNewCpuStats) { 2368 if (mOnBattery) { 2369 int perc = bstats.startAddingCpuLocked(); 2370 int totalUTime = 0; 2371 int totalSTime = 0; 2372 final int N = mProcessCpuTracker.countStats(); 2373 for (int i=0; i<N; i++) { 2374 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2375 if (!st.working) { 2376 continue; 2377 } 2378 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2379 int otherUTime = (st.rel_utime*perc)/100; 2380 int otherSTime = (st.rel_stime*perc)/100; 2381 totalUTime += otherUTime; 2382 totalSTime += otherSTime; 2383 if (pr != null) { 2384 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2385 if (ps == null || !ps.isActive()) { 2386 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2387 pr.info.uid, pr.processName); 2388 } 2389 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2390 st.rel_stime-otherSTime); 2391 ps.addSpeedStepTimes(cpuSpeedTimes); 2392 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2393 } else { 2394 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2395 if (ps == null || !ps.isActive()) { 2396 st.batteryStats = ps = bstats.getProcessStatsLocked( 2397 bstats.mapUid(st.uid), st.name); 2398 } 2399 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2400 st.rel_stime-otherSTime); 2401 ps.addSpeedStepTimes(cpuSpeedTimes); 2402 } 2403 } 2404 bstats.finishAddingCpuLocked(perc, totalUTime, 2405 totalSTime, cpuSpeedTimes); 2406 } 2407 } 2408 } 2409 2410 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2411 mLastWriteTime = now; 2412 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2413 } 2414 } 2415 } 2416 } 2417 2418 @Override 2419 public void batteryNeedsCpuUpdate() { 2420 updateCpuStatsNow(); 2421 } 2422 2423 @Override 2424 public void batteryPowerChanged(boolean onBattery) { 2425 // When plugging in, update the CPU stats first before changing 2426 // the plug state. 2427 updateCpuStatsNow(); 2428 synchronized (this) { 2429 synchronized(mPidsSelfLocked) { 2430 mOnBattery = DEBUG_POWER ? true : onBattery; 2431 } 2432 } 2433 } 2434 2435 /** 2436 * Initialize the application bind args. These are passed to each 2437 * process when the bindApplication() IPC is sent to the process. They're 2438 * lazily setup to make sure the services are running when they're asked for. 2439 */ 2440 private HashMap<String, IBinder> getCommonServicesLocked() { 2441 if (mAppBindArgs == null) { 2442 mAppBindArgs = new HashMap<String, IBinder>(); 2443 2444 // Setup the application init args 2445 mAppBindArgs.put("package", ServiceManager.getService("package")); 2446 mAppBindArgs.put("window", ServiceManager.getService("window")); 2447 mAppBindArgs.put(Context.ALARM_SERVICE, 2448 ServiceManager.getService(Context.ALARM_SERVICE)); 2449 } 2450 return mAppBindArgs; 2451 } 2452 2453 final void setFocusedActivityLocked(ActivityRecord r) { 2454 if (mFocusedActivity != r) { 2455 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2456 mFocusedActivity = r; 2457 if (r.task != null && r.task.voiceInteractor != null) { 2458 startRunningVoiceLocked(); 2459 } else { 2460 finishRunningVoiceLocked(); 2461 } 2462 mStackSupervisor.setFocusedStack(r); 2463 if (r != null) { 2464 mWindowManager.setFocusedApp(r.appToken, true); 2465 } 2466 applyUpdateLockStateLocked(r); 2467 } 2468 } 2469 2470 final void clearFocusedActivity(ActivityRecord r) { 2471 if (mFocusedActivity == r) { 2472 mFocusedActivity = null; 2473 } 2474 } 2475 2476 @Override 2477 public void setFocusedStack(int stackId) { 2478 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2479 synchronized (ActivityManagerService.this) { 2480 ActivityStack stack = mStackSupervisor.getStack(stackId); 2481 if (stack != null) { 2482 ActivityRecord r = stack.topRunningActivityLocked(null); 2483 if (r != null) { 2484 setFocusedActivityLocked(r); 2485 } 2486 } 2487 } 2488 } 2489 2490 @Override 2491 public void notifyActivityDrawn(IBinder token) { 2492 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2493 synchronized (this) { 2494 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2495 if (r != null) { 2496 r.task.stack.notifyActivityDrawnLocked(r); 2497 } 2498 } 2499 } 2500 2501 final void applyUpdateLockStateLocked(ActivityRecord r) { 2502 // Modifications to the UpdateLock state are done on our handler, outside 2503 // the activity manager's locks. The new state is determined based on the 2504 // state *now* of the relevant activity record. The object is passed to 2505 // the handler solely for logging detail, not to be consulted/modified. 2506 final boolean nextState = r != null && r.immersive; 2507 mHandler.sendMessage( 2508 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2509 } 2510 2511 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2512 Message msg = Message.obtain(); 2513 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2514 msg.obj = r.task.askedCompatMode ? null : r; 2515 mHandler.sendMessage(msg); 2516 } 2517 2518 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2519 String what, Object obj, ProcessRecord srcApp) { 2520 app.lastActivityTime = now; 2521 2522 if (app.activities.size() > 0) { 2523 // Don't want to touch dependent processes that are hosting activities. 2524 return index; 2525 } 2526 2527 int lrui = mLruProcesses.lastIndexOf(app); 2528 if (lrui < 0) { 2529 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2530 + what + " " + obj + " from " + srcApp); 2531 return index; 2532 } 2533 2534 if (lrui >= index) { 2535 // Don't want to cause this to move dependent processes *back* in the 2536 // list as if they were less frequently used. 2537 return index; 2538 } 2539 2540 if (lrui >= mLruProcessActivityStart) { 2541 // Don't want to touch dependent processes that are hosting activities. 2542 return index; 2543 } 2544 2545 mLruProcesses.remove(lrui); 2546 if (index > 0) { 2547 index--; 2548 } 2549 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2550 + " in LRU list: " + app); 2551 mLruProcesses.add(index, app); 2552 return index; 2553 } 2554 2555 final void removeLruProcessLocked(ProcessRecord app) { 2556 int lrui = mLruProcesses.lastIndexOf(app); 2557 if (lrui >= 0) { 2558 if (lrui <= mLruProcessActivityStart) { 2559 mLruProcessActivityStart--; 2560 } 2561 if (lrui <= mLruProcessServiceStart) { 2562 mLruProcessServiceStart--; 2563 } 2564 mLruProcesses.remove(lrui); 2565 } 2566 } 2567 2568 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2569 ProcessRecord client) { 2570 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2571 || app.treatLikeActivity; 2572 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2573 if (!activityChange && hasActivity) { 2574 // The process has activities, so we are only allowing activity-based adjustments 2575 // to move it. It should be kept in the front of the list with other 2576 // processes that have activities, and we don't want those to change their 2577 // order except due to activity operations. 2578 return; 2579 } 2580 2581 mLruSeq++; 2582 final long now = SystemClock.uptimeMillis(); 2583 app.lastActivityTime = now; 2584 2585 // First a quick reject: if the app is already at the position we will 2586 // put it, then there is nothing to do. 2587 if (hasActivity) { 2588 final int N = mLruProcesses.size(); 2589 if (N > 0 && mLruProcesses.get(N-1) == app) { 2590 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2591 return; 2592 } 2593 } else { 2594 if (mLruProcessServiceStart > 0 2595 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2596 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2597 return; 2598 } 2599 } 2600 2601 int lrui = mLruProcesses.lastIndexOf(app); 2602 2603 if (app.persistent && lrui >= 0) { 2604 // We don't care about the position of persistent processes, as long as 2605 // they are in the list. 2606 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2607 return; 2608 } 2609 2610 /* In progress: compute new position first, so we can avoid doing work 2611 if the process is not actually going to move. Not yet working. 2612 int addIndex; 2613 int nextIndex; 2614 boolean inActivity = false, inService = false; 2615 if (hasActivity) { 2616 // Process has activities, put it at the very tipsy-top. 2617 addIndex = mLruProcesses.size(); 2618 nextIndex = mLruProcessServiceStart; 2619 inActivity = true; 2620 } else if (hasService) { 2621 // Process has services, put it at the top of the service list. 2622 addIndex = mLruProcessActivityStart; 2623 nextIndex = mLruProcessServiceStart; 2624 inActivity = true; 2625 inService = true; 2626 } else { 2627 // Process not otherwise of interest, it goes to the top of the non-service area. 2628 addIndex = mLruProcessServiceStart; 2629 if (client != null) { 2630 int clientIndex = mLruProcesses.lastIndexOf(client); 2631 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2632 + app); 2633 if (clientIndex >= 0 && addIndex > clientIndex) { 2634 addIndex = clientIndex; 2635 } 2636 } 2637 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2638 } 2639 2640 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2641 + mLruProcessActivityStart + "): " + app); 2642 */ 2643 2644 if (lrui >= 0) { 2645 if (lrui < mLruProcessActivityStart) { 2646 mLruProcessActivityStart--; 2647 } 2648 if (lrui < mLruProcessServiceStart) { 2649 mLruProcessServiceStart--; 2650 } 2651 /* 2652 if (addIndex > lrui) { 2653 addIndex--; 2654 } 2655 if (nextIndex > lrui) { 2656 nextIndex--; 2657 } 2658 */ 2659 mLruProcesses.remove(lrui); 2660 } 2661 2662 /* 2663 mLruProcesses.add(addIndex, app); 2664 if (inActivity) { 2665 mLruProcessActivityStart++; 2666 } 2667 if (inService) { 2668 mLruProcessActivityStart++; 2669 } 2670 */ 2671 2672 int nextIndex; 2673 if (hasActivity) { 2674 final int N = mLruProcesses.size(); 2675 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2676 // Process doesn't have activities, but has clients with 2677 // activities... move it up, but one below the top (the top 2678 // should always have a real activity). 2679 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2680 mLruProcesses.add(N-1, app); 2681 // To keep it from spamming the LRU list (by making a bunch of clients), 2682 // we will push down any other entries owned by the app. 2683 final int uid = app.info.uid; 2684 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2685 ProcessRecord subProc = mLruProcesses.get(i); 2686 if (subProc.info.uid == uid) { 2687 // We want to push this one down the list. If the process after 2688 // it is for the same uid, however, don't do so, because we don't 2689 // want them internally to be re-ordered. 2690 if (mLruProcesses.get(i-1).info.uid != uid) { 2691 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2692 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2693 ProcessRecord tmp = mLruProcesses.get(i); 2694 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2695 mLruProcesses.set(i-1, tmp); 2696 i--; 2697 } 2698 } else { 2699 // A gap, we can stop here. 2700 break; 2701 } 2702 } 2703 } else { 2704 // Process has activities, put it at the very tipsy-top. 2705 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2706 mLruProcesses.add(app); 2707 } 2708 nextIndex = mLruProcessServiceStart; 2709 } else if (hasService) { 2710 // Process has services, put it at the top of the service list. 2711 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2712 mLruProcesses.add(mLruProcessActivityStart, app); 2713 nextIndex = mLruProcessServiceStart; 2714 mLruProcessActivityStart++; 2715 } else { 2716 // Process not otherwise of interest, it goes to the top of the non-service area. 2717 int index = mLruProcessServiceStart; 2718 if (client != null) { 2719 // If there is a client, don't allow the process to be moved up higher 2720 // in the list than that client. 2721 int clientIndex = mLruProcesses.lastIndexOf(client); 2722 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2723 + " when updating " + app); 2724 if (clientIndex <= lrui) { 2725 // Don't allow the client index restriction to push it down farther in the 2726 // list than it already is. 2727 clientIndex = lrui; 2728 } 2729 if (clientIndex >= 0 && index > clientIndex) { 2730 index = clientIndex; 2731 } 2732 } 2733 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2734 mLruProcesses.add(index, app); 2735 nextIndex = index-1; 2736 mLruProcessActivityStart++; 2737 mLruProcessServiceStart++; 2738 } 2739 2740 // If the app is currently using a content provider or service, 2741 // bump those processes as well. 2742 for (int j=app.connections.size()-1; j>=0; j--) { 2743 ConnectionRecord cr = app.connections.valueAt(j); 2744 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2745 && cr.binding.service.app != null 2746 && cr.binding.service.app.lruSeq != mLruSeq 2747 && !cr.binding.service.app.persistent) { 2748 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2749 "service connection", cr, app); 2750 } 2751 } 2752 for (int j=app.conProviders.size()-1; j>=0; j--) { 2753 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2754 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2755 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2756 "provider reference", cpr, app); 2757 } 2758 } 2759 } 2760 2761 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2762 if (uid == Process.SYSTEM_UID) { 2763 // The system gets to run in any process. If there are multiple 2764 // processes with the same uid, just pick the first (this 2765 // should never happen). 2766 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2767 if (procs == null) return null; 2768 final int N = procs.size(); 2769 for (int i = 0; i < N; i++) { 2770 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2771 } 2772 } 2773 ProcessRecord proc = mProcessNames.get(processName, uid); 2774 if (false && proc != null && !keepIfLarge 2775 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2776 && proc.lastCachedPss >= 4000) { 2777 // Turn this condition on to cause killing to happen regularly, for testing. 2778 if (proc.baseProcessTracker != null) { 2779 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2780 } 2781 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2782 + "k from cached"); 2783 } else if (proc != null && !keepIfLarge 2784 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2785 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2786 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2787 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2788 if (proc.baseProcessTracker != null) { 2789 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2790 } 2791 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2792 + "k from cached"); 2793 } 2794 } 2795 return proc; 2796 } 2797 2798 void ensurePackageDexOpt(String packageName) { 2799 IPackageManager pm = AppGlobals.getPackageManager(); 2800 try { 2801 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2802 mDidDexOpt = true; 2803 } 2804 } catch (RemoteException e) { 2805 } 2806 } 2807 2808 boolean isNextTransitionForward() { 2809 int transit = mWindowManager.getPendingAppTransition(); 2810 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2811 || transit == AppTransition.TRANSIT_TASK_OPEN 2812 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2813 } 2814 2815 final ProcessRecord startProcessLocked(String processName, 2816 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2817 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2818 boolean isolated, boolean keepIfLarge) { 2819 ProcessRecord app; 2820 if (!isolated) { 2821 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2822 } else { 2823 // If this is an isolated process, it can't re-use an existing process. 2824 app = null; 2825 } 2826 // We don't have to do anything more if: 2827 // (1) There is an existing application record; and 2828 // (2) The caller doesn't think it is dead, OR there is no thread 2829 // object attached to it so we know it couldn't have crashed; and 2830 // (3) There is a pid assigned to it, so it is either starting or 2831 // already running. 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2833 + " app=" + app + " knownToBeDead=" + knownToBeDead 2834 + " thread=" + (app != null ? app.thread : null) 2835 + " pid=" + (app != null ? app.pid : -1)); 2836 if (app != null && app.pid > 0) { 2837 if (!knownToBeDead || app.thread == null) { 2838 // We already have the app running, or are waiting for it to 2839 // come up (we have a pid but not yet its thread), so keep it. 2840 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2841 // If this is a new package in the process, add the package to the list 2842 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2843 return app; 2844 } 2845 2846 // An application record is attached to a previous process, 2847 // clean it up now. 2848 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2849 Process.killProcessGroup(app.info.uid, app.pid); 2850 handleAppDiedLocked(app, true, true); 2851 } 2852 2853 String hostingNameStr = hostingName != null 2854 ? hostingName.flattenToShortString() : null; 2855 2856 if (!isolated) { 2857 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2858 // If we are in the background, then check to see if this process 2859 // is bad. If so, we will just silently fail. 2860 if (mBadProcesses.get(info.processName, info.uid) != null) { 2861 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2862 + "/" + info.processName); 2863 return null; 2864 } 2865 } else { 2866 // When the user is explicitly starting a process, then clear its 2867 // crash count so that we won't make it bad until they see at 2868 // least one crash dialog again, and make the process good again 2869 // if it had been bad. 2870 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2871 + "/" + info.processName); 2872 mProcessCrashTimes.remove(info.processName, info.uid); 2873 if (mBadProcesses.get(info.processName, info.uid) != null) { 2874 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2875 UserHandle.getUserId(info.uid), info.uid, 2876 info.processName); 2877 mBadProcesses.remove(info.processName, info.uid); 2878 if (app != null) { 2879 app.bad = false; 2880 } 2881 } 2882 } 2883 } 2884 2885 if (app == null) { 2886 app = newProcessRecordLocked(info, processName, isolated); 2887 if (app == null) { 2888 Slog.w(TAG, "Failed making new process record for " 2889 + processName + "/" + info.uid + " isolated=" + isolated); 2890 return null; 2891 } 2892 mProcessNames.put(processName, app.uid, app); 2893 if (isolated) { 2894 mIsolatedProcesses.put(app.uid, app); 2895 } 2896 } else { 2897 // If this is a new package in the process, add the package to the list 2898 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2899 } 2900 2901 // If the system is not ready yet, then hold off on starting this 2902 // process until it is. 2903 if (!mProcessesReady 2904 && !isAllowedWhileBooting(info) 2905 && !allowWhileBooting) { 2906 if (!mProcessesOnHold.contains(app)) { 2907 mProcessesOnHold.add(app); 2908 } 2909 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2910 return app; 2911 } 2912 2913 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2914 return (app.pid != 0) ? app : null; 2915 } 2916 2917 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2918 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2919 } 2920 2921 private final void startProcessLocked(ProcessRecord app, 2922 String hostingType, String hostingNameStr, String abiOverride) { 2923 if (app.pid > 0 && app.pid != MY_PID) { 2924 synchronized (mPidsSelfLocked) { 2925 mPidsSelfLocked.remove(app.pid); 2926 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2927 } 2928 app.setPid(0); 2929 } 2930 2931 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2932 "startProcessLocked removing on hold: " + app); 2933 mProcessesOnHold.remove(app); 2934 2935 updateCpuStats(); 2936 2937 try { 2938 int uid = app.uid; 2939 2940 int[] gids = null; 2941 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2942 if (!app.isolated) { 2943 int[] permGids = null; 2944 try { 2945 final PackageManager pm = mContext.getPackageManager(); 2946 permGids = pm.getPackageGids(app.info.packageName); 2947 2948 if (Environment.isExternalStorageEmulated()) { 2949 if (pm.checkPermission( 2950 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2951 app.info.packageName) == PERMISSION_GRANTED) { 2952 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2953 } else { 2954 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2955 } 2956 } 2957 } catch (PackageManager.NameNotFoundException e) { 2958 Slog.w(TAG, "Unable to retrieve gids", e); 2959 } 2960 2961 /* 2962 * Add shared application and profile GIDs so applications can share some 2963 * resources like shared libraries and access user-wide resources 2964 */ 2965 if (permGids == null) { 2966 gids = new int[2]; 2967 } else { 2968 gids = new int[permGids.length + 2]; 2969 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2970 } 2971 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2972 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2973 } 2974 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2975 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2976 && mTopComponent != null 2977 && app.processName.equals(mTopComponent.getPackageName())) { 2978 uid = 0; 2979 } 2980 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2981 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2982 uid = 0; 2983 } 2984 } 2985 int debugFlags = 0; 2986 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2988 // Also turn on CheckJNI for debuggable apps. It's quite 2989 // awkward to turn on otherwise. 2990 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2991 } 2992 // Run the app in safe mode if its manifest requests so or the 2993 // system is booted in safe mode. 2994 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2995 mSafeMode == true) { 2996 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2997 } 2998 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2999 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3000 } 3001 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3002 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3003 } 3004 if ("1".equals(SystemProperties.get("debug.assert"))) { 3005 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3006 } 3007 3008 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3009 if (requiredAbi == null) { 3010 requiredAbi = Build.SUPPORTED_ABIS[0]; 3011 } 3012 3013 // Start the process. It will either succeed and return a result containing 3014 // the PID of the new process, or else throw a RuntimeException. 3015 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 3016 app.processName, uid, uid, gids, debugFlags, mountExternal, 3017 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3018 3019 if (app.isolated) { 3020 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3021 } 3022 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3023 3024 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3025 UserHandle.getUserId(uid), startResult.pid, uid, 3026 app.processName, hostingType, 3027 hostingNameStr != null ? hostingNameStr : ""); 3028 3029 if (app.persistent) { 3030 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3031 } 3032 3033 StringBuilder buf = mStringBuilder; 3034 buf.setLength(0); 3035 buf.append("Start proc "); 3036 buf.append(app.processName); 3037 buf.append(" for "); 3038 buf.append(hostingType); 3039 if (hostingNameStr != null) { 3040 buf.append(" "); 3041 buf.append(hostingNameStr); 3042 } 3043 buf.append(": pid="); 3044 buf.append(startResult.pid); 3045 buf.append(" uid="); 3046 buf.append(uid); 3047 buf.append(" gids={"); 3048 if (gids != null) { 3049 for (int gi=0; gi<gids.length; gi++) { 3050 if (gi != 0) buf.append(", "); 3051 buf.append(gids[gi]); 3052 3053 } 3054 } 3055 buf.append("}"); 3056 if (requiredAbi != null) { 3057 buf.append(" abi="); 3058 buf.append(requiredAbi); 3059 } 3060 Slog.i(TAG, buf.toString()); 3061 app.setPid(startResult.pid); 3062 app.usingWrapper = startResult.usingWrapper; 3063 app.removed = false; 3064 app.killedByAm = false; 3065 synchronized (mPidsSelfLocked) { 3066 this.mPidsSelfLocked.put(startResult.pid, app); 3067 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3068 msg.obj = app; 3069 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3070 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3071 } 3072 } catch (RuntimeException e) { 3073 // XXX do better error recovery. 3074 app.setPid(0); 3075 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3076 if (app.isolated) { 3077 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3078 } 3079 Slog.e(TAG, "Failure starting process " + app.processName, e); 3080 } 3081 } 3082 3083 void updateUsageStats(ActivityRecord component, boolean resumed) { 3084 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3085 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3086 if (resumed) { 3087 if (mUsageStatsService != null) { 3088 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3089 UsageStats.Event.MOVE_TO_FOREGROUND); 3090 } 3091 synchronized (stats) { 3092 stats.noteActivityResumedLocked(component.app.uid); 3093 } 3094 } else { 3095 if (mUsageStatsService != null) { 3096 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3097 UsageStats.Event.MOVE_TO_BACKGROUND); 3098 } 3099 synchronized (stats) { 3100 stats.noteActivityPausedLocked(component.app.uid); 3101 } 3102 } 3103 } 3104 3105 Intent getHomeIntent() { 3106 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3107 intent.setComponent(mTopComponent); 3108 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3109 intent.addCategory(Intent.CATEGORY_HOME); 3110 } 3111 return intent; 3112 } 3113 3114 boolean startHomeActivityLocked(int userId) { 3115 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3116 && mTopAction == null) { 3117 // We are running in factory test mode, but unable to find 3118 // the factory test app, so just sit around displaying the 3119 // error message and don't try to start anything. 3120 return false; 3121 } 3122 Intent intent = getHomeIntent(); 3123 ActivityInfo aInfo = 3124 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3125 if (aInfo != null) { 3126 intent.setComponent(new ComponentName( 3127 aInfo.applicationInfo.packageName, aInfo.name)); 3128 // Don't do this if the home app is currently being 3129 // instrumented. 3130 aInfo = new ActivityInfo(aInfo); 3131 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3132 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3133 aInfo.applicationInfo.uid, true); 3134 if (app == null || app.instrumentationClass == null) { 3135 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3136 mStackSupervisor.startHomeActivity(intent, aInfo); 3137 } 3138 } 3139 3140 return true; 3141 } 3142 3143 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3144 ActivityInfo ai = null; 3145 ComponentName comp = intent.getComponent(); 3146 try { 3147 if (comp != null) { 3148 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3149 } else { 3150 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3151 intent, 3152 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3153 flags, userId); 3154 3155 if (info != null) { 3156 ai = info.activityInfo; 3157 } 3158 } 3159 } catch (RemoteException e) { 3160 // ignore 3161 } 3162 3163 return ai; 3164 } 3165 3166 /** 3167 * Starts the "new version setup screen" if appropriate. 3168 */ 3169 void startSetupActivityLocked() { 3170 // Only do this once per boot. 3171 if (mCheckedForSetup) { 3172 return; 3173 } 3174 3175 // We will show this screen if the current one is a different 3176 // version than the last one shown, and we are not running in 3177 // low-level factory test mode. 3178 final ContentResolver resolver = mContext.getContentResolver(); 3179 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3180 Settings.Global.getInt(resolver, 3181 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3182 mCheckedForSetup = true; 3183 3184 // See if we should be showing the platform update setup UI. 3185 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3186 List<ResolveInfo> ris = mContext.getPackageManager() 3187 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3188 3189 // We don't allow third party apps to replace this. 3190 ResolveInfo ri = null; 3191 for (int i=0; ris != null && i<ris.size(); i++) { 3192 if ((ris.get(i).activityInfo.applicationInfo.flags 3193 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3194 ri = ris.get(i); 3195 break; 3196 } 3197 } 3198 3199 if (ri != null) { 3200 String vers = ri.activityInfo.metaData != null 3201 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3202 : null; 3203 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3204 vers = ri.activityInfo.applicationInfo.metaData.getString( 3205 Intent.METADATA_SETUP_VERSION); 3206 } 3207 String lastVers = Settings.Secure.getString( 3208 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3209 if (vers != null && !vers.equals(lastVers)) { 3210 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3211 intent.setComponent(new ComponentName( 3212 ri.activityInfo.packageName, ri.activityInfo.name)); 3213 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3214 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3215 } 3216 } 3217 } 3218 } 3219 3220 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3221 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3222 } 3223 3224 void enforceNotIsolatedCaller(String caller) { 3225 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3226 throw new SecurityException("Isolated process not allowed to call " + caller); 3227 } 3228 } 3229 3230 @Override 3231 public int getFrontActivityScreenCompatMode() { 3232 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3233 synchronized (this) { 3234 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3235 } 3236 } 3237 3238 @Override 3239 public void setFrontActivityScreenCompatMode(int mode) { 3240 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3241 "setFrontActivityScreenCompatMode"); 3242 synchronized (this) { 3243 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3244 } 3245 } 3246 3247 @Override 3248 public int getPackageScreenCompatMode(String packageName) { 3249 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3250 synchronized (this) { 3251 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3252 } 3253 } 3254 3255 @Override 3256 public void setPackageScreenCompatMode(String packageName, int mode) { 3257 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3258 "setPackageScreenCompatMode"); 3259 synchronized (this) { 3260 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3261 } 3262 } 3263 3264 @Override 3265 public boolean getPackageAskScreenCompat(String packageName) { 3266 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3267 synchronized (this) { 3268 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3269 } 3270 } 3271 3272 @Override 3273 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3274 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3275 "setPackageAskScreenCompat"); 3276 synchronized (this) { 3277 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3278 } 3279 } 3280 3281 private void dispatchProcessesChanged() { 3282 int N; 3283 synchronized (this) { 3284 N = mPendingProcessChanges.size(); 3285 if (mActiveProcessChanges.length < N) { 3286 mActiveProcessChanges = new ProcessChangeItem[N]; 3287 } 3288 mPendingProcessChanges.toArray(mActiveProcessChanges); 3289 mAvailProcessChanges.addAll(mPendingProcessChanges); 3290 mPendingProcessChanges.clear(); 3291 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3292 } 3293 3294 int i = mProcessObservers.beginBroadcast(); 3295 while (i > 0) { 3296 i--; 3297 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3298 if (observer != null) { 3299 try { 3300 for (int j=0; j<N; j++) { 3301 ProcessChangeItem item = mActiveProcessChanges[j]; 3302 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3303 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3304 + item.pid + " uid=" + item.uid + ": " 3305 + item.foregroundActivities); 3306 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3307 item.foregroundActivities); 3308 } 3309 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3311 + item.pid + " uid=" + item.uid + ": " + item.processState); 3312 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3313 } 3314 } 3315 } catch (RemoteException e) { 3316 } 3317 } 3318 } 3319 mProcessObservers.finishBroadcast(); 3320 } 3321 3322 private void dispatchProcessDied(int pid, int uid) { 3323 int i = mProcessObservers.beginBroadcast(); 3324 while (i > 0) { 3325 i--; 3326 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3327 if (observer != null) { 3328 try { 3329 observer.onProcessDied(pid, uid); 3330 } catch (RemoteException e) { 3331 } 3332 } 3333 } 3334 mProcessObservers.finishBroadcast(); 3335 } 3336 3337 @Override 3338 public final int startActivity(IApplicationThread caller, String callingPackage, 3339 Intent intent, String resolvedType, IBinder resultTo, 3340 String resultWho, int requestCode, int startFlags, 3341 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3342 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3343 resultWho, requestCode, 3344 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3345 } 3346 3347 @Override 3348 public final int startActivityAsUser(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, int userId) { 3352 enforceNotIsolatedCaller("startActivity"); 3353 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3354 false, ALLOW_FULL_ONLY, "startActivity", null); 3355 // TODO: Switch to user app stacks here. 3356 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3357 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3358 null, null, options, userId, null); 3359 } 3360 3361 @Override 3362 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3363 Intent intent, String resolvedType, IBinder resultTo, 3364 String resultWho, int requestCode, int startFlags, String profileFile, 3365 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3366 enforceNotIsolatedCaller("startActivityAndWait"); 3367 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3368 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3369 WaitResult res = new WaitResult(); 3370 // TODO: Switch to user app stacks here. 3371 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3372 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3373 res, null, options, userId, null); 3374 return res; 3375 } 3376 3377 @Override 3378 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3379 Intent intent, String resolvedType, IBinder resultTo, 3380 String resultWho, int requestCode, int startFlags, Configuration config, 3381 Bundle options, int userId) { 3382 enforceNotIsolatedCaller("startActivityWithConfig"); 3383 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3384 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3385 // TODO: Switch to user app stacks here. 3386 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3387 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3388 null, null, null, config, options, userId, null); 3389 return ret; 3390 } 3391 3392 @Override 3393 public int startActivityIntentSender(IApplicationThread caller, 3394 IntentSender intent, Intent fillInIntent, String resolvedType, 3395 IBinder resultTo, String resultWho, int requestCode, 3396 int flagsMask, int flagsValues, Bundle options) { 3397 enforceNotIsolatedCaller("startActivityIntentSender"); 3398 // Refuse possible leaked file descriptors 3399 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3400 throw new IllegalArgumentException("File descriptors passed in Intent"); 3401 } 3402 3403 IIntentSender sender = intent.getTarget(); 3404 if (!(sender instanceof PendingIntentRecord)) { 3405 throw new IllegalArgumentException("Bad PendingIntent object"); 3406 } 3407 3408 PendingIntentRecord pir = (PendingIntentRecord)sender; 3409 3410 synchronized (this) { 3411 // If this is coming from the currently resumed activity, it is 3412 // effectively saying that app switches are allowed at this point. 3413 final ActivityStack stack = getFocusedStack(); 3414 if (stack.mResumedActivity != null && 3415 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3416 mAppSwitchesAllowedTime = 0; 3417 } 3418 } 3419 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3420 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3421 return ret; 3422 } 3423 3424 @Override 3425 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3426 Intent intent, String resolvedType, IVoiceInteractionSession session, 3427 IVoiceInteractor interactor, int startFlags, String profileFile, 3428 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3429 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3430 != PackageManager.PERMISSION_GRANTED) { 3431 String msg = "Permission Denial: startVoiceActivity() from pid=" 3432 + Binder.getCallingPid() 3433 + ", uid=" + Binder.getCallingUid() 3434 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3435 Slog.w(TAG, msg); 3436 throw new SecurityException(msg); 3437 } 3438 if (session == null || interactor == null) { 3439 throw new NullPointerException("null session or interactor"); 3440 } 3441 userId = handleIncomingUser(callingPid, callingUid, userId, 3442 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3443 // TODO: Switch to user app stacks here. 3444 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3445 resolvedType, session, interactor, null, null, 0, startFlags, 3446 profileFile, profileFd, null, null, options, userId, null); 3447 } 3448 3449 @Override 3450 public boolean startNextMatchingActivity(IBinder callingActivity, 3451 Intent intent, Bundle options) { 3452 // Refuse possible leaked file descriptors 3453 if (intent != null && intent.hasFileDescriptors() == true) { 3454 throw new IllegalArgumentException("File descriptors passed in Intent"); 3455 } 3456 3457 synchronized (this) { 3458 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3459 if (r == null) { 3460 ActivityOptions.abort(options); 3461 return false; 3462 } 3463 if (r.app == null || r.app.thread == null) { 3464 // The caller is not running... d'oh! 3465 ActivityOptions.abort(options); 3466 return false; 3467 } 3468 intent = new Intent(intent); 3469 // The caller is not allowed to change the data. 3470 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3471 // And we are resetting to find the next component... 3472 intent.setComponent(null); 3473 3474 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3475 3476 ActivityInfo aInfo = null; 3477 try { 3478 List<ResolveInfo> resolves = 3479 AppGlobals.getPackageManager().queryIntentActivities( 3480 intent, r.resolvedType, 3481 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3482 UserHandle.getCallingUserId()); 3483 3484 // Look for the original activity in the list... 3485 final int N = resolves != null ? resolves.size() : 0; 3486 for (int i=0; i<N; i++) { 3487 ResolveInfo rInfo = resolves.get(i); 3488 if (rInfo.activityInfo.packageName.equals(r.packageName) 3489 && rInfo.activityInfo.name.equals(r.info.name)) { 3490 // We found the current one... the next matching is 3491 // after it. 3492 i++; 3493 if (i<N) { 3494 aInfo = resolves.get(i).activityInfo; 3495 } 3496 if (debug) { 3497 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3498 + "/" + r.info.name); 3499 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3500 + "/" + aInfo.name); 3501 } 3502 break; 3503 } 3504 } 3505 } catch (RemoteException e) { 3506 } 3507 3508 if (aInfo == null) { 3509 // Nobody who is next! 3510 ActivityOptions.abort(options); 3511 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3512 return false; 3513 } 3514 3515 intent.setComponent(new ComponentName( 3516 aInfo.applicationInfo.packageName, aInfo.name)); 3517 intent.setFlags(intent.getFlags()&~( 3518 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3519 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3520 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3521 Intent.FLAG_ACTIVITY_NEW_TASK)); 3522 3523 // Okay now we need to start the new activity, replacing the 3524 // currently running activity. This is a little tricky because 3525 // we want to start the new one as if the current one is finished, 3526 // but not finish the current one first so that there is no flicker. 3527 // And thus... 3528 final boolean wasFinishing = r.finishing; 3529 r.finishing = true; 3530 3531 // Propagate reply information over to the new activity. 3532 final ActivityRecord resultTo = r.resultTo; 3533 final String resultWho = r.resultWho; 3534 final int requestCode = r.requestCode; 3535 r.resultTo = null; 3536 if (resultTo != null) { 3537 resultTo.removeResultsLocked(r, resultWho, requestCode); 3538 } 3539 3540 final long origId = Binder.clearCallingIdentity(); 3541 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3542 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3543 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3544 options, false, null, null); 3545 Binder.restoreCallingIdentity(origId); 3546 3547 r.finishing = wasFinishing; 3548 if (res != ActivityManager.START_SUCCESS) { 3549 return false; 3550 } 3551 return true; 3552 } 3553 } 3554 3555 @Override 3556 public final int startActivityFromRecents(int taskId, Bundle options) { 3557 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3558 String msg = "Permission Denial: startActivityFromRecents called without " + 3559 START_TASKS_FROM_RECENTS; 3560 Slog.w(TAG, msg); 3561 throw new SecurityException(msg); 3562 } 3563 final int callingUid; 3564 final String callingPackage; 3565 final Intent intent; 3566 final int userId; 3567 synchronized (this) { 3568 final TaskRecord task = recentTaskForIdLocked(taskId); 3569 if (task == null) { 3570 throw new ActivityNotFoundException("Task " + taskId + " not found."); 3571 } 3572 callingUid = task.mCallingUid; 3573 callingPackage = task.mCallingPackage; 3574 intent = task.intent; 3575 userId = task.userId; 3576 } 3577 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3578 options, userId, null); 3579 } 3580 3581 final int startActivityInPackage(int uid, String callingPackage, 3582 Intent intent, String resolvedType, IBinder resultTo, 3583 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3584 IActivityContainer container) { 3585 3586 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3587 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3588 3589 // TODO: Switch to user app stacks here. 3590 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3591 null, null, resultTo, resultWho, requestCode, startFlags, 3592 null, null, null, null, options, userId, container); 3593 return ret; 3594 } 3595 3596 @Override 3597 public final int startActivities(IApplicationThread caller, String callingPackage, 3598 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3599 int userId) { 3600 enforceNotIsolatedCaller("startActivities"); 3601 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3602 false, ALLOW_FULL_ONLY, "startActivity", null); 3603 // TODO: Switch to user app stacks here. 3604 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3605 resolvedTypes, resultTo, options, userId); 3606 return ret; 3607 } 3608 3609 final int startActivitiesInPackage(int uid, String callingPackage, 3610 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3611 Bundle options, int userId) { 3612 3613 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3614 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3615 // TODO: Switch to user app stacks here. 3616 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3617 resultTo, options, userId); 3618 return ret; 3619 } 3620 3621 final void addRecentTaskLocked(TaskRecord task) { 3622 int N = mRecentTasks.size(); 3623 // Quick case: check if the top-most recent task is the same. 3624 if (N > 0 && mRecentTasks.get(0) == task) { 3625 return; 3626 } 3627 // Another quick case: never add voice sessions. 3628 if (task.voiceSession != null) { 3629 return; 3630 } 3631 // Remove any existing entries that are the same kind of task. 3632 final Intent intent = task.intent; 3633 final boolean document = intent != null && intent.isDocument(); 3634 final ComponentName comp = intent.getComponent(); 3635 3636 int maxRecents = task.maxRecents - 1; 3637 for (int i=0; i<N; i++) { 3638 final TaskRecord tr = mRecentTasks.get(i); 3639 if (task != tr) { 3640 if (task.userId != tr.userId) { 3641 continue; 3642 } 3643 if (i > MAX_RECENT_BITMAPS) { 3644 tr.freeLastThumbnail(); 3645 } 3646 final Intent trIntent = tr.intent; 3647 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3648 (intent == null || !intent.filterEquals(trIntent))) { 3649 continue; 3650 } 3651 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3652 if (document && trIsDocument) { 3653 // These are the same document activity (not necessarily the same doc). 3654 if (maxRecents > 0) { 3655 --maxRecents; 3656 continue; 3657 } 3658 // Hit the maximum number of documents for this task. Fall through 3659 // and remove this document from recents. 3660 } else if (document || trIsDocument) { 3661 // Only one of these is a document. Not the droid we're looking for. 3662 continue; 3663 } 3664 } 3665 3666 // Either task and tr are the same or, their affinities match or their intents match 3667 // and neither of them is a document, or they are documents using the same activity 3668 // and their maxRecents has been reached. 3669 tr.disposeThumbnail(); 3670 mRecentTasks.remove(i); 3671 if (task != tr) { 3672 tr.closeRecentsChain(); 3673 } 3674 i--; 3675 N--; 3676 if (task.intent == null) { 3677 // If the new recent task we are adding is not fully 3678 // specified, then replace it with the existing recent task. 3679 task = tr; 3680 } 3681 mTaskPersister.notify(tr, false); 3682 } 3683 if (N >= MAX_RECENT_TASKS) { 3684 final TaskRecord tr = mRecentTasks.remove(N - 1); 3685 tr.disposeThumbnail(); 3686 tr.closeRecentsChain(); 3687 } 3688 mRecentTasks.add(0, task); 3689 } 3690 3691 @Override 3692 public void reportActivityFullyDrawn(IBinder token) { 3693 synchronized (this) { 3694 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3695 if (r == null) { 3696 return; 3697 } 3698 r.reportFullyDrawnLocked(); 3699 } 3700 } 3701 3702 @Override 3703 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3704 synchronized (this) { 3705 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3706 if (r == null) { 3707 return; 3708 } 3709 final long origId = Binder.clearCallingIdentity(); 3710 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3711 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3712 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3713 if (config != null) { 3714 r.frozenBeforeDestroy = true; 3715 if (!updateConfigurationLocked(config, r, false, false)) { 3716 mStackSupervisor.resumeTopActivitiesLocked(); 3717 } 3718 } 3719 Binder.restoreCallingIdentity(origId); 3720 } 3721 } 3722 3723 @Override 3724 public int getRequestedOrientation(IBinder token) { 3725 synchronized (this) { 3726 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3727 if (r == null) { 3728 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3729 } 3730 return mWindowManager.getAppOrientation(r.appToken); 3731 } 3732 } 3733 3734 /** 3735 * This is the internal entry point for handling Activity.finish(). 3736 * 3737 * @param token The Binder token referencing the Activity we want to finish. 3738 * @param resultCode Result code, if any, from this Activity. 3739 * @param resultData Result data (Intent), if any, from this Activity. 3740 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3741 * the root Activity in the task. 3742 * 3743 * @return Returns true if the activity successfully finished, or false if it is still running. 3744 */ 3745 @Override 3746 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3747 boolean finishTask) { 3748 // Refuse possible leaked file descriptors 3749 if (resultData != null && resultData.hasFileDescriptors() == true) { 3750 throw new IllegalArgumentException("File descriptors passed in Intent"); 3751 } 3752 3753 synchronized(this) { 3754 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3755 if (r == null) { 3756 return true; 3757 } 3758 // Keep track of the root activity of the task before we finish it 3759 TaskRecord tr = r.task; 3760 ActivityRecord rootR = tr.getRootActivity(); 3761 // Do not allow task to finish in Lock Task mode. 3762 if (tr == mStackSupervisor.mLockTaskModeTask) { 3763 if (rootR == r) { 3764 mStackSupervisor.showLockTaskToast(); 3765 return false; 3766 } 3767 } 3768 if (mController != null) { 3769 // Find the first activity that is not finishing. 3770 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3771 if (next != null) { 3772 // ask watcher if this is allowed 3773 boolean resumeOK = true; 3774 try { 3775 resumeOK = mController.activityResuming(next.packageName); 3776 } catch (RemoteException e) { 3777 mController = null; 3778 Watchdog.getInstance().setActivityController(null); 3779 } 3780 3781 if (!resumeOK) { 3782 return false; 3783 } 3784 } 3785 } 3786 final long origId = Binder.clearCallingIdentity(); 3787 try { 3788 boolean res; 3789 if (finishTask && r == rootR) { 3790 // If requested, remove the task that is associated to this activity only if it 3791 // was the root activity in the task. The result code and data is ignored because 3792 // we don't support returning them across task boundaries. 3793 res = removeTaskByIdLocked(tr.taskId, 0); 3794 } else { 3795 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3796 resultData, "app-request", true); 3797 } 3798 return res; 3799 } finally { 3800 Binder.restoreCallingIdentity(origId); 3801 } 3802 } 3803 } 3804 3805 @Override 3806 public final void finishHeavyWeightApp() { 3807 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3808 != PackageManager.PERMISSION_GRANTED) { 3809 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3810 + Binder.getCallingPid() 3811 + ", uid=" + Binder.getCallingUid() 3812 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3813 Slog.w(TAG, msg); 3814 throw new SecurityException(msg); 3815 } 3816 3817 synchronized(this) { 3818 if (mHeavyWeightProcess == null) { 3819 return; 3820 } 3821 3822 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3823 mHeavyWeightProcess.activities); 3824 for (int i=0; i<activities.size(); i++) { 3825 ActivityRecord r = activities.get(i); 3826 if (!r.finishing) { 3827 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3828 null, "finish-heavy", true); 3829 } 3830 } 3831 3832 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3833 mHeavyWeightProcess.userId, 0)); 3834 mHeavyWeightProcess = null; 3835 } 3836 } 3837 3838 @Override 3839 public void crashApplication(int uid, int initialPid, String packageName, 3840 String message) { 3841 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3842 != PackageManager.PERMISSION_GRANTED) { 3843 String msg = "Permission Denial: crashApplication() from pid=" 3844 + Binder.getCallingPid() 3845 + ", uid=" + Binder.getCallingUid() 3846 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3847 Slog.w(TAG, msg); 3848 throw new SecurityException(msg); 3849 } 3850 3851 synchronized(this) { 3852 ProcessRecord proc = null; 3853 3854 // Figure out which process to kill. We don't trust that initialPid 3855 // still has any relation to current pids, so must scan through the 3856 // list. 3857 synchronized (mPidsSelfLocked) { 3858 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3859 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3860 if (p.uid != uid) { 3861 continue; 3862 } 3863 if (p.pid == initialPid) { 3864 proc = p; 3865 break; 3866 } 3867 if (p.pkgList.containsKey(packageName)) { 3868 proc = p; 3869 } 3870 } 3871 } 3872 3873 if (proc == null) { 3874 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3875 + " initialPid=" + initialPid 3876 + " packageName=" + packageName); 3877 return; 3878 } 3879 3880 if (proc.thread != null) { 3881 if (proc.pid == Process.myPid()) { 3882 Log.w(TAG, "crashApplication: trying to crash self!"); 3883 return; 3884 } 3885 long ident = Binder.clearCallingIdentity(); 3886 try { 3887 proc.thread.scheduleCrash(message); 3888 } catch (RemoteException e) { 3889 } 3890 Binder.restoreCallingIdentity(ident); 3891 } 3892 } 3893 } 3894 3895 @Override 3896 public final void finishSubActivity(IBinder token, String resultWho, 3897 int requestCode) { 3898 synchronized(this) { 3899 final long origId = Binder.clearCallingIdentity(); 3900 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3901 if (r != null) { 3902 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3903 } 3904 Binder.restoreCallingIdentity(origId); 3905 } 3906 } 3907 3908 @Override 3909 public boolean finishActivityAffinity(IBinder token) { 3910 synchronized(this) { 3911 final long origId = Binder.clearCallingIdentity(); 3912 try { 3913 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3914 3915 ActivityRecord rootR = r.task.getRootActivity(); 3916 // Do not allow task to finish in Lock Task mode. 3917 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3918 if (rootR == r) { 3919 mStackSupervisor.showLockTaskToast(); 3920 return false; 3921 } 3922 } 3923 boolean res = false; 3924 if (r != null) { 3925 res = r.task.stack.finishActivityAffinityLocked(r); 3926 } 3927 return res; 3928 } finally { 3929 Binder.restoreCallingIdentity(origId); 3930 } 3931 } 3932 } 3933 3934 @Override 3935 public void finishVoiceTask(IVoiceInteractionSession session) { 3936 synchronized(this) { 3937 final long origId = Binder.clearCallingIdentity(); 3938 try { 3939 mStackSupervisor.finishVoiceTask(session); 3940 } finally { 3941 Binder.restoreCallingIdentity(origId); 3942 } 3943 } 3944 3945 } 3946 3947 @Override 3948 public boolean willActivityBeVisible(IBinder token) { 3949 synchronized(this) { 3950 ActivityStack stack = ActivityRecord.getStackLocked(token); 3951 if (stack != null) { 3952 return stack.willActivityBeVisibleLocked(token); 3953 } 3954 return false; 3955 } 3956 } 3957 3958 @Override 3959 public void overridePendingTransition(IBinder token, String packageName, 3960 int enterAnim, int exitAnim) { 3961 synchronized(this) { 3962 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3963 if (self == null) { 3964 return; 3965 } 3966 3967 final long origId = Binder.clearCallingIdentity(); 3968 3969 if (self.state == ActivityState.RESUMED 3970 || self.state == ActivityState.PAUSING) { 3971 mWindowManager.overridePendingAppTransition(packageName, 3972 enterAnim, exitAnim, null); 3973 } 3974 3975 Binder.restoreCallingIdentity(origId); 3976 } 3977 } 3978 3979 /** 3980 * Main function for removing an existing process from the activity manager 3981 * as a result of that process going away. Clears out all connections 3982 * to the process. 3983 */ 3984 private final void handleAppDiedLocked(ProcessRecord app, 3985 boolean restarting, boolean allowRestart) { 3986 int pid = app.pid; 3987 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3988 if (!restarting) { 3989 removeLruProcessLocked(app); 3990 if (pid > 0) { 3991 ProcessList.remove(pid); 3992 } 3993 } 3994 3995 if (mProfileProc == app) { 3996 clearProfilerLocked(); 3997 } 3998 3999 // Remove this application's activities from active lists. 4000 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4001 4002 app.activities.clear(); 4003 4004 if (app.instrumentationClass != null) { 4005 Slog.w(TAG, "Crash of app " + app.processName 4006 + " running instrumentation " + app.instrumentationClass); 4007 Bundle info = new Bundle(); 4008 info.putString("shortMsg", "Process crashed."); 4009 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4010 } 4011 4012 if (!restarting) { 4013 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4014 // If there was nothing to resume, and we are not already 4015 // restarting this process, but there is a visible activity that 4016 // is hosted by the process... then make sure all visible 4017 // activities are running, taking care of restarting this 4018 // process. 4019 if (hasVisibleActivities) { 4020 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4021 } 4022 } 4023 } 4024 } 4025 4026 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4027 IBinder threadBinder = thread.asBinder(); 4028 // Find the application record. 4029 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4030 ProcessRecord rec = mLruProcesses.get(i); 4031 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4032 return i; 4033 } 4034 } 4035 return -1; 4036 } 4037 4038 final ProcessRecord getRecordForAppLocked( 4039 IApplicationThread thread) { 4040 if (thread == null) { 4041 return null; 4042 } 4043 4044 int appIndex = getLRURecordIndexForAppLocked(thread); 4045 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4046 } 4047 4048 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4049 // If there are no longer any background processes running, 4050 // and the app that died was not running instrumentation, 4051 // then tell everyone we are now low on memory. 4052 boolean haveBg = false; 4053 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4054 ProcessRecord rec = mLruProcesses.get(i); 4055 if (rec.thread != null 4056 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4057 haveBg = true; 4058 break; 4059 } 4060 } 4061 4062 if (!haveBg) { 4063 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4064 if (doReport) { 4065 long now = SystemClock.uptimeMillis(); 4066 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4067 doReport = false; 4068 } else { 4069 mLastMemUsageReportTime = now; 4070 } 4071 } 4072 final ArrayList<ProcessMemInfo> memInfos 4073 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4074 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4075 long now = SystemClock.uptimeMillis(); 4076 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4077 ProcessRecord rec = mLruProcesses.get(i); 4078 if (rec == dyingProc || rec.thread == null) { 4079 continue; 4080 } 4081 if (doReport) { 4082 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4083 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4084 } 4085 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4086 // The low memory report is overriding any current 4087 // state for a GC request. Make sure to do 4088 // heavy/important/visible/foreground processes first. 4089 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4090 rec.lastRequestedGc = 0; 4091 } else { 4092 rec.lastRequestedGc = rec.lastLowMemory; 4093 } 4094 rec.reportLowMemory = true; 4095 rec.lastLowMemory = now; 4096 mProcessesToGc.remove(rec); 4097 addProcessToGcListLocked(rec); 4098 } 4099 } 4100 if (doReport) { 4101 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4102 mHandler.sendMessage(msg); 4103 } 4104 scheduleAppGcsLocked(); 4105 } 4106 } 4107 4108 final void appDiedLocked(ProcessRecord app, int pid, 4109 IApplicationThread thread) { 4110 4111 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4112 synchronized (stats) { 4113 stats.noteProcessDiedLocked(app.info.uid, pid); 4114 } 4115 4116 Process.killProcessGroup(app.info.uid, pid); 4117 4118 // Clean up already done if the process has been re-started. 4119 if (app.pid == pid && app.thread != null && 4120 app.thread.asBinder() == thread.asBinder()) { 4121 boolean doLowMem = app.instrumentationClass == null; 4122 boolean doOomAdj = doLowMem; 4123 if (!app.killedByAm) { 4124 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4125 + ") has died."); 4126 mAllowLowerMemLevel = true; 4127 } else { 4128 // Note that we always want to do oom adj to update our state with the 4129 // new number of procs. 4130 mAllowLowerMemLevel = false; 4131 doLowMem = false; 4132 } 4133 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4134 if (DEBUG_CLEANUP) Slog.v( 4135 TAG, "Dying app: " + app + ", pid: " + pid 4136 + ", thread: " + thread.asBinder()); 4137 handleAppDiedLocked(app, false, true); 4138 4139 if (doOomAdj) { 4140 updateOomAdjLocked(); 4141 } 4142 if (doLowMem) { 4143 doLowMemReportIfNeededLocked(app); 4144 } 4145 } else if (app.pid != pid) { 4146 // A new process has already been started. 4147 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4148 + ") has died and restarted (pid " + app.pid + ")."); 4149 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4150 } else if (DEBUG_PROCESSES) { 4151 Slog.d(TAG, "Received spurious death notification for thread " 4152 + thread.asBinder()); 4153 } 4154 } 4155 4156 /** 4157 * If a stack trace dump file is configured, dump process stack traces. 4158 * @param clearTraces causes the dump file to be erased prior to the new 4159 * traces being written, if true; when false, the new traces will be 4160 * appended to any existing file content. 4161 * @param firstPids of dalvik VM processes to dump stack traces for first 4162 * @param lastPids of dalvik VM processes to dump stack traces for last 4163 * @param nativeProcs optional list of native process names to dump stack crawls 4164 * @return file containing stack traces, or null if no dump file is configured 4165 */ 4166 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4167 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4168 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4169 if (tracesPath == null || tracesPath.length() == 0) { 4170 return null; 4171 } 4172 4173 File tracesFile = new File(tracesPath); 4174 try { 4175 File tracesDir = tracesFile.getParentFile(); 4176 if (!tracesDir.exists()) { 4177 tracesFile.mkdirs(); 4178 if (!SELinux.restorecon(tracesDir)) { 4179 return null; 4180 } 4181 } 4182 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4183 4184 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4185 tracesFile.createNewFile(); 4186 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4187 } catch (IOException e) { 4188 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4189 return null; 4190 } 4191 4192 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4193 return tracesFile; 4194 } 4195 4196 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4197 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4198 // Use a FileObserver to detect when traces finish writing. 4199 // The order of traces is considered important to maintain for legibility. 4200 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4201 @Override 4202 public synchronized void onEvent(int event, String path) { notify(); } 4203 }; 4204 4205 try { 4206 observer.startWatching(); 4207 4208 // First collect all of the stacks of the most important pids. 4209 if (firstPids != null) { 4210 try { 4211 int num = firstPids.size(); 4212 for (int i = 0; i < num; i++) { 4213 synchronized (observer) { 4214 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4215 observer.wait(200); // Wait for write-close, give up after 200msec 4216 } 4217 } 4218 } catch (InterruptedException e) { 4219 Log.wtf(TAG, e); 4220 } 4221 } 4222 4223 // Next collect the stacks of the native pids 4224 if (nativeProcs != null) { 4225 int[] pids = Process.getPidsForCommands(nativeProcs); 4226 if (pids != null) { 4227 for (int pid : pids) { 4228 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4229 } 4230 } 4231 } 4232 4233 // Lastly, measure CPU usage. 4234 if (processCpuTracker != null) { 4235 processCpuTracker.init(); 4236 System.gc(); 4237 processCpuTracker.update(); 4238 try { 4239 synchronized (processCpuTracker) { 4240 processCpuTracker.wait(500); // measure over 1/2 second. 4241 } 4242 } catch (InterruptedException e) { 4243 } 4244 processCpuTracker.update(); 4245 4246 // We'll take the stack crawls of just the top apps using CPU. 4247 final int N = processCpuTracker.countWorkingStats(); 4248 int numProcs = 0; 4249 for (int i=0; i<N && numProcs<5; i++) { 4250 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4251 if (lastPids.indexOfKey(stats.pid) >= 0) { 4252 numProcs++; 4253 try { 4254 synchronized (observer) { 4255 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4256 observer.wait(200); // Wait for write-close, give up after 200msec 4257 } 4258 } catch (InterruptedException e) { 4259 Log.wtf(TAG, e); 4260 } 4261 4262 } 4263 } 4264 } 4265 } finally { 4266 observer.stopWatching(); 4267 } 4268 } 4269 4270 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4271 if (true || IS_USER_BUILD) { 4272 return; 4273 } 4274 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4275 if (tracesPath == null || tracesPath.length() == 0) { 4276 return; 4277 } 4278 4279 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4280 StrictMode.allowThreadDiskWrites(); 4281 try { 4282 final File tracesFile = new File(tracesPath); 4283 final File tracesDir = tracesFile.getParentFile(); 4284 final File tracesTmp = new File(tracesDir, "__tmp__"); 4285 try { 4286 if (!tracesDir.exists()) { 4287 tracesFile.mkdirs(); 4288 if (!SELinux.restorecon(tracesDir.getPath())) { 4289 return; 4290 } 4291 } 4292 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4293 4294 if (tracesFile.exists()) { 4295 tracesTmp.delete(); 4296 tracesFile.renameTo(tracesTmp); 4297 } 4298 StringBuilder sb = new StringBuilder(); 4299 Time tobj = new Time(); 4300 tobj.set(System.currentTimeMillis()); 4301 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4302 sb.append(": "); 4303 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4304 sb.append(" since "); 4305 sb.append(msg); 4306 FileOutputStream fos = new FileOutputStream(tracesFile); 4307 fos.write(sb.toString().getBytes()); 4308 if (app == null) { 4309 fos.write("\n*** No application process!".getBytes()); 4310 } 4311 fos.close(); 4312 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4313 } catch (IOException e) { 4314 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4315 return; 4316 } 4317 4318 if (app != null) { 4319 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4320 firstPids.add(app.pid); 4321 dumpStackTraces(tracesPath, firstPids, null, null, null); 4322 } 4323 4324 File lastTracesFile = null; 4325 File curTracesFile = null; 4326 for (int i=9; i>=0; i--) { 4327 String name = String.format(Locale.US, "slow%02d.txt", i); 4328 curTracesFile = new File(tracesDir, name); 4329 if (curTracesFile.exists()) { 4330 if (lastTracesFile != null) { 4331 curTracesFile.renameTo(lastTracesFile); 4332 } else { 4333 curTracesFile.delete(); 4334 } 4335 } 4336 lastTracesFile = curTracesFile; 4337 } 4338 tracesFile.renameTo(curTracesFile); 4339 if (tracesTmp.exists()) { 4340 tracesTmp.renameTo(tracesFile); 4341 } 4342 } finally { 4343 StrictMode.setThreadPolicy(oldPolicy); 4344 } 4345 } 4346 4347 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4348 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4349 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4350 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4351 4352 if (mController != null) { 4353 try { 4354 // 0 == continue, -1 = kill process immediately 4355 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4356 if (res < 0 && app.pid != MY_PID) { 4357 Process.killProcess(app.pid); 4358 Process.killProcessGroup(app.info.uid, app.pid); 4359 } 4360 } catch (RemoteException e) { 4361 mController = null; 4362 Watchdog.getInstance().setActivityController(null); 4363 } 4364 } 4365 4366 long anrTime = SystemClock.uptimeMillis(); 4367 if (MONITOR_CPU_USAGE) { 4368 updateCpuStatsNow(); 4369 } 4370 4371 synchronized (this) { 4372 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4373 if (mShuttingDown) { 4374 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4375 return; 4376 } else if (app.notResponding) { 4377 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4378 return; 4379 } else if (app.crashing) { 4380 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4381 return; 4382 } 4383 4384 // In case we come through here for the same app before completing 4385 // this one, mark as anring now so we will bail out. 4386 app.notResponding = true; 4387 4388 // Log the ANR to the event log. 4389 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4390 app.processName, app.info.flags, annotation); 4391 4392 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4393 firstPids.add(app.pid); 4394 4395 int parentPid = app.pid; 4396 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4397 if (parentPid != app.pid) firstPids.add(parentPid); 4398 4399 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4400 4401 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4402 ProcessRecord r = mLruProcesses.get(i); 4403 if (r != null && r.thread != null) { 4404 int pid = r.pid; 4405 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4406 if (r.persistent) { 4407 firstPids.add(pid); 4408 } else { 4409 lastPids.put(pid, Boolean.TRUE); 4410 } 4411 } 4412 } 4413 } 4414 } 4415 4416 // Log the ANR to the main log. 4417 StringBuilder info = new StringBuilder(); 4418 info.setLength(0); 4419 info.append("ANR in ").append(app.processName); 4420 if (activity != null && activity.shortComponentName != null) { 4421 info.append(" (").append(activity.shortComponentName).append(")"); 4422 } 4423 info.append("\n"); 4424 info.append("PID: ").append(app.pid).append("\n"); 4425 if (annotation != null) { 4426 info.append("Reason: ").append(annotation).append("\n"); 4427 } 4428 if (parent != null && parent != activity) { 4429 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4430 } 4431 4432 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4433 4434 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4435 NATIVE_STACKS_OF_INTEREST); 4436 4437 String cpuInfo = null; 4438 if (MONITOR_CPU_USAGE) { 4439 updateCpuStatsNow(); 4440 synchronized (mProcessCpuThread) { 4441 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4442 } 4443 info.append(processCpuTracker.printCurrentLoad()); 4444 info.append(cpuInfo); 4445 } 4446 4447 info.append(processCpuTracker.printCurrentState(anrTime)); 4448 4449 Slog.e(TAG, info.toString()); 4450 if (tracesFile == null) { 4451 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4452 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4453 } 4454 4455 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4456 cpuInfo, tracesFile, null); 4457 4458 if (mController != null) { 4459 try { 4460 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4461 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4462 if (res != 0) { 4463 if (res < 0 && app.pid != MY_PID) { 4464 Process.killProcess(app.pid); 4465 Process.killProcessGroup(app.info.uid, app.pid); 4466 } else { 4467 synchronized (this) { 4468 mServices.scheduleServiceTimeoutLocked(app); 4469 } 4470 } 4471 return; 4472 } 4473 } catch (RemoteException e) { 4474 mController = null; 4475 Watchdog.getInstance().setActivityController(null); 4476 } 4477 } 4478 4479 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4480 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4481 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4482 4483 synchronized (this) { 4484 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4485 killUnneededProcessLocked(app, "background ANR"); 4486 return; 4487 } 4488 4489 // Set the app's notResponding state, and look up the errorReportReceiver 4490 makeAppNotRespondingLocked(app, 4491 activity != null ? activity.shortComponentName : null, 4492 annotation != null ? "ANR " + annotation : "ANR", 4493 info.toString()); 4494 4495 // Bring up the infamous App Not Responding dialog 4496 Message msg = Message.obtain(); 4497 HashMap<String, Object> map = new HashMap<String, Object>(); 4498 msg.what = SHOW_NOT_RESPONDING_MSG; 4499 msg.obj = map; 4500 msg.arg1 = aboveSystem ? 1 : 0; 4501 map.put("app", app); 4502 if (activity != null) { 4503 map.put("activity", activity); 4504 } 4505 4506 mHandler.sendMessage(msg); 4507 } 4508 } 4509 4510 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4511 if (!mLaunchWarningShown) { 4512 mLaunchWarningShown = true; 4513 mHandler.post(new Runnable() { 4514 @Override 4515 public void run() { 4516 synchronized (ActivityManagerService.this) { 4517 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4518 d.show(); 4519 mHandler.postDelayed(new Runnable() { 4520 @Override 4521 public void run() { 4522 synchronized (ActivityManagerService.this) { 4523 d.dismiss(); 4524 mLaunchWarningShown = false; 4525 } 4526 } 4527 }, 4000); 4528 } 4529 } 4530 }); 4531 } 4532 } 4533 4534 @Override 4535 public boolean clearApplicationUserData(final String packageName, 4536 final IPackageDataObserver observer, int userId) { 4537 enforceNotIsolatedCaller("clearApplicationUserData"); 4538 int uid = Binder.getCallingUid(); 4539 int pid = Binder.getCallingPid(); 4540 userId = handleIncomingUser(pid, uid, 4541 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4542 long callingId = Binder.clearCallingIdentity(); 4543 try { 4544 IPackageManager pm = AppGlobals.getPackageManager(); 4545 int pkgUid = -1; 4546 synchronized(this) { 4547 try { 4548 pkgUid = pm.getPackageUid(packageName, userId); 4549 } catch (RemoteException e) { 4550 } 4551 if (pkgUid == -1) { 4552 Slog.w(TAG, "Invalid packageName: " + packageName); 4553 if (observer != null) { 4554 try { 4555 observer.onRemoveCompleted(packageName, false); 4556 } catch (RemoteException e) { 4557 Slog.i(TAG, "Observer no longer exists."); 4558 } 4559 } 4560 return false; 4561 } 4562 if (uid == pkgUid || checkComponentPermission( 4563 android.Manifest.permission.CLEAR_APP_USER_DATA, 4564 pid, uid, -1, true) 4565 == PackageManager.PERMISSION_GRANTED) { 4566 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4567 } else { 4568 throw new SecurityException("PID " + pid + " does not have permission " 4569 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4570 + " of package " + packageName); 4571 } 4572 } 4573 4574 try { 4575 // Clear application user data 4576 pm.clearApplicationUserData(packageName, observer, userId); 4577 4578 // Remove all permissions granted from/to this package 4579 removeUriPermissionsForPackageLocked(packageName, userId, true); 4580 4581 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4582 Uri.fromParts("package", packageName, null)); 4583 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4584 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4585 null, null, 0, null, null, null, false, false, userId); 4586 } catch (RemoteException e) { 4587 } 4588 } finally { 4589 Binder.restoreCallingIdentity(callingId); 4590 } 4591 return true; 4592 } 4593 4594 @Override 4595 public void killBackgroundProcesses(final String packageName, int userId) { 4596 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4597 != PackageManager.PERMISSION_GRANTED && 4598 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4599 != PackageManager.PERMISSION_GRANTED) { 4600 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4601 + Binder.getCallingPid() 4602 + ", uid=" + Binder.getCallingUid() 4603 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4604 Slog.w(TAG, msg); 4605 throw new SecurityException(msg); 4606 } 4607 4608 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4609 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4610 long callingId = Binder.clearCallingIdentity(); 4611 try { 4612 IPackageManager pm = AppGlobals.getPackageManager(); 4613 synchronized(this) { 4614 int appId = -1; 4615 try { 4616 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4617 } catch (RemoteException e) { 4618 } 4619 if (appId == -1) { 4620 Slog.w(TAG, "Invalid packageName: " + packageName); 4621 return; 4622 } 4623 killPackageProcessesLocked(packageName, appId, userId, 4624 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4625 } 4626 } finally { 4627 Binder.restoreCallingIdentity(callingId); 4628 } 4629 } 4630 4631 @Override 4632 public void killAllBackgroundProcesses() { 4633 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4634 != PackageManager.PERMISSION_GRANTED) { 4635 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4636 + Binder.getCallingPid() 4637 + ", uid=" + Binder.getCallingUid() 4638 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4639 Slog.w(TAG, msg); 4640 throw new SecurityException(msg); 4641 } 4642 4643 long callingId = Binder.clearCallingIdentity(); 4644 try { 4645 synchronized(this) { 4646 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4647 final int NP = mProcessNames.getMap().size(); 4648 for (int ip=0; ip<NP; ip++) { 4649 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4650 final int NA = apps.size(); 4651 for (int ia=0; ia<NA; ia++) { 4652 ProcessRecord app = apps.valueAt(ia); 4653 if (app.persistent) { 4654 // we don't kill persistent processes 4655 continue; 4656 } 4657 if (app.removed) { 4658 procs.add(app); 4659 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4660 app.removed = true; 4661 procs.add(app); 4662 } 4663 } 4664 } 4665 4666 int N = procs.size(); 4667 for (int i=0; i<N; i++) { 4668 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4669 } 4670 mAllowLowerMemLevel = true; 4671 updateOomAdjLocked(); 4672 doLowMemReportIfNeededLocked(null); 4673 } 4674 } finally { 4675 Binder.restoreCallingIdentity(callingId); 4676 } 4677 } 4678 4679 @Override 4680 public void forceStopPackage(final String packageName, int userId) { 4681 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4682 != PackageManager.PERMISSION_GRANTED) { 4683 String msg = "Permission Denial: forceStopPackage() from pid=" 4684 + Binder.getCallingPid() 4685 + ", uid=" + Binder.getCallingUid() 4686 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4687 Slog.w(TAG, msg); 4688 throw new SecurityException(msg); 4689 } 4690 final int callingPid = Binder.getCallingPid(); 4691 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4692 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4693 long callingId = Binder.clearCallingIdentity(); 4694 try { 4695 IPackageManager pm = AppGlobals.getPackageManager(); 4696 synchronized(this) { 4697 int[] users = userId == UserHandle.USER_ALL 4698 ? getUsersLocked() : new int[] { userId }; 4699 for (int user : users) { 4700 int pkgUid = -1; 4701 try { 4702 pkgUid = pm.getPackageUid(packageName, user); 4703 } catch (RemoteException e) { 4704 } 4705 if (pkgUid == -1) { 4706 Slog.w(TAG, "Invalid packageName: " + packageName); 4707 continue; 4708 } 4709 try { 4710 pm.setPackageStoppedState(packageName, true, user); 4711 } catch (RemoteException e) { 4712 } catch (IllegalArgumentException e) { 4713 Slog.w(TAG, "Failed trying to unstop package " 4714 + packageName + ": " + e); 4715 } 4716 if (isUserRunningLocked(user, false)) { 4717 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4718 } 4719 } 4720 } 4721 } finally { 4722 Binder.restoreCallingIdentity(callingId); 4723 } 4724 } 4725 4726 @Override 4727 public void addPackageDependency(String packageName) { 4728 synchronized (this) { 4729 int callingPid = Binder.getCallingPid(); 4730 if (callingPid == Process.myPid()) { 4731 // Yeah, um, no. 4732 Slog.w(TAG, "Can't addPackageDependency on system process"); 4733 return; 4734 } 4735 ProcessRecord proc; 4736 synchronized (mPidsSelfLocked) { 4737 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4738 } 4739 if (proc != null) { 4740 if (proc.pkgDeps == null) { 4741 proc.pkgDeps = new ArraySet<String>(1); 4742 } 4743 proc.pkgDeps.add(packageName); 4744 } 4745 } 4746 } 4747 4748 /* 4749 * The pkg name and app id have to be specified. 4750 */ 4751 @Override 4752 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4753 if (pkg == null) { 4754 return; 4755 } 4756 // Make sure the uid is valid. 4757 if (appid < 0) { 4758 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4759 return; 4760 } 4761 int callerUid = Binder.getCallingUid(); 4762 // Only the system server can kill an application 4763 if (callerUid == Process.SYSTEM_UID) { 4764 // Post an aysnc message to kill the application 4765 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4766 msg.arg1 = appid; 4767 msg.arg2 = 0; 4768 Bundle bundle = new Bundle(); 4769 bundle.putString("pkg", pkg); 4770 bundle.putString("reason", reason); 4771 msg.obj = bundle; 4772 mHandler.sendMessage(msg); 4773 } else { 4774 throw new SecurityException(callerUid + " cannot kill pkg: " + 4775 pkg); 4776 } 4777 } 4778 4779 @Override 4780 public void closeSystemDialogs(String reason) { 4781 enforceNotIsolatedCaller("closeSystemDialogs"); 4782 4783 final int pid = Binder.getCallingPid(); 4784 final int uid = Binder.getCallingUid(); 4785 final long origId = Binder.clearCallingIdentity(); 4786 try { 4787 synchronized (this) { 4788 // Only allow this from foreground processes, so that background 4789 // applications can't abuse it to prevent system UI from being shown. 4790 if (uid >= Process.FIRST_APPLICATION_UID) { 4791 ProcessRecord proc; 4792 synchronized (mPidsSelfLocked) { 4793 proc = mPidsSelfLocked.get(pid); 4794 } 4795 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4796 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4797 + " from background process " + proc); 4798 return; 4799 } 4800 } 4801 closeSystemDialogsLocked(reason); 4802 } 4803 } finally { 4804 Binder.restoreCallingIdentity(origId); 4805 } 4806 } 4807 4808 void closeSystemDialogsLocked(String reason) { 4809 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4810 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4811 | Intent.FLAG_RECEIVER_FOREGROUND); 4812 if (reason != null) { 4813 intent.putExtra("reason", reason); 4814 } 4815 mWindowManager.closeSystemDialogs(reason); 4816 4817 mStackSupervisor.closeSystemDialogsLocked(); 4818 4819 broadcastIntentLocked(null, null, intent, null, 4820 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4821 Process.SYSTEM_UID, UserHandle.USER_ALL); 4822 } 4823 4824 @Override 4825 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4826 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4827 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4828 for (int i=pids.length-1; i>=0; i--) { 4829 ProcessRecord proc; 4830 int oomAdj; 4831 synchronized (this) { 4832 synchronized (mPidsSelfLocked) { 4833 proc = mPidsSelfLocked.get(pids[i]); 4834 oomAdj = proc != null ? proc.setAdj : 0; 4835 } 4836 } 4837 infos[i] = new Debug.MemoryInfo(); 4838 Debug.getMemoryInfo(pids[i], infos[i]); 4839 if (proc != null) { 4840 synchronized (this) { 4841 if (proc.thread != null && proc.setAdj == oomAdj) { 4842 // Record this for posterity if the process has been stable. 4843 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4844 infos[i].getTotalUss(), false, proc.pkgList); 4845 } 4846 } 4847 } 4848 } 4849 return infos; 4850 } 4851 4852 @Override 4853 public long[] getProcessPss(int[] pids) { 4854 enforceNotIsolatedCaller("getProcessPss"); 4855 long[] pss = new long[pids.length]; 4856 for (int i=pids.length-1; i>=0; i--) { 4857 ProcessRecord proc; 4858 int oomAdj; 4859 synchronized (this) { 4860 synchronized (mPidsSelfLocked) { 4861 proc = mPidsSelfLocked.get(pids[i]); 4862 oomAdj = proc != null ? proc.setAdj : 0; 4863 } 4864 } 4865 long[] tmpUss = new long[1]; 4866 pss[i] = Debug.getPss(pids[i], tmpUss); 4867 if (proc != null) { 4868 synchronized (this) { 4869 if (proc.thread != null && proc.setAdj == oomAdj) { 4870 // Record this for posterity if the process has been stable. 4871 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4872 } 4873 } 4874 } 4875 } 4876 return pss; 4877 } 4878 4879 @Override 4880 public void killApplicationProcess(String processName, int uid) { 4881 if (processName == null) { 4882 return; 4883 } 4884 4885 int callerUid = Binder.getCallingUid(); 4886 // Only the system server can kill an application 4887 if (callerUid == Process.SYSTEM_UID) { 4888 synchronized (this) { 4889 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4890 if (app != null && app.thread != null) { 4891 try { 4892 app.thread.scheduleSuicide(); 4893 } catch (RemoteException e) { 4894 // If the other end already died, then our work here is done. 4895 } 4896 } else { 4897 Slog.w(TAG, "Process/uid not found attempting kill of " 4898 + processName + " / " + uid); 4899 } 4900 } 4901 } else { 4902 throw new SecurityException(callerUid + " cannot kill app process: " + 4903 processName); 4904 } 4905 } 4906 4907 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4908 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4909 false, true, false, false, UserHandle.getUserId(uid), reason); 4910 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4911 Uri.fromParts("package", packageName, null)); 4912 if (!mProcessesReady) { 4913 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4914 | Intent.FLAG_RECEIVER_FOREGROUND); 4915 } 4916 intent.putExtra(Intent.EXTRA_UID, uid); 4917 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4918 broadcastIntentLocked(null, null, intent, 4919 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4920 false, false, 4921 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4922 } 4923 4924 private void forceStopUserLocked(int userId, String reason) { 4925 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4926 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4927 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4928 | Intent.FLAG_RECEIVER_FOREGROUND); 4929 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4930 broadcastIntentLocked(null, null, intent, 4931 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4932 false, false, 4933 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4934 } 4935 4936 private final boolean killPackageProcessesLocked(String packageName, int appId, 4937 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4938 boolean doit, boolean evenPersistent, String reason) { 4939 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4940 4941 // Remove all processes this package may have touched: all with the 4942 // same UID (except for the system or root user), and all whose name 4943 // matches the package name. 4944 final int NP = mProcessNames.getMap().size(); 4945 for (int ip=0; ip<NP; ip++) { 4946 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4947 final int NA = apps.size(); 4948 for (int ia=0; ia<NA; ia++) { 4949 ProcessRecord app = apps.valueAt(ia); 4950 if (app.persistent && !evenPersistent) { 4951 // we don't kill persistent processes 4952 continue; 4953 } 4954 if (app.removed) { 4955 if (doit) { 4956 procs.add(app); 4957 } 4958 continue; 4959 } 4960 4961 // Skip process if it doesn't meet our oom adj requirement. 4962 if (app.setAdj < minOomAdj) { 4963 continue; 4964 } 4965 4966 // If no package is specified, we call all processes under the 4967 // give user id. 4968 if (packageName == null) { 4969 if (app.userId != userId) { 4970 continue; 4971 } 4972 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4973 continue; 4974 } 4975 // Package has been specified, we want to hit all processes 4976 // that match it. We need to qualify this by the processes 4977 // that are running under the specified app and user ID. 4978 } else { 4979 final boolean isDep = app.pkgDeps != null 4980 && app.pkgDeps.contains(packageName); 4981 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 4982 continue; 4983 } 4984 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4985 continue; 4986 } 4987 if (!app.pkgList.containsKey(packageName) && !isDep) { 4988 continue; 4989 } 4990 } 4991 4992 // Process has passed all conditions, kill it! 4993 if (!doit) { 4994 return true; 4995 } 4996 app.removed = true; 4997 procs.add(app); 4998 } 4999 } 5000 5001 int N = procs.size(); 5002 for (int i=0; i<N; i++) { 5003 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5004 } 5005 updateOomAdjLocked(); 5006 return N > 0; 5007 } 5008 5009 private final boolean forceStopPackageLocked(String name, int appId, 5010 boolean callerWillRestart, boolean purgeCache, boolean doit, 5011 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5012 int i; 5013 int N; 5014 5015 if (userId == UserHandle.USER_ALL && name == null) { 5016 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5017 } 5018 5019 if (appId < 0 && name != null) { 5020 try { 5021 appId = UserHandle.getAppId( 5022 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5023 } catch (RemoteException e) { 5024 } 5025 } 5026 5027 if (doit) { 5028 if (name != null) { 5029 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5030 + " user=" + userId + ": " + reason); 5031 } else { 5032 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5033 } 5034 5035 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5036 for (int ip=pmap.size()-1; ip>=0; ip--) { 5037 SparseArray<Long> ba = pmap.valueAt(ip); 5038 for (i=ba.size()-1; i>=0; i--) { 5039 boolean remove = false; 5040 final int entUid = ba.keyAt(i); 5041 if (name != null) { 5042 if (userId == UserHandle.USER_ALL) { 5043 if (UserHandle.getAppId(entUid) == appId) { 5044 remove = true; 5045 } 5046 } else { 5047 if (entUid == UserHandle.getUid(userId, appId)) { 5048 remove = true; 5049 } 5050 } 5051 } else if (UserHandle.getUserId(entUid) == userId) { 5052 remove = true; 5053 } 5054 if (remove) { 5055 ba.removeAt(i); 5056 } 5057 } 5058 if (ba.size() == 0) { 5059 pmap.removeAt(ip); 5060 } 5061 } 5062 } 5063 5064 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5065 -100, callerWillRestart, true, doit, evenPersistent, 5066 name == null ? ("stop user " + userId) : ("stop " + name)); 5067 5068 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5069 if (!doit) { 5070 return true; 5071 } 5072 didSomething = true; 5073 } 5074 5075 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5076 if (!doit) { 5077 return true; 5078 } 5079 didSomething = true; 5080 } 5081 5082 if (name == null) { 5083 // Remove all sticky broadcasts from this user. 5084 mStickyBroadcasts.remove(userId); 5085 } 5086 5087 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5088 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5089 userId, providers)) { 5090 if (!doit) { 5091 return true; 5092 } 5093 didSomething = true; 5094 } 5095 N = providers.size(); 5096 for (i=0; i<N; i++) { 5097 removeDyingProviderLocked(null, providers.get(i), true); 5098 } 5099 5100 // Remove transient permissions granted from/to this package/user 5101 removeUriPermissionsForPackageLocked(name, userId, false); 5102 5103 if (name == null || uninstalling) { 5104 // Remove pending intents. For now we only do this when force 5105 // stopping users, because we have some problems when doing this 5106 // for packages -- app widgets are not currently cleaned up for 5107 // such packages, so they can be left with bad pending intents. 5108 if (mIntentSenderRecords.size() > 0) { 5109 Iterator<WeakReference<PendingIntentRecord>> it 5110 = mIntentSenderRecords.values().iterator(); 5111 while (it.hasNext()) { 5112 WeakReference<PendingIntentRecord> wpir = it.next(); 5113 if (wpir == null) { 5114 it.remove(); 5115 continue; 5116 } 5117 PendingIntentRecord pir = wpir.get(); 5118 if (pir == null) { 5119 it.remove(); 5120 continue; 5121 } 5122 if (name == null) { 5123 // Stopping user, remove all objects for the user. 5124 if (pir.key.userId != userId) { 5125 // Not the same user, skip it. 5126 continue; 5127 } 5128 } else { 5129 if (UserHandle.getAppId(pir.uid) != appId) { 5130 // Different app id, skip it. 5131 continue; 5132 } 5133 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5134 // Different user, skip it. 5135 continue; 5136 } 5137 if (!pir.key.packageName.equals(name)) { 5138 // Different package, skip it. 5139 continue; 5140 } 5141 } 5142 if (!doit) { 5143 return true; 5144 } 5145 didSomething = true; 5146 it.remove(); 5147 pir.canceled = true; 5148 if (pir.key.activity != null) { 5149 pir.key.activity.pendingResults.remove(pir.ref); 5150 } 5151 } 5152 } 5153 } 5154 5155 if (doit) { 5156 if (purgeCache && name != null) { 5157 AttributeCache ac = AttributeCache.instance(); 5158 if (ac != null) { 5159 ac.removePackage(name); 5160 } 5161 } 5162 if (mBooted) { 5163 mStackSupervisor.resumeTopActivitiesLocked(); 5164 mStackSupervisor.scheduleIdleLocked(); 5165 } 5166 } 5167 5168 return didSomething; 5169 } 5170 5171 private final boolean removeProcessLocked(ProcessRecord app, 5172 boolean callerWillRestart, boolean allowRestart, String reason) { 5173 final String name = app.processName; 5174 final int uid = app.uid; 5175 if (DEBUG_PROCESSES) Slog.d( 5176 TAG, "Force removing proc " + app.toShortString() + " (" + name 5177 + "/" + uid + ")"); 5178 5179 mProcessNames.remove(name, uid); 5180 mIsolatedProcesses.remove(app.uid); 5181 if (mHeavyWeightProcess == app) { 5182 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5183 mHeavyWeightProcess.userId, 0)); 5184 mHeavyWeightProcess = null; 5185 } 5186 boolean needRestart = false; 5187 if (app.pid > 0 && app.pid != MY_PID) { 5188 int pid = app.pid; 5189 synchronized (mPidsSelfLocked) { 5190 mPidsSelfLocked.remove(pid); 5191 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5192 } 5193 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5194 if (app.isolated) { 5195 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5196 } 5197 killUnneededProcessLocked(app, reason); 5198 Process.killProcessGroup(app.info.uid, app.pid); 5199 handleAppDiedLocked(app, true, allowRestart); 5200 removeLruProcessLocked(app); 5201 5202 if (app.persistent && !app.isolated) { 5203 if (!callerWillRestart) { 5204 addAppLocked(app.info, false, null /* ABI override */); 5205 } else { 5206 needRestart = true; 5207 } 5208 } 5209 } else { 5210 mRemovedProcesses.add(app); 5211 } 5212 5213 return needRestart; 5214 } 5215 5216 private final void processStartTimedOutLocked(ProcessRecord app) { 5217 final int pid = app.pid; 5218 boolean gone = false; 5219 synchronized (mPidsSelfLocked) { 5220 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5221 if (knownApp != null && knownApp.thread == null) { 5222 mPidsSelfLocked.remove(pid); 5223 gone = true; 5224 } 5225 } 5226 5227 if (gone) { 5228 Slog.w(TAG, "Process " + app + " failed to attach"); 5229 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5230 pid, app.uid, app.processName); 5231 mProcessNames.remove(app.processName, app.uid); 5232 mIsolatedProcesses.remove(app.uid); 5233 if (mHeavyWeightProcess == app) { 5234 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5235 mHeavyWeightProcess.userId, 0)); 5236 mHeavyWeightProcess = null; 5237 } 5238 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5239 if (app.isolated) { 5240 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5241 } 5242 // Take care of any launching providers waiting for this process. 5243 checkAppInLaunchingProvidersLocked(app, true); 5244 // Take care of any services that are waiting for the process. 5245 mServices.processStartTimedOutLocked(app); 5246 killUnneededProcessLocked(app, "start timeout"); 5247 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5248 Slog.w(TAG, "Unattached app died before backup, skipping"); 5249 try { 5250 IBackupManager bm = IBackupManager.Stub.asInterface( 5251 ServiceManager.getService(Context.BACKUP_SERVICE)); 5252 bm.agentDisconnected(app.info.packageName); 5253 } catch (RemoteException e) { 5254 // Can't happen; the backup manager is local 5255 } 5256 } 5257 if (isPendingBroadcastProcessLocked(pid)) { 5258 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5259 skipPendingBroadcastLocked(pid); 5260 } 5261 } else { 5262 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5263 } 5264 } 5265 5266 private final boolean attachApplicationLocked(IApplicationThread thread, 5267 int pid) { 5268 5269 // Find the application record that is being attached... either via 5270 // the pid if we are running in multiple processes, or just pull the 5271 // next app record if we are emulating process with anonymous threads. 5272 ProcessRecord app; 5273 if (pid != MY_PID && pid >= 0) { 5274 synchronized (mPidsSelfLocked) { 5275 app = mPidsSelfLocked.get(pid); 5276 } 5277 } else { 5278 app = null; 5279 } 5280 5281 if (app == null) { 5282 Slog.w(TAG, "No pending application record for pid " + pid 5283 + " (IApplicationThread " + thread + "); dropping process"); 5284 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5285 if (pid > 0 && pid != MY_PID) { 5286 Process.killProcessQuiet(pid); 5287 //TODO: Process.killProcessGroup(app.info.uid, pid); 5288 } else { 5289 try { 5290 thread.scheduleExit(); 5291 } catch (Exception e) { 5292 // Ignore exceptions. 5293 } 5294 } 5295 return false; 5296 } 5297 5298 // If this application record is still attached to a previous 5299 // process, clean it up now. 5300 if (app.thread != null) { 5301 handleAppDiedLocked(app, true, true); 5302 } 5303 5304 // Tell the process all about itself. 5305 5306 if (localLOGV) Slog.v( 5307 TAG, "Binding process pid " + pid + " to record " + app); 5308 5309 final String processName = app.processName; 5310 try { 5311 AppDeathRecipient adr = new AppDeathRecipient( 5312 app, pid, thread); 5313 thread.asBinder().linkToDeath(adr, 0); 5314 app.deathRecipient = adr; 5315 } catch (RemoteException e) { 5316 app.resetPackageList(mProcessStats); 5317 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5318 return false; 5319 } 5320 5321 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5322 5323 app.makeActive(thread, mProcessStats); 5324 app.curAdj = app.setAdj = -100; 5325 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5326 app.forcingToForeground = null; 5327 updateProcessForegroundLocked(app, false, false); 5328 app.hasShownUi = false; 5329 app.debugging = false; 5330 app.cached = false; 5331 5332 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5333 5334 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5335 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5336 5337 if (!normalMode) { 5338 Slog.i(TAG, "Launching preboot mode app: " + app); 5339 } 5340 5341 if (localLOGV) Slog.v( 5342 TAG, "New app record " + app 5343 + " thread=" + thread.asBinder() + " pid=" + pid); 5344 try { 5345 int testMode = IApplicationThread.DEBUG_OFF; 5346 if (mDebugApp != null && mDebugApp.equals(processName)) { 5347 testMode = mWaitForDebugger 5348 ? IApplicationThread.DEBUG_WAIT 5349 : IApplicationThread.DEBUG_ON; 5350 app.debugging = true; 5351 if (mDebugTransient) { 5352 mDebugApp = mOrigDebugApp; 5353 mWaitForDebugger = mOrigWaitForDebugger; 5354 } 5355 } 5356 String profileFile = app.instrumentationProfileFile; 5357 ParcelFileDescriptor profileFd = null; 5358 boolean profileAutoStop = false; 5359 if (mProfileApp != null && mProfileApp.equals(processName)) { 5360 mProfileProc = app; 5361 profileFile = mProfileFile; 5362 profileFd = mProfileFd; 5363 profileAutoStop = mAutoStopProfiler; 5364 } 5365 boolean enableOpenGlTrace = false; 5366 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5367 enableOpenGlTrace = true; 5368 mOpenGlTraceApp = null; 5369 } 5370 5371 // If the app is being launched for restore or full backup, set it up specially 5372 boolean isRestrictedBackupMode = false; 5373 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5374 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5375 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5376 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5377 } 5378 5379 ensurePackageDexOpt(app.instrumentationInfo != null 5380 ? app.instrumentationInfo.packageName 5381 : app.info.packageName); 5382 if (app.instrumentationClass != null) { 5383 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5384 } 5385 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5386 + processName + " with config " + mConfiguration); 5387 ApplicationInfo appInfo = app.instrumentationInfo != null 5388 ? app.instrumentationInfo : app.info; 5389 app.compat = compatibilityInfoForPackageLocked(appInfo); 5390 if (profileFd != null) { 5391 profileFd = profileFd.dup(); 5392 } 5393 thread.bindApplication(processName, appInfo, providers, 5394 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5395 app.instrumentationArguments, app.instrumentationWatcher, 5396 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5397 isRestrictedBackupMode || !normalMode, app.persistent, 5398 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5399 mCoreSettingsObserver.getCoreSettingsLocked()); 5400 updateLruProcessLocked(app, false, null); 5401 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5402 } catch (Exception e) { 5403 // todo: Yikes! What should we do? For now we will try to 5404 // start another process, but that could easily get us in 5405 // an infinite loop of restarting processes... 5406 Slog.w(TAG, "Exception thrown during bind!", e); 5407 5408 app.resetPackageList(mProcessStats); 5409 app.unlinkDeathRecipient(); 5410 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5411 return false; 5412 } 5413 5414 // Remove this record from the list of starting applications. 5415 mPersistentStartingProcesses.remove(app); 5416 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5417 "Attach application locked removing on hold: " + app); 5418 mProcessesOnHold.remove(app); 5419 5420 boolean badApp = false; 5421 boolean didSomething = false; 5422 5423 // See if the top visible activity is waiting to run in this process... 5424 if (normalMode) { 5425 try { 5426 if (mStackSupervisor.attachApplicationLocked(app)) { 5427 didSomething = true; 5428 } 5429 } catch (Exception e) { 5430 badApp = true; 5431 } 5432 } 5433 5434 // Find any services that should be running in this process... 5435 if (!badApp) { 5436 try { 5437 didSomething |= mServices.attachApplicationLocked(app, processName); 5438 } catch (Exception e) { 5439 badApp = true; 5440 } 5441 } 5442 5443 // Check if a next-broadcast receiver is in this process... 5444 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5445 try { 5446 didSomething |= sendPendingBroadcastsLocked(app); 5447 } catch (Exception e) { 5448 // If the app died trying to launch the receiver we declare it 'bad' 5449 badApp = true; 5450 } 5451 } 5452 5453 // Check whether the next backup agent is in this process... 5454 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5455 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5456 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5457 try { 5458 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5459 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5460 mBackupTarget.backupMode); 5461 } catch (Exception e) { 5462 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5463 e.printStackTrace(); 5464 } 5465 } 5466 5467 if (badApp) { 5468 // todo: Also need to kill application to deal with all 5469 // kinds of exceptions. 5470 handleAppDiedLocked(app, false, true); 5471 return false; 5472 } 5473 5474 if (!didSomething) { 5475 updateOomAdjLocked(); 5476 } 5477 5478 return true; 5479 } 5480 5481 @Override 5482 public final void attachApplication(IApplicationThread thread) { 5483 synchronized (this) { 5484 int callingPid = Binder.getCallingPid(); 5485 final long origId = Binder.clearCallingIdentity(); 5486 attachApplicationLocked(thread, callingPid); 5487 Binder.restoreCallingIdentity(origId); 5488 } 5489 } 5490 5491 @Override 5492 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5493 final long origId = Binder.clearCallingIdentity(); 5494 synchronized (this) { 5495 ActivityStack stack = ActivityRecord.getStackLocked(token); 5496 if (stack != null) { 5497 ActivityRecord r = 5498 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5499 if (stopProfiling) { 5500 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5501 try { 5502 mProfileFd.close(); 5503 } catch (IOException e) { 5504 } 5505 clearProfilerLocked(); 5506 } 5507 } 5508 } 5509 } 5510 Binder.restoreCallingIdentity(origId); 5511 } 5512 5513 void enableScreenAfterBoot() { 5514 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5515 SystemClock.uptimeMillis()); 5516 mWindowManager.enableScreenAfterBoot(); 5517 5518 synchronized (this) { 5519 updateEventDispatchingLocked(); 5520 } 5521 } 5522 5523 @Override 5524 public void showBootMessage(final CharSequence msg, final boolean always) { 5525 enforceNotIsolatedCaller("showBootMessage"); 5526 mWindowManager.showBootMessage(msg, always); 5527 } 5528 5529 @Override 5530 public void dismissKeyguardOnNextActivity() { 5531 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5532 final long token = Binder.clearCallingIdentity(); 5533 try { 5534 synchronized (this) { 5535 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5536 if (mLockScreenShown) { 5537 mLockScreenShown = false; 5538 comeOutOfSleepIfNeededLocked(); 5539 } 5540 mStackSupervisor.setDismissKeyguard(true); 5541 } 5542 } finally { 5543 Binder.restoreCallingIdentity(token); 5544 } 5545 } 5546 5547 final void finishBooting() { 5548 // Register receivers to handle package update events 5549 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5550 5551 synchronized (this) { 5552 // Ensure that any processes we had put on hold are now started 5553 // up. 5554 final int NP = mProcessesOnHold.size(); 5555 if (NP > 0) { 5556 ArrayList<ProcessRecord> procs = 5557 new ArrayList<ProcessRecord>(mProcessesOnHold); 5558 for (int ip=0; ip<NP; ip++) { 5559 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5560 + procs.get(ip)); 5561 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5562 } 5563 } 5564 5565 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5566 // Start looking for apps that are abusing wake locks. 5567 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5568 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5569 // Tell anyone interested that we are done booting! 5570 SystemProperties.set("sys.boot_completed", "1"); 5571 SystemProperties.set("dev.bootcomplete", "1"); 5572 for (int i=0; i<mStartedUsers.size(); i++) { 5573 UserStartedState uss = mStartedUsers.valueAt(i); 5574 if (uss.mState == UserStartedState.STATE_BOOTING) { 5575 uss.mState = UserStartedState.STATE_RUNNING; 5576 final int userId = mStartedUsers.keyAt(i); 5577 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5578 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5579 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5580 broadcastIntentLocked(null, null, intent, null, 5581 new IIntentReceiver.Stub() { 5582 @Override 5583 public void performReceive(Intent intent, int resultCode, 5584 String data, Bundle extras, boolean ordered, 5585 boolean sticky, int sendingUser) { 5586 synchronized (ActivityManagerService.this) { 5587 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5588 true, false); 5589 } 5590 } 5591 }, 5592 0, null, null, 5593 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5594 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5595 userId); 5596 } 5597 } 5598 scheduleStartProfilesLocked(); 5599 } 5600 } 5601 } 5602 5603 final void ensureBootCompleted() { 5604 boolean booting; 5605 boolean enableScreen; 5606 synchronized (this) { 5607 booting = mBooting; 5608 mBooting = false; 5609 enableScreen = !mBooted; 5610 mBooted = true; 5611 } 5612 5613 if (booting) { 5614 finishBooting(); 5615 } 5616 5617 if (enableScreen) { 5618 enableScreenAfterBoot(); 5619 } 5620 } 5621 5622 @Override 5623 public final void activityResumed(IBinder token) { 5624 final long origId = Binder.clearCallingIdentity(); 5625 synchronized(this) { 5626 ActivityStack stack = ActivityRecord.getStackLocked(token); 5627 if (stack != null) { 5628 ActivityRecord.activityResumedLocked(token); 5629 } 5630 } 5631 Binder.restoreCallingIdentity(origId); 5632 } 5633 5634 @Override 5635 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5636 final long origId = Binder.clearCallingIdentity(); 5637 synchronized(this) { 5638 ActivityStack stack = ActivityRecord.getStackLocked(token); 5639 if (stack != null) { 5640 stack.activityPausedLocked(token, false, persistentState); 5641 } 5642 } 5643 Binder.restoreCallingIdentity(origId); 5644 } 5645 5646 @Override 5647 public final void activityStopped(IBinder token, Bundle icicle, 5648 PersistableBundle persistentState, CharSequence description) { 5649 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5650 5651 // Refuse possible leaked file descriptors 5652 if (icicle != null && icicle.hasFileDescriptors()) { 5653 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5654 } 5655 5656 final long origId = Binder.clearCallingIdentity(); 5657 5658 synchronized (this) { 5659 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5660 if (r != null) { 5661 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5662 } 5663 } 5664 5665 trimApplications(); 5666 5667 Binder.restoreCallingIdentity(origId); 5668 } 5669 5670 @Override 5671 public final void activityDestroyed(IBinder token) { 5672 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5673 synchronized (this) { 5674 ActivityStack stack = ActivityRecord.getStackLocked(token); 5675 if (stack != null) { 5676 stack.activityDestroyedLocked(token); 5677 } 5678 } 5679 } 5680 5681 @Override 5682 public final void mediaResourcesReleased(IBinder token) { 5683 final long origId = Binder.clearCallingIdentity(); 5684 try { 5685 synchronized (this) { 5686 ActivityStack stack = ActivityRecord.getStackLocked(token); 5687 if (stack != null) { 5688 stack.mediaResourcesReleased(token); 5689 } 5690 } 5691 } finally { 5692 Binder.restoreCallingIdentity(origId); 5693 } 5694 } 5695 5696 @Override 5697 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5698 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5699 } 5700 5701 @Override 5702 public String getCallingPackage(IBinder token) { 5703 synchronized (this) { 5704 ActivityRecord r = getCallingRecordLocked(token); 5705 return r != null ? r.info.packageName : null; 5706 } 5707 } 5708 5709 @Override 5710 public ComponentName getCallingActivity(IBinder token) { 5711 synchronized (this) { 5712 ActivityRecord r = getCallingRecordLocked(token); 5713 return r != null ? r.intent.getComponent() : null; 5714 } 5715 } 5716 5717 private ActivityRecord getCallingRecordLocked(IBinder token) { 5718 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5719 if (r == null) { 5720 return null; 5721 } 5722 return r.resultTo; 5723 } 5724 5725 @Override 5726 public ComponentName getActivityClassForToken(IBinder token) { 5727 synchronized(this) { 5728 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5729 if (r == null) { 5730 return null; 5731 } 5732 return r.intent.getComponent(); 5733 } 5734 } 5735 5736 @Override 5737 public String getPackageForToken(IBinder token) { 5738 synchronized(this) { 5739 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5740 if (r == null) { 5741 return null; 5742 } 5743 return r.packageName; 5744 } 5745 } 5746 5747 @Override 5748 public IIntentSender getIntentSender(int type, 5749 String packageName, IBinder token, String resultWho, 5750 int requestCode, Intent[] intents, String[] resolvedTypes, 5751 int flags, Bundle options, int userId) { 5752 enforceNotIsolatedCaller("getIntentSender"); 5753 // Refuse possible leaked file descriptors 5754 if (intents != null) { 5755 if (intents.length < 1) { 5756 throw new IllegalArgumentException("Intents array length must be >= 1"); 5757 } 5758 for (int i=0; i<intents.length; i++) { 5759 Intent intent = intents[i]; 5760 if (intent != null) { 5761 if (intent.hasFileDescriptors()) { 5762 throw new IllegalArgumentException("File descriptors passed in Intent"); 5763 } 5764 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5765 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5766 throw new IllegalArgumentException( 5767 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5768 } 5769 intents[i] = new Intent(intent); 5770 } 5771 } 5772 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5773 throw new IllegalArgumentException( 5774 "Intent array length does not match resolvedTypes length"); 5775 } 5776 } 5777 if (options != null) { 5778 if (options.hasFileDescriptors()) { 5779 throw new IllegalArgumentException("File descriptors passed in options"); 5780 } 5781 } 5782 5783 synchronized(this) { 5784 int callingUid = Binder.getCallingUid(); 5785 int origUserId = userId; 5786 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5787 type == ActivityManager.INTENT_SENDER_BROADCAST, 5788 ALLOW_NON_FULL, "getIntentSender", null); 5789 if (origUserId == UserHandle.USER_CURRENT) { 5790 // We don't want to evaluate this until the pending intent is 5791 // actually executed. However, we do want to always do the 5792 // security checking for it above. 5793 userId = UserHandle.USER_CURRENT; 5794 } 5795 try { 5796 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5797 int uid = AppGlobals.getPackageManager() 5798 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5799 if (!UserHandle.isSameApp(callingUid, uid)) { 5800 String msg = "Permission Denial: getIntentSender() from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + ", (need uid=" + uid + ")" 5804 + " is not allowed to send as package " + packageName; 5805 Slog.w(TAG, msg); 5806 throw new SecurityException(msg); 5807 } 5808 } 5809 5810 return getIntentSenderLocked(type, packageName, callingUid, userId, 5811 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5812 5813 } catch (RemoteException e) { 5814 throw new SecurityException(e); 5815 } 5816 } 5817 } 5818 5819 IIntentSender getIntentSenderLocked(int type, String packageName, 5820 int callingUid, int userId, IBinder token, String resultWho, 5821 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5822 Bundle options) { 5823 if (DEBUG_MU) 5824 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5825 ActivityRecord activity = null; 5826 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5827 activity = ActivityRecord.isInStackLocked(token); 5828 if (activity == null) { 5829 return null; 5830 } 5831 if (activity.finishing) { 5832 return null; 5833 } 5834 } 5835 5836 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5837 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5838 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5839 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5840 |PendingIntent.FLAG_UPDATE_CURRENT); 5841 5842 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5843 type, packageName, activity, resultWho, 5844 requestCode, intents, resolvedTypes, flags, options, userId); 5845 WeakReference<PendingIntentRecord> ref; 5846 ref = mIntentSenderRecords.get(key); 5847 PendingIntentRecord rec = ref != null ? ref.get() : null; 5848 if (rec != null) { 5849 if (!cancelCurrent) { 5850 if (updateCurrent) { 5851 if (rec.key.requestIntent != null) { 5852 rec.key.requestIntent.replaceExtras(intents != null ? 5853 intents[intents.length - 1] : null); 5854 } 5855 if (intents != null) { 5856 intents[intents.length-1] = rec.key.requestIntent; 5857 rec.key.allIntents = intents; 5858 rec.key.allResolvedTypes = resolvedTypes; 5859 } else { 5860 rec.key.allIntents = null; 5861 rec.key.allResolvedTypes = null; 5862 } 5863 } 5864 return rec; 5865 } 5866 rec.canceled = true; 5867 mIntentSenderRecords.remove(key); 5868 } 5869 if (noCreate) { 5870 return rec; 5871 } 5872 rec = new PendingIntentRecord(this, key, callingUid); 5873 mIntentSenderRecords.put(key, rec.ref); 5874 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5875 if (activity.pendingResults == null) { 5876 activity.pendingResults 5877 = new HashSet<WeakReference<PendingIntentRecord>>(); 5878 } 5879 activity.pendingResults.add(rec.ref); 5880 } 5881 return rec; 5882 } 5883 5884 @Override 5885 public void cancelIntentSender(IIntentSender sender) { 5886 if (!(sender instanceof PendingIntentRecord)) { 5887 return; 5888 } 5889 synchronized(this) { 5890 PendingIntentRecord rec = (PendingIntentRecord)sender; 5891 try { 5892 int uid = AppGlobals.getPackageManager() 5893 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5894 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5895 String msg = "Permission Denial: cancelIntentSender() from pid=" 5896 + Binder.getCallingPid() 5897 + ", uid=" + Binder.getCallingUid() 5898 + " is not allowed to cancel packges " 5899 + rec.key.packageName; 5900 Slog.w(TAG, msg); 5901 throw new SecurityException(msg); 5902 } 5903 } catch (RemoteException e) { 5904 throw new SecurityException(e); 5905 } 5906 cancelIntentSenderLocked(rec, true); 5907 } 5908 } 5909 5910 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5911 rec.canceled = true; 5912 mIntentSenderRecords.remove(rec.key); 5913 if (cleanActivity && rec.key.activity != null) { 5914 rec.key.activity.pendingResults.remove(rec.ref); 5915 } 5916 } 5917 5918 @Override 5919 public String getPackageForIntentSender(IIntentSender pendingResult) { 5920 if (!(pendingResult instanceof PendingIntentRecord)) { 5921 return null; 5922 } 5923 try { 5924 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5925 return res.key.packageName; 5926 } catch (ClassCastException e) { 5927 } 5928 return null; 5929 } 5930 5931 @Override 5932 public int getUidForIntentSender(IIntentSender sender) { 5933 if (sender instanceof PendingIntentRecord) { 5934 try { 5935 PendingIntentRecord res = (PendingIntentRecord)sender; 5936 return res.uid; 5937 } catch (ClassCastException e) { 5938 } 5939 } 5940 return -1; 5941 } 5942 5943 @Override 5944 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5945 if (!(pendingResult instanceof PendingIntentRecord)) { 5946 return false; 5947 } 5948 try { 5949 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5950 if (res.key.allIntents == null) { 5951 return false; 5952 } 5953 for (int i=0; i<res.key.allIntents.length; i++) { 5954 Intent intent = res.key.allIntents[i]; 5955 if (intent.getPackage() != null && intent.getComponent() != null) { 5956 return false; 5957 } 5958 } 5959 return true; 5960 } catch (ClassCastException e) { 5961 } 5962 return false; 5963 } 5964 5965 @Override 5966 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5967 if (!(pendingResult instanceof PendingIntentRecord)) { 5968 return false; 5969 } 5970 try { 5971 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5972 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5973 return true; 5974 } 5975 return false; 5976 } catch (ClassCastException e) { 5977 } 5978 return false; 5979 } 5980 5981 @Override 5982 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5983 if (!(pendingResult instanceof PendingIntentRecord)) { 5984 return null; 5985 } 5986 try { 5987 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5988 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5989 } catch (ClassCastException e) { 5990 } 5991 return null; 5992 } 5993 5994 @Override 5995 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5996 if (!(pendingResult instanceof PendingIntentRecord)) { 5997 return null; 5998 } 5999 try { 6000 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6001 Intent intent = res.key.requestIntent; 6002 if (intent != null) { 6003 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6004 || res.lastTagPrefix.equals(prefix))) { 6005 return res.lastTag; 6006 } 6007 res.lastTagPrefix = prefix; 6008 StringBuilder sb = new StringBuilder(128); 6009 if (prefix != null) { 6010 sb.append(prefix); 6011 } 6012 if (intent.getAction() != null) { 6013 sb.append(intent.getAction()); 6014 } else if (intent.getComponent() != null) { 6015 intent.getComponent().appendShortString(sb); 6016 } else { 6017 sb.append("?"); 6018 } 6019 return res.lastTag = sb.toString(); 6020 } 6021 } catch (ClassCastException e) { 6022 } 6023 return null; 6024 } 6025 6026 @Override 6027 public void setProcessLimit(int max) { 6028 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6029 "setProcessLimit()"); 6030 synchronized (this) { 6031 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6032 mProcessLimitOverride = max; 6033 } 6034 trimApplications(); 6035 } 6036 6037 @Override 6038 public int getProcessLimit() { 6039 synchronized (this) { 6040 return mProcessLimitOverride; 6041 } 6042 } 6043 6044 void foregroundTokenDied(ForegroundToken token) { 6045 synchronized (ActivityManagerService.this) { 6046 synchronized (mPidsSelfLocked) { 6047 ForegroundToken cur 6048 = mForegroundProcesses.get(token.pid); 6049 if (cur != token) { 6050 return; 6051 } 6052 mForegroundProcesses.remove(token.pid); 6053 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6054 if (pr == null) { 6055 return; 6056 } 6057 pr.forcingToForeground = null; 6058 updateProcessForegroundLocked(pr, false, false); 6059 } 6060 updateOomAdjLocked(); 6061 } 6062 } 6063 6064 @Override 6065 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6066 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6067 "setProcessForeground()"); 6068 synchronized(this) { 6069 boolean changed = false; 6070 6071 synchronized (mPidsSelfLocked) { 6072 ProcessRecord pr = mPidsSelfLocked.get(pid); 6073 if (pr == null && isForeground) { 6074 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6075 return; 6076 } 6077 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6078 if (oldToken != null) { 6079 oldToken.token.unlinkToDeath(oldToken, 0); 6080 mForegroundProcesses.remove(pid); 6081 if (pr != null) { 6082 pr.forcingToForeground = null; 6083 } 6084 changed = true; 6085 } 6086 if (isForeground && token != null) { 6087 ForegroundToken newToken = new ForegroundToken() { 6088 @Override 6089 public void binderDied() { 6090 foregroundTokenDied(this); 6091 } 6092 }; 6093 newToken.pid = pid; 6094 newToken.token = token; 6095 try { 6096 token.linkToDeath(newToken, 0); 6097 mForegroundProcesses.put(pid, newToken); 6098 pr.forcingToForeground = token; 6099 changed = true; 6100 } catch (RemoteException e) { 6101 // If the process died while doing this, we will later 6102 // do the cleanup with the process death link. 6103 } 6104 } 6105 } 6106 6107 if (changed) { 6108 updateOomAdjLocked(); 6109 } 6110 } 6111 } 6112 6113 // ========================================================= 6114 // PERMISSIONS 6115 // ========================================================= 6116 6117 static class PermissionController extends IPermissionController.Stub { 6118 ActivityManagerService mActivityManagerService; 6119 PermissionController(ActivityManagerService activityManagerService) { 6120 mActivityManagerService = activityManagerService; 6121 } 6122 6123 @Override 6124 public boolean checkPermission(String permission, int pid, int uid) { 6125 return mActivityManagerService.checkPermission(permission, pid, 6126 uid) == PackageManager.PERMISSION_GRANTED; 6127 } 6128 } 6129 6130 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6131 @Override 6132 public int checkComponentPermission(String permission, int pid, int uid, 6133 int owningUid, boolean exported) { 6134 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6135 owningUid, exported); 6136 } 6137 6138 @Override 6139 public Object getAMSLock() { 6140 return ActivityManagerService.this; 6141 } 6142 } 6143 6144 /** 6145 * This can be called with or without the global lock held. 6146 */ 6147 int checkComponentPermission(String permission, int pid, int uid, 6148 int owningUid, boolean exported) { 6149 // We might be performing an operation on behalf of an indirect binder 6150 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6151 // client identity accordingly before proceeding. 6152 Identity tlsIdentity = sCallerIdentity.get(); 6153 if (tlsIdentity != null) { 6154 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6155 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6156 uid = tlsIdentity.uid; 6157 pid = tlsIdentity.pid; 6158 } 6159 6160 if (pid == MY_PID) { 6161 return PackageManager.PERMISSION_GRANTED; 6162 } 6163 6164 return ActivityManager.checkComponentPermission(permission, uid, 6165 owningUid, exported); 6166 } 6167 6168 /** 6169 * As the only public entry point for permissions checking, this method 6170 * can enforce the semantic that requesting a check on a null global 6171 * permission is automatically denied. (Internally a null permission 6172 * string is used when calling {@link #checkComponentPermission} in cases 6173 * when only uid-based security is needed.) 6174 * 6175 * This can be called with or without the global lock held. 6176 */ 6177 @Override 6178 public int checkPermission(String permission, int pid, int uid) { 6179 if (permission == null) { 6180 return PackageManager.PERMISSION_DENIED; 6181 } 6182 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6183 } 6184 6185 /** 6186 * Binder IPC calls go through the public entry point. 6187 * This can be called with or without the global lock held. 6188 */ 6189 int checkCallingPermission(String permission) { 6190 return checkPermission(permission, 6191 Binder.getCallingPid(), 6192 UserHandle.getAppId(Binder.getCallingUid())); 6193 } 6194 6195 /** 6196 * This can be called with or without the global lock held. 6197 */ 6198 void enforceCallingPermission(String permission, String func) { 6199 if (checkCallingPermission(permission) 6200 == PackageManager.PERMISSION_GRANTED) { 6201 return; 6202 } 6203 6204 String msg = "Permission Denial: " + func + " from pid=" 6205 + Binder.getCallingPid() 6206 + ", uid=" + Binder.getCallingUid() 6207 + " requires " + permission; 6208 Slog.w(TAG, msg); 6209 throw new SecurityException(msg); 6210 } 6211 6212 /** 6213 * Determine if UID is holding permissions required to access {@link Uri} in 6214 * the given {@link ProviderInfo}. Final permission checking is always done 6215 * in {@link ContentProvider}. 6216 */ 6217 private final boolean checkHoldingPermissionsLocked( 6218 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6220 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6221 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6222 return false; 6223 } 6224 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6225 } 6226 6227 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6228 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6229 if (pi.applicationInfo.uid == uid) { 6230 return true; 6231 } else if (!pi.exported) { 6232 return false; 6233 } 6234 6235 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6236 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6237 try { 6238 // check if target holds top-level <provider> permissions 6239 if (!readMet && pi.readPermission != null && considerUidPermissions 6240 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6241 readMet = true; 6242 } 6243 if (!writeMet && pi.writePermission != null && considerUidPermissions 6244 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6245 writeMet = true; 6246 } 6247 6248 // track if unprotected read/write is allowed; any denied 6249 // <path-permission> below removes this ability 6250 boolean allowDefaultRead = pi.readPermission == null; 6251 boolean allowDefaultWrite = pi.writePermission == null; 6252 6253 // check if target holds any <path-permission> that match uri 6254 final PathPermission[] pps = pi.pathPermissions; 6255 if (pps != null) { 6256 final String path = grantUri.uri.getPath(); 6257 int i = pps.length; 6258 while (i > 0 && (!readMet || !writeMet)) { 6259 i--; 6260 PathPermission pp = pps[i]; 6261 if (pp.match(path)) { 6262 if (!readMet) { 6263 final String pprperm = pp.getReadPermission(); 6264 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6265 + pprperm + " for " + pp.getPath() 6266 + ": match=" + pp.match(path) 6267 + " check=" + pm.checkUidPermission(pprperm, uid)); 6268 if (pprperm != null) { 6269 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6270 == PERMISSION_GRANTED) { 6271 readMet = true; 6272 } else { 6273 allowDefaultRead = false; 6274 } 6275 } 6276 } 6277 if (!writeMet) { 6278 final String ppwperm = pp.getWritePermission(); 6279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6280 + ppwperm + " for " + pp.getPath() 6281 + ": match=" + pp.match(path) 6282 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6283 if (ppwperm != null) { 6284 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6285 == PERMISSION_GRANTED) { 6286 writeMet = true; 6287 } else { 6288 allowDefaultWrite = false; 6289 } 6290 } 6291 } 6292 } 6293 } 6294 } 6295 6296 // grant unprotected <provider> read/write, if not blocked by 6297 // <path-permission> above 6298 if (allowDefaultRead) readMet = true; 6299 if (allowDefaultWrite) writeMet = true; 6300 6301 } catch (RemoteException e) { 6302 return false; 6303 } 6304 6305 return readMet && writeMet; 6306 } 6307 6308 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6309 ProviderInfo pi = null; 6310 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6311 if (cpr != null) { 6312 pi = cpr.info; 6313 } else { 6314 try { 6315 pi = AppGlobals.getPackageManager().resolveContentProvider( 6316 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6317 } catch (RemoteException ex) { 6318 } 6319 } 6320 return pi; 6321 } 6322 6323 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6324 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6325 if (targetUris != null) { 6326 return targetUris.get(grantUri); 6327 } 6328 return null; 6329 } 6330 6331 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6332 String targetPkg, int targetUid, GrantUri grantUri) { 6333 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6334 if (targetUris == null) { 6335 targetUris = Maps.newArrayMap(); 6336 mGrantedUriPermissions.put(targetUid, targetUris); 6337 } 6338 6339 UriPermission perm = targetUris.get(grantUri); 6340 if (perm == null) { 6341 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6342 targetUris.put(grantUri, perm); 6343 } 6344 6345 return perm; 6346 } 6347 6348 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6349 final int modeFlags) { 6350 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6351 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6352 : UriPermission.STRENGTH_OWNED; 6353 6354 // Root gets to do everything. 6355 if (uid == 0) { 6356 return true; 6357 } 6358 6359 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6360 if (perms == null) return false; 6361 6362 // First look for exact match 6363 final UriPermission exactPerm = perms.get(grantUri); 6364 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6365 return true; 6366 } 6367 6368 // No exact match, look for prefixes 6369 final int N = perms.size(); 6370 for (int i = 0; i < N; i++) { 6371 final UriPermission perm = perms.valueAt(i); 6372 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6373 && perm.getStrength(modeFlags) >= minStrength) { 6374 return true; 6375 } 6376 } 6377 6378 return false; 6379 } 6380 6381 @Override 6382 public int checkUriPermission(Uri uri, int pid, int uid, 6383 final int modeFlags, int userId) { 6384 enforceNotIsolatedCaller("checkUriPermission"); 6385 6386 // Another redirected-binder-call permissions check as in 6387 // {@link checkComponentPermission}. 6388 Identity tlsIdentity = sCallerIdentity.get(); 6389 if (tlsIdentity != null) { 6390 uid = tlsIdentity.uid; 6391 pid = tlsIdentity.pid; 6392 } 6393 6394 // Our own process gets to do everything. 6395 if (pid == MY_PID) { 6396 return PackageManager.PERMISSION_GRANTED; 6397 } 6398 synchronized (this) { 6399 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6400 ? PackageManager.PERMISSION_GRANTED 6401 : PackageManager.PERMISSION_DENIED; 6402 } 6403 } 6404 6405 /** 6406 * Check if the targetPkg can be granted permission to access uri by 6407 * the callingUid using the given modeFlags. Throws a security exception 6408 * if callingUid is not allowed to do this. Returns the uid of the target 6409 * if the URI permission grant should be performed; returns -1 if it is not 6410 * needed (for example targetPkg already has permission to access the URI). 6411 * If you already know the uid of the target, you can supply it in 6412 * lastTargetUid else set that to -1. 6413 */ 6414 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6415 final int modeFlags, int lastTargetUid) { 6416 if (!Intent.isAccessUriMode(modeFlags)) { 6417 return -1; 6418 } 6419 6420 if (targetPkg != null) { 6421 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6422 "Checking grant " + targetPkg + " permission to " + grantUri); 6423 } 6424 6425 final IPackageManager pm = AppGlobals.getPackageManager(); 6426 6427 // If this is not a content: uri, we can't do anything with it. 6428 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6429 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6430 "Can't grant URI permission for non-content URI: " + grantUri); 6431 return -1; 6432 } 6433 6434 final String authority = grantUri.uri.getAuthority(); 6435 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6436 if (pi == null) { 6437 Slog.w(TAG, "No content provider found for permission check: " + 6438 grantUri.uri.toSafeString()); 6439 return -1; 6440 } 6441 6442 int targetUid = lastTargetUid; 6443 if (targetUid < 0 && targetPkg != null) { 6444 try { 6445 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6446 if (targetUid < 0) { 6447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6448 "Can't grant URI permission no uid for: " + targetPkg); 6449 return -1; 6450 } 6451 } catch (RemoteException ex) { 6452 return -1; 6453 } 6454 } 6455 6456 if (targetUid >= 0) { 6457 // First... does the target actually need this permission? 6458 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6459 // No need to grant the target this permission. 6460 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6461 "Target " + targetPkg + " already has full permission to " + grantUri); 6462 return -1; 6463 } 6464 } else { 6465 // First... there is no target package, so can anyone access it? 6466 boolean allowed = pi.exported; 6467 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6468 if (pi.readPermission != null) { 6469 allowed = false; 6470 } 6471 } 6472 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6473 if (pi.writePermission != null) { 6474 allowed = false; 6475 } 6476 } 6477 if (allowed) { 6478 return -1; 6479 } 6480 } 6481 6482 /* There is a special cross user grant if: 6483 * - The target is on another user. 6484 * - Apps on the current user can access the uri without any uid permissions. 6485 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6486 * grant uri permissions. 6487 */ 6488 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6489 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6490 modeFlags, false /*without considering the uid permissions*/); 6491 6492 // Second... is the provider allowing granting of URI permissions? 6493 if (!specialCrossUserGrant) { 6494 if (!pi.grantUriPermissions) { 6495 throw new SecurityException("Provider " + pi.packageName 6496 + "/" + pi.name 6497 + " does not allow granting of Uri permissions (uri " 6498 + grantUri + ")"); 6499 } 6500 if (pi.uriPermissionPatterns != null) { 6501 final int N = pi.uriPermissionPatterns.length; 6502 boolean allowed = false; 6503 for (int i=0; i<N; i++) { 6504 if (pi.uriPermissionPatterns[i] != null 6505 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6506 allowed = true; 6507 break; 6508 } 6509 } 6510 if (!allowed) { 6511 throw new SecurityException("Provider " + pi.packageName 6512 + "/" + pi.name 6513 + " does not allow granting of permission to path of Uri " 6514 + grantUri); 6515 } 6516 } 6517 } 6518 6519 // Third... does the caller itself have permission to access 6520 // this uri? 6521 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6522 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6523 // Require they hold a strong enough Uri permission 6524 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6525 throw new SecurityException("Uid " + callingUid 6526 + " does not have permission to uri " + grantUri); 6527 } 6528 } 6529 } 6530 return targetUid; 6531 } 6532 6533 @Override 6534 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6535 final int modeFlags, int userId) { 6536 enforceNotIsolatedCaller("checkGrantUriPermission"); 6537 synchronized(this) { 6538 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6539 new GrantUri(userId, uri, false), modeFlags, -1); 6540 } 6541 } 6542 6543 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6544 final int modeFlags, UriPermissionOwner owner) { 6545 if (!Intent.isAccessUriMode(modeFlags)) { 6546 return; 6547 } 6548 6549 // So here we are: the caller has the assumed permission 6550 // to the uri, and the target doesn't. Let's now give this to 6551 // the target. 6552 6553 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6554 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6555 6556 final String authority = grantUri.uri.getAuthority(); 6557 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6558 if (pi == null) { 6559 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6560 return; 6561 } 6562 6563 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6564 grantUri.prefix = true; 6565 } 6566 final UriPermission perm = findOrCreateUriPermissionLocked( 6567 pi.packageName, targetPkg, targetUid, grantUri); 6568 perm.grantModes(modeFlags, owner); 6569 } 6570 6571 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6572 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 6573 if (targetPkg == null) { 6574 throw new NullPointerException("targetPkg"); 6575 } 6576 int targetUid; 6577 final IPackageManager pm = AppGlobals.getPackageManager(); 6578 try { 6579 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6580 } catch (RemoteException ex) { 6581 return; 6582 } 6583 6584 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6585 targetUid); 6586 if (targetUid < 0) { 6587 return; 6588 } 6589 6590 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6591 owner); 6592 } 6593 6594 static class NeededUriGrants extends ArrayList<GrantUri> { 6595 final String targetPkg; 6596 final int targetUid; 6597 final int flags; 6598 6599 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6600 this.targetPkg = targetPkg; 6601 this.targetUid = targetUid; 6602 this.flags = flags; 6603 } 6604 } 6605 6606 /** 6607 * Like checkGrantUriPermissionLocked, but takes an Intent. 6608 */ 6609 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6610 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6611 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6612 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6613 + " clip=" + (intent != null ? intent.getClipData() : null) 6614 + " from " + intent + "; flags=0x" 6615 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6616 6617 if (targetPkg == null) { 6618 throw new NullPointerException("targetPkg"); 6619 } 6620 6621 if (intent == null) { 6622 return null; 6623 } 6624 Uri data = intent.getData(); 6625 ClipData clip = intent.getClipData(); 6626 if (data == null && clip == null) { 6627 return null; 6628 } 6629 final IPackageManager pm = AppGlobals.getPackageManager(); 6630 int targetUid; 6631 if (needed != null) { 6632 targetUid = needed.targetUid; 6633 } else { 6634 try { 6635 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6636 } catch (RemoteException ex) { 6637 return null; 6638 } 6639 if (targetUid < 0) { 6640 if (DEBUG_URI_PERMISSION) { 6641 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6642 + " on user " + targetUserId); 6643 } 6644 return null; 6645 } 6646 } 6647 if (data != null) { 6648 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6649 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6650 targetUid); 6651 if (targetUid > 0) { 6652 if (needed == null) { 6653 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6654 } 6655 needed.add(grantUri); 6656 } 6657 } 6658 if (clip != null) { 6659 for (int i=0; i<clip.getItemCount(); i++) { 6660 Uri uri = clip.getItemAt(i).getUri(); 6661 if (uri != null) { 6662 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6663 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6664 targetUid); 6665 if (targetUid > 0) { 6666 if (needed == null) { 6667 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6668 } 6669 needed.add(grantUri); 6670 } 6671 } else { 6672 Intent clipIntent = clip.getItemAt(i).getIntent(); 6673 if (clipIntent != null) { 6674 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6675 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6676 if (newNeeded != null) { 6677 needed = newNeeded; 6678 } 6679 } 6680 } 6681 } 6682 } 6683 6684 return needed; 6685 } 6686 6687 /** 6688 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6689 */ 6690 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6691 UriPermissionOwner owner) { 6692 if (needed != null) { 6693 for (int i=0; i<needed.size(); i++) { 6694 GrantUri grantUri = needed.get(i); 6695 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6696 grantUri, needed.flags, owner); 6697 } 6698 } 6699 } 6700 6701 void grantUriPermissionFromIntentLocked(int callingUid, 6702 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6703 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6704 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6705 if (needed == null) { 6706 return; 6707 } 6708 6709 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6710 } 6711 6712 @Override 6713 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6714 final int modeFlags, int userId) { 6715 enforceNotIsolatedCaller("grantUriPermission"); 6716 GrantUri grantUri = new GrantUri(userId, uri, false); 6717 synchronized(this) { 6718 final ProcessRecord r = getRecordForAppLocked(caller); 6719 if (r == null) { 6720 throw new SecurityException("Unable to find app for caller " 6721 + caller 6722 + " when granting permission to uri " + grantUri); 6723 } 6724 if (targetPkg == null) { 6725 throw new IllegalArgumentException("null target"); 6726 } 6727 if (grantUri == null) { 6728 throw new IllegalArgumentException("null uri"); 6729 } 6730 6731 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6732 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6733 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6734 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6735 6736 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 6737 UserHandle.getUserId(r.uid)); 6738 } 6739 } 6740 6741 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6742 if (perm.modeFlags == 0) { 6743 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6744 perm.targetUid); 6745 if (perms != null) { 6746 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6747 "Removing " + perm.targetUid + " permission to " + perm.uri); 6748 6749 perms.remove(perm.uri); 6750 if (perms.isEmpty()) { 6751 mGrantedUriPermissions.remove(perm.targetUid); 6752 } 6753 } 6754 } 6755 } 6756 6757 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6758 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6759 6760 final IPackageManager pm = AppGlobals.getPackageManager(); 6761 final String authority = grantUri.uri.getAuthority(); 6762 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6763 if (pi == null) { 6764 Slog.w(TAG, "No content provider found for permission revoke: " 6765 + grantUri.toSafeString()); 6766 return; 6767 } 6768 6769 // Does the caller have this permission on the URI? 6770 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6771 // Right now, if you are not the original owner of the permission, 6772 // you are not allowed to revoke it. 6773 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6774 throw new SecurityException("Uid " + callingUid 6775 + " does not have permission to uri " + grantUri); 6776 //} 6777 } 6778 6779 boolean persistChanged = false; 6780 6781 // Go through all of the permissions and remove any that match. 6782 int N = mGrantedUriPermissions.size(); 6783 for (int i = 0; i < N; i++) { 6784 final int targetUid = mGrantedUriPermissions.keyAt(i); 6785 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6786 6787 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6788 final UriPermission perm = it.next(); 6789 if (perm.uri.sourceUserId == grantUri.sourceUserId 6790 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6791 if (DEBUG_URI_PERMISSION) 6792 Slog.v(TAG, 6793 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6794 persistChanged |= perm.revokeModes( 6795 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6796 if (perm.modeFlags == 0) { 6797 it.remove(); 6798 } 6799 } 6800 } 6801 6802 if (perms.isEmpty()) { 6803 mGrantedUriPermissions.remove(targetUid); 6804 N--; 6805 i--; 6806 } 6807 } 6808 6809 if (persistChanged) { 6810 schedulePersistUriGrants(); 6811 } 6812 } 6813 6814 @Override 6815 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6816 int userId) { 6817 enforceNotIsolatedCaller("revokeUriPermission"); 6818 synchronized(this) { 6819 final ProcessRecord r = getRecordForAppLocked(caller); 6820 if (r == null) { 6821 throw new SecurityException("Unable to find app for caller " 6822 + caller 6823 + " when revoking permission to uri " + uri); 6824 } 6825 if (uri == null) { 6826 Slog.w(TAG, "revokeUriPermission: null uri"); 6827 return; 6828 } 6829 6830 if (!Intent.isAccessUriMode(modeFlags)) { 6831 return; 6832 } 6833 6834 final IPackageManager pm = AppGlobals.getPackageManager(); 6835 final String authority = uri.getAuthority(); 6836 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6837 if (pi == null) { 6838 Slog.w(TAG, "No content provider found for permission revoke: " 6839 + uri.toSafeString()); 6840 return; 6841 } 6842 6843 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6844 } 6845 } 6846 6847 /** 6848 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6849 * given package. 6850 * 6851 * @param packageName Package name to match, or {@code null} to apply to all 6852 * packages. 6853 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6854 * to all users. 6855 * @param persistable If persistable grants should be removed. 6856 */ 6857 private void removeUriPermissionsForPackageLocked( 6858 String packageName, int userHandle, boolean persistable) { 6859 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6860 throw new IllegalArgumentException("Must narrow by either package or user"); 6861 } 6862 6863 boolean persistChanged = false; 6864 6865 int N = mGrantedUriPermissions.size(); 6866 for (int i = 0; i < N; i++) { 6867 final int targetUid = mGrantedUriPermissions.keyAt(i); 6868 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6869 6870 // Only inspect grants matching user 6871 if (userHandle == UserHandle.USER_ALL 6872 || userHandle == UserHandle.getUserId(targetUid)) { 6873 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6874 final UriPermission perm = it.next(); 6875 6876 // Only inspect grants matching package 6877 if (packageName == null || perm.sourcePkg.equals(packageName) 6878 || perm.targetPkg.equals(packageName)) { 6879 persistChanged |= perm.revokeModes( 6880 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6881 6882 // Only remove when no modes remain; any persisted grants 6883 // will keep this alive. 6884 if (perm.modeFlags == 0) { 6885 it.remove(); 6886 } 6887 } 6888 } 6889 6890 if (perms.isEmpty()) { 6891 mGrantedUriPermissions.remove(targetUid); 6892 N--; 6893 i--; 6894 } 6895 } 6896 } 6897 6898 if (persistChanged) { 6899 schedulePersistUriGrants(); 6900 } 6901 } 6902 6903 @Override 6904 public IBinder newUriPermissionOwner(String name) { 6905 enforceNotIsolatedCaller("newUriPermissionOwner"); 6906 synchronized(this) { 6907 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6908 return owner.getExternalTokenLocked(); 6909 } 6910 } 6911 6912 @Override 6913 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6914 final int modeFlags, int sourceUserId, int targetUserId) { 6915 synchronized(this) { 6916 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6917 if (owner == null) { 6918 throw new IllegalArgumentException("Unknown owner: " + token); 6919 } 6920 if (fromUid != Binder.getCallingUid()) { 6921 if (Binder.getCallingUid() != Process.myUid()) { 6922 // Only system code can grant URI permissions on behalf 6923 // of other users. 6924 throw new SecurityException("nice try"); 6925 } 6926 } 6927 if (targetPkg == null) { 6928 throw new IllegalArgumentException("null target"); 6929 } 6930 if (uri == null) { 6931 throw new IllegalArgumentException("null uri"); 6932 } 6933 6934 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 6935 modeFlags, owner, targetUserId); 6936 } 6937 } 6938 6939 @Override 6940 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6941 synchronized(this) { 6942 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6943 if (owner == null) { 6944 throw new IllegalArgumentException("Unknown owner: " + token); 6945 } 6946 6947 if (uri == null) { 6948 owner.removeUriPermissionsLocked(mode); 6949 } else { 6950 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6951 } 6952 } 6953 } 6954 6955 private void schedulePersistUriGrants() { 6956 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6957 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6958 10 * DateUtils.SECOND_IN_MILLIS); 6959 } 6960 } 6961 6962 private void writeGrantedUriPermissions() { 6963 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6964 6965 // Snapshot permissions so we can persist without lock 6966 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6967 synchronized (this) { 6968 final int size = mGrantedUriPermissions.size(); 6969 for (int i = 0; i < size; i++) { 6970 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6971 for (UriPermission perm : perms.values()) { 6972 if (perm.persistedModeFlags != 0) { 6973 persist.add(perm.snapshot()); 6974 } 6975 } 6976 } 6977 } 6978 6979 FileOutputStream fos = null; 6980 try { 6981 fos = mGrantFile.startWrite(); 6982 6983 XmlSerializer out = new FastXmlSerializer(); 6984 out.setOutput(fos, "utf-8"); 6985 out.startDocument(null, true); 6986 out.startTag(null, TAG_URI_GRANTS); 6987 for (UriPermission.Snapshot perm : persist) { 6988 out.startTag(null, TAG_URI_GRANT); 6989 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6990 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6991 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6992 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6993 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6994 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6995 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6996 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6997 out.endTag(null, TAG_URI_GRANT); 6998 } 6999 out.endTag(null, TAG_URI_GRANTS); 7000 out.endDocument(); 7001 7002 mGrantFile.finishWrite(fos); 7003 } catch (IOException e) { 7004 if (fos != null) { 7005 mGrantFile.failWrite(fos); 7006 } 7007 } 7008 } 7009 7010 private void readGrantedUriPermissionsLocked() { 7011 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7012 7013 final long now = System.currentTimeMillis(); 7014 7015 FileInputStream fis = null; 7016 try { 7017 fis = mGrantFile.openRead(); 7018 final XmlPullParser in = Xml.newPullParser(); 7019 in.setInput(fis, null); 7020 7021 int type; 7022 while ((type = in.next()) != END_DOCUMENT) { 7023 final String tag = in.getName(); 7024 if (type == START_TAG) { 7025 if (TAG_URI_GRANT.equals(tag)) { 7026 final int sourceUserId; 7027 final int targetUserId; 7028 final int userHandle = readIntAttribute(in, 7029 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7030 if (userHandle != UserHandle.USER_NULL) { 7031 // For backwards compatibility. 7032 sourceUserId = userHandle; 7033 targetUserId = userHandle; 7034 } else { 7035 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7036 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7037 } 7038 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7039 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7040 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7041 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7042 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7043 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7044 7045 // Sanity check that provider still belongs to source package 7046 final ProviderInfo pi = getProviderInfoLocked( 7047 uri.getAuthority(), sourceUserId); 7048 if (pi != null && sourcePkg.equals(pi.packageName)) { 7049 int targetUid = -1; 7050 try { 7051 targetUid = AppGlobals.getPackageManager() 7052 .getPackageUid(targetPkg, targetUserId); 7053 } catch (RemoteException e) { 7054 } 7055 if (targetUid != -1) { 7056 final UriPermission perm = findOrCreateUriPermissionLocked( 7057 sourcePkg, targetPkg, targetUid, 7058 new GrantUri(sourceUserId, uri, prefix)); 7059 perm.initPersistedModes(modeFlags, createdTime); 7060 } 7061 } else { 7062 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7063 + " but instead found " + pi); 7064 } 7065 } 7066 } 7067 } 7068 } catch (FileNotFoundException e) { 7069 // Missing grants is okay 7070 } catch (IOException e) { 7071 Log.wtf(TAG, "Failed reading Uri grants", e); 7072 } catch (XmlPullParserException e) { 7073 Log.wtf(TAG, "Failed reading Uri grants", e); 7074 } finally { 7075 IoUtils.closeQuietly(fis); 7076 } 7077 } 7078 7079 @Override 7080 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7081 enforceNotIsolatedCaller("takePersistableUriPermission"); 7082 7083 Preconditions.checkFlagsArgument(modeFlags, 7084 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7085 7086 synchronized (this) { 7087 final int callingUid = Binder.getCallingUid(); 7088 boolean persistChanged = false; 7089 GrantUri grantUri = new GrantUri(userId, uri, false); 7090 7091 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7092 new GrantUri(userId, uri, false)); 7093 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7094 new GrantUri(userId, uri, true)); 7095 7096 final boolean exactValid = (exactPerm != null) 7097 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7098 final boolean prefixValid = (prefixPerm != null) 7099 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7100 7101 if (!(exactValid || prefixValid)) { 7102 throw new SecurityException("No persistable permission grants found for UID " 7103 + callingUid + " and Uri " + grantUri.toSafeString()); 7104 } 7105 7106 if (exactValid) { 7107 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7108 } 7109 if (prefixValid) { 7110 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7111 } 7112 7113 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7114 7115 if (persistChanged) { 7116 schedulePersistUriGrants(); 7117 } 7118 } 7119 } 7120 7121 @Override 7122 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7123 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7124 7125 Preconditions.checkFlagsArgument(modeFlags, 7126 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7127 7128 synchronized (this) { 7129 final int callingUid = Binder.getCallingUid(); 7130 boolean persistChanged = false; 7131 7132 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7133 new GrantUri(userId, uri, false)); 7134 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7135 new GrantUri(userId, uri, true)); 7136 if (exactPerm == null && prefixPerm == null) { 7137 throw new SecurityException("No permission grants found for UID " + callingUid 7138 + " and Uri " + uri.toSafeString()); 7139 } 7140 7141 if (exactPerm != null) { 7142 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7143 removeUriPermissionIfNeededLocked(exactPerm); 7144 } 7145 if (prefixPerm != null) { 7146 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7147 removeUriPermissionIfNeededLocked(prefixPerm); 7148 } 7149 7150 if (persistChanged) { 7151 schedulePersistUriGrants(); 7152 } 7153 } 7154 } 7155 7156 /** 7157 * Prune any older {@link UriPermission} for the given UID until outstanding 7158 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7159 * 7160 * @return if any mutations occured that require persisting. 7161 */ 7162 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7163 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7164 if (perms == null) return false; 7165 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7166 7167 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7168 for (UriPermission perm : perms.values()) { 7169 if (perm.persistedModeFlags != 0) { 7170 persisted.add(perm); 7171 } 7172 } 7173 7174 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7175 if (trimCount <= 0) return false; 7176 7177 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7178 for (int i = 0; i < trimCount; i++) { 7179 final UriPermission perm = persisted.get(i); 7180 7181 if (DEBUG_URI_PERMISSION) { 7182 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7183 } 7184 7185 perm.releasePersistableModes(~0); 7186 removeUriPermissionIfNeededLocked(perm); 7187 } 7188 7189 return true; 7190 } 7191 7192 @Override 7193 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7194 String packageName, boolean incoming) { 7195 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7196 Preconditions.checkNotNull(packageName, "packageName"); 7197 7198 final int callingUid = Binder.getCallingUid(); 7199 final IPackageManager pm = AppGlobals.getPackageManager(); 7200 try { 7201 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7202 if (packageUid != callingUid) { 7203 throw new SecurityException( 7204 "Package " + packageName + " does not belong to calling UID " + callingUid); 7205 } 7206 } catch (RemoteException e) { 7207 throw new SecurityException("Failed to verify package name ownership"); 7208 } 7209 7210 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7211 synchronized (this) { 7212 if (incoming) { 7213 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7214 callingUid); 7215 if (perms == null) { 7216 Slog.w(TAG, "No permission grants found for " + packageName); 7217 } else { 7218 for (UriPermission perm : perms.values()) { 7219 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7220 result.add(perm.buildPersistedPublicApiObject()); 7221 } 7222 } 7223 } 7224 } else { 7225 final int size = mGrantedUriPermissions.size(); 7226 for (int i = 0; i < size; i++) { 7227 final ArrayMap<GrantUri, UriPermission> perms = 7228 mGrantedUriPermissions.valueAt(i); 7229 for (UriPermission perm : perms.values()) { 7230 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7231 result.add(perm.buildPersistedPublicApiObject()); 7232 } 7233 } 7234 } 7235 } 7236 } 7237 return new ParceledListSlice<android.content.UriPermission>(result); 7238 } 7239 7240 @Override 7241 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7242 synchronized (this) { 7243 ProcessRecord app = 7244 who != null ? getRecordForAppLocked(who) : null; 7245 if (app == null) return; 7246 7247 Message msg = Message.obtain(); 7248 msg.what = WAIT_FOR_DEBUGGER_MSG; 7249 msg.obj = app; 7250 msg.arg1 = waiting ? 1 : 0; 7251 mHandler.sendMessage(msg); 7252 } 7253 } 7254 7255 @Override 7256 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7257 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7258 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7259 outInfo.availMem = Process.getFreeMemory(); 7260 outInfo.totalMem = Process.getTotalMemory(); 7261 outInfo.threshold = homeAppMem; 7262 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7263 outInfo.hiddenAppThreshold = cachedAppMem; 7264 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7265 ProcessList.SERVICE_ADJ); 7266 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7267 ProcessList.VISIBLE_APP_ADJ); 7268 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7269 ProcessList.FOREGROUND_APP_ADJ); 7270 } 7271 7272 // ========================================================= 7273 // TASK MANAGEMENT 7274 // ========================================================= 7275 7276 @Override 7277 public List<IAppTask> getAppTasks() { 7278 final PackageManager pm = mContext.getPackageManager(); 7279 int callingUid = Binder.getCallingUid(); 7280 long ident = Binder.clearCallingIdentity(); 7281 7282 // Compose the list of packages for this id to test against 7283 HashSet<String> packages = new HashSet<String>(); 7284 String[] uidPackages = pm.getPackagesForUid(callingUid); 7285 for (int i = 0; i < uidPackages.length; i++) { 7286 packages.add(uidPackages[i]); 7287 } 7288 7289 synchronized(this) { 7290 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7291 try { 7292 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7293 7294 final int N = mRecentTasks.size(); 7295 for (int i = 0; i < N; i++) { 7296 TaskRecord tr = mRecentTasks.get(i); 7297 // Skip tasks that are not created by the caller 7298 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7299 ActivityManager.RecentTaskInfo taskInfo = 7300 createRecentTaskInfoFromTaskRecord(tr); 7301 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7302 list.add(taskImpl); 7303 } 7304 } 7305 } finally { 7306 Binder.restoreCallingIdentity(ident); 7307 } 7308 return list; 7309 } 7310 } 7311 7312 @Override 7313 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7314 final int callingUid = Binder.getCallingUid(); 7315 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7316 7317 synchronized(this) { 7318 if (localLOGV) Slog.v( 7319 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7320 7321 final boolean allowed = checkCallingPermission( 7322 android.Manifest.permission.GET_TASKS) 7323 == PackageManager.PERMISSION_GRANTED; 7324 if (!allowed) { 7325 Slog.w(TAG, "getTasks: caller " + callingUid 7326 + " does not hold GET_TASKS; limiting output"); 7327 } 7328 7329 // TODO: Improve with MRU list from all ActivityStacks. 7330 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7331 } 7332 7333 return list; 7334 } 7335 7336 TaskRecord getMostRecentTask() { 7337 return mRecentTasks.get(0); 7338 } 7339 7340 /** 7341 * Creates a new RecentTaskInfo from a TaskRecord. 7342 */ 7343 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7344 // Update the task description to reflect any changes in the task stack 7345 tr.updateTaskDescription(); 7346 7347 // Compose the recent task info 7348 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7349 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7350 rti.persistentId = tr.taskId; 7351 rti.baseIntent = new Intent(tr.getBaseIntent()); 7352 rti.origActivity = tr.origActivity; 7353 rti.description = tr.lastDescription; 7354 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7355 rti.userId = tr.userId; 7356 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7357 rti.firstActiveTime = tr.firstActiveTime; 7358 rti.lastActiveTime = tr.lastActiveTime; 7359 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7360 return rti; 7361 } 7362 7363 @Override 7364 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7365 final int callingUid = Binder.getCallingUid(); 7366 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7367 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7368 7369 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7370 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7371 synchronized (this) { 7372 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7373 == PackageManager.PERMISSION_GRANTED; 7374 if (!allowed) { 7375 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7376 + " does not hold GET_TASKS; limiting output"); 7377 } 7378 final boolean detailed = checkCallingPermission( 7379 android.Manifest.permission.GET_DETAILED_TASKS) 7380 == PackageManager.PERMISSION_GRANTED; 7381 7382 IPackageManager pm = AppGlobals.getPackageManager(); 7383 7384 final int N = mRecentTasks.size(); 7385 ArrayList<ActivityManager.RecentTaskInfo> res 7386 = new ArrayList<ActivityManager.RecentTaskInfo>( 7387 maxNum < N ? maxNum : N); 7388 7389 final Set<Integer> includedUsers; 7390 if (includeProfiles) { 7391 includedUsers = getProfileIdsLocked(userId); 7392 } else { 7393 includedUsers = new HashSet<Integer>(); 7394 } 7395 includedUsers.add(Integer.valueOf(userId)); 7396 7397 // Regroup affiliated tasks together. 7398 for (int i = 0; i < N; ) { 7399 TaskRecord task = mRecentTasks.remove(i); 7400 if (mTmpRecents.contains(task)) { 7401 continue; 7402 } 7403 int affiliatedTaskId = task.mAffiliatedTaskId; 7404 while (true) { 7405 TaskRecord next = task.mNextAffiliate; 7406 if (next == null) { 7407 break; 7408 } 7409 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7410 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7411 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7412 task.setNextAffiliate(null); 7413 if (next.mPrevAffiliate == task) { 7414 next.setPrevAffiliate(null); 7415 } 7416 break; 7417 } 7418 if (next.mPrevAffiliate != task) { 7419 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7420 next.mPrevAffiliate + " task=" + task); 7421 next.setPrevAffiliate(null); 7422 break; 7423 } 7424 if (!mRecentTasks.contains(next)) { 7425 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7426 task.setNextAffiliate(null); 7427 if (next.mPrevAffiliate == task) { 7428 next.setPrevAffiliate(null); 7429 } 7430 break; 7431 } 7432 task = next; 7433 } 7434 // task is now the end of the list 7435 do { 7436 mRecentTasks.remove(task); 7437 mRecentTasks.add(i++, task); 7438 mTmpRecents.add(task); 7439 } while ((task = task.mPrevAffiliate) != null); 7440 } 7441 mTmpRecents.clear(); 7442 // mRecentTasks is now in sorted, affiliated order. 7443 7444 for (int i=0; i<N && maxNum > 0; i++) { 7445 TaskRecord tr = mRecentTasks.get(i); 7446 // Only add calling user or related users recent tasks 7447 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7448 7449 // Return the entry if desired by the caller. We always return 7450 // the first entry, because callers always expect this to be the 7451 // foreground app. We may filter others if the caller has 7452 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7453 // we should exclude the entry. 7454 7455 if (i == 0 7456 || withExcluded 7457 || (tr.intent == null) 7458 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7459 == 0)) { 7460 if (!allowed) { 7461 // If the caller doesn't have the GET_TASKS permission, then only 7462 // allow them to see a small subset of tasks -- their own and home. 7463 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7464 continue; 7465 } 7466 } 7467 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7468 // Don't include auto remove tasks that are finished or finishing. 7469 continue; 7470 } 7471 7472 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7473 if (!detailed) { 7474 rti.baseIntent.replaceExtras((Bundle)null); 7475 } 7476 7477 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7478 // Check whether this activity is currently available. 7479 try { 7480 if (rti.origActivity != null) { 7481 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7482 == null) { 7483 continue; 7484 } 7485 } else if (rti.baseIntent != null) { 7486 if (pm.queryIntentActivities(rti.baseIntent, 7487 null, 0, userId) == null) { 7488 continue; 7489 } 7490 } 7491 } catch (RemoteException e) { 7492 // Will never happen. 7493 } 7494 } 7495 7496 res.add(rti); 7497 maxNum--; 7498 } 7499 } 7500 return res; 7501 } 7502 } 7503 7504 private TaskRecord recentTaskForIdLocked(int id) { 7505 final int N = mRecentTasks.size(); 7506 for (int i=0; i<N; i++) { 7507 TaskRecord tr = mRecentTasks.get(i); 7508 if (tr.taskId == id) { 7509 return tr; 7510 } 7511 } 7512 return null; 7513 } 7514 7515 @Override 7516 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7517 synchronized (this) { 7518 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7519 "getTaskThumbnail()"); 7520 TaskRecord tr = recentTaskForIdLocked(id); 7521 if (tr != null) { 7522 return tr.getTaskThumbnailLocked(); 7523 } 7524 } 7525 return null; 7526 } 7527 7528 @Override 7529 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7530 synchronized (this) { 7531 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7532 if (r != null) { 7533 r.taskDescription = td; 7534 r.task.updateTaskDescription(); 7535 } 7536 } 7537 } 7538 7539 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7540 if (!pr.killedByAm) { 7541 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7542 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7543 pr.processName, pr.setAdj, reason); 7544 pr.killedByAm = true; 7545 Process.killProcessQuiet(pr.pid); 7546 Process.killProcessGroup(pr.info.uid, pr.pid); 7547 } 7548 } 7549 7550 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7551 tr.disposeThumbnail(); 7552 mRecentTasks.remove(tr); 7553 tr.closeRecentsChain(); 7554 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7555 Intent baseIntent = new Intent( 7556 tr.intent != null ? tr.intent : tr.affinityIntent); 7557 ComponentName component = baseIntent.getComponent(); 7558 if (component == null) { 7559 Slog.w(TAG, "Now component for base intent of task: " + tr); 7560 return; 7561 } 7562 7563 // Find any running services associated with this app. 7564 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7565 7566 if (killProcesses) { 7567 // Find any running processes associated with this app. 7568 final String pkg = component.getPackageName(); 7569 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7570 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7571 for (int i=0; i<pmap.size(); i++) { 7572 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7573 for (int j=0; j<uids.size(); j++) { 7574 ProcessRecord proc = uids.valueAt(j); 7575 if (proc.userId != tr.userId) { 7576 continue; 7577 } 7578 if (!proc.pkgList.containsKey(pkg)) { 7579 continue; 7580 } 7581 procs.add(proc); 7582 } 7583 } 7584 7585 // Kill the running processes. 7586 for (int i=0; i<procs.size(); i++) { 7587 ProcessRecord pr = procs.get(i); 7588 if (pr == mHomeProcess) { 7589 // Don't kill the home process along with tasks from the same package. 7590 continue; 7591 } 7592 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7593 killUnneededProcessLocked(pr, "remove task"); 7594 } else { 7595 pr.waitingToKill = "remove task"; 7596 } 7597 } 7598 } 7599 } 7600 7601 /** 7602 * Removes the task with the specified task id. 7603 * 7604 * @param taskId Identifier of the task to be removed. 7605 * @param flags Additional operational flags. May be 0 or 7606 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7607 * @return Returns true if the given task was found and removed. 7608 */ 7609 private boolean removeTaskByIdLocked(int taskId, int flags) { 7610 TaskRecord tr = recentTaskForIdLocked(taskId); 7611 if (tr != null) { 7612 tr.removeTaskActivitiesLocked(); 7613 cleanUpRemovedTaskLocked(tr, flags); 7614 if (tr.isPersistable) { 7615 notifyTaskPersisterLocked(tr, true); 7616 } 7617 return true; 7618 } 7619 return false; 7620 } 7621 7622 @Override 7623 public boolean removeTask(int taskId, int flags) { 7624 synchronized (this) { 7625 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7626 "removeTask()"); 7627 long ident = Binder.clearCallingIdentity(); 7628 try { 7629 return removeTaskByIdLocked(taskId, flags); 7630 } finally { 7631 Binder.restoreCallingIdentity(ident); 7632 } 7633 } 7634 } 7635 7636 /** 7637 * TODO: Add mController hook 7638 */ 7639 @Override 7640 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7641 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7642 "moveTaskToFront()"); 7643 7644 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7645 synchronized(this) { 7646 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7647 Binder.getCallingUid(), "Task to front")) { 7648 ActivityOptions.abort(options); 7649 return; 7650 } 7651 final long origId = Binder.clearCallingIdentity(); 7652 try { 7653 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7654 if (task == null) { 7655 return; 7656 } 7657 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7658 mStackSupervisor.showLockTaskToast(); 7659 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7660 return; 7661 } 7662 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7663 if (prev != null && prev.isRecentsActivity()) { 7664 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7665 } 7666 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7667 } finally { 7668 Binder.restoreCallingIdentity(origId); 7669 } 7670 ActivityOptions.abort(options); 7671 } 7672 } 7673 7674 @Override 7675 public void moveTaskToBack(int taskId) { 7676 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7677 "moveTaskToBack()"); 7678 7679 synchronized(this) { 7680 TaskRecord tr = recentTaskForIdLocked(taskId); 7681 if (tr != null) { 7682 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7683 ActivityStack stack = tr.stack; 7684 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7685 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7686 Binder.getCallingUid(), "Task to back")) { 7687 return; 7688 } 7689 } 7690 final long origId = Binder.clearCallingIdentity(); 7691 try { 7692 stack.moveTaskToBackLocked(taskId, null); 7693 } finally { 7694 Binder.restoreCallingIdentity(origId); 7695 } 7696 } 7697 } 7698 } 7699 7700 /** 7701 * Moves an activity, and all of the other activities within the same task, to the bottom 7702 * of the history stack. The activity's order within the task is unchanged. 7703 * 7704 * @param token A reference to the activity we wish to move 7705 * @param nonRoot If false then this only works if the activity is the root 7706 * of a task; if true it will work for any activity in a task. 7707 * @return Returns true if the move completed, false if not. 7708 */ 7709 @Override 7710 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7711 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7712 synchronized(this) { 7713 final long origId = Binder.clearCallingIdentity(); 7714 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7715 if (taskId >= 0) { 7716 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7717 } 7718 Binder.restoreCallingIdentity(origId); 7719 } 7720 return false; 7721 } 7722 7723 @Override 7724 public void moveTaskBackwards(int task) { 7725 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7726 "moveTaskBackwards()"); 7727 7728 synchronized(this) { 7729 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7730 Binder.getCallingUid(), "Task backwards")) { 7731 return; 7732 } 7733 final long origId = Binder.clearCallingIdentity(); 7734 moveTaskBackwardsLocked(task); 7735 Binder.restoreCallingIdentity(origId); 7736 } 7737 } 7738 7739 private final void moveTaskBackwardsLocked(int task) { 7740 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7741 } 7742 7743 @Override 7744 public IBinder getHomeActivityToken() throws RemoteException { 7745 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7746 "getHomeActivityToken()"); 7747 synchronized (this) { 7748 return mStackSupervisor.getHomeActivityToken(); 7749 } 7750 } 7751 7752 @Override 7753 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7754 IActivityContainerCallback callback) throws RemoteException { 7755 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7756 "createActivityContainer()"); 7757 synchronized (this) { 7758 if (parentActivityToken == null) { 7759 throw new IllegalArgumentException("parent token must not be null"); 7760 } 7761 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7762 if (r == null) { 7763 return null; 7764 } 7765 if (callback == null) { 7766 throw new IllegalArgumentException("callback must not be null"); 7767 } 7768 return mStackSupervisor.createActivityContainer(r, callback); 7769 } 7770 } 7771 7772 @Override 7773 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7774 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7775 "deleteActivityContainer()"); 7776 synchronized (this) { 7777 mStackSupervisor.deleteActivityContainer(container); 7778 } 7779 } 7780 7781 @Override 7782 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7783 throws RemoteException { 7784 synchronized (this) { 7785 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7786 if (stack != null) { 7787 return stack.mActivityContainer; 7788 } 7789 return null; 7790 } 7791 } 7792 7793 @Override 7794 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7795 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7796 "moveTaskToStack()"); 7797 if (stackId == HOME_STACK_ID) { 7798 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7799 new RuntimeException("here").fillInStackTrace()); 7800 } 7801 synchronized (this) { 7802 long ident = Binder.clearCallingIdentity(); 7803 try { 7804 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7805 + stackId + " toTop=" + toTop); 7806 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7807 } finally { 7808 Binder.restoreCallingIdentity(ident); 7809 } 7810 } 7811 } 7812 7813 @Override 7814 public void resizeStack(int stackBoxId, Rect bounds) { 7815 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7816 "resizeStackBox()"); 7817 long ident = Binder.clearCallingIdentity(); 7818 try { 7819 mWindowManager.resizeStack(stackBoxId, bounds); 7820 } finally { 7821 Binder.restoreCallingIdentity(ident); 7822 } 7823 } 7824 7825 @Override 7826 public List<StackInfo> getAllStackInfos() { 7827 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7828 "getAllStackInfos()"); 7829 long ident = Binder.clearCallingIdentity(); 7830 try { 7831 synchronized (this) { 7832 return mStackSupervisor.getAllStackInfosLocked(); 7833 } 7834 } finally { 7835 Binder.restoreCallingIdentity(ident); 7836 } 7837 } 7838 7839 @Override 7840 public StackInfo getStackInfo(int stackId) { 7841 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7842 "getStackInfo()"); 7843 long ident = Binder.clearCallingIdentity(); 7844 try { 7845 synchronized (this) { 7846 return mStackSupervisor.getStackInfoLocked(stackId); 7847 } 7848 } finally { 7849 Binder.restoreCallingIdentity(ident); 7850 } 7851 } 7852 7853 @Override 7854 public boolean isInHomeStack(int taskId) { 7855 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7856 "getStackInfo()"); 7857 long ident = Binder.clearCallingIdentity(); 7858 try { 7859 synchronized (this) { 7860 TaskRecord tr = recentTaskForIdLocked(taskId); 7861 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7862 } 7863 } finally { 7864 Binder.restoreCallingIdentity(ident); 7865 } 7866 } 7867 7868 @Override 7869 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7870 synchronized(this) { 7871 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7872 } 7873 } 7874 7875 private boolean isLockTaskAuthorized(String pkg) { 7876 final DevicePolicyManager dpm = (DevicePolicyManager) 7877 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7878 try { 7879 int uid = mContext.getPackageManager().getPackageUid(pkg, 7880 Binder.getCallingUserHandle().getIdentifier()); 7881 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7882 } catch (NameNotFoundException e) { 7883 return false; 7884 } 7885 } 7886 7887 void startLockTaskMode(TaskRecord task) { 7888 final String pkg; 7889 synchronized (this) { 7890 pkg = task.intent.getComponent().getPackageName(); 7891 } 7892 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7893 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7894 final TaskRecord taskRecord = task; 7895 mHandler.post(new Runnable() { 7896 @Override 7897 public void run() { 7898 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7899 } 7900 }); 7901 return; 7902 } 7903 long ident = Binder.clearCallingIdentity(); 7904 try { 7905 synchronized (this) { 7906 // Since we lost lock on task, make sure it is still there. 7907 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7908 if (task != null) { 7909 if (!isSystemInitiated 7910 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7911 throw new IllegalArgumentException("Invalid task, not in foreground"); 7912 } 7913 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7914 } 7915 } 7916 } finally { 7917 Binder.restoreCallingIdentity(ident); 7918 } 7919 } 7920 7921 @Override 7922 public void startLockTaskMode(int taskId) { 7923 final TaskRecord task; 7924 long ident = Binder.clearCallingIdentity(); 7925 try { 7926 synchronized (this) { 7927 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7928 } 7929 } finally { 7930 Binder.restoreCallingIdentity(ident); 7931 } 7932 if (task != null) { 7933 startLockTaskMode(task); 7934 } 7935 } 7936 7937 @Override 7938 public void startLockTaskMode(IBinder token) { 7939 final TaskRecord task; 7940 long ident = Binder.clearCallingIdentity(); 7941 try { 7942 synchronized (this) { 7943 final ActivityRecord r = ActivityRecord.forToken(token); 7944 if (r == null) { 7945 return; 7946 } 7947 task = r.task; 7948 } 7949 } finally { 7950 Binder.restoreCallingIdentity(ident); 7951 } 7952 if (task != null) { 7953 startLockTaskMode(task); 7954 } 7955 } 7956 7957 @Override 7958 public void startLockTaskModeOnCurrent() throws RemoteException { 7959 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7960 ActivityRecord r = null; 7961 synchronized (this) { 7962 r = mStackSupervisor.topRunningActivityLocked(); 7963 } 7964 startLockTaskMode(r.task); 7965 } 7966 7967 @Override 7968 public void stopLockTaskMode() { 7969 // Verify that the user matches the package of the intent for the TaskRecord 7970 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7971 // and stopLockTaskMode. 7972 final int callingUid = Binder.getCallingUid(); 7973 if (callingUid != Process.SYSTEM_UID) { 7974 try { 7975 String pkg = 7976 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7977 int uid = mContext.getPackageManager().getPackageUid(pkg, 7978 Binder.getCallingUserHandle().getIdentifier()); 7979 if (uid != callingUid) { 7980 throw new SecurityException("Invalid uid, expected " + uid); 7981 } 7982 } catch (NameNotFoundException e) { 7983 Log.d(TAG, "stopLockTaskMode " + e); 7984 return; 7985 } 7986 } 7987 long ident = Binder.clearCallingIdentity(); 7988 try { 7989 Log.d(TAG, "stopLockTaskMode"); 7990 // Stop lock task 7991 synchronized (this) { 7992 mStackSupervisor.setLockTaskModeLocked(null, false); 7993 } 7994 } finally { 7995 Binder.restoreCallingIdentity(ident); 7996 } 7997 } 7998 7999 @Override 8000 public void stopLockTaskModeOnCurrent() throws RemoteException { 8001 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8002 long ident = Binder.clearCallingIdentity(); 8003 try { 8004 stopLockTaskMode(); 8005 } finally { 8006 Binder.restoreCallingIdentity(ident); 8007 } 8008 } 8009 8010 @Override 8011 public boolean isInLockTaskMode() { 8012 synchronized (this) { 8013 return mStackSupervisor.isInLockTaskMode(); 8014 } 8015 } 8016 8017 // ========================================================= 8018 // CONTENT PROVIDERS 8019 // ========================================================= 8020 8021 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8022 List<ProviderInfo> providers = null; 8023 try { 8024 providers = AppGlobals.getPackageManager(). 8025 queryContentProviders(app.processName, app.uid, 8026 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8027 } catch (RemoteException ex) { 8028 } 8029 if (DEBUG_MU) 8030 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8031 int userId = app.userId; 8032 if (providers != null) { 8033 int N = providers.size(); 8034 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8035 for (int i=0; i<N; i++) { 8036 ProviderInfo cpi = 8037 (ProviderInfo)providers.get(i); 8038 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8039 cpi.name, cpi.flags); 8040 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8041 // This is a singleton provider, but a user besides the 8042 // default user is asking to initialize a process it runs 8043 // in... well, no, it doesn't actually run in this process, 8044 // it runs in the process of the default user. Get rid of it. 8045 providers.remove(i); 8046 N--; 8047 i--; 8048 continue; 8049 } 8050 8051 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8052 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8053 if (cpr == null) { 8054 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8055 mProviderMap.putProviderByClass(comp, cpr); 8056 } 8057 if (DEBUG_MU) 8058 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8059 app.pubProviders.put(cpi.name, cpr); 8060 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8061 // Don't add this if it is a platform component that is marked 8062 // to run in multiple processes, because this is actually 8063 // part of the framework so doesn't make sense to track as a 8064 // separate apk in the process. 8065 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8066 mProcessStats); 8067 } 8068 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8069 } 8070 } 8071 return providers; 8072 } 8073 8074 /** 8075 * Check if {@link ProcessRecord} has a possible chance at accessing the 8076 * given {@link ProviderInfo}. Final permission checking is always done 8077 * in {@link ContentProvider}. 8078 */ 8079 private final String checkContentProviderPermissionLocked( 8080 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8081 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8082 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8083 boolean checkedGrants = false; 8084 if (checkUser) { 8085 // Looking for cross-user grants before enforcing the typical cross-users permissions 8086 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8087 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8088 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8089 return null; 8090 } 8091 checkedGrants = true; 8092 } 8093 userId = handleIncomingUser(callingPid, callingUid, userId, 8094 false, ALLOW_NON_FULL, 8095 "checkContentProviderPermissionLocked " + cpi.authority, null); 8096 if (userId != tmpTargetUserId) { 8097 // When we actually went to determine the final targer user ID, this ended 8098 // up different than our initial check for the authority. This is because 8099 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8100 // SELF. So we need to re-check the grants again. 8101 checkedGrants = false; 8102 } 8103 } 8104 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8105 cpi.applicationInfo.uid, cpi.exported) 8106 == PackageManager.PERMISSION_GRANTED) { 8107 return null; 8108 } 8109 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8110 cpi.applicationInfo.uid, cpi.exported) 8111 == PackageManager.PERMISSION_GRANTED) { 8112 return null; 8113 } 8114 8115 PathPermission[] pps = cpi.pathPermissions; 8116 if (pps != null) { 8117 int i = pps.length; 8118 while (i > 0) { 8119 i--; 8120 PathPermission pp = pps[i]; 8121 String pprperm = pp.getReadPermission(); 8122 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8123 cpi.applicationInfo.uid, cpi.exported) 8124 == PackageManager.PERMISSION_GRANTED) { 8125 return null; 8126 } 8127 String ppwperm = pp.getWritePermission(); 8128 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8129 cpi.applicationInfo.uid, cpi.exported) 8130 == PackageManager.PERMISSION_GRANTED) { 8131 return null; 8132 } 8133 } 8134 } 8135 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8136 return null; 8137 } 8138 8139 String msg; 8140 if (!cpi.exported) { 8141 msg = "Permission Denial: opening provider " + cpi.name 8142 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8143 + ", uid=" + callingUid + ") that is not exported from uid " 8144 + cpi.applicationInfo.uid; 8145 } else { 8146 msg = "Permission Denial: opening provider " + cpi.name 8147 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8148 + ", uid=" + callingUid + ") requires " 8149 + cpi.readPermission + " or " + cpi.writePermission; 8150 } 8151 Slog.w(TAG, msg); 8152 return msg; 8153 } 8154 8155 /** 8156 * Returns if the ContentProvider has granted a uri to callingUid 8157 */ 8158 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8159 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8160 if (perms != null) { 8161 for (int i=perms.size()-1; i>=0; i--) { 8162 GrantUri grantUri = perms.keyAt(i); 8163 if (grantUri.sourceUserId == userId || !checkUser) { 8164 if (matchesProvider(grantUri.uri, cpi)) { 8165 return true; 8166 } 8167 } 8168 } 8169 } 8170 return false; 8171 } 8172 8173 /** 8174 * Returns true if the uri authority is one of the authorities specified in the provider. 8175 */ 8176 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8177 String uriAuth = uri.getAuthority(); 8178 String cpiAuth = cpi.authority; 8179 if (cpiAuth.indexOf(';') == -1) { 8180 return cpiAuth.equals(uriAuth); 8181 } 8182 String[] cpiAuths = cpiAuth.split(";"); 8183 int length = cpiAuths.length; 8184 for (int i = 0; i < length; i++) { 8185 if (cpiAuths[i].equals(uriAuth)) return true; 8186 } 8187 return false; 8188 } 8189 8190 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8191 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8192 if (r != null) { 8193 for (int i=0; i<r.conProviders.size(); i++) { 8194 ContentProviderConnection conn = r.conProviders.get(i); 8195 if (conn.provider == cpr) { 8196 if (DEBUG_PROVIDER) Slog.v(TAG, 8197 "Adding provider requested by " 8198 + r.processName + " from process " 8199 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8200 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8201 if (stable) { 8202 conn.stableCount++; 8203 conn.numStableIncs++; 8204 } else { 8205 conn.unstableCount++; 8206 conn.numUnstableIncs++; 8207 } 8208 return conn; 8209 } 8210 } 8211 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8212 if (stable) { 8213 conn.stableCount = 1; 8214 conn.numStableIncs = 1; 8215 } else { 8216 conn.unstableCount = 1; 8217 conn.numUnstableIncs = 1; 8218 } 8219 cpr.connections.add(conn); 8220 r.conProviders.add(conn); 8221 return conn; 8222 } 8223 cpr.addExternalProcessHandleLocked(externalProcessToken); 8224 return null; 8225 } 8226 8227 boolean decProviderCountLocked(ContentProviderConnection conn, 8228 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8229 if (conn != null) { 8230 cpr = conn.provider; 8231 if (DEBUG_PROVIDER) Slog.v(TAG, 8232 "Removing provider requested by " 8233 + conn.client.processName + " from process " 8234 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8235 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8236 if (stable) { 8237 conn.stableCount--; 8238 } else { 8239 conn.unstableCount--; 8240 } 8241 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8242 cpr.connections.remove(conn); 8243 conn.client.conProviders.remove(conn); 8244 return true; 8245 } 8246 return false; 8247 } 8248 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8249 return false; 8250 } 8251 8252 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8253 String name, IBinder token, boolean stable, int userId) { 8254 ContentProviderRecord cpr; 8255 ContentProviderConnection conn = null; 8256 ProviderInfo cpi = null; 8257 8258 synchronized(this) { 8259 ProcessRecord r = null; 8260 if (caller != null) { 8261 r = getRecordForAppLocked(caller); 8262 if (r == null) { 8263 throw new SecurityException( 8264 "Unable to find app for caller " + caller 8265 + " (pid=" + Binder.getCallingPid() 8266 + ") when getting content provider " + name); 8267 } 8268 } 8269 8270 boolean checkCrossUser = true; 8271 8272 // First check if this content provider has been published... 8273 cpr = mProviderMap.getProviderByName(name, userId); 8274 // If that didn't work, check if it exists for user 0 and then 8275 // verify that it's a singleton provider before using it. 8276 if (cpr == null && userId != UserHandle.USER_OWNER) { 8277 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8278 if (cpr != null) { 8279 cpi = cpr.info; 8280 if (isSingleton(cpi.processName, cpi.applicationInfo, 8281 cpi.name, cpi.flags) 8282 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8283 userId = UserHandle.USER_OWNER; 8284 checkCrossUser = false; 8285 } else { 8286 cpr = null; 8287 cpi = null; 8288 } 8289 } 8290 } 8291 8292 boolean providerRunning = cpr != null; 8293 if (providerRunning) { 8294 cpi = cpr.info; 8295 String msg; 8296 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8297 != null) { 8298 throw new SecurityException(msg); 8299 } 8300 8301 if (r != null && cpr.canRunHere(r)) { 8302 // This provider has been published or is in the process 8303 // of being published... but it is also allowed to run 8304 // in the caller's process, so don't make a connection 8305 // and just let the caller instantiate its own instance. 8306 ContentProviderHolder holder = cpr.newHolder(null); 8307 // don't give caller the provider object, it needs 8308 // to make its own. 8309 holder.provider = null; 8310 return holder; 8311 } 8312 8313 final long origId = Binder.clearCallingIdentity(); 8314 8315 // In this case the provider instance already exists, so we can 8316 // return it right away. 8317 conn = incProviderCountLocked(r, cpr, token, stable); 8318 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8319 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8320 // If this is a perceptible app accessing the provider, 8321 // make sure to count it as being accessed and thus 8322 // back up on the LRU list. This is good because 8323 // content providers are often expensive to start. 8324 updateLruProcessLocked(cpr.proc, false, null); 8325 } 8326 } 8327 8328 if (cpr.proc != null) { 8329 if (false) { 8330 if (cpr.name.flattenToShortString().equals( 8331 "com.android.providers.calendar/.CalendarProvider2")) { 8332 Slog.v(TAG, "****************** KILLING " 8333 + cpr.name.flattenToShortString()); 8334 Process.killProcess(cpr.proc.pid); 8335 } 8336 } 8337 boolean success = updateOomAdjLocked(cpr.proc); 8338 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8339 // NOTE: there is still a race here where a signal could be 8340 // pending on the process even though we managed to update its 8341 // adj level. Not sure what to do about this, but at least 8342 // the race is now smaller. 8343 if (!success) { 8344 // Uh oh... it looks like the provider's process 8345 // has been killed on us. We need to wait for a new 8346 // process to be started, and make sure its death 8347 // doesn't kill our process. 8348 Slog.i(TAG, 8349 "Existing provider " + cpr.name.flattenToShortString() 8350 + " is crashing; detaching " + r); 8351 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8352 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8353 if (!lastRef) { 8354 // This wasn't the last ref our process had on 8355 // the provider... we have now been killed, bail. 8356 return null; 8357 } 8358 providerRunning = false; 8359 conn = null; 8360 } 8361 } 8362 8363 Binder.restoreCallingIdentity(origId); 8364 } 8365 8366 boolean singleton; 8367 if (!providerRunning) { 8368 try { 8369 cpi = AppGlobals.getPackageManager(). 8370 resolveContentProvider(name, 8371 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8372 } catch (RemoteException ex) { 8373 } 8374 if (cpi == null) { 8375 return null; 8376 } 8377 // If the provider is a singleton AND 8378 // (it's a call within the same user || the provider is a 8379 // privileged app) 8380 // Then allow connecting to the singleton provider 8381 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8382 cpi.name, cpi.flags) 8383 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8384 if (singleton) { 8385 userId = UserHandle.USER_OWNER; 8386 } 8387 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8388 8389 String msg; 8390 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8391 != null) { 8392 throw new SecurityException(msg); 8393 } 8394 8395 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8396 && !cpi.processName.equals("system")) { 8397 // If this content provider does not run in the system 8398 // process, and the system is not yet ready to run other 8399 // processes, then fail fast instead of hanging. 8400 throw new IllegalArgumentException( 8401 "Attempt to launch content provider before system ready"); 8402 } 8403 8404 // Make sure that the user who owns this provider is started. If not, 8405 // we don't want to allow it to run. 8406 if (mStartedUsers.get(userId) == null) { 8407 Slog.w(TAG, "Unable to launch app " 8408 + cpi.applicationInfo.packageName + "/" 8409 + cpi.applicationInfo.uid + " for provider " 8410 + name + ": user " + userId + " is stopped"); 8411 return null; 8412 } 8413 8414 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8415 cpr = mProviderMap.getProviderByClass(comp, userId); 8416 final boolean firstClass = cpr == null; 8417 if (firstClass) { 8418 try { 8419 ApplicationInfo ai = 8420 AppGlobals.getPackageManager(). 8421 getApplicationInfo( 8422 cpi.applicationInfo.packageName, 8423 STOCK_PM_FLAGS, userId); 8424 if (ai == null) { 8425 Slog.w(TAG, "No package info for content provider " 8426 + cpi.name); 8427 return null; 8428 } 8429 ai = getAppInfoForUser(ai, userId); 8430 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8431 } catch (RemoteException ex) { 8432 // pm is in same process, this will never happen. 8433 } 8434 } 8435 8436 if (r != null && cpr.canRunHere(r)) { 8437 // If this is a multiprocess provider, then just return its 8438 // info and allow the caller to instantiate it. Only do 8439 // this if the provider is the same user as the caller's 8440 // process, or can run as root (so can be in any process). 8441 return cpr.newHolder(null); 8442 } 8443 8444 if (DEBUG_PROVIDER) { 8445 RuntimeException e = new RuntimeException("here"); 8446 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8447 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8448 } 8449 8450 // This is single process, and our app is now connecting to it. 8451 // See if we are already in the process of launching this 8452 // provider. 8453 final int N = mLaunchingProviders.size(); 8454 int i; 8455 for (i=0; i<N; i++) { 8456 if (mLaunchingProviders.get(i) == cpr) { 8457 break; 8458 } 8459 } 8460 8461 // If the provider is not already being launched, then get it 8462 // started. 8463 if (i >= N) { 8464 final long origId = Binder.clearCallingIdentity(); 8465 8466 try { 8467 // Content provider is now in use, its package can't be stopped. 8468 try { 8469 AppGlobals.getPackageManager().setPackageStoppedState( 8470 cpr.appInfo.packageName, false, userId); 8471 } catch (RemoteException e) { 8472 } catch (IllegalArgumentException e) { 8473 Slog.w(TAG, "Failed trying to unstop package " 8474 + cpr.appInfo.packageName + ": " + e); 8475 } 8476 8477 // Use existing process if already started 8478 ProcessRecord proc = getProcessRecordLocked( 8479 cpi.processName, cpr.appInfo.uid, false); 8480 if (proc != null && proc.thread != null) { 8481 if (DEBUG_PROVIDER) { 8482 Slog.d(TAG, "Installing in existing process " + proc); 8483 } 8484 proc.pubProviders.put(cpi.name, cpr); 8485 try { 8486 proc.thread.scheduleInstallProvider(cpi); 8487 } catch (RemoteException e) { 8488 } 8489 } else { 8490 proc = startProcessLocked(cpi.processName, 8491 cpr.appInfo, false, 0, "content provider", 8492 new ComponentName(cpi.applicationInfo.packageName, 8493 cpi.name), false, false, false); 8494 if (proc == null) { 8495 Slog.w(TAG, "Unable to launch app " 8496 + cpi.applicationInfo.packageName + "/" 8497 + cpi.applicationInfo.uid + " for provider " 8498 + name + ": process is bad"); 8499 return null; 8500 } 8501 } 8502 cpr.launchingApp = proc; 8503 mLaunchingProviders.add(cpr); 8504 } finally { 8505 Binder.restoreCallingIdentity(origId); 8506 } 8507 } 8508 8509 // Make sure the provider is published (the same provider class 8510 // may be published under multiple names). 8511 if (firstClass) { 8512 mProviderMap.putProviderByClass(comp, cpr); 8513 } 8514 8515 mProviderMap.putProviderByName(name, cpr); 8516 conn = incProviderCountLocked(r, cpr, token, stable); 8517 if (conn != null) { 8518 conn.waiting = true; 8519 } 8520 } 8521 } 8522 8523 // Wait for the provider to be published... 8524 synchronized (cpr) { 8525 while (cpr.provider == null) { 8526 if (cpr.launchingApp == null) { 8527 Slog.w(TAG, "Unable to launch app " 8528 + cpi.applicationInfo.packageName + "/" 8529 + cpi.applicationInfo.uid + " for provider " 8530 + name + ": launching app became null"); 8531 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8532 UserHandle.getUserId(cpi.applicationInfo.uid), 8533 cpi.applicationInfo.packageName, 8534 cpi.applicationInfo.uid, name); 8535 return null; 8536 } 8537 try { 8538 if (DEBUG_MU) { 8539 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8540 + cpr.launchingApp); 8541 } 8542 if (conn != null) { 8543 conn.waiting = true; 8544 } 8545 cpr.wait(); 8546 } catch (InterruptedException ex) { 8547 } finally { 8548 if (conn != null) { 8549 conn.waiting = false; 8550 } 8551 } 8552 } 8553 } 8554 return cpr != null ? cpr.newHolder(conn) : null; 8555 } 8556 8557 @Override 8558 public final ContentProviderHolder getContentProvider( 8559 IApplicationThread caller, String name, int userId, boolean stable) { 8560 enforceNotIsolatedCaller("getContentProvider"); 8561 if (caller == null) { 8562 String msg = "null IApplicationThread when getting content provider " 8563 + name; 8564 Slog.w(TAG, msg); 8565 throw new SecurityException(msg); 8566 } 8567 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8568 // with cross-user grant. 8569 return getContentProviderImpl(caller, name, null, stable, userId); 8570 } 8571 8572 public ContentProviderHolder getContentProviderExternal( 8573 String name, int userId, IBinder token) { 8574 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8575 "Do not have permission in call getContentProviderExternal()"); 8576 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8577 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8578 return getContentProviderExternalUnchecked(name, token, userId); 8579 } 8580 8581 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8582 IBinder token, int userId) { 8583 return getContentProviderImpl(null, name, token, true, userId); 8584 } 8585 8586 /** 8587 * Drop a content provider from a ProcessRecord's bookkeeping 8588 */ 8589 public void removeContentProvider(IBinder connection, boolean stable) { 8590 enforceNotIsolatedCaller("removeContentProvider"); 8591 long ident = Binder.clearCallingIdentity(); 8592 try { 8593 synchronized (this) { 8594 ContentProviderConnection conn; 8595 try { 8596 conn = (ContentProviderConnection)connection; 8597 } catch (ClassCastException e) { 8598 String msg ="removeContentProvider: " + connection 8599 + " not a ContentProviderConnection"; 8600 Slog.w(TAG, msg); 8601 throw new IllegalArgumentException(msg); 8602 } 8603 if (conn == null) { 8604 throw new NullPointerException("connection is null"); 8605 } 8606 if (decProviderCountLocked(conn, null, null, stable)) { 8607 updateOomAdjLocked(); 8608 } 8609 } 8610 } finally { 8611 Binder.restoreCallingIdentity(ident); 8612 } 8613 } 8614 8615 public void removeContentProviderExternal(String name, IBinder token) { 8616 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8617 "Do not have permission in call removeContentProviderExternal()"); 8618 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8619 } 8620 8621 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8622 synchronized (this) { 8623 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8624 if(cpr == null) { 8625 //remove from mProvidersByClass 8626 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8627 return; 8628 } 8629 8630 //update content provider record entry info 8631 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8632 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8633 if (localCpr.hasExternalProcessHandles()) { 8634 if (localCpr.removeExternalProcessHandleLocked(token)) { 8635 updateOomAdjLocked(); 8636 } else { 8637 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8638 + " with no external reference for token: " 8639 + token + "."); 8640 } 8641 } else { 8642 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8643 + " with no external references."); 8644 } 8645 } 8646 } 8647 8648 public final void publishContentProviders(IApplicationThread caller, 8649 List<ContentProviderHolder> providers) { 8650 if (providers == null) { 8651 return; 8652 } 8653 8654 enforceNotIsolatedCaller("publishContentProviders"); 8655 synchronized (this) { 8656 final ProcessRecord r = getRecordForAppLocked(caller); 8657 if (DEBUG_MU) 8658 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8659 if (r == null) { 8660 throw new SecurityException( 8661 "Unable to find app for caller " + caller 8662 + " (pid=" + Binder.getCallingPid() 8663 + ") when publishing content providers"); 8664 } 8665 8666 final long origId = Binder.clearCallingIdentity(); 8667 8668 final int N = providers.size(); 8669 for (int i=0; i<N; i++) { 8670 ContentProviderHolder src = providers.get(i); 8671 if (src == null || src.info == null || src.provider == null) { 8672 continue; 8673 } 8674 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8675 if (DEBUG_MU) 8676 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8677 if (dst != null) { 8678 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8679 mProviderMap.putProviderByClass(comp, dst); 8680 String names[] = dst.info.authority.split(";"); 8681 for (int j = 0; j < names.length; j++) { 8682 mProviderMap.putProviderByName(names[j], dst); 8683 } 8684 8685 int NL = mLaunchingProviders.size(); 8686 int j; 8687 for (j=0; j<NL; j++) { 8688 if (mLaunchingProviders.get(j) == dst) { 8689 mLaunchingProviders.remove(j); 8690 j--; 8691 NL--; 8692 } 8693 } 8694 synchronized (dst) { 8695 dst.provider = src.provider; 8696 dst.proc = r; 8697 dst.notifyAll(); 8698 } 8699 updateOomAdjLocked(r); 8700 } 8701 } 8702 8703 Binder.restoreCallingIdentity(origId); 8704 } 8705 } 8706 8707 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8708 ContentProviderConnection conn; 8709 try { 8710 conn = (ContentProviderConnection)connection; 8711 } catch (ClassCastException e) { 8712 String msg ="refContentProvider: " + connection 8713 + " not a ContentProviderConnection"; 8714 Slog.w(TAG, msg); 8715 throw new IllegalArgumentException(msg); 8716 } 8717 if (conn == null) { 8718 throw new NullPointerException("connection is null"); 8719 } 8720 8721 synchronized (this) { 8722 if (stable > 0) { 8723 conn.numStableIncs += stable; 8724 } 8725 stable = conn.stableCount + stable; 8726 if (stable < 0) { 8727 throw new IllegalStateException("stableCount < 0: " + stable); 8728 } 8729 8730 if (unstable > 0) { 8731 conn.numUnstableIncs += unstable; 8732 } 8733 unstable = conn.unstableCount + unstable; 8734 if (unstable < 0) { 8735 throw new IllegalStateException("unstableCount < 0: " + unstable); 8736 } 8737 8738 if ((stable+unstable) <= 0) { 8739 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8740 + stable + " unstable=" + unstable); 8741 } 8742 conn.stableCount = stable; 8743 conn.unstableCount = unstable; 8744 return !conn.dead; 8745 } 8746 } 8747 8748 public void unstableProviderDied(IBinder connection) { 8749 ContentProviderConnection conn; 8750 try { 8751 conn = (ContentProviderConnection)connection; 8752 } catch (ClassCastException e) { 8753 String msg ="refContentProvider: " + connection 8754 + " not a ContentProviderConnection"; 8755 Slog.w(TAG, msg); 8756 throw new IllegalArgumentException(msg); 8757 } 8758 if (conn == null) { 8759 throw new NullPointerException("connection is null"); 8760 } 8761 8762 // Safely retrieve the content provider associated with the connection. 8763 IContentProvider provider; 8764 synchronized (this) { 8765 provider = conn.provider.provider; 8766 } 8767 8768 if (provider == null) { 8769 // Um, yeah, we're way ahead of you. 8770 return; 8771 } 8772 8773 // Make sure the caller is being honest with us. 8774 if (provider.asBinder().pingBinder()) { 8775 // Er, no, still looks good to us. 8776 synchronized (this) { 8777 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8778 + " says " + conn + " died, but we don't agree"); 8779 return; 8780 } 8781 } 8782 8783 // Well look at that! It's dead! 8784 synchronized (this) { 8785 if (conn.provider.provider != provider) { 8786 // But something changed... good enough. 8787 return; 8788 } 8789 8790 ProcessRecord proc = conn.provider.proc; 8791 if (proc == null || proc.thread == null) { 8792 // Seems like the process is already cleaned up. 8793 return; 8794 } 8795 8796 // As far as we're concerned, this is just like receiving a 8797 // death notification... just a bit prematurely. 8798 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8799 + ") early provider death"); 8800 final long ident = Binder.clearCallingIdentity(); 8801 try { 8802 appDiedLocked(proc, proc.pid, proc.thread); 8803 } finally { 8804 Binder.restoreCallingIdentity(ident); 8805 } 8806 } 8807 } 8808 8809 @Override 8810 public void appNotRespondingViaProvider(IBinder connection) { 8811 enforceCallingPermission( 8812 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8813 8814 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8815 if (conn == null) { 8816 Slog.w(TAG, "ContentProviderConnection is null"); 8817 return; 8818 } 8819 8820 final ProcessRecord host = conn.provider.proc; 8821 if (host == null) { 8822 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8823 return; 8824 } 8825 8826 final long token = Binder.clearCallingIdentity(); 8827 try { 8828 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8829 } finally { 8830 Binder.restoreCallingIdentity(token); 8831 } 8832 } 8833 8834 public final void installSystemProviders() { 8835 List<ProviderInfo> providers; 8836 synchronized (this) { 8837 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8838 providers = generateApplicationProvidersLocked(app); 8839 if (providers != null) { 8840 for (int i=providers.size()-1; i>=0; i--) { 8841 ProviderInfo pi = (ProviderInfo)providers.get(i); 8842 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8843 Slog.w(TAG, "Not installing system proc provider " + pi.name 8844 + ": not system .apk"); 8845 providers.remove(i); 8846 } 8847 } 8848 } 8849 } 8850 if (providers != null) { 8851 mSystemThread.installSystemProviders(providers); 8852 } 8853 8854 mCoreSettingsObserver = new CoreSettingsObserver(this); 8855 8856 //mUsageStatsService.monitorPackages(); 8857 } 8858 8859 /** 8860 * Allows app to retrieve the MIME type of a URI without having permission 8861 * to access its content provider. 8862 * 8863 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8864 * 8865 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8866 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8867 */ 8868 public String getProviderMimeType(Uri uri, int userId) { 8869 enforceNotIsolatedCaller("getProviderMimeType"); 8870 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8871 userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null); 8872 final String name = uri.getAuthority(); 8873 final long ident = Binder.clearCallingIdentity(); 8874 ContentProviderHolder holder = null; 8875 8876 try { 8877 holder = getContentProviderExternalUnchecked(name, null, userId); 8878 if (holder != null) { 8879 return holder.provider.getType(uri); 8880 } 8881 } catch (RemoteException e) { 8882 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8883 return null; 8884 } finally { 8885 if (holder != null) { 8886 removeContentProviderExternalUnchecked(name, null, userId); 8887 } 8888 Binder.restoreCallingIdentity(ident); 8889 } 8890 8891 return null; 8892 } 8893 8894 // ========================================================= 8895 // GLOBAL MANAGEMENT 8896 // ========================================================= 8897 8898 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8899 boolean isolated) { 8900 String proc = customProcess != null ? customProcess : info.processName; 8901 BatteryStatsImpl.Uid.Proc ps = null; 8902 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8903 int uid = info.uid; 8904 if (isolated) { 8905 int userId = UserHandle.getUserId(uid); 8906 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8907 while (true) { 8908 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8909 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8910 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8911 } 8912 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8913 mNextIsolatedProcessUid++; 8914 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8915 // No process for this uid, use it. 8916 break; 8917 } 8918 stepsLeft--; 8919 if (stepsLeft <= 0) { 8920 return null; 8921 } 8922 } 8923 } 8924 return new ProcessRecord(stats, info, proc, uid); 8925 } 8926 8927 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8928 String abiOverride) { 8929 ProcessRecord app; 8930 if (!isolated) { 8931 app = getProcessRecordLocked(info.processName, info.uid, true); 8932 } else { 8933 app = null; 8934 } 8935 8936 if (app == null) { 8937 app = newProcessRecordLocked(info, null, isolated); 8938 mProcessNames.put(info.processName, app.uid, app); 8939 if (isolated) { 8940 mIsolatedProcesses.put(app.uid, app); 8941 } 8942 updateLruProcessLocked(app, false, null); 8943 updateOomAdjLocked(); 8944 } 8945 8946 // This package really, really can not be stopped. 8947 try { 8948 AppGlobals.getPackageManager().setPackageStoppedState( 8949 info.packageName, false, UserHandle.getUserId(app.uid)); 8950 } catch (RemoteException e) { 8951 } catch (IllegalArgumentException e) { 8952 Slog.w(TAG, "Failed trying to unstop package " 8953 + info.packageName + ": " + e); 8954 } 8955 8956 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8957 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8958 app.persistent = true; 8959 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8960 } 8961 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8962 mPersistentStartingProcesses.add(app); 8963 startProcessLocked(app, "added application", app.processName, 8964 abiOverride); 8965 } 8966 8967 return app; 8968 } 8969 8970 public void unhandledBack() { 8971 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8972 "unhandledBack()"); 8973 8974 synchronized(this) { 8975 final long origId = Binder.clearCallingIdentity(); 8976 try { 8977 getFocusedStack().unhandledBackLocked(); 8978 } finally { 8979 Binder.restoreCallingIdentity(origId); 8980 } 8981 } 8982 } 8983 8984 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8985 enforceNotIsolatedCaller("openContentUri"); 8986 final int userId = UserHandle.getCallingUserId(); 8987 String name = uri.getAuthority(); 8988 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8989 ParcelFileDescriptor pfd = null; 8990 if (cph != null) { 8991 // We record the binder invoker's uid in thread-local storage before 8992 // going to the content provider to open the file. Later, in the code 8993 // that handles all permissions checks, we look for this uid and use 8994 // that rather than the Activity Manager's own uid. The effect is that 8995 // we do the check against the caller's permissions even though it looks 8996 // to the content provider like the Activity Manager itself is making 8997 // the request. 8998 sCallerIdentity.set(new Identity( 8999 Binder.getCallingPid(), Binder.getCallingUid())); 9000 try { 9001 pfd = cph.provider.openFile(null, uri, "r", null); 9002 } catch (FileNotFoundException e) { 9003 // do nothing; pfd will be returned null 9004 } finally { 9005 // Ensure that whatever happens, we clean up the identity state 9006 sCallerIdentity.remove(); 9007 } 9008 9009 // We've got the fd now, so we're done with the provider. 9010 removeContentProviderExternalUnchecked(name, null, userId); 9011 } else { 9012 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9013 } 9014 return pfd; 9015 } 9016 9017 // Actually is sleeping or shutting down or whatever else in the future 9018 // is an inactive state. 9019 public boolean isSleepingOrShuttingDown() { 9020 return mSleeping || mShuttingDown; 9021 } 9022 9023 public boolean isSleeping() { 9024 return mSleeping; 9025 } 9026 9027 void goingToSleep() { 9028 synchronized(this) { 9029 mWentToSleep = true; 9030 updateEventDispatchingLocked(); 9031 goToSleepIfNeededLocked(); 9032 } 9033 } 9034 9035 void finishRunningVoiceLocked() { 9036 if (mRunningVoice) { 9037 mRunningVoice = false; 9038 goToSleepIfNeededLocked(); 9039 } 9040 } 9041 9042 void goToSleepIfNeededLocked() { 9043 if (mWentToSleep && !mRunningVoice) { 9044 if (!mSleeping) { 9045 mSleeping = true; 9046 mStackSupervisor.goingToSleepLocked(); 9047 9048 // Initialize the wake times of all processes. 9049 checkExcessivePowerUsageLocked(false); 9050 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9051 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9052 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9053 } 9054 } 9055 } 9056 9057 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9058 mTaskPersister.notify(task, flush); 9059 } 9060 9061 @Override 9062 public boolean shutdown(int timeout) { 9063 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9064 != PackageManager.PERMISSION_GRANTED) { 9065 throw new SecurityException("Requires permission " 9066 + android.Manifest.permission.SHUTDOWN); 9067 } 9068 9069 boolean timedout = false; 9070 9071 synchronized(this) { 9072 mShuttingDown = true; 9073 updateEventDispatchingLocked(); 9074 timedout = mStackSupervisor.shutdownLocked(timeout); 9075 } 9076 9077 mAppOpsService.shutdown(); 9078 if (mUsageStatsService != null) { 9079 mUsageStatsService.prepareShutdown(); 9080 } 9081 mBatteryStatsService.shutdown(); 9082 synchronized (this) { 9083 mProcessStats.shutdownLocked(); 9084 } 9085 notifyTaskPersisterLocked(null, true); 9086 9087 return timedout; 9088 } 9089 9090 public final void activitySlept(IBinder token) { 9091 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9092 9093 final long origId = Binder.clearCallingIdentity(); 9094 9095 synchronized (this) { 9096 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9097 if (r != null) { 9098 mStackSupervisor.activitySleptLocked(r); 9099 } 9100 } 9101 9102 Binder.restoreCallingIdentity(origId); 9103 } 9104 9105 void logLockScreen(String msg) { 9106 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9107 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9108 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 9109 mStackSupervisor.mDismissKeyguardOnNextActivity); 9110 } 9111 9112 private void comeOutOfSleepIfNeededLocked() { 9113 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9114 if (mSleeping) { 9115 mSleeping = false; 9116 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9117 } 9118 } 9119 } 9120 9121 void wakingUp() { 9122 synchronized(this) { 9123 mWentToSleep = false; 9124 updateEventDispatchingLocked(); 9125 comeOutOfSleepIfNeededLocked(); 9126 } 9127 } 9128 9129 void startRunningVoiceLocked() { 9130 if (!mRunningVoice) { 9131 mRunningVoice = true; 9132 comeOutOfSleepIfNeededLocked(); 9133 } 9134 } 9135 9136 private void updateEventDispatchingLocked() { 9137 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9138 } 9139 9140 public void setLockScreenShown(boolean shown) { 9141 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9142 != PackageManager.PERMISSION_GRANTED) { 9143 throw new SecurityException("Requires permission " 9144 + android.Manifest.permission.DEVICE_POWER); 9145 } 9146 9147 synchronized(this) { 9148 long ident = Binder.clearCallingIdentity(); 9149 try { 9150 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9151 mLockScreenShown = shown; 9152 comeOutOfSleepIfNeededLocked(); 9153 } finally { 9154 Binder.restoreCallingIdentity(ident); 9155 } 9156 } 9157 } 9158 9159 @Override 9160 public void stopAppSwitches() { 9161 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9162 != PackageManager.PERMISSION_GRANTED) { 9163 throw new SecurityException("Requires permission " 9164 + android.Manifest.permission.STOP_APP_SWITCHES); 9165 } 9166 9167 synchronized(this) { 9168 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9169 + APP_SWITCH_DELAY_TIME; 9170 mDidAppSwitch = false; 9171 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9172 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9173 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9174 } 9175 } 9176 9177 public void resumeAppSwitches() { 9178 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9179 != PackageManager.PERMISSION_GRANTED) { 9180 throw new SecurityException("Requires permission " 9181 + android.Manifest.permission.STOP_APP_SWITCHES); 9182 } 9183 9184 synchronized(this) { 9185 // Note that we don't execute any pending app switches... we will 9186 // let those wait until either the timeout, or the next start 9187 // activity request. 9188 mAppSwitchesAllowedTime = 0; 9189 } 9190 } 9191 9192 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9193 String name) { 9194 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9195 return true; 9196 } 9197 9198 final int perm = checkComponentPermission( 9199 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9200 callingUid, -1, true); 9201 if (perm == PackageManager.PERMISSION_GRANTED) { 9202 return true; 9203 } 9204 9205 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9206 return false; 9207 } 9208 9209 public void setDebugApp(String packageName, boolean waitForDebugger, 9210 boolean persistent) { 9211 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9212 "setDebugApp()"); 9213 9214 long ident = Binder.clearCallingIdentity(); 9215 try { 9216 // Note that this is not really thread safe if there are multiple 9217 // callers into it at the same time, but that's not a situation we 9218 // care about. 9219 if (persistent) { 9220 final ContentResolver resolver = mContext.getContentResolver(); 9221 Settings.Global.putString( 9222 resolver, Settings.Global.DEBUG_APP, 9223 packageName); 9224 Settings.Global.putInt( 9225 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9226 waitForDebugger ? 1 : 0); 9227 } 9228 9229 synchronized (this) { 9230 if (!persistent) { 9231 mOrigDebugApp = mDebugApp; 9232 mOrigWaitForDebugger = mWaitForDebugger; 9233 } 9234 mDebugApp = packageName; 9235 mWaitForDebugger = waitForDebugger; 9236 mDebugTransient = !persistent; 9237 if (packageName != null) { 9238 forceStopPackageLocked(packageName, -1, false, false, true, true, 9239 false, UserHandle.USER_ALL, "set debug app"); 9240 } 9241 } 9242 } finally { 9243 Binder.restoreCallingIdentity(ident); 9244 } 9245 } 9246 9247 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9248 synchronized (this) { 9249 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9250 if (!isDebuggable) { 9251 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9252 throw new SecurityException("Process not debuggable: " + app.packageName); 9253 } 9254 } 9255 9256 mOpenGlTraceApp = processName; 9257 } 9258 } 9259 9260 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9261 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9262 synchronized (this) { 9263 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9264 if (!isDebuggable) { 9265 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9266 throw new SecurityException("Process not debuggable: " + app.packageName); 9267 } 9268 } 9269 mProfileApp = processName; 9270 mProfileFile = profileFile; 9271 if (mProfileFd != null) { 9272 try { 9273 mProfileFd.close(); 9274 } catch (IOException e) { 9275 } 9276 mProfileFd = null; 9277 } 9278 mProfileFd = profileFd; 9279 mProfileType = 0; 9280 mAutoStopProfiler = autoStopProfiler; 9281 } 9282 } 9283 9284 @Override 9285 public void setAlwaysFinish(boolean enabled) { 9286 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9287 "setAlwaysFinish()"); 9288 9289 Settings.Global.putInt( 9290 mContext.getContentResolver(), 9291 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9292 9293 synchronized (this) { 9294 mAlwaysFinishActivities = enabled; 9295 } 9296 } 9297 9298 @Override 9299 public void setActivityController(IActivityController controller) { 9300 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9301 "setActivityController()"); 9302 synchronized (this) { 9303 mController = controller; 9304 Watchdog.getInstance().setActivityController(controller); 9305 } 9306 } 9307 9308 @Override 9309 public void setUserIsMonkey(boolean userIsMonkey) { 9310 synchronized (this) { 9311 synchronized (mPidsSelfLocked) { 9312 final int callingPid = Binder.getCallingPid(); 9313 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9314 if (precessRecord == null) { 9315 throw new SecurityException("Unknown process: " + callingPid); 9316 } 9317 if (precessRecord.instrumentationUiAutomationConnection == null) { 9318 throw new SecurityException("Only an instrumentation process " 9319 + "with a UiAutomation can call setUserIsMonkey"); 9320 } 9321 } 9322 mUserIsMonkey = userIsMonkey; 9323 } 9324 } 9325 9326 @Override 9327 public boolean isUserAMonkey() { 9328 synchronized (this) { 9329 // If there is a controller also implies the user is a monkey. 9330 return (mUserIsMonkey || mController != null); 9331 } 9332 } 9333 9334 public void requestBugReport() { 9335 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9336 SystemProperties.set("ctl.start", "bugreport"); 9337 } 9338 9339 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9340 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9341 } 9342 9343 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9344 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9345 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9346 } 9347 return KEY_DISPATCHING_TIMEOUT; 9348 } 9349 9350 @Override 9351 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9352 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9353 != PackageManager.PERMISSION_GRANTED) { 9354 throw new SecurityException("Requires permission " 9355 + android.Manifest.permission.FILTER_EVENTS); 9356 } 9357 ProcessRecord proc; 9358 long timeout; 9359 synchronized (this) { 9360 synchronized (mPidsSelfLocked) { 9361 proc = mPidsSelfLocked.get(pid); 9362 } 9363 timeout = getInputDispatchingTimeoutLocked(proc); 9364 } 9365 9366 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9367 return -1; 9368 } 9369 9370 return timeout; 9371 } 9372 9373 /** 9374 * Handle input dispatching timeouts. 9375 * Returns whether input dispatching should be aborted or not. 9376 */ 9377 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9378 final ActivityRecord activity, final ActivityRecord parent, 9379 final boolean aboveSystem, String reason) { 9380 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9381 != PackageManager.PERMISSION_GRANTED) { 9382 throw new SecurityException("Requires permission " 9383 + android.Manifest.permission.FILTER_EVENTS); 9384 } 9385 9386 final String annotation; 9387 if (reason == null) { 9388 annotation = "Input dispatching timed out"; 9389 } else { 9390 annotation = "Input dispatching timed out (" + reason + ")"; 9391 } 9392 9393 if (proc != null) { 9394 synchronized (this) { 9395 if (proc.debugging) { 9396 return false; 9397 } 9398 9399 if (mDidDexOpt) { 9400 // Give more time since we were dexopting. 9401 mDidDexOpt = false; 9402 return false; 9403 } 9404 9405 if (proc.instrumentationClass != null) { 9406 Bundle info = new Bundle(); 9407 info.putString("shortMsg", "keyDispatchingTimedOut"); 9408 info.putString("longMsg", annotation); 9409 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9410 return true; 9411 } 9412 } 9413 mHandler.post(new Runnable() { 9414 @Override 9415 public void run() { 9416 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9417 } 9418 }); 9419 } 9420 9421 return true; 9422 } 9423 9424 public Bundle getAssistContextExtras(int requestType) { 9425 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9426 "getAssistContextExtras()"); 9427 PendingAssistExtras pae; 9428 Bundle extras = new Bundle(); 9429 synchronized (this) { 9430 ActivityRecord activity = getFocusedStack().mResumedActivity; 9431 if (activity == null) { 9432 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9433 return null; 9434 } 9435 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9436 if (activity.app == null || activity.app.thread == null) { 9437 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9438 return extras; 9439 } 9440 if (activity.app.pid == Binder.getCallingPid()) { 9441 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9442 return extras; 9443 } 9444 pae = new PendingAssistExtras(activity); 9445 try { 9446 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9447 requestType); 9448 mPendingAssistExtras.add(pae); 9449 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9450 } catch (RemoteException e) { 9451 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9452 return extras; 9453 } 9454 } 9455 synchronized (pae) { 9456 while (!pae.haveResult) { 9457 try { 9458 pae.wait(); 9459 } catch (InterruptedException e) { 9460 } 9461 } 9462 if (pae.result != null) { 9463 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9464 } 9465 } 9466 synchronized (this) { 9467 mPendingAssistExtras.remove(pae); 9468 mHandler.removeCallbacks(pae); 9469 } 9470 return extras; 9471 } 9472 9473 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9474 PendingAssistExtras pae = (PendingAssistExtras)token; 9475 synchronized (pae) { 9476 pae.result = extras; 9477 pae.haveResult = true; 9478 pae.notifyAll(); 9479 } 9480 } 9481 9482 public void registerProcessObserver(IProcessObserver observer) { 9483 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9484 "registerProcessObserver()"); 9485 synchronized (this) { 9486 mProcessObservers.register(observer); 9487 } 9488 } 9489 9490 @Override 9491 public void unregisterProcessObserver(IProcessObserver observer) { 9492 synchronized (this) { 9493 mProcessObservers.unregister(observer); 9494 } 9495 } 9496 9497 @Override 9498 public boolean convertFromTranslucent(IBinder token) { 9499 final long origId = Binder.clearCallingIdentity(); 9500 try { 9501 synchronized (this) { 9502 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9503 if (r == null) { 9504 return false; 9505 } 9506 if (r.changeWindowTranslucency(true)) { 9507 mWindowManager.setAppFullscreen(token, true); 9508 r.task.stack.releaseMediaResources(); 9509 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9510 return true; 9511 } 9512 return false; 9513 } 9514 } finally { 9515 Binder.restoreCallingIdentity(origId); 9516 } 9517 } 9518 9519 @Override 9520 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9521 final long origId = Binder.clearCallingIdentity(); 9522 try { 9523 synchronized (this) { 9524 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9525 if (r == null) { 9526 return false; 9527 } 9528 if (r.changeWindowTranslucency(false)) { 9529 r.task.stack.convertToTranslucent(r, options); 9530 mWindowManager.setAppFullscreen(token, false); 9531 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9532 return true; 9533 } else { 9534 r.task.stack.mReturningActivityOptions = options; 9535 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9536 return false; 9537 } 9538 } 9539 } finally { 9540 Binder.restoreCallingIdentity(origId); 9541 } 9542 } 9543 9544 @Override 9545 public boolean setMediaPlaying(IBinder token, boolean playing) { 9546 final long origId = Binder.clearCallingIdentity(); 9547 try { 9548 synchronized (this) { 9549 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9550 if (r != null) { 9551 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9552 } 9553 } 9554 return false; 9555 } finally { 9556 Binder.restoreCallingIdentity(origId); 9557 } 9558 } 9559 9560 @Override 9561 public boolean isBackgroundMediaPlaying(IBinder token) { 9562 final long origId = Binder.clearCallingIdentity(); 9563 try { 9564 synchronized (this) { 9565 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9566 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9567 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9568 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9569 return playing; 9570 } 9571 } finally { 9572 Binder.restoreCallingIdentity(origId); 9573 } 9574 } 9575 9576 @Override 9577 public ActivityOptions getActivityOptions(IBinder token) { 9578 final long origId = Binder.clearCallingIdentity(); 9579 try { 9580 synchronized (this) { 9581 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9582 if (r != null) { 9583 final ActivityOptions activityOptions = r.pendingOptions; 9584 r.pendingOptions = null; 9585 return activityOptions; 9586 } 9587 return null; 9588 } 9589 } finally { 9590 Binder.restoreCallingIdentity(origId); 9591 } 9592 } 9593 9594 @Override 9595 public void setImmersive(IBinder token, boolean immersive) { 9596 synchronized(this) { 9597 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9598 if (r == null) { 9599 throw new IllegalArgumentException(); 9600 } 9601 r.immersive = immersive; 9602 9603 // update associated state if we're frontmost 9604 if (r == mFocusedActivity) { 9605 if (DEBUG_IMMERSIVE) { 9606 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9607 } 9608 applyUpdateLockStateLocked(r); 9609 } 9610 } 9611 } 9612 9613 @Override 9614 public boolean isImmersive(IBinder token) { 9615 synchronized (this) { 9616 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9617 if (r == null) { 9618 throw new IllegalArgumentException(); 9619 } 9620 return r.immersive; 9621 } 9622 } 9623 9624 public boolean isTopActivityImmersive() { 9625 enforceNotIsolatedCaller("startActivity"); 9626 synchronized (this) { 9627 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9628 return (r != null) ? r.immersive : false; 9629 } 9630 } 9631 9632 @Override 9633 public boolean isTopOfTask(IBinder token) { 9634 synchronized (this) { 9635 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9636 if (r == null) { 9637 throw new IllegalArgumentException(); 9638 } 9639 return r.task.getTopActivity() == r; 9640 } 9641 } 9642 9643 public final void enterSafeMode() { 9644 synchronized(this) { 9645 // It only makes sense to do this before the system is ready 9646 // and started launching other packages. 9647 if (!mSystemReady) { 9648 try { 9649 AppGlobals.getPackageManager().enterSafeMode(); 9650 } catch (RemoteException e) { 9651 } 9652 } 9653 9654 mSafeMode = true; 9655 } 9656 } 9657 9658 public final void showSafeModeOverlay() { 9659 View v = LayoutInflater.from(mContext).inflate( 9660 com.android.internal.R.layout.safe_mode, null); 9661 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9662 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9663 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9664 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9665 lp.gravity = Gravity.BOTTOM | Gravity.START; 9666 lp.format = v.getBackground().getOpacity(); 9667 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9668 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9669 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9670 ((WindowManager)mContext.getSystemService( 9671 Context.WINDOW_SERVICE)).addView(v, lp); 9672 } 9673 9674 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9675 if (!(sender instanceof PendingIntentRecord)) { 9676 return; 9677 } 9678 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9679 synchronized (stats) { 9680 if (mBatteryStatsService.isOnBattery()) { 9681 mBatteryStatsService.enforceCallingPermission(); 9682 PendingIntentRecord rec = (PendingIntentRecord)sender; 9683 int MY_UID = Binder.getCallingUid(); 9684 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9685 BatteryStatsImpl.Uid.Pkg pkg = 9686 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9687 sourcePkg != null ? sourcePkg : rec.key.packageName); 9688 pkg.incWakeupsLocked(); 9689 } 9690 } 9691 } 9692 9693 public boolean killPids(int[] pids, String pReason, boolean secure) { 9694 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9695 throw new SecurityException("killPids only available to the system"); 9696 } 9697 String reason = (pReason == null) ? "Unknown" : pReason; 9698 // XXX Note: don't acquire main activity lock here, because the window 9699 // manager calls in with its locks held. 9700 9701 boolean killed = false; 9702 synchronized (mPidsSelfLocked) { 9703 int[] types = new int[pids.length]; 9704 int worstType = 0; 9705 for (int i=0; i<pids.length; i++) { 9706 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9707 if (proc != null) { 9708 int type = proc.setAdj; 9709 types[i] = type; 9710 if (type > worstType) { 9711 worstType = type; 9712 } 9713 } 9714 } 9715 9716 // If the worst oom_adj is somewhere in the cached proc LRU range, 9717 // then constrain it so we will kill all cached procs. 9718 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9719 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9720 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9721 } 9722 9723 // If this is not a secure call, don't let it kill processes that 9724 // are important. 9725 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9726 worstType = ProcessList.SERVICE_ADJ; 9727 } 9728 9729 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9730 for (int i=0; i<pids.length; i++) { 9731 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9732 if (proc == null) { 9733 continue; 9734 } 9735 int adj = proc.setAdj; 9736 if (adj >= worstType && !proc.killedByAm) { 9737 killUnneededProcessLocked(proc, reason); 9738 killed = true; 9739 } 9740 } 9741 } 9742 return killed; 9743 } 9744 9745 @Override 9746 public void killUid(int uid, String reason) { 9747 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9748 throw new SecurityException("killUid only available to the system"); 9749 } 9750 synchronized (this) { 9751 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9752 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9753 reason != null ? reason : "kill uid"); 9754 } 9755 } 9756 9757 @Override 9758 public boolean killProcessesBelowForeground(String reason) { 9759 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9760 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9761 } 9762 9763 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9764 } 9765 9766 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9767 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9768 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9769 } 9770 9771 boolean killed = false; 9772 synchronized (mPidsSelfLocked) { 9773 final int size = mPidsSelfLocked.size(); 9774 for (int i = 0; i < size; i++) { 9775 final int pid = mPidsSelfLocked.keyAt(i); 9776 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9777 if (proc == null) continue; 9778 9779 final int adj = proc.setAdj; 9780 if (adj > belowAdj && !proc.killedByAm) { 9781 killUnneededProcessLocked(proc, reason); 9782 killed = true; 9783 } 9784 } 9785 } 9786 return killed; 9787 } 9788 9789 @Override 9790 public void hang(final IBinder who, boolean allowRestart) { 9791 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9792 != PackageManager.PERMISSION_GRANTED) { 9793 throw new SecurityException("Requires permission " 9794 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9795 } 9796 9797 final IBinder.DeathRecipient death = new DeathRecipient() { 9798 @Override 9799 public void binderDied() { 9800 synchronized (this) { 9801 notifyAll(); 9802 } 9803 } 9804 }; 9805 9806 try { 9807 who.linkToDeath(death, 0); 9808 } catch (RemoteException e) { 9809 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9810 return; 9811 } 9812 9813 synchronized (this) { 9814 Watchdog.getInstance().setAllowRestart(allowRestart); 9815 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9816 synchronized (death) { 9817 while (who.isBinderAlive()) { 9818 try { 9819 death.wait(); 9820 } catch (InterruptedException e) { 9821 } 9822 } 9823 } 9824 Watchdog.getInstance().setAllowRestart(true); 9825 } 9826 } 9827 9828 @Override 9829 public void restart() { 9830 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9831 != PackageManager.PERMISSION_GRANTED) { 9832 throw new SecurityException("Requires permission " 9833 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9834 } 9835 9836 Log.i(TAG, "Sending shutdown broadcast..."); 9837 9838 BroadcastReceiver br = new BroadcastReceiver() { 9839 @Override public void onReceive(Context context, Intent intent) { 9840 // Now the broadcast is done, finish up the low-level shutdown. 9841 Log.i(TAG, "Shutting down activity manager..."); 9842 shutdown(10000); 9843 Log.i(TAG, "Shutdown complete, restarting!"); 9844 Process.killProcess(Process.myPid()); 9845 System.exit(10); 9846 } 9847 }; 9848 9849 // First send the high-level shut down broadcast. 9850 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9851 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9852 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9853 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9854 mContext.sendOrderedBroadcastAsUser(intent, 9855 UserHandle.ALL, null, br, mHandler, 0, null, null); 9856 */ 9857 br.onReceive(mContext, intent); 9858 } 9859 9860 private long getLowRamTimeSinceIdle(long now) { 9861 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9862 } 9863 9864 @Override 9865 public void performIdleMaintenance() { 9866 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9867 != PackageManager.PERMISSION_GRANTED) { 9868 throw new SecurityException("Requires permission " 9869 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9870 } 9871 9872 synchronized (this) { 9873 final long now = SystemClock.uptimeMillis(); 9874 final long timeSinceLastIdle = now - mLastIdleTime; 9875 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9876 mLastIdleTime = now; 9877 mLowRamTimeSinceLastIdle = 0; 9878 if (mLowRamStartTime != 0) { 9879 mLowRamStartTime = now; 9880 } 9881 9882 StringBuilder sb = new StringBuilder(128); 9883 sb.append("Idle maintenance over "); 9884 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9885 sb.append(" low RAM for "); 9886 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9887 Slog.i(TAG, sb.toString()); 9888 9889 // If at least 1/3 of our time since the last idle period has been spent 9890 // with RAM low, then we want to kill processes. 9891 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9892 9893 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9894 ProcessRecord proc = mLruProcesses.get(i); 9895 if (proc.notCachedSinceIdle) { 9896 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9897 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9898 if (doKilling && proc.initialIdlePss != 0 9899 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9900 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9901 + " from " + proc.initialIdlePss + ")"); 9902 } 9903 } 9904 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9905 proc.notCachedSinceIdle = true; 9906 proc.initialIdlePss = 0; 9907 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9908 isSleeping(), now); 9909 } 9910 } 9911 9912 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9913 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9914 } 9915 } 9916 9917 private void retrieveSettings() { 9918 final ContentResolver resolver = mContext.getContentResolver(); 9919 String debugApp = Settings.Global.getString( 9920 resolver, Settings.Global.DEBUG_APP); 9921 boolean waitForDebugger = Settings.Global.getInt( 9922 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9923 boolean alwaysFinishActivities = Settings.Global.getInt( 9924 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9925 boolean forceRtl = Settings.Global.getInt( 9926 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9927 // Transfer any global setting for forcing RTL layout, into a System Property 9928 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9929 9930 Configuration configuration = new Configuration(); 9931 Settings.System.getConfiguration(resolver, configuration); 9932 if (forceRtl) { 9933 // This will take care of setting the correct layout direction flags 9934 configuration.setLayoutDirection(configuration.locale); 9935 } 9936 9937 synchronized (this) { 9938 mDebugApp = mOrigDebugApp = debugApp; 9939 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9940 mAlwaysFinishActivities = alwaysFinishActivities; 9941 // This happens before any activities are started, so we can 9942 // change mConfiguration in-place. 9943 updateConfigurationLocked(configuration, null, false, true); 9944 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9945 } 9946 } 9947 9948 public boolean testIsSystemReady() { 9949 // no need to synchronize(this) just to read & return the value 9950 return mSystemReady; 9951 } 9952 9953 private static File getCalledPreBootReceiversFile() { 9954 File dataDir = Environment.getDataDirectory(); 9955 File systemDir = new File(dataDir, "system"); 9956 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 9957 return fname; 9958 } 9959 9960 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9961 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9962 File file = getCalledPreBootReceiversFile(); 9963 FileInputStream fis = null; 9964 try { 9965 fis = new FileInputStream(file); 9966 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9967 int fvers = dis.readInt(); 9968 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 9969 String vers = dis.readUTF(); 9970 String codename = dis.readUTF(); 9971 String build = dis.readUTF(); 9972 if (android.os.Build.VERSION.RELEASE.equals(vers) 9973 && android.os.Build.VERSION.CODENAME.equals(codename) 9974 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9975 int num = dis.readInt(); 9976 while (num > 0) { 9977 num--; 9978 String pkg = dis.readUTF(); 9979 String cls = dis.readUTF(); 9980 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9981 } 9982 } 9983 } 9984 } catch (FileNotFoundException e) { 9985 } catch (IOException e) { 9986 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9987 } finally { 9988 if (fis != null) { 9989 try { 9990 fis.close(); 9991 } catch (IOException e) { 9992 } 9993 } 9994 } 9995 return lastDoneReceivers; 9996 } 9997 9998 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9999 File file = getCalledPreBootReceiversFile(); 10000 FileOutputStream fos = null; 10001 DataOutputStream dos = null; 10002 try { 10003 fos = new FileOutputStream(file); 10004 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10005 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10006 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10007 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10008 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10009 dos.writeInt(list.size()); 10010 for (int i=0; i<list.size(); i++) { 10011 dos.writeUTF(list.get(i).getPackageName()); 10012 dos.writeUTF(list.get(i).getClassName()); 10013 } 10014 } catch (IOException e) { 10015 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10016 file.delete(); 10017 } finally { 10018 FileUtils.sync(fos); 10019 if (dos != null) { 10020 try { 10021 dos.close(); 10022 } catch (IOException e) { 10023 // TODO Auto-generated catch block 10024 e.printStackTrace(); 10025 } 10026 } 10027 } 10028 } 10029 10030 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10031 ArrayList<ComponentName> doneReceivers, int userId) { 10032 boolean waitingUpdate = false; 10033 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10034 List<ResolveInfo> ris = null; 10035 try { 10036 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10037 intent, null, 0, userId); 10038 } catch (RemoteException e) { 10039 } 10040 if (ris != null) { 10041 for (int i=ris.size()-1; i>=0; i--) { 10042 if ((ris.get(i).activityInfo.applicationInfo.flags 10043 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10044 ris.remove(i); 10045 } 10046 } 10047 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10048 10049 // For User 0, load the version number. When delivering to a new user, deliver 10050 // to all receivers. 10051 if (userId == UserHandle.USER_OWNER) { 10052 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10053 for (int i=0; i<ris.size(); i++) { 10054 ActivityInfo ai = ris.get(i).activityInfo; 10055 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10056 if (lastDoneReceivers.contains(comp)) { 10057 // We already did the pre boot receiver for this app with the current 10058 // platform version, so don't do it again... 10059 ris.remove(i); 10060 i--; 10061 // ...however, do keep it as one that has been done, so we don't 10062 // forget about it when rewriting the file of last done receivers. 10063 doneReceivers.add(comp); 10064 } 10065 } 10066 } 10067 10068 // If primary user, send broadcast to all available users, else just to userId 10069 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10070 : new int[] { userId }; 10071 for (int i = 0; i < ris.size(); i++) { 10072 ActivityInfo ai = ris.get(i).activityInfo; 10073 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10074 doneReceivers.add(comp); 10075 intent.setComponent(comp); 10076 for (int j=0; j<users.length; j++) { 10077 IIntentReceiver finisher = null; 10078 // On last receiver and user, set up a completion callback 10079 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10080 finisher = new IIntentReceiver.Stub() { 10081 public void performReceive(Intent intent, int resultCode, 10082 String data, Bundle extras, boolean ordered, 10083 boolean sticky, int sendingUser) { 10084 // The raw IIntentReceiver interface is called 10085 // with the AM lock held, so redispatch to 10086 // execute our code without the lock. 10087 mHandler.post(onFinishCallback); 10088 } 10089 }; 10090 } 10091 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10092 + " for user " + users[j]); 10093 broadcastIntentLocked(null, null, intent, null, finisher, 10094 0, null, null, null, AppOpsManager.OP_NONE, 10095 true, false, MY_PID, Process.SYSTEM_UID, 10096 users[j]); 10097 if (finisher != null) { 10098 waitingUpdate = true; 10099 } 10100 } 10101 } 10102 } 10103 10104 return waitingUpdate; 10105 } 10106 10107 public void systemReady(final Runnable goingCallback) { 10108 synchronized(this) { 10109 if (mSystemReady) { 10110 // If we're done calling all the receivers, run the next "boot phase" passed in 10111 // by the SystemServer 10112 if (goingCallback != null) { 10113 goingCallback.run(); 10114 } 10115 return; 10116 } 10117 10118 // Make sure we have the current profile info, since it is needed for 10119 // security checks. 10120 updateCurrentProfileIdsLocked(); 10121 10122 if (mRecentTasks == null) { 10123 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10124 if (!mRecentTasks.isEmpty()) { 10125 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10126 } 10127 mTaskPersister.startPersisting(); 10128 } 10129 10130 // Check to see if there are any update receivers to run. 10131 if (!mDidUpdate) { 10132 if (mWaitingUpdate) { 10133 return; 10134 } 10135 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10136 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10137 public void run() { 10138 synchronized (ActivityManagerService.this) { 10139 mDidUpdate = true; 10140 } 10141 writeLastDonePreBootReceivers(doneReceivers); 10142 showBootMessage(mContext.getText( 10143 R.string.android_upgrading_complete), 10144 false); 10145 systemReady(goingCallback); 10146 } 10147 }, doneReceivers, UserHandle.USER_OWNER); 10148 10149 if (mWaitingUpdate) { 10150 return; 10151 } 10152 mDidUpdate = true; 10153 } 10154 10155 mAppOpsService.systemReady(); 10156 mSystemReady = true; 10157 } 10158 10159 ArrayList<ProcessRecord> procsToKill = null; 10160 synchronized(mPidsSelfLocked) { 10161 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10162 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10163 if (!isAllowedWhileBooting(proc.info)){ 10164 if (procsToKill == null) { 10165 procsToKill = new ArrayList<ProcessRecord>(); 10166 } 10167 procsToKill.add(proc); 10168 } 10169 } 10170 } 10171 10172 synchronized(this) { 10173 if (procsToKill != null) { 10174 for (int i=procsToKill.size()-1; i>=0; i--) { 10175 ProcessRecord proc = procsToKill.get(i); 10176 Slog.i(TAG, "Removing system update proc: " + proc); 10177 removeProcessLocked(proc, true, false, "system update done"); 10178 } 10179 } 10180 10181 // Now that we have cleaned up any update processes, we 10182 // are ready to start launching real processes and know that 10183 // we won't trample on them any more. 10184 mProcessesReady = true; 10185 } 10186 10187 Slog.i(TAG, "System now ready"); 10188 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10189 SystemClock.uptimeMillis()); 10190 10191 synchronized(this) { 10192 // Make sure we have no pre-ready processes sitting around. 10193 10194 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10195 ResolveInfo ri = mContext.getPackageManager() 10196 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10197 STOCK_PM_FLAGS); 10198 CharSequence errorMsg = null; 10199 if (ri != null) { 10200 ActivityInfo ai = ri.activityInfo; 10201 ApplicationInfo app = ai.applicationInfo; 10202 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10203 mTopAction = Intent.ACTION_FACTORY_TEST; 10204 mTopData = null; 10205 mTopComponent = new ComponentName(app.packageName, 10206 ai.name); 10207 } else { 10208 errorMsg = mContext.getResources().getText( 10209 com.android.internal.R.string.factorytest_not_system); 10210 } 10211 } else { 10212 errorMsg = mContext.getResources().getText( 10213 com.android.internal.R.string.factorytest_no_action); 10214 } 10215 if (errorMsg != null) { 10216 mTopAction = null; 10217 mTopData = null; 10218 mTopComponent = null; 10219 Message msg = Message.obtain(); 10220 msg.what = SHOW_FACTORY_ERROR_MSG; 10221 msg.getData().putCharSequence("msg", errorMsg); 10222 mHandler.sendMessage(msg); 10223 } 10224 } 10225 } 10226 10227 retrieveSettings(); 10228 10229 synchronized (this) { 10230 readGrantedUriPermissionsLocked(); 10231 } 10232 10233 if (goingCallback != null) goingCallback.run(); 10234 10235 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10236 Integer.toString(mCurrentUserId), mCurrentUserId); 10237 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10238 Integer.toString(mCurrentUserId), mCurrentUserId); 10239 mSystemServiceManager.startUser(mCurrentUserId); 10240 10241 synchronized (this) { 10242 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10243 try { 10244 List apps = AppGlobals.getPackageManager(). 10245 getPersistentApplications(STOCK_PM_FLAGS); 10246 if (apps != null) { 10247 int N = apps.size(); 10248 int i; 10249 for (i=0; i<N; i++) { 10250 ApplicationInfo info 10251 = (ApplicationInfo)apps.get(i); 10252 if (info != null && 10253 !info.packageName.equals("android")) { 10254 addAppLocked(info, false, null /* ABI override */); 10255 } 10256 } 10257 } 10258 } catch (RemoteException ex) { 10259 // pm is in same process, this will never happen. 10260 } 10261 } 10262 10263 // Start up initial activity. 10264 mBooting = true; 10265 10266 try { 10267 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10268 Message msg = Message.obtain(); 10269 msg.what = SHOW_UID_ERROR_MSG; 10270 mHandler.sendMessage(msg); 10271 } 10272 } catch (RemoteException e) { 10273 } 10274 10275 long ident = Binder.clearCallingIdentity(); 10276 try { 10277 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10279 | Intent.FLAG_RECEIVER_FOREGROUND); 10280 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10281 broadcastIntentLocked(null, null, intent, 10282 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10283 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10284 intent = new Intent(Intent.ACTION_USER_STARTING); 10285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10286 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10287 broadcastIntentLocked(null, null, intent, 10288 null, new IIntentReceiver.Stub() { 10289 @Override 10290 public void performReceive(Intent intent, int resultCode, String data, 10291 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10292 throws RemoteException { 10293 } 10294 }, 0, null, null, 10295 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10296 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10297 } catch (Throwable t) { 10298 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10299 } finally { 10300 Binder.restoreCallingIdentity(ident); 10301 } 10302 mStackSupervisor.resumeTopActivitiesLocked(); 10303 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10304 } 10305 } 10306 10307 private boolean makeAppCrashingLocked(ProcessRecord app, 10308 String shortMsg, String longMsg, String stackTrace) { 10309 app.crashing = true; 10310 app.crashingReport = generateProcessError(app, 10311 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10312 startAppProblemLocked(app); 10313 app.stopFreezingAllLocked(); 10314 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10315 } 10316 10317 private void makeAppNotRespondingLocked(ProcessRecord app, 10318 String activity, String shortMsg, String longMsg) { 10319 app.notResponding = true; 10320 app.notRespondingReport = generateProcessError(app, 10321 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10322 activity, shortMsg, longMsg, null); 10323 startAppProblemLocked(app); 10324 app.stopFreezingAllLocked(); 10325 } 10326 10327 /** 10328 * Generate a process error record, suitable for attachment to a ProcessRecord. 10329 * 10330 * @param app The ProcessRecord in which the error occurred. 10331 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10332 * ActivityManager.AppErrorStateInfo 10333 * @param activity The activity associated with the crash, if known. 10334 * @param shortMsg Short message describing the crash. 10335 * @param longMsg Long message describing the crash. 10336 * @param stackTrace Full crash stack trace, may be null. 10337 * 10338 * @return Returns a fully-formed AppErrorStateInfo record. 10339 */ 10340 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10341 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10342 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10343 10344 report.condition = condition; 10345 report.processName = app.processName; 10346 report.pid = app.pid; 10347 report.uid = app.info.uid; 10348 report.tag = activity; 10349 report.shortMsg = shortMsg; 10350 report.longMsg = longMsg; 10351 report.stackTrace = stackTrace; 10352 10353 return report; 10354 } 10355 10356 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10357 synchronized (this) { 10358 app.crashing = false; 10359 app.crashingReport = null; 10360 app.notResponding = false; 10361 app.notRespondingReport = null; 10362 if (app.anrDialog == fromDialog) { 10363 app.anrDialog = null; 10364 } 10365 if (app.waitDialog == fromDialog) { 10366 app.waitDialog = null; 10367 } 10368 if (app.pid > 0 && app.pid != MY_PID) { 10369 handleAppCrashLocked(app, null, null, null); 10370 killUnneededProcessLocked(app, "user request after error"); 10371 } 10372 } 10373 } 10374 10375 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10376 String stackTrace) { 10377 long now = SystemClock.uptimeMillis(); 10378 10379 Long crashTime; 10380 if (!app.isolated) { 10381 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10382 } else { 10383 crashTime = null; 10384 } 10385 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10386 // This process loses! 10387 Slog.w(TAG, "Process " + app.info.processName 10388 + " has crashed too many times: killing!"); 10389 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10390 app.userId, app.info.processName, app.uid); 10391 mStackSupervisor.handleAppCrashLocked(app); 10392 if (!app.persistent) { 10393 // We don't want to start this process again until the user 10394 // explicitly does so... but for persistent process, we really 10395 // need to keep it running. If a persistent process is actually 10396 // repeatedly crashing, then badness for everyone. 10397 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10398 app.info.processName); 10399 if (!app.isolated) { 10400 // XXX We don't have a way to mark isolated processes 10401 // as bad, since they don't have a peristent identity. 10402 mBadProcesses.put(app.info.processName, app.uid, 10403 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10404 mProcessCrashTimes.remove(app.info.processName, app.uid); 10405 } 10406 app.bad = true; 10407 app.removed = true; 10408 // Don't let services in this process be restarted and potentially 10409 // annoy the user repeatedly. Unless it is persistent, since those 10410 // processes run critical code. 10411 removeProcessLocked(app, false, false, "crash"); 10412 mStackSupervisor.resumeTopActivitiesLocked(); 10413 return false; 10414 } 10415 mStackSupervisor.resumeTopActivitiesLocked(); 10416 } else { 10417 mStackSupervisor.finishTopRunningActivityLocked(app); 10418 } 10419 10420 // Bump up the crash count of any services currently running in the proc. 10421 for (int i=app.services.size()-1; i>=0; i--) { 10422 // Any services running in the application need to be placed 10423 // back in the pending list. 10424 ServiceRecord sr = app.services.valueAt(i); 10425 sr.crashCount++; 10426 } 10427 10428 // If the crashing process is what we consider to be the "home process" and it has been 10429 // replaced by a third-party app, clear the package preferred activities from packages 10430 // with a home activity running in the process to prevent a repeatedly crashing app 10431 // from blocking the user to manually clear the list. 10432 final ArrayList<ActivityRecord> activities = app.activities; 10433 if (app == mHomeProcess && activities.size() > 0 10434 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10435 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10436 final ActivityRecord r = activities.get(activityNdx); 10437 if (r.isHomeActivity()) { 10438 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10439 try { 10440 ActivityThread.getPackageManager() 10441 .clearPackagePreferredActivities(r.packageName); 10442 } catch (RemoteException c) { 10443 // pm is in same process, this will never happen. 10444 } 10445 } 10446 } 10447 } 10448 10449 if (!app.isolated) { 10450 // XXX Can't keep track of crash times for isolated processes, 10451 // because they don't have a perisistent identity. 10452 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10453 } 10454 10455 return true; 10456 } 10457 10458 void startAppProblemLocked(ProcessRecord app) { 10459 if (app.userId == mCurrentUserId) { 10460 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10461 mContext, app.info.packageName, app.info.flags); 10462 } else { 10463 // If this app is not running under the current user, then we 10464 // can't give it a report button because that would require 10465 // launching the report UI under a different user. 10466 app.errorReportReceiver = null; 10467 } 10468 skipCurrentReceiverLocked(app); 10469 } 10470 10471 void skipCurrentReceiverLocked(ProcessRecord app) { 10472 for (BroadcastQueue queue : mBroadcastQueues) { 10473 queue.skipCurrentReceiverLocked(app); 10474 } 10475 } 10476 10477 /** 10478 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10479 * The application process will exit immediately after this call returns. 10480 * @param app object of the crashing app, null for the system server 10481 * @param crashInfo describing the exception 10482 */ 10483 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10484 ProcessRecord r = findAppProcess(app, "Crash"); 10485 final String processName = app == null ? "system_server" 10486 : (r == null ? "unknown" : r.processName); 10487 10488 handleApplicationCrashInner("crash", r, processName, crashInfo); 10489 } 10490 10491 /* Native crash reporting uses this inner version because it needs to be somewhat 10492 * decoupled from the AM-managed cleanup lifecycle 10493 */ 10494 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10495 ApplicationErrorReport.CrashInfo crashInfo) { 10496 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10497 UserHandle.getUserId(Binder.getCallingUid()), processName, 10498 r == null ? -1 : r.info.flags, 10499 crashInfo.exceptionClassName, 10500 crashInfo.exceptionMessage, 10501 crashInfo.throwFileName, 10502 crashInfo.throwLineNumber); 10503 10504 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10505 10506 crashApplication(r, crashInfo); 10507 } 10508 10509 public void handleApplicationStrictModeViolation( 10510 IBinder app, 10511 int violationMask, 10512 StrictMode.ViolationInfo info) { 10513 ProcessRecord r = findAppProcess(app, "StrictMode"); 10514 if (r == null) { 10515 return; 10516 } 10517 10518 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10519 Integer stackFingerprint = info.hashCode(); 10520 boolean logIt = true; 10521 synchronized (mAlreadyLoggedViolatedStacks) { 10522 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10523 logIt = false; 10524 // TODO: sub-sample into EventLog for these, with 10525 // the info.durationMillis? Then we'd get 10526 // the relative pain numbers, without logging all 10527 // the stack traces repeatedly. We'd want to do 10528 // likewise in the client code, which also does 10529 // dup suppression, before the Binder call. 10530 } else { 10531 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10532 mAlreadyLoggedViolatedStacks.clear(); 10533 } 10534 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10535 } 10536 } 10537 if (logIt) { 10538 logStrictModeViolationToDropBox(r, info); 10539 } 10540 } 10541 10542 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10543 AppErrorResult result = new AppErrorResult(); 10544 synchronized (this) { 10545 final long origId = Binder.clearCallingIdentity(); 10546 10547 Message msg = Message.obtain(); 10548 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10549 HashMap<String, Object> data = new HashMap<String, Object>(); 10550 data.put("result", result); 10551 data.put("app", r); 10552 data.put("violationMask", violationMask); 10553 data.put("info", info); 10554 msg.obj = data; 10555 mHandler.sendMessage(msg); 10556 10557 Binder.restoreCallingIdentity(origId); 10558 } 10559 int res = result.get(); 10560 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10561 } 10562 } 10563 10564 // Depending on the policy in effect, there could be a bunch of 10565 // these in quick succession so we try to batch these together to 10566 // minimize disk writes, number of dropbox entries, and maximize 10567 // compression, by having more fewer, larger records. 10568 private void logStrictModeViolationToDropBox( 10569 ProcessRecord process, 10570 StrictMode.ViolationInfo info) { 10571 if (info == null) { 10572 return; 10573 } 10574 final boolean isSystemApp = process == null || 10575 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10576 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10577 final String processName = process == null ? "unknown" : process.processName; 10578 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10579 final DropBoxManager dbox = (DropBoxManager) 10580 mContext.getSystemService(Context.DROPBOX_SERVICE); 10581 10582 // Exit early if the dropbox isn't configured to accept this report type. 10583 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10584 10585 boolean bufferWasEmpty; 10586 boolean needsFlush; 10587 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10588 synchronized (sb) { 10589 bufferWasEmpty = sb.length() == 0; 10590 appendDropBoxProcessHeaders(process, processName, sb); 10591 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10592 sb.append("System-App: ").append(isSystemApp).append("\n"); 10593 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10594 if (info.violationNumThisLoop != 0) { 10595 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10596 } 10597 if (info.numAnimationsRunning != 0) { 10598 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10599 } 10600 if (info.broadcastIntentAction != null) { 10601 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10602 } 10603 if (info.durationMillis != -1) { 10604 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10605 } 10606 if (info.numInstances != -1) { 10607 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10608 } 10609 if (info.tags != null) { 10610 for (String tag : info.tags) { 10611 sb.append("Span-Tag: ").append(tag).append("\n"); 10612 } 10613 } 10614 sb.append("\n"); 10615 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10616 sb.append(info.crashInfo.stackTrace); 10617 } 10618 sb.append("\n"); 10619 10620 // Only buffer up to ~64k. Various logging bits truncate 10621 // things at 128k. 10622 needsFlush = (sb.length() > 64 * 1024); 10623 } 10624 10625 // Flush immediately if the buffer's grown too large, or this 10626 // is a non-system app. Non-system apps are isolated with a 10627 // different tag & policy and not batched. 10628 // 10629 // Batching is useful during internal testing with 10630 // StrictMode settings turned up high. Without batching, 10631 // thousands of separate files could be created on boot. 10632 if (!isSystemApp || needsFlush) { 10633 new Thread("Error dump: " + dropboxTag) { 10634 @Override 10635 public void run() { 10636 String report; 10637 synchronized (sb) { 10638 report = sb.toString(); 10639 sb.delete(0, sb.length()); 10640 sb.trimToSize(); 10641 } 10642 if (report.length() != 0) { 10643 dbox.addText(dropboxTag, report); 10644 } 10645 } 10646 }.start(); 10647 return; 10648 } 10649 10650 // System app batching: 10651 if (!bufferWasEmpty) { 10652 // An existing dropbox-writing thread is outstanding, so 10653 // we don't need to start it up. The existing thread will 10654 // catch the buffer appends we just did. 10655 return; 10656 } 10657 10658 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10659 // (After this point, we shouldn't access AMS internal data structures.) 10660 new Thread("Error dump: " + dropboxTag) { 10661 @Override 10662 public void run() { 10663 // 5 second sleep to let stacks arrive and be batched together 10664 try { 10665 Thread.sleep(5000); // 5 seconds 10666 } catch (InterruptedException e) {} 10667 10668 String errorReport; 10669 synchronized (mStrictModeBuffer) { 10670 errorReport = mStrictModeBuffer.toString(); 10671 if (errorReport.length() == 0) { 10672 return; 10673 } 10674 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10675 mStrictModeBuffer.trimToSize(); 10676 } 10677 dbox.addText(dropboxTag, errorReport); 10678 } 10679 }.start(); 10680 } 10681 10682 /** 10683 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10684 * @param app object of the crashing app, null for the system server 10685 * @param tag reported by the caller 10686 * @param crashInfo describing the context of the error 10687 * @return true if the process should exit immediately (WTF is fatal) 10688 */ 10689 public boolean handleApplicationWtf(IBinder app, String tag, 10690 ApplicationErrorReport.CrashInfo crashInfo) { 10691 ProcessRecord r = findAppProcess(app, "WTF"); 10692 final String processName = app == null ? "system_server" 10693 : (r == null ? "unknown" : r.processName); 10694 10695 EventLog.writeEvent(EventLogTags.AM_WTF, 10696 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10697 processName, 10698 r == null ? -1 : r.info.flags, 10699 tag, crashInfo.exceptionMessage); 10700 10701 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10702 10703 if (r != null && r.pid != Process.myPid() && 10704 Settings.Global.getInt(mContext.getContentResolver(), 10705 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10706 crashApplication(r, crashInfo); 10707 return true; 10708 } else { 10709 return false; 10710 } 10711 } 10712 10713 /** 10714 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10715 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10716 */ 10717 private ProcessRecord findAppProcess(IBinder app, String reason) { 10718 if (app == null) { 10719 return null; 10720 } 10721 10722 synchronized (this) { 10723 final int NP = mProcessNames.getMap().size(); 10724 for (int ip=0; ip<NP; ip++) { 10725 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10726 final int NA = apps.size(); 10727 for (int ia=0; ia<NA; ia++) { 10728 ProcessRecord p = apps.valueAt(ia); 10729 if (p.thread != null && p.thread.asBinder() == app) { 10730 return p; 10731 } 10732 } 10733 } 10734 10735 Slog.w(TAG, "Can't find mystery application for " + reason 10736 + " from pid=" + Binder.getCallingPid() 10737 + " uid=" + Binder.getCallingUid() + ": " + app); 10738 return null; 10739 } 10740 } 10741 10742 /** 10743 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10744 * to append various headers to the dropbox log text. 10745 */ 10746 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10747 StringBuilder sb) { 10748 // Watchdog thread ends up invoking this function (with 10749 // a null ProcessRecord) to add the stack file to dropbox. 10750 // Do not acquire a lock on this (am) in such cases, as it 10751 // could cause a potential deadlock, if and when watchdog 10752 // is invoked due to unavailability of lock on am and it 10753 // would prevent watchdog from killing system_server. 10754 if (process == null) { 10755 sb.append("Process: ").append(processName).append("\n"); 10756 return; 10757 } 10758 // Note: ProcessRecord 'process' is guarded by the service 10759 // instance. (notably process.pkgList, which could otherwise change 10760 // concurrently during execution of this method) 10761 synchronized (this) { 10762 sb.append("Process: ").append(processName).append("\n"); 10763 int flags = process.info.flags; 10764 IPackageManager pm = AppGlobals.getPackageManager(); 10765 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10766 for (int ip=0; ip<process.pkgList.size(); ip++) { 10767 String pkg = process.pkgList.keyAt(ip); 10768 sb.append("Package: ").append(pkg); 10769 try { 10770 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10771 if (pi != null) { 10772 sb.append(" v").append(pi.versionCode); 10773 if (pi.versionName != null) { 10774 sb.append(" (").append(pi.versionName).append(")"); 10775 } 10776 } 10777 } catch (RemoteException e) { 10778 Slog.e(TAG, "Error getting package info: " + pkg, e); 10779 } 10780 sb.append("\n"); 10781 } 10782 } 10783 } 10784 10785 private static String processClass(ProcessRecord process) { 10786 if (process == null || process.pid == MY_PID) { 10787 return "system_server"; 10788 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10789 return "system_app"; 10790 } else { 10791 return "data_app"; 10792 } 10793 } 10794 10795 /** 10796 * Write a description of an error (crash, WTF, ANR) to the drop box. 10797 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10798 * @param process which caused the error, null means the system server 10799 * @param activity which triggered the error, null if unknown 10800 * @param parent activity related to the error, null if unknown 10801 * @param subject line related to the error, null if absent 10802 * @param report in long form describing the error, null if absent 10803 * @param logFile to include in the report, null if none 10804 * @param crashInfo giving an application stack trace, null if absent 10805 */ 10806 public void addErrorToDropBox(String eventType, 10807 ProcessRecord process, String processName, ActivityRecord activity, 10808 ActivityRecord parent, String subject, 10809 final String report, final File logFile, 10810 final ApplicationErrorReport.CrashInfo crashInfo) { 10811 // NOTE -- this must never acquire the ActivityManagerService lock, 10812 // otherwise the watchdog may be prevented from resetting the system. 10813 10814 final String dropboxTag = processClass(process) + "_" + eventType; 10815 final DropBoxManager dbox = (DropBoxManager) 10816 mContext.getSystemService(Context.DROPBOX_SERVICE); 10817 10818 // Exit early if the dropbox isn't configured to accept this report type. 10819 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10820 10821 final StringBuilder sb = new StringBuilder(1024); 10822 appendDropBoxProcessHeaders(process, processName, sb); 10823 if (activity != null) { 10824 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10825 } 10826 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10827 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10828 } 10829 if (parent != null && parent != activity) { 10830 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10831 } 10832 if (subject != null) { 10833 sb.append("Subject: ").append(subject).append("\n"); 10834 } 10835 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10836 if (Debug.isDebuggerConnected()) { 10837 sb.append("Debugger: Connected\n"); 10838 } 10839 sb.append("\n"); 10840 10841 // Do the rest in a worker thread to avoid blocking the caller on I/O 10842 // (After this point, we shouldn't access AMS internal data structures.) 10843 Thread worker = new Thread("Error dump: " + dropboxTag) { 10844 @Override 10845 public void run() { 10846 if (report != null) { 10847 sb.append(report); 10848 } 10849 if (logFile != null) { 10850 try { 10851 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10852 "\n\n[[TRUNCATED]]")); 10853 } catch (IOException e) { 10854 Slog.e(TAG, "Error reading " + logFile, e); 10855 } 10856 } 10857 if (crashInfo != null && crashInfo.stackTrace != null) { 10858 sb.append(crashInfo.stackTrace); 10859 } 10860 10861 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10862 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10863 if (lines > 0) { 10864 sb.append("\n"); 10865 10866 // Merge several logcat streams, and take the last N lines 10867 InputStreamReader input = null; 10868 try { 10869 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10870 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10871 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10872 10873 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10874 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10875 input = new InputStreamReader(logcat.getInputStream()); 10876 10877 int num; 10878 char[] buf = new char[8192]; 10879 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10880 } catch (IOException e) { 10881 Slog.e(TAG, "Error running logcat", e); 10882 } finally { 10883 if (input != null) try { input.close(); } catch (IOException e) {} 10884 } 10885 } 10886 10887 dbox.addText(dropboxTag, sb.toString()); 10888 } 10889 }; 10890 10891 if (process == null) { 10892 // If process is null, we are being called from some internal code 10893 // and may be about to die -- run this synchronously. 10894 worker.run(); 10895 } else { 10896 worker.start(); 10897 } 10898 } 10899 10900 /** 10901 * Bring up the "unexpected error" dialog box for a crashing app. 10902 * Deal with edge cases (intercepts from instrumented applications, 10903 * ActivityController, error intent receivers, that sort of thing). 10904 * @param r the application crashing 10905 * @param crashInfo describing the failure 10906 */ 10907 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10908 long timeMillis = System.currentTimeMillis(); 10909 String shortMsg = crashInfo.exceptionClassName; 10910 String longMsg = crashInfo.exceptionMessage; 10911 String stackTrace = crashInfo.stackTrace; 10912 if (shortMsg != null && longMsg != null) { 10913 longMsg = shortMsg + ": " + longMsg; 10914 } else if (shortMsg != null) { 10915 longMsg = shortMsg; 10916 } 10917 10918 AppErrorResult result = new AppErrorResult(); 10919 synchronized (this) { 10920 if (mController != null) { 10921 try { 10922 String name = r != null ? r.processName : null; 10923 int pid = r != null ? r.pid : Binder.getCallingPid(); 10924 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10925 if (!mController.appCrashed(name, pid, 10926 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10927 Slog.w(TAG, "Force-killing crashed app " + name 10928 + " at watcher's request"); 10929 Process.killProcess(pid); 10930 if (r != null) { 10931 Process.killProcessGroup(uid, pid); 10932 } 10933 return; 10934 } 10935 } catch (RemoteException e) { 10936 mController = null; 10937 Watchdog.getInstance().setActivityController(null); 10938 } 10939 } 10940 10941 final long origId = Binder.clearCallingIdentity(); 10942 10943 // If this process is running instrumentation, finish it. 10944 if (r != null && r.instrumentationClass != null) { 10945 Slog.w(TAG, "Error in app " + r.processName 10946 + " running instrumentation " + r.instrumentationClass + ":"); 10947 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10948 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10949 Bundle info = new Bundle(); 10950 info.putString("shortMsg", shortMsg); 10951 info.putString("longMsg", longMsg); 10952 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10953 Binder.restoreCallingIdentity(origId); 10954 return; 10955 } 10956 10957 // If we can't identify the process or it's already exceeded its crash quota, 10958 // quit right away without showing a crash dialog. 10959 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10960 Binder.restoreCallingIdentity(origId); 10961 return; 10962 } 10963 10964 Message msg = Message.obtain(); 10965 msg.what = SHOW_ERROR_MSG; 10966 HashMap data = new HashMap(); 10967 data.put("result", result); 10968 data.put("app", r); 10969 msg.obj = data; 10970 mHandler.sendMessage(msg); 10971 10972 Binder.restoreCallingIdentity(origId); 10973 } 10974 10975 int res = result.get(); 10976 10977 Intent appErrorIntent = null; 10978 synchronized (this) { 10979 if (r != null && !r.isolated) { 10980 // XXX Can't keep track of crash time for isolated processes, 10981 // since they don't have a persistent identity. 10982 mProcessCrashTimes.put(r.info.processName, r.uid, 10983 SystemClock.uptimeMillis()); 10984 } 10985 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10986 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10987 } 10988 } 10989 10990 if (appErrorIntent != null) { 10991 try { 10992 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10993 } catch (ActivityNotFoundException e) { 10994 Slog.w(TAG, "bug report receiver dissappeared", e); 10995 } 10996 } 10997 } 10998 10999 Intent createAppErrorIntentLocked(ProcessRecord r, 11000 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11001 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11002 if (report == null) { 11003 return null; 11004 } 11005 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11006 result.setComponent(r.errorReportReceiver); 11007 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11008 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11009 return result; 11010 } 11011 11012 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11013 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11014 if (r.errorReportReceiver == null) { 11015 return null; 11016 } 11017 11018 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11019 return null; 11020 } 11021 11022 ApplicationErrorReport report = new ApplicationErrorReport(); 11023 report.packageName = r.info.packageName; 11024 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11025 report.processName = r.processName; 11026 report.time = timeMillis; 11027 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11028 11029 if (r.crashing || r.forceCrashReport) { 11030 report.type = ApplicationErrorReport.TYPE_CRASH; 11031 report.crashInfo = crashInfo; 11032 } else if (r.notResponding) { 11033 report.type = ApplicationErrorReport.TYPE_ANR; 11034 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11035 11036 report.anrInfo.activity = r.notRespondingReport.tag; 11037 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11038 report.anrInfo.info = r.notRespondingReport.longMsg; 11039 } 11040 11041 return report; 11042 } 11043 11044 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11045 enforceNotIsolatedCaller("getProcessesInErrorState"); 11046 // assume our apps are happy - lazy create the list 11047 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11048 11049 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11050 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11051 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11052 11053 synchronized (this) { 11054 11055 // iterate across all processes 11056 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11057 ProcessRecord app = mLruProcesses.get(i); 11058 if (!allUsers && app.userId != userId) { 11059 continue; 11060 } 11061 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11062 // This one's in trouble, so we'll generate a report for it 11063 // crashes are higher priority (in case there's a crash *and* an anr) 11064 ActivityManager.ProcessErrorStateInfo report = null; 11065 if (app.crashing) { 11066 report = app.crashingReport; 11067 } else if (app.notResponding) { 11068 report = app.notRespondingReport; 11069 } 11070 11071 if (report != null) { 11072 if (errList == null) { 11073 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11074 } 11075 errList.add(report); 11076 } else { 11077 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11078 " crashing = " + app.crashing + 11079 " notResponding = " + app.notResponding); 11080 } 11081 } 11082 } 11083 } 11084 11085 return errList; 11086 } 11087 11088 static int procStateToImportance(int procState, int memAdj, 11089 ActivityManager.RunningAppProcessInfo currApp) { 11090 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11091 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11092 currApp.lru = memAdj; 11093 } else { 11094 currApp.lru = 0; 11095 } 11096 return imp; 11097 } 11098 11099 private void fillInProcMemInfo(ProcessRecord app, 11100 ActivityManager.RunningAppProcessInfo outInfo) { 11101 outInfo.pid = app.pid; 11102 outInfo.uid = app.info.uid; 11103 if (mHeavyWeightProcess == app) { 11104 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11105 } 11106 if (app.persistent) { 11107 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11108 } 11109 if (app.activities.size() > 0) { 11110 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11111 } 11112 outInfo.lastTrimLevel = app.trimMemoryLevel; 11113 int adj = app.curAdj; 11114 int procState = app.curProcState; 11115 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11116 outInfo.importanceReasonCode = app.adjTypeCode; 11117 outInfo.processState = app.curProcState; 11118 } 11119 11120 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11121 enforceNotIsolatedCaller("getRunningAppProcesses"); 11122 // Lazy instantiation of list 11123 List<ActivityManager.RunningAppProcessInfo> runList = null; 11124 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11125 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11126 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11127 synchronized (this) { 11128 // Iterate across all processes 11129 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11130 ProcessRecord app = mLruProcesses.get(i); 11131 if (!allUsers && app.userId != userId) { 11132 continue; 11133 } 11134 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11135 // Generate process state info for running application 11136 ActivityManager.RunningAppProcessInfo currApp = 11137 new ActivityManager.RunningAppProcessInfo(app.processName, 11138 app.pid, app.getPackageList()); 11139 fillInProcMemInfo(app, currApp); 11140 if (app.adjSource instanceof ProcessRecord) { 11141 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11142 currApp.importanceReasonImportance = 11143 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11144 app.adjSourceProcState); 11145 } else if (app.adjSource instanceof ActivityRecord) { 11146 ActivityRecord r = (ActivityRecord)app.adjSource; 11147 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11148 } 11149 if (app.adjTarget instanceof ComponentName) { 11150 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11151 } 11152 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11153 // + " lru=" + currApp.lru); 11154 if (runList == null) { 11155 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11156 } 11157 runList.add(currApp); 11158 } 11159 } 11160 } 11161 return runList; 11162 } 11163 11164 public List<ApplicationInfo> getRunningExternalApplications() { 11165 enforceNotIsolatedCaller("getRunningExternalApplications"); 11166 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11167 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11168 if (runningApps != null && runningApps.size() > 0) { 11169 Set<String> extList = new HashSet<String>(); 11170 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11171 if (app.pkgList != null) { 11172 for (String pkg : app.pkgList) { 11173 extList.add(pkg); 11174 } 11175 } 11176 } 11177 IPackageManager pm = AppGlobals.getPackageManager(); 11178 for (String pkg : extList) { 11179 try { 11180 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11181 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11182 retList.add(info); 11183 } 11184 } catch (RemoteException e) { 11185 } 11186 } 11187 } 11188 return retList; 11189 } 11190 11191 @Override 11192 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11193 enforceNotIsolatedCaller("getMyMemoryState"); 11194 synchronized (this) { 11195 ProcessRecord proc; 11196 synchronized (mPidsSelfLocked) { 11197 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11198 } 11199 fillInProcMemInfo(proc, outInfo); 11200 } 11201 } 11202 11203 @Override 11204 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11205 if (checkCallingPermission(android.Manifest.permission.DUMP) 11206 != PackageManager.PERMISSION_GRANTED) { 11207 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11208 + Binder.getCallingPid() 11209 + ", uid=" + Binder.getCallingUid() 11210 + " without permission " 11211 + android.Manifest.permission.DUMP); 11212 return; 11213 } 11214 11215 boolean dumpAll = false; 11216 boolean dumpClient = false; 11217 String dumpPackage = null; 11218 11219 int opti = 0; 11220 while (opti < args.length) { 11221 String opt = args[opti]; 11222 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11223 break; 11224 } 11225 opti++; 11226 if ("-a".equals(opt)) { 11227 dumpAll = true; 11228 } else if ("-c".equals(opt)) { 11229 dumpClient = true; 11230 } else if ("-h".equals(opt)) { 11231 pw.println("Activity manager dump options:"); 11232 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11233 pw.println(" cmd may be one of:"); 11234 pw.println(" a[ctivities]: activity stack state"); 11235 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11236 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11237 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11238 pw.println(" o[om]: out of memory management"); 11239 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11240 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11241 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11242 pw.println(" service [COMP_SPEC]: service client-side state"); 11243 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11244 pw.println(" all: dump all activities"); 11245 pw.println(" top: dump the top activity"); 11246 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11247 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11248 pw.println(" a partial substring in a component name, a"); 11249 pw.println(" hex object identifier."); 11250 pw.println(" -a: include all available server state."); 11251 pw.println(" -c: include client state."); 11252 return; 11253 } else { 11254 pw.println("Unknown argument: " + opt + "; use -h for help"); 11255 } 11256 } 11257 11258 long origId = Binder.clearCallingIdentity(); 11259 boolean more = false; 11260 // Is the caller requesting to dump a particular piece of data? 11261 if (opti < args.length) { 11262 String cmd = args[opti]; 11263 opti++; 11264 if ("activities".equals(cmd) || "a".equals(cmd)) { 11265 synchronized (this) { 11266 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11267 } 11268 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11269 String[] newArgs; 11270 String name; 11271 if (opti >= args.length) { 11272 name = null; 11273 newArgs = EMPTY_STRING_ARRAY; 11274 } else { 11275 name = args[opti]; 11276 opti++; 11277 newArgs = new String[args.length - opti]; 11278 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11279 args.length - opti); 11280 } 11281 synchronized (this) { 11282 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11283 } 11284 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11285 String[] newArgs; 11286 String name; 11287 if (opti >= args.length) { 11288 name = null; 11289 newArgs = EMPTY_STRING_ARRAY; 11290 } else { 11291 name = args[opti]; 11292 opti++; 11293 newArgs = new String[args.length - opti]; 11294 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11295 args.length - opti); 11296 } 11297 synchronized (this) { 11298 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11299 } 11300 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11301 String[] newArgs; 11302 String name; 11303 if (opti >= args.length) { 11304 name = null; 11305 newArgs = EMPTY_STRING_ARRAY; 11306 } else { 11307 name = args[opti]; 11308 opti++; 11309 newArgs = new String[args.length - opti]; 11310 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11311 args.length - opti); 11312 } 11313 synchronized (this) { 11314 dumpProcessesLocked(fd, pw, args, opti, true, name); 11315 } 11316 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11317 synchronized (this) { 11318 dumpOomLocked(fd, pw, args, opti, true); 11319 } 11320 } else if ("provider".equals(cmd)) { 11321 String[] newArgs; 11322 String name; 11323 if (opti >= args.length) { 11324 name = null; 11325 newArgs = EMPTY_STRING_ARRAY; 11326 } else { 11327 name = args[opti]; 11328 opti++; 11329 newArgs = new String[args.length - opti]; 11330 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11331 } 11332 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11333 pw.println("No providers match: " + name); 11334 pw.println("Use -h for help."); 11335 } 11336 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11337 synchronized (this) { 11338 dumpProvidersLocked(fd, pw, args, opti, true, null); 11339 } 11340 } else if ("service".equals(cmd)) { 11341 String[] newArgs; 11342 String name; 11343 if (opti >= args.length) { 11344 name = null; 11345 newArgs = EMPTY_STRING_ARRAY; 11346 } else { 11347 name = args[opti]; 11348 opti++; 11349 newArgs = new String[args.length - opti]; 11350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11351 args.length - opti); 11352 } 11353 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11354 pw.println("No services match: " + name); 11355 pw.println("Use -h for help."); 11356 } 11357 } else if ("package".equals(cmd)) { 11358 String[] newArgs; 11359 if (opti >= args.length) { 11360 pw.println("package: no package name specified"); 11361 pw.println("Use -h for help."); 11362 } else { 11363 dumpPackage = args[opti]; 11364 opti++; 11365 newArgs = new String[args.length - opti]; 11366 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11367 args.length - opti); 11368 args = newArgs; 11369 opti = 0; 11370 more = true; 11371 } 11372 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11373 synchronized (this) { 11374 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11375 } 11376 } else { 11377 // Dumping a single activity? 11378 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11379 pw.println("Bad activity command, or no activities match: " + cmd); 11380 pw.println("Use -h for help."); 11381 } 11382 } 11383 if (!more) { 11384 Binder.restoreCallingIdentity(origId); 11385 return; 11386 } 11387 } 11388 11389 // No piece of data specified, dump everything. 11390 synchronized (this) { 11391 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11392 pw.println(); 11393 if (dumpAll) { 11394 pw.println("-------------------------------------------------------------------------------"); 11395 } 11396 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11397 pw.println(); 11398 if (dumpAll) { 11399 pw.println("-------------------------------------------------------------------------------"); 11400 } 11401 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11402 pw.println(); 11403 if (dumpAll) { 11404 pw.println("-------------------------------------------------------------------------------"); 11405 } 11406 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11407 pw.println(); 11408 if (dumpAll) { 11409 pw.println("-------------------------------------------------------------------------------"); 11410 } 11411 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11412 pw.println(); 11413 if (dumpAll) { 11414 pw.println("-------------------------------------------------------------------------------"); 11415 } 11416 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11417 } 11418 Binder.restoreCallingIdentity(origId); 11419 } 11420 11421 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11422 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11423 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11424 11425 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11426 dumpPackage); 11427 boolean needSep = printedAnything; 11428 11429 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11430 dumpPackage, needSep, " mFocusedActivity: "); 11431 if (printed) { 11432 printedAnything = true; 11433 needSep = false; 11434 } 11435 11436 if (dumpPackage == null) { 11437 if (needSep) { 11438 pw.println(); 11439 } 11440 needSep = true; 11441 printedAnything = true; 11442 mStackSupervisor.dump(pw, " "); 11443 } 11444 11445 if (mRecentTasks.size() > 0) { 11446 boolean printedHeader = false; 11447 11448 final int N = mRecentTasks.size(); 11449 for (int i=0; i<N; i++) { 11450 TaskRecord tr = mRecentTasks.get(i); 11451 if (dumpPackage != null) { 11452 if (tr.realActivity == null || 11453 !dumpPackage.equals(tr.realActivity)) { 11454 continue; 11455 } 11456 } 11457 if (!printedHeader) { 11458 if (needSep) { 11459 pw.println(); 11460 } 11461 pw.println(" Recent tasks:"); 11462 printedHeader = true; 11463 printedAnything = true; 11464 } 11465 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11466 pw.println(tr); 11467 if (dumpAll) { 11468 mRecentTasks.get(i).dump(pw, " "); 11469 } 11470 } 11471 } 11472 11473 if (!printedAnything) { 11474 pw.println(" (nothing)"); 11475 } 11476 } 11477 11478 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11479 int opti, boolean dumpAll, String dumpPackage) { 11480 boolean needSep = false; 11481 boolean printedAnything = false; 11482 int numPers = 0; 11483 11484 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11485 11486 if (dumpAll) { 11487 final int NP = mProcessNames.getMap().size(); 11488 for (int ip=0; ip<NP; ip++) { 11489 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11490 final int NA = procs.size(); 11491 for (int ia=0; ia<NA; ia++) { 11492 ProcessRecord r = procs.valueAt(ia); 11493 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11494 continue; 11495 } 11496 if (!needSep) { 11497 pw.println(" All known processes:"); 11498 needSep = true; 11499 printedAnything = true; 11500 } 11501 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11502 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11503 pw.print(" "); pw.println(r); 11504 r.dump(pw, " "); 11505 if (r.persistent) { 11506 numPers++; 11507 } 11508 } 11509 } 11510 } 11511 11512 if (mIsolatedProcesses.size() > 0) { 11513 boolean printed = false; 11514 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11515 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11516 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11517 continue; 11518 } 11519 if (!printed) { 11520 if (needSep) { 11521 pw.println(); 11522 } 11523 pw.println(" Isolated process list (sorted by uid):"); 11524 printedAnything = true; 11525 printed = true; 11526 needSep = true; 11527 } 11528 pw.println(String.format("%sIsolated #%2d: %s", 11529 " ", i, r.toString())); 11530 } 11531 } 11532 11533 if (mLruProcesses.size() > 0) { 11534 if (needSep) { 11535 pw.println(); 11536 } 11537 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11538 pw.print(" total, non-act at "); 11539 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11540 pw.print(", non-svc at "); 11541 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11542 pw.println("):"); 11543 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11544 needSep = true; 11545 printedAnything = true; 11546 } 11547 11548 if (dumpAll || dumpPackage != null) { 11549 synchronized (mPidsSelfLocked) { 11550 boolean printed = false; 11551 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11552 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11553 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11554 continue; 11555 } 11556 if (!printed) { 11557 if (needSep) pw.println(); 11558 needSep = true; 11559 pw.println(" PID mappings:"); 11560 printed = true; 11561 printedAnything = true; 11562 } 11563 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11564 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11565 } 11566 } 11567 } 11568 11569 if (mForegroundProcesses.size() > 0) { 11570 synchronized (mPidsSelfLocked) { 11571 boolean printed = false; 11572 for (int i=0; i<mForegroundProcesses.size(); i++) { 11573 ProcessRecord r = mPidsSelfLocked.get( 11574 mForegroundProcesses.valueAt(i).pid); 11575 if (dumpPackage != null && (r == null 11576 || !r.pkgList.containsKey(dumpPackage))) { 11577 continue; 11578 } 11579 if (!printed) { 11580 if (needSep) pw.println(); 11581 needSep = true; 11582 pw.println(" Foreground Processes:"); 11583 printed = true; 11584 printedAnything = true; 11585 } 11586 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11587 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11588 } 11589 } 11590 } 11591 11592 if (mPersistentStartingProcesses.size() > 0) { 11593 if (needSep) pw.println(); 11594 needSep = true; 11595 printedAnything = true; 11596 pw.println(" Persisent processes that are starting:"); 11597 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11598 "Starting Norm", "Restarting PERS", dumpPackage); 11599 } 11600 11601 if (mRemovedProcesses.size() > 0) { 11602 if (needSep) pw.println(); 11603 needSep = true; 11604 printedAnything = true; 11605 pw.println(" Processes that are being removed:"); 11606 dumpProcessList(pw, this, mRemovedProcesses, " ", 11607 "Removed Norm", "Removed PERS", dumpPackage); 11608 } 11609 11610 if (mProcessesOnHold.size() > 0) { 11611 if (needSep) pw.println(); 11612 needSep = true; 11613 printedAnything = true; 11614 pw.println(" Processes that are on old until the system is ready:"); 11615 dumpProcessList(pw, this, mProcessesOnHold, " ", 11616 "OnHold Norm", "OnHold PERS", dumpPackage); 11617 } 11618 11619 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11620 11621 if (mProcessCrashTimes.getMap().size() > 0) { 11622 boolean printed = false; 11623 long now = SystemClock.uptimeMillis(); 11624 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11625 final int NP = pmap.size(); 11626 for (int ip=0; ip<NP; ip++) { 11627 String pname = pmap.keyAt(ip); 11628 SparseArray<Long> uids = pmap.valueAt(ip); 11629 final int N = uids.size(); 11630 for (int i=0; i<N; i++) { 11631 int puid = uids.keyAt(i); 11632 ProcessRecord r = mProcessNames.get(pname, puid); 11633 if (dumpPackage != null && (r == null 11634 || !r.pkgList.containsKey(dumpPackage))) { 11635 continue; 11636 } 11637 if (!printed) { 11638 if (needSep) pw.println(); 11639 needSep = true; 11640 pw.println(" Time since processes crashed:"); 11641 printed = true; 11642 printedAnything = true; 11643 } 11644 pw.print(" Process "); pw.print(pname); 11645 pw.print(" uid "); pw.print(puid); 11646 pw.print(": last crashed "); 11647 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11648 pw.println(" ago"); 11649 } 11650 } 11651 } 11652 11653 if (mBadProcesses.getMap().size() > 0) { 11654 boolean printed = false; 11655 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11656 final int NP = pmap.size(); 11657 for (int ip=0; ip<NP; ip++) { 11658 String pname = pmap.keyAt(ip); 11659 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11660 final int N = uids.size(); 11661 for (int i=0; i<N; i++) { 11662 int puid = uids.keyAt(i); 11663 ProcessRecord r = mProcessNames.get(pname, puid); 11664 if (dumpPackage != null && (r == null 11665 || !r.pkgList.containsKey(dumpPackage))) { 11666 continue; 11667 } 11668 if (!printed) { 11669 if (needSep) pw.println(); 11670 needSep = true; 11671 pw.println(" Bad processes:"); 11672 printedAnything = true; 11673 } 11674 BadProcessInfo info = uids.valueAt(i); 11675 pw.print(" Bad process "); pw.print(pname); 11676 pw.print(" uid "); pw.print(puid); 11677 pw.print(": crashed at time "); pw.println(info.time); 11678 if (info.shortMsg != null) { 11679 pw.print(" Short msg: "); pw.println(info.shortMsg); 11680 } 11681 if (info.longMsg != null) { 11682 pw.print(" Long msg: "); pw.println(info.longMsg); 11683 } 11684 if (info.stack != null) { 11685 pw.println(" Stack:"); 11686 int lastPos = 0; 11687 for (int pos=0; pos<info.stack.length(); pos++) { 11688 if (info.stack.charAt(pos) == '\n') { 11689 pw.print(" "); 11690 pw.write(info.stack, lastPos, pos-lastPos); 11691 pw.println(); 11692 lastPos = pos+1; 11693 } 11694 } 11695 if (lastPos < info.stack.length()) { 11696 pw.print(" "); 11697 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11698 pw.println(); 11699 } 11700 } 11701 } 11702 } 11703 } 11704 11705 if (dumpPackage == null) { 11706 pw.println(); 11707 needSep = false; 11708 pw.println(" mStartedUsers:"); 11709 for (int i=0; i<mStartedUsers.size(); i++) { 11710 UserStartedState uss = mStartedUsers.valueAt(i); 11711 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11712 pw.print(": "); uss.dump("", pw); 11713 } 11714 pw.print(" mStartedUserArray: ["); 11715 for (int i=0; i<mStartedUserArray.length; i++) { 11716 if (i > 0) pw.print(", "); 11717 pw.print(mStartedUserArray[i]); 11718 } 11719 pw.println("]"); 11720 pw.print(" mUserLru: ["); 11721 for (int i=0; i<mUserLru.size(); i++) { 11722 if (i > 0) pw.print(", "); 11723 pw.print(mUserLru.get(i)); 11724 } 11725 pw.println("]"); 11726 if (dumpAll) { 11727 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11728 } 11729 synchronized (mUserProfileGroupIdsSelfLocked) { 11730 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 11731 pw.println(" mUserProfileGroupIds:"); 11732 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 11733 pw.print(" User #"); 11734 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 11735 pw.print(" -> profile #"); 11736 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 11737 } 11738 } 11739 } 11740 } 11741 if (mHomeProcess != null && (dumpPackage == null 11742 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11743 if (needSep) { 11744 pw.println(); 11745 needSep = false; 11746 } 11747 pw.println(" mHomeProcess: " + mHomeProcess); 11748 } 11749 if (mPreviousProcess != null && (dumpPackage == null 11750 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11751 if (needSep) { 11752 pw.println(); 11753 needSep = false; 11754 } 11755 pw.println(" mPreviousProcess: " + mPreviousProcess); 11756 } 11757 if (dumpAll) { 11758 StringBuilder sb = new StringBuilder(128); 11759 sb.append(" mPreviousProcessVisibleTime: "); 11760 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11761 pw.println(sb); 11762 } 11763 if (mHeavyWeightProcess != null && (dumpPackage == null 11764 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11765 if (needSep) { 11766 pw.println(); 11767 needSep = false; 11768 } 11769 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11770 } 11771 if (dumpPackage == null) { 11772 pw.println(" mConfiguration: " + mConfiguration); 11773 } 11774 if (dumpAll) { 11775 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11776 if (mCompatModePackages.getPackages().size() > 0) { 11777 boolean printed = false; 11778 for (Map.Entry<String, Integer> entry 11779 : mCompatModePackages.getPackages().entrySet()) { 11780 String pkg = entry.getKey(); 11781 int mode = entry.getValue(); 11782 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11783 continue; 11784 } 11785 if (!printed) { 11786 pw.println(" mScreenCompatPackages:"); 11787 printed = true; 11788 } 11789 pw.print(" "); pw.print(pkg); pw.print(": "); 11790 pw.print(mode); pw.println(); 11791 } 11792 } 11793 } 11794 if (dumpPackage == null) { 11795 if (mSleeping || mWentToSleep || mLockScreenShown) { 11796 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11797 + " mLockScreenShown " + mLockScreenShown); 11798 } 11799 if (mShuttingDown || mRunningVoice) { 11800 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11801 } 11802 } 11803 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11804 || mOrigWaitForDebugger) { 11805 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11806 || dumpPackage.equals(mOrigDebugApp)) { 11807 if (needSep) { 11808 pw.println(); 11809 needSep = false; 11810 } 11811 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11812 + " mDebugTransient=" + mDebugTransient 11813 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11814 } 11815 } 11816 if (mOpenGlTraceApp != null) { 11817 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11818 if (needSep) { 11819 pw.println(); 11820 needSep = false; 11821 } 11822 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11823 } 11824 } 11825 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11826 || mProfileFd != null) { 11827 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11828 if (needSep) { 11829 pw.println(); 11830 needSep = false; 11831 } 11832 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11833 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11834 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11835 + mAutoStopProfiler); 11836 } 11837 } 11838 if (dumpPackage == null) { 11839 if (mAlwaysFinishActivities || mController != null) { 11840 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11841 + " mController=" + mController); 11842 } 11843 if (dumpAll) { 11844 pw.println(" Total persistent processes: " + numPers); 11845 pw.println(" mProcessesReady=" + mProcessesReady 11846 + " mSystemReady=" + mSystemReady); 11847 pw.println(" mBooting=" + mBooting 11848 + " mBooted=" + mBooted 11849 + " mFactoryTest=" + mFactoryTest); 11850 pw.print(" mLastPowerCheckRealtime="); 11851 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11852 pw.println(""); 11853 pw.print(" mLastPowerCheckUptime="); 11854 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11855 pw.println(""); 11856 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11857 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11858 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11859 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11860 + " (" + mLruProcesses.size() + " total)" 11861 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11862 + " mNumServiceProcs=" + mNumServiceProcs 11863 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11864 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11865 + " mLastMemoryLevel" + mLastMemoryLevel 11866 + " mLastNumProcesses" + mLastNumProcesses); 11867 long now = SystemClock.uptimeMillis(); 11868 pw.print(" mLastIdleTime="); 11869 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11870 pw.print(" mLowRamSinceLastIdle="); 11871 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11872 pw.println(); 11873 } 11874 } 11875 11876 if (!printedAnything) { 11877 pw.println(" (nothing)"); 11878 } 11879 } 11880 11881 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11882 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11883 if (mProcessesToGc.size() > 0) { 11884 boolean printed = false; 11885 long now = SystemClock.uptimeMillis(); 11886 for (int i=0; i<mProcessesToGc.size(); i++) { 11887 ProcessRecord proc = mProcessesToGc.get(i); 11888 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11889 continue; 11890 } 11891 if (!printed) { 11892 if (needSep) pw.println(); 11893 needSep = true; 11894 pw.println(" Processes that are waiting to GC:"); 11895 printed = true; 11896 } 11897 pw.print(" Process "); pw.println(proc); 11898 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11899 pw.print(", last gced="); 11900 pw.print(now-proc.lastRequestedGc); 11901 pw.print(" ms ago, last lowMem="); 11902 pw.print(now-proc.lastLowMemory); 11903 pw.println(" ms ago"); 11904 11905 } 11906 } 11907 return needSep; 11908 } 11909 11910 void printOomLevel(PrintWriter pw, String name, int adj) { 11911 pw.print(" "); 11912 if (adj >= 0) { 11913 pw.print(' '); 11914 if (adj < 10) pw.print(' '); 11915 } else { 11916 if (adj > -10) pw.print(' '); 11917 } 11918 pw.print(adj); 11919 pw.print(": "); 11920 pw.print(name); 11921 pw.print(" ("); 11922 pw.print(mProcessList.getMemLevel(adj)/1024); 11923 pw.println(" kB)"); 11924 } 11925 11926 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11927 int opti, boolean dumpAll) { 11928 boolean needSep = false; 11929 11930 if (mLruProcesses.size() > 0) { 11931 if (needSep) pw.println(); 11932 needSep = true; 11933 pw.println(" OOM levels:"); 11934 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11935 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11936 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11937 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11938 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11939 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11940 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11941 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11942 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11943 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11944 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11945 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11946 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11947 11948 if (needSep) pw.println(); 11949 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11950 pw.print(" total, non-act at "); 11951 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11952 pw.print(", non-svc at "); 11953 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11954 pw.println("):"); 11955 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11956 needSep = true; 11957 } 11958 11959 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11960 11961 pw.println(); 11962 pw.println(" mHomeProcess: " + mHomeProcess); 11963 pw.println(" mPreviousProcess: " + mPreviousProcess); 11964 if (mHeavyWeightProcess != null) { 11965 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11966 } 11967 11968 return true; 11969 } 11970 11971 /** 11972 * There are three ways to call this: 11973 * - no provider specified: dump all the providers 11974 * - a flattened component name that matched an existing provider was specified as the 11975 * first arg: dump that one provider 11976 * - the first arg isn't the flattened component name of an existing provider: 11977 * dump all providers whose component contains the first arg as a substring 11978 */ 11979 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11980 int opti, boolean dumpAll) { 11981 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11982 } 11983 11984 static class ItemMatcher { 11985 ArrayList<ComponentName> components; 11986 ArrayList<String> strings; 11987 ArrayList<Integer> objects; 11988 boolean all; 11989 11990 ItemMatcher() { 11991 all = true; 11992 } 11993 11994 void build(String name) { 11995 ComponentName componentName = ComponentName.unflattenFromString(name); 11996 if (componentName != null) { 11997 if (components == null) { 11998 components = new ArrayList<ComponentName>(); 11999 } 12000 components.add(componentName); 12001 all = false; 12002 } else { 12003 int objectId = 0; 12004 // Not a '/' separated full component name; maybe an object ID? 12005 try { 12006 objectId = Integer.parseInt(name, 16); 12007 if (objects == null) { 12008 objects = new ArrayList<Integer>(); 12009 } 12010 objects.add(objectId); 12011 all = false; 12012 } catch (RuntimeException e) { 12013 // Not an integer; just do string match. 12014 if (strings == null) { 12015 strings = new ArrayList<String>(); 12016 } 12017 strings.add(name); 12018 all = false; 12019 } 12020 } 12021 } 12022 12023 int build(String[] args, int opti) { 12024 for (; opti<args.length; opti++) { 12025 String name = args[opti]; 12026 if ("--".equals(name)) { 12027 return opti+1; 12028 } 12029 build(name); 12030 } 12031 return opti; 12032 } 12033 12034 boolean match(Object object, ComponentName comp) { 12035 if (all) { 12036 return true; 12037 } 12038 if (components != null) { 12039 for (int i=0; i<components.size(); i++) { 12040 if (components.get(i).equals(comp)) { 12041 return true; 12042 } 12043 } 12044 } 12045 if (objects != null) { 12046 for (int i=0; i<objects.size(); i++) { 12047 if (System.identityHashCode(object) == objects.get(i)) { 12048 return true; 12049 } 12050 } 12051 } 12052 if (strings != null) { 12053 String flat = comp.flattenToString(); 12054 for (int i=0; i<strings.size(); i++) { 12055 if (flat.contains(strings.get(i))) { 12056 return true; 12057 } 12058 } 12059 } 12060 return false; 12061 } 12062 } 12063 12064 /** 12065 * There are three things that cmd can be: 12066 * - a flattened component name that matches an existing activity 12067 * - the cmd arg isn't the flattened component name of an existing activity: 12068 * dump all activity whose component contains the cmd as a substring 12069 * - A hex number of the ActivityRecord object instance. 12070 */ 12071 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12072 int opti, boolean dumpAll) { 12073 ArrayList<ActivityRecord> activities; 12074 12075 synchronized (this) { 12076 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12077 } 12078 12079 if (activities.size() <= 0) { 12080 return false; 12081 } 12082 12083 String[] newArgs = new String[args.length - opti]; 12084 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12085 12086 TaskRecord lastTask = null; 12087 boolean needSep = false; 12088 for (int i=activities.size()-1; i>=0; i--) { 12089 ActivityRecord r = activities.get(i); 12090 if (needSep) { 12091 pw.println(); 12092 } 12093 needSep = true; 12094 synchronized (this) { 12095 if (lastTask != r.task) { 12096 lastTask = r.task; 12097 pw.print("TASK "); pw.print(lastTask.affinity); 12098 pw.print(" id="); pw.println(lastTask.taskId); 12099 if (dumpAll) { 12100 lastTask.dump(pw, " "); 12101 } 12102 } 12103 } 12104 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12105 } 12106 return true; 12107 } 12108 12109 /** 12110 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12111 * there is a thread associated with the activity. 12112 */ 12113 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12114 final ActivityRecord r, String[] args, boolean dumpAll) { 12115 String innerPrefix = prefix + " "; 12116 synchronized (this) { 12117 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12118 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12119 pw.print(" pid="); 12120 if (r.app != null) pw.println(r.app.pid); 12121 else pw.println("(not running)"); 12122 if (dumpAll) { 12123 r.dump(pw, innerPrefix); 12124 } 12125 } 12126 if (r.app != null && r.app.thread != null) { 12127 // flush anything that is already in the PrintWriter since the thread is going 12128 // to write to the file descriptor directly 12129 pw.flush(); 12130 try { 12131 TransferPipe tp = new TransferPipe(); 12132 try { 12133 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12134 r.appToken, innerPrefix, args); 12135 tp.go(fd); 12136 } finally { 12137 tp.kill(); 12138 } 12139 } catch (IOException e) { 12140 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12141 } catch (RemoteException e) { 12142 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12143 } 12144 } 12145 } 12146 12147 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12148 int opti, boolean dumpAll, String dumpPackage) { 12149 boolean needSep = false; 12150 boolean onlyHistory = false; 12151 boolean printedAnything = false; 12152 12153 if ("history".equals(dumpPackage)) { 12154 if (opti < args.length && "-s".equals(args[opti])) { 12155 dumpAll = false; 12156 } 12157 onlyHistory = true; 12158 dumpPackage = null; 12159 } 12160 12161 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12162 if (!onlyHistory && dumpAll) { 12163 if (mRegisteredReceivers.size() > 0) { 12164 boolean printed = false; 12165 Iterator it = mRegisteredReceivers.values().iterator(); 12166 while (it.hasNext()) { 12167 ReceiverList r = (ReceiverList)it.next(); 12168 if (dumpPackage != null && (r.app == null || 12169 !dumpPackage.equals(r.app.info.packageName))) { 12170 continue; 12171 } 12172 if (!printed) { 12173 pw.println(" Registered Receivers:"); 12174 needSep = true; 12175 printed = true; 12176 printedAnything = true; 12177 } 12178 pw.print(" * "); pw.println(r); 12179 r.dump(pw, " "); 12180 } 12181 } 12182 12183 if (mReceiverResolver.dump(pw, needSep ? 12184 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12185 " ", dumpPackage, false)) { 12186 needSep = true; 12187 printedAnything = true; 12188 } 12189 } 12190 12191 for (BroadcastQueue q : mBroadcastQueues) { 12192 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12193 printedAnything |= needSep; 12194 } 12195 12196 needSep = true; 12197 12198 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12199 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12200 if (needSep) { 12201 pw.println(); 12202 } 12203 needSep = true; 12204 printedAnything = true; 12205 pw.print(" Sticky broadcasts for user "); 12206 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12207 StringBuilder sb = new StringBuilder(128); 12208 for (Map.Entry<String, ArrayList<Intent>> ent 12209 : mStickyBroadcasts.valueAt(user).entrySet()) { 12210 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12211 if (dumpAll) { 12212 pw.println(":"); 12213 ArrayList<Intent> intents = ent.getValue(); 12214 final int N = intents.size(); 12215 for (int i=0; i<N; i++) { 12216 sb.setLength(0); 12217 sb.append(" Intent: "); 12218 intents.get(i).toShortString(sb, false, true, false, false); 12219 pw.println(sb.toString()); 12220 Bundle bundle = intents.get(i).getExtras(); 12221 if (bundle != null) { 12222 pw.print(" "); 12223 pw.println(bundle.toString()); 12224 } 12225 } 12226 } else { 12227 pw.println(""); 12228 } 12229 } 12230 } 12231 } 12232 12233 if (!onlyHistory && dumpAll) { 12234 pw.println(); 12235 for (BroadcastQueue queue : mBroadcastQueues) { 12236 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12237 + queue.mBroadcastsScheduled); 12238 } 12239 pw.println(" mHandler:"); 12240 mHandler.dump(new PrintWriterPrinter(pw), " "); 12241 needSep = true; 12242 printedAnything = true; 12243 } 12244 12245 if (!printedAnything) { 12246 pw.println(" (nothing)"); 12247 } 12248 } 12249 12250 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12251 int opti, boolean dumpAll, String dumpPackage) { 12252 boolean needSep; 12253 boolean printedAnything = false; 12254 12255 ItemMatcher matcher = new ItemMatcher(); 12256 matcher.build(args, opti); 12257 12258 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12259 12260 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12261 printedAnything |= needSep; 12262 12263 if (mLaunchingProviders.size() > 0) { 12264 boolean printed = false; 12265 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12266 ContentProviderRecord r = mLaunchingProviders.get(i); 12267 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12268 continue; 12269 } 12270 if (!printed) { 12271 if (needSep) pw.println(); 12272 needSep = true; 12273 pw.println(" Launching content providers:"); 12274 printed = true; 12275 printedAnything = true; 12276 } 12277 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12278 pw.println(r); 12279 } 12280 } 12281 12282 if (mGrantedUriPermissions.size() > 0) { 12283 boolean printed = false; 12284 int dumpUid = -2; 12285 if (dumpPackage != null) { 12286 try { 12287 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12288 } catch (NameNotFoundException e) { 12289 dumpUid = -1; 12290 } 12291 } 12292 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12293 int uid = mGrantedUriPermissions.keyAt(i); 12294 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12295 continue; 12296 } 12297 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12298 if (!printed) { 12299 if (needSep) pw.println(); 12300 needSep = true; 12301 pw.println(" Granted Uri Permissions:"); 12302 printed = true; 12303 printedAnything = true; 12304 } 12305 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12306 for (UriPermission perm : perms.values()) { 12307 pw.print(" "); pw.println(perm); 12308 if (dumpAll) { 12309 perm.dump(pw, " "); 12310 } 12311 } 12312 } 12313 } 12314 12315 if (!printedAnything) { 12316 pw.println(" (nothing)"); 12317 } 12318 } 12319 12320 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12321 int opti, boolean dumpAll, String dumpPackage) { 12322 boolean printed = false; 12323 12324 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12325 12326 if (mIntentSenderRecords.size() > 0) { 12327 Iterator<WeakReference<PendingIntentRecord>> it 12328 = mIntentSenderRecords.values().iterator(); 12329 while (it.hasNext()) { 12330 WeakReference<PendingIntentRecord> ref = it.next(); 12331 PendingIntentRecord rec = ref != null ? ref.get(): null; 12332 if (dumpPackage != null && (rec == null 12333 || !dumpPackage.equals(rec.key.packageName))) { 12334 continue; 12335 } 12336 printed = true; 12337 if (rec != null) { 12338 pw.print(" * "); pw.println(rec); 12339 if (dumpAll) { 12340 rec.dump(pw, " "); 12341 } 12342 } else { 12343 pw.print(" * "); pw.println(ref); 12344 } 12345 } 12346 } 12347 12348 if (!printed) { 12349 pw.println(" (nothing)"); 12350 } 12351 } 12352 12353 private static final int dumpProcessList(PrintWriter pw, 12354 ActivityManagerService service, List list, 12355 String prefix, String normalLabel, String persistentLabel, 12356 String dumpPackage) { 12357 int numPers = 0; 12358 final int N = list.size()-1; 12359 for (int i=N; i>=0; i--) { 12360 ProcessRecord r = (ProcessRecord)list.get(i); 12361 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12362 continue; 12363 } 12364 pw.println(String.format("%s%s #%2d: %s", 12365 prefix, (r.persistent ? persistentLabel : normalLabel), 12366 i, r.toString())); 12367 if (r.persistent) { 12368 numPers++; 12369 } 12370 } 12371 return numPers; 12372 } 12373 12374 private static final boolean dumpProcessOomList(PrintWriter pw, 12375 ActivityManagerService service, List<ProcessRecord> origList, 12376 String prefix, String normalLabel, String persistentLabel, 12377 boolean inclDetails, String dumpPackage) { 12378 12379 ArrayList<Pair<ProcessRecord, Integer>> list 12380 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12381 for (int i=0; i<origList.size(); i++) { 12382 ProcessRecord r = origList.get(i); 12383 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12384 continue; 12385 } 12386 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12387 } 12388 12389 if (list.size() <= 0) { 12390 return false; 12391 } 12392 12393 Comparator<Pair<ProcessRecord, Integer>> comparator 12394 = new Comparator<Pair<ProcessRecord, Integer>>() { 12395 @Override 12396 public int compare(Pair<ProcessRecord, Integer> object1, 12397 Pair<ProcessRecord, Integer> object2) { 12398 if (object1.first.setAdj != object2.first.setAdj) { 12399 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12400 } 12401 if (object1.second.intValue() != object2.second.intValue()) { 12402 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12403 } 12404 return 0; 12405 } 12406 }; 12407 12408 Collections.sort(list, comparator); 12409 12410 final long curRealtime = SystemClock.elapsedRealtime(); 12411 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12412 final long curUptime = SystemClock.uptimeMillis(); 12413 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12414 12415 for (int i=list.size()-1; i>=0; i--) { 12416 ProcessRecord r = list.get(i).first; 12417 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12418 char schedGroup; 12419 switch (r.setSchedGroup) { 12420 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12421 schedGroup = 'B'; 12422 break; 12423 case Process.THREAD_GROUP_DEFAULT: 12424 schedGroup = 'F'; 12425 break; 12426 default: 12427 schedGroup = '?'; 12428 break; 12429 } 12430 char foreground; 12431 if (r.foregroundActivities) { 12432 foreground = 'A'; 12433 } else if (r.foregroundServices) { 12434 foreground = 'S'; 12435 } else { 12436 foreground = ' '; 12437 } 12438 String procState = ProcessList.makeProcStateString(r.curProcState); 12439 pw.print(prefix); 12440 pw.print(r.persistent ? persistentLabel : normalLabel); 12441 pw.print(" #"); 12442 int num = (origList.size()-1)-list.get(i).second; 12443 if (num < 10) pw.print(' '); 12444 pw.print(num); 12445 pw.print(": "); 12446 pw.print(oomAdj); 12447 pw.print(' '); 12448 pw.print(schedGroup); 12449 pw.print('/'); 12450 pw.print(foreground); 12451 pw.print('/'); 12452 pw.print(procState); 12453 pw.print(" trm:"); 12454 if (r.trimMemoryLevel < 10) pw.print(' '); 12455 pw.print(r.trimMemoryLevel); 12456 pw.print(' '); 12457 pw.print(r.toShortString()); 12458 pw.print(" ("); 12459 pw.print(r.adjType); 12460 pw.println(')'); 12461 if (r.adjSource != null || r.adjTarget != null) { 12462 pw.print(prefix); 12463 pw.print(" "); 12464 if (r.adjTarget instanceof ComponentName) { 12465 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12466 } else if (r.adjTarget != null) { 12467 pw.print(r.adjTarget.toString()); 12468 } else { 12469 pw.print("{null}"); 12470 } 12471 pw.print("<="); 12472 if (r.adjSource instanceof ProcessRecord) { 12473 pw.print("Proc{"); 12474 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12475 pw.println("}"); 12476 } else if (r.adjSource != null) { 12477 pw.println(r.adjSource.toString()); 12478 } else { 12479 pw.println("{null}"); 12480 } 12481 } 12482 if (inclDetails) { 12483 pw.print(prefix); 12484 pw.print(" "); 12485 pw.print("oom: max="); pw.print(r.maxAdj); 12486 pw.print(" curRaw="); pw.print(r.curRawAdj); 12487 pw.print(" setRaw="); pw.print(r.setRawAdj); 12488 pw.print(" cur="); pw.print(r.curAdj); 12489 pw.print(" set="); pw.println(r.setAdj); 12490 pw.print(prefix); 12491 pw.print(" "); 12492 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12493 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12494 pw.print(" lastPss="); pw.print(r.lastPss); 12495 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12496 pw.print(prefix); 12497 pw.print(" "); 12498 pw.print("cached="); pw.print(r.cached); 12499 pw.print(" empty="); pw.print(r.empty); 12500 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12501 12502 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12503 if (r.lastWakeTime != 0) { 12504 long wtime; 12505 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12506 synchronized (stats) { 12507 wtime = stats.getProcessWakeTime(r.info.uid, 12508 r.pid, curRealtime); 12509 } 12510 long timeUsed = wtime - r.lastWakeTime; 12511 pw.print(prefix); 12512 pw.print(" "); 12513 pw.print("keep awake over "); 12514 TimeUtils.formatDuration(realtimeSince, pw); 12515 pw.print(" used "); 12516 TimeUtils.formatDuration(timeUsed, pw); 12517 pw.print(" ("); 12518 pw.print((timeUsed*100)/realtimeSince); 12519 pw.println("%)"); 12520 } 12521 if (r.lastCpuTime != 0) { 12522 long timeUsed = r.curCpuTime - r.lastCpuTime; 12523 pw.print(prefix); 12524 pw.print(" "); 12525 pw.print("run cpu over "); 12526 TimeUtils.formatDuration(uptimeSince, pw); 12527 pw.print(" used "); 12528 TimeUtils.formatDuration(timeUsed, pw); 12529 pw.print(" ("); 12530 pw.print((timeUsed*100)/uptimeSince); 12531 pw.println("%)"); 12532 } 12533 } 12534 } 12535 } 12536 return true; 12537 } 12538 12539 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12540 ArrayList<ProcessRecord> procs; 12541 synchronized (this) { 12542 if (args != null && args.length > start 12543 && args[start].charAt(0) != '-') { 12544 procs = new ArrayList<ProcessRecord>(); 12545 int pid = -1; 12546 try { 12547 pid = Integer.parseInt(args[start]); 12548 } catch (NumberFormatException e) { 12549 } 12550 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12551 ProcessRecord proc = mLruProcesses.get(i); 12552 if (proc.pid == pid) { 12553 procs.add(proc); 12554 } else if (proc.processName.equals(args[start])) { 12555 procs.add(proc); 12556 } 12557 } 12558 if (procs.size() <= 0) { 12559 return null; 12560 } 12561 } else { 12562 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12563 } 12564 } 12565 return procs; 12566 } 12567 12568 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12569 PrintWriter pw, String[] args) { 12570 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12571 if (procs == null) { 12572 pw.println("No process found for: " + args[0]); 12573 return; 12574 } 12575 12576 long uptime = SystemClock.uptimeMillis(); 12577 long realtime = SystemClock.elapsedRealtime(); 12578 pw.println("Applications Graphics Acceleration Info:"); 12579 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12580 12581 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12582 ProcessRecord r = procs.get(i); 12583 if (r.thread != null) { 12584 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12585 pw.flush(); 12586 try { 12587 TransferPipe tp = new TransferPipe(); 12588 try { 12589 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12590 tp.go(fd); 12591 } finally { 12592 tp.kill(); 12593 } 12594 } catch (IOException e) { 12595 pw.println("Failure while dumping the app: " + r); 12596 pw.flush(); 12597 } catch (RemoteException e) { 12598 pw.println("Got a RemoteException while dumping the app " + r); 12599 pw.flush(); 12600 } 12601 } 12602 } 12603 } 12604 12605 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12606 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12607 if (procs == null) { 12608 pw.println("No process found for: " + args[0]); 12609 return; 12610 } 12611 12612 pw.println("Applications Database Info:"); 12613 12614 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12615 ProcessRecord r = procs.get(i); 12616 if (r.thread != null) { 12617 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12618 pw.flush(); 12619 try { 12620 TransferPipe tp = new TransferPipe(); 12621 try { 12622 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12623 tp.go(fd); 12624 } finally { 12625 tp.kill(); 12626 } 12627 } catch (IOException e) { 12628 pw.println("Failure while dumping the app: " + r); 12629 pw.flush(); 12630 } catch (RemoteException e) { 12631 pw.println("Got a RemoteException while dumping the app " + r); 12632 pw.flush(); 12633 } 12634 } 12635 } 12636 } 12637 12638 final static class MemItem { 12639 final boolean isProc; 12640 final String label; 12641 final String shortLabel; 12642 final long pss; 12643 final int id; 12644 final boolean hasActivities; 12645 ArrayList<MemItem> subitems; 12646 12647 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12648 boolean _hasActivities) { 12649 isProc = true; 12650 label = _label; 12651 shortLabel = _shortLabel; 12652 pss = _pss; 12653 id = _id; 12654 hasActivities = _hasActivities; 12655 } 12656 12657 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12658 isProc = false; 12659 label = _label; 12660 shortLabel = _shortLabel; 12661 pss = _pss; 12662 id = _id; 12663 hasActivities = false; 12664 } 12665 } 12666 12667 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12668 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12669 if (sort && !isCompact) { 12670 Collections.sort(items, new Comparator<MemItem>() { 12671 @Override 12672 public int compare(MemItem lhs, MemItem rhs) { 12673 if (lhs.pss < rhs.pss) { 12674 return 1; 12675 } else if (lhs.pss > rhs.pss) { 12676 return -1; 12677 } 12678 return 0; 12679 } 12680 }); 12681 } 12682 12683 for (int i=0; i<items.size(); i++) { 12684 MemItem mi = items.get(i); 12685 if (!isCompact) { 12686 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12687 } else if (mi.isProc) { 12688 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12689 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12690 pw.println(mi.hasActivities ? ",a" : ",e"); 12691 } else { 12692 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12693 pw.println(mi.pss); 12694 } 12695 if (mi.subitems != null) { 12696 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12697 true, isCompact); 12698 } 12699 } 12700 } 12701 12702 // These are in KB. 12703 static final long[] DUMP_MEM_BUCKETS = new long[] { 12704 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12705 120*1024, 160*1024, 200*1024, 12706 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12707 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12708 }; 12709 12710 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12711 boolean stackLike) { 12712 int start = label.lastIndexOf('.'); 12713 if (start >= 0) start++; 12714 else start = 0; 12715 int end = label.length(); 12716 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12717 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12718 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12719 out.append(bucket); 12720 out.append(stackLike ? "MB." : "MB "); 12721 out.append(label, start, end); 12722 return; 12723 } 12724 } 12725 out.append(memKB/1024); 12726 out.append(stackLike ? "MB." : "MB "); 12727 out.append(label, start, end); 12728 } 12729 12730 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12731 ProcessList.NATIVE_ADJ, 12732 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12733 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12734 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12735 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12736 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12737 }; 12738 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12739 "Native", 12740 "System", "Persistent", "Foreground", 12741 "Visible", "Perceptible", 12742 "Heavy Weight", "Backup", 12743 "A Services", "Home", 12744 "Previous", "B Services", "Cached" 12745 }; 12746 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12747 "native", 12748 "sys", "pers", "fore", 12749 "vis", "percept", 12750 "heavy", "backup", 12751 "servicea", "home", 12752 "prev", "serviceb", "cached" 12753 }; 12754 12755 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12756 long realtime, boolean isCheckinRequest, boolean isCompact) { 12757 if (isCheckinRequest || isCompact) { 12758 // short checkin version 12759 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12760 } else { 12761 pw.println("Applications Memory Usage (kB):"); 12762 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12763 } 12764 } 12765 12766 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12767 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12768 boolean dumpDetails = false; 12769 boolean dumpFullDetails = false; 12770 boolean dumpDalvik = false; 12771 boolean oomOnly = false; 12772 boolean isCompact = false; 12773 boolean localOnly = false; 12774 12775 int opti = 0; 12776 while (opti < args.length) { 12777 String opt = args[opti]; 12778 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12779 break; 12780 } 12781 opti++; 12782 if ("-a".equals(opt)) { 12783 dumpDetails = true; 12784 dumpFullDetails = true; 12785 dumpDalvik = true; 12786 } else if ("-d".equals(opt)) { 12787 dumpDalvik = true; 12788 } else if ("-c".equals(opt)) { 12789 isCompact = true; 12790 } else if ("--oom".equals(opt)) { 12791 oomOnly = true; 12792 } else if ("--local".equals(opt)) { 12793 localOnly = true; 12794 } else if ("-h".equals(opt)) { 12795 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12796 pw.println(" -a: include all available information for each process."); 12797 pw.println(" -d: include dalvik details when dumping process details."); 12798 pw.println(" -c: dump in a compact machine-parseable representation."); 12799 pw.println(" --oom: only show processes organized by oom adj."); 12800 pw.println(" --local: only collect details locally, don't call process."); 12801 pw.println("If [process] is specified it can be the name or "); 12802 pw.println("pid of a specific process to dump."); 12803 return; 12804 } else { 12805 pw.println("Unknown argument: " + opt + "; use -h for help"); 12806 } 12807 } 12808 12809 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12810 long uptime = SystemClock.uptimeMillis(); 12811 long realtime = SystemClock.elapsedRealtime(); 12812 final long[] tmpLong = new long[1]; 12813 12814 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12815 if (procs == null) { 12816 // No Java processes. Maybe they want to print a native process. 12817 if (args != null && args.length > opti 12818 && args[opti].charAt(0) != '-') { 12819 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12820 = new ArrayList<ProcessCpuTracker.Stats>(); 12821 updateCpuStatsNow(); 12822 int findPid = -1; 12823 try { 12824 findPid = Integer.parseInt(args[opti]); 12825 } catch (NumberFormatException e) { 12826 } 12827 synchronized (mProcessCpuThread) { 12828 final int N = mProcessCpuTracker.countStats(); 12829 for (int i=0; i<N; i++) { 12830 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12831 if (st.pid == findPid || (st.baseName != null 12832 && st.baseName.equals(args[opti]))) { 12833 nativeProcs.add(st); 12834 } 12835 } 12836 } 12837 if (nativeProcs.size() > 0) { 12838 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12839 isCompact); 12840 Debug.MemoryInfo mi = null; 12841 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12842 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12843 final int pid = r.pid; 12844 if (!isCheckinRequest && dumpDetails) { 12845 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12846 } 12847 if (mi == null) { 12848 mi = new Debug.MemoryInfo(); 12849 } 12850 if (dumpDetails || (!brief && !oomOnly)) { 12851 Debug.getMemoryInfo(pid, mi); 12852 } else { 12853 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12854 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12855 } 12856 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12857 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12858 if (isCheckinRequest) { 12859 pw.println(); 12860 } 12861 } 12862 return; 12863 } 12864 } 12865 pw.println("No process found for: " + args[opti]); 12866 return; 12867 } 12868 12869 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12870 dumpDetails = true; 12871 } 12872 12873 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12874 12875 String[] innerArgs = new String[args.length-opti]; 12876 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12877 12878 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12879 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12880 long nativePss=0, dalvikPss=0, otherPss=0; 12881 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12882 12883 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12884 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12885 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12886 12887 long totalPss = 0; 12888 long cachedPss = 0; 12889 12890 Debug.MemoryInfo mi = null; 12891 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12892 final ProcessRecord r = procs.get(i); 12893 final IApplicationThread thread; 12894 final int pid; 12895 final int oomAdj; 12896 final boolean hasActivities; 12897 synchronized (this) { 12898 thread = r.thread; 12899 pid = r.pid; 12900 oomAdj = r.getSetAdjWithServices(); 12901 hasActivities = r.activities.size() > 0; 12902 } 12903 if (thread != null) { 12904 if (!isCheckinRequest && dumpDetails) { 12905 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12906 } 12907 if (mi == null) { 12908 mi = new Debug.MemoryInfo(); 12909 } 12910 if (dumpDetails || (!brief && !oomOnly)) { 12911 Debug.getMemoryInfo(pid, mi); 12912 } else { 12913 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12914 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12915 } 12916 if (dumpDetails) { 12917 if (localOnly) { 12918 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12919 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12920 if (isCheckinRequest) { 12921 pw.println(); 12922 } 12923 } else { 12924 try { 12925 pw.flush(); 12926 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12927 dumpDalvik, innerArgs); 12928 } catch (RemoteException e) { 12929 if (!isCheckinRequest) { 12930 pw.println("Got RemoteException!"); 12931 pw.flush(); 12932 } 12933 } 12934 } 12935 } 12936 12937 final long myTotalPss = mi.getTotalPss(); 12938 final long myTotalUss = mi.getTotalUss(); 12939 12940 synchronized (this) { 12941 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12942 // Record this for posterity if the process has been stable. 12943 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12944 } 12945 } 12946 12947 if (!isCheckinRequest && mi != null) { 12948 totalPss += myTotalPss; 12949 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12950 (hasActivities ? " / activities)" : ")"), 12951 r.processName, myTotalPss, pid, hasActivities); 12952 procMems.add(pssItem); 12953 procMemsMap.put(pid, pssItem); 12954 12955 nativePss += mi.nativePss; 12956 dalvikPss += mi.dalvikPss; 12957 otherPss += mi.otherPss; 12958 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12959 long mem = mi.getOtherPss(j); 12960 miscPss[j] += mem; 12961 otherPss -= mem; 12962 } 12963 12964 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12965 cachedPss += myTotalPss; 12966 } 12967 12968 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12969 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12970 || oomIndex == (oomPss.length-1)) { 12971 oomPss[oomIndex] += myTotalPss; 12972 if (oomProcs[oomIndex] == null) { 12973 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12974 } 12975 oomProcs[oomIndex].add(pssItem); 12976 break; 12977 } 12978 } 12979 } 12980 } 12981 } 12982 12983 long nativeProcTotalPss = 0; 12984 12985 if (!isCheckinRequest && procs.size() > 1) { 12986 // If we are showing aggregations, also look for native processes to 12987 // include so that our aggregations are more accurate. 12988 updateCpuStatsNow(); 12989 synchronized (mProcessCpuThread) { 12990 final int N = mProcessCpuTracker.countStats(); 12991 for (int i=0; i<N; i++) { 12992 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12993 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12994 if (mi == null) { 12995 mi = new Debug.MemoryInfo(); 12996 } 12997 if (!brief && !oomOnly) { 12998 Debug.getMemoryInfo(st.pid, mi); 12999 } else { 13000 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13001 mi.nativePrivateDirty = (int)tmpLong[0]; 13002 } 13003 13004 final long myTotalPss = mi.getTotalPss(); 13005 totalPss += myTotalPss; 13006 nativeProcTotalPss += myTotalPss; 13007 13008 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13009 st.name, myTotalPss, st.pid, false); 13010 procMems.add(pssItem); 13011 13012 nativePss += mi.nativePss; 13013 dalvikPss += mi.dalvikPss; 13014 otherPss += mi.otherPss; 13015 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13016 long mem = mi.getOtherPss(j); 13017 miscPss[j] += mem; 13018 otherPss -= mem; 13019 } 13020 oomPss[0] += myTotalPss; 13021 if (oomProcs[0] == null) { 13022 oomProcs[0] = new ArrayList<MemItem>(); 13023 } 13024 oomProcs[0].add(pssItem); 13025 } 13026 } 13027 } 13028 13029 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13030 13031 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13032 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13033 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13034 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13035 String label = Debug.MemoryInfo.getOtherLabel(j); 13036 catMems.add(new MemItem(label, label, miscPss[j], j)); 13037 } 13038 13039 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13040 for (int j=0; j<oomPss.length; j++) { 13041 if (oomPss[j] != 0) { 13042 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13043 : DUMP_MEM_OOM_LABEL[j]; 13044 MemItem item = new MemItem(label, label, oomPss[j], 13045 DUMP_MEM_OOM_ADJ[j]); 13046 item.subitems = oomProcs[j]; 13047 oomMems.add(item); 13048 } 13049 } 13050 13051 if (!brief && !oomOnly && !isCompact) { 13052 pw.println(); 13053 pw.println("Total PSS by process:"); 13054 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13055 pw.println(); 13056 } 13057 if (!isCompact) { 13058 pw.println("Total PSS by OOM adjustment:"); 13059 } 13060 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13061 if (!brief && !oomOnly) { 13062 PrintWriter out = categoryPw != null ? categoryPw : pw; 13063 if (!isCompact) { 13064 out.println(); 13065 out.println("Total PSS by category:"); 13066 } 13067 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13068 } 13069 if (!isCompact) { 13070 pw.println(); 13071 } 13072 MemInfoReader memInfo = new MemInfoReader(); 13073 memInfo.readMemInfo(); 13074 if (nativeProcTotalPss > 0) { 13075 synchronized (this) { 13076 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13077 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13078 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13079 nativeProcTotalPss); 13080 } 13081 } 13082 if (!brief) { 13083 if (!isCompact) { 13084 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13085 pw.print(" kB (status "); 13086 switch (mLastMemoryLevel) { 13087 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13088 pw.println("normal)"); 13089 break; 13090 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13091 pw.println("moderate)"); 13092 break; 13093 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13094 pw.println("low)"); 13095 break; 13096 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13097 pw.println("critical)"); 13098 break; 13099 default: 13100 pw.print(mLastMemoryLevel); 13101 pw.println(")"); 13102 break; 13103 } 13104 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13105 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13106 pw.print(cachedPss); pw.print(" cached pss + "); 13107 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13108 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13109 } else { 13110 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13111 pw.print(cachedPss + memInfo.getCachedSizeKb() 13112 + memInfo.getFreeSizeKb()); pw.print(","); 13113 pw.println(totalPss - cachedPss); 13114 } 13115 } 13116 if (!isCompact) { 13117 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13118 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13119 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13120 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13121 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13122 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13123 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13124 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13125 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13126 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13127 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13128 } 13129 if (!brief) { 13130 if (memInfo.getZramTotalSizeKb() != 0) { 13131 if (!isCompact) { 13132 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13133 pw.print(" kB physical used for "); 13134 pw.print(memInfo.getSwapTotalSizeKb() 13135 - memInfo.getSwapFreeSizeKb()); 13136 pw.print(" kB in swap ("); 13137 pw.print(memInfo.getSwapTotalSizeKb()); 13138 pw.println(" kB total swap)"); 13139 } else { 13140 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13141 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13142 pw.println(memInfo.getSwapFreeSizeKb()); 13143 } 13144 } 13145 final int[] SINGLE_LONG_FORMAT = new int[] { 13146 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13147 }; 13148 long[] longOut = new long[1]; 13149 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13150 SINGLE_LONG_FORMAT, null, longOut, null); 13151 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13152 longOut[0] = 0; 13153 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13154 SINGLE_LONG_FORMAT, null, longOut, null); 13155 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13156 longOut[0] = 0; 13157 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13158 SINGLE_LONG_FORMAT, null, longOut, null); 13159 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13160 longOut[0] = 0; 13161 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13162 SINGLE_LONG_FORMAT, null, longOut, null); 13163 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13164 if (!isCompact) { 13165 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13166 pw.print(" KSM: "); pw.print(sharing); 13167 pw.print(" kB saved from shared "); 13168 pw.print(shared); pw.println(" kB"); 13169 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13170 pw.print(voltile); pw.println(" kB volatile"); 13171 } 13172 pw.print(" Tuning: "); 13173 pw.print(ActivityManager.staticGetMemoryClass()); 13174 pw.print(" (large "); 13175 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13176 pw.print("), oom "); 13177 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13178 pw.print(" kB"); 13179 pw.print(", restore limit "); 13180 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13181 pw.print(" kB"); 13182 if (ActivityManager.isLowRamDeviceStatic()) { 13183 pw.print(" (low-ram)"); 13184 } 13185 if (ActivityManager.isHighEndGfx()) { 13186 pw.print(" (high-end-gfx)"); 13187 } 13188 pw.println(); 13189 } else { 13190 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13191 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13192 pw.println(voltile); 13193 pw.print("tuning,"); 13194 pw.print(ActivityManager.staticGetMemoryClass()); 13195 pw.print(','); 13196 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13197 pw.print(','); 13198 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13199 if (ActivityManager.isLowRamDeviceStatic()) { 13200 pw.print(",low-ram"); 13201 } 13202 if (ActivityManager.isHighEndGfx()) { 13203 pw.print(",high-end-gfx"); 13204 } 13205 pw.println(); 13206 } 13207 } 13208 } 13209 } 13210 13211 /** 13212 * Searches array of arguments for the specified string 13213 * @param args array of argument strings 13214 * @param value value to search for 13215 * @return true if the value is contained in the array 13216 */ 13217 private static boolean scanArgs(String[] args, String value) { 13218 if (args != null) { 13219 for (String arg : args) { 13220 if (value.equals(arg)) { 13221 return true; 13222 } 13223 } 13224 } 13225 return false; 13226 } 13227 13228 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13229 ContentProviderRecord cpr, boolean always) { 13230 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13231 13232 if (!inLaunching || always) { 13233 synchronized (cpr) { 13234 cpr.launchingApp = null; 13235 cpr.notifyAll(); 13236 } 13237 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13238 String names[] = cpr.info.authority.split(";"); 13239 for (int j = 0; j < names.length; j++) { 13240 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13241 } 13242 } 13243 13244 for (int i=0; i<cpr.connections.size(); i++) { 13245 ContentProviderConnection conn = cpr.connections.get(i); 13246 if (conn.waiting) { 13247 // If this connection is waiting for the provider, then we don't 13248 // need to mess with its process unless we are always removing 13249 // or for some reason the provider is not currently launching. 13250 if (inLaunching && !always) { 13251 continue; 13252 } 13253 } 13254 ProcessRecord capp = conn.client; 13255 conn.dead = true; 13256 if (conn.stableCount > 0) { 13257 if (!capp.persistent && capp.thread != null 13258 && capp.pid != 0 13259 && capp.pid != MY_PID) { 13260 killUnneededProcessLocked(capp, "depends on provider " 13261 + cpr.name.flattenToShortString() 13262 + " in dying proc " + (proc != null ? proc.processName : "??")); 13263 } 13264 } else if (capp.thread != null && conn.provider.provider != null) { 13265 try { 13266 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13267 } catch (RemoteException e) { 13268 } 13269 // In the protocol here, we don't expect the client to correctly 13270 // clean up this connection, we'll just remove it. 13271 cpr.connections.remove(i); 13272 conn.client.conProviders.remove(conn); 13273 } 13274 } 13275 13276 if (inLaunching && always) { 13277 mLaunchingProviders.remove(cpr); 13278 } 13279 return inLaunching; 13280 } 13281 13282 /** 13283 * Main code for cleaning up a process when it has gone away. This is 13284 * called both as a result of the process dying, or directly when stopping 13285 * a process when running in single process mode. 13286 */ 13287 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13288 boolean restarting, boolean allowRestart, int index) { 13289 if (index >= 0) { 13290 removeLruProcessLocked(app); 13291 ProcessList.remove(app.pid); 13292 } 13293 13294 mProcessesToGc.remove(app); 13295 mPendingPssProcesses.remove(app); 13296 13297 // Dismiss any open dialogs. 13298 if (app.crashDialog != null && !app.forceCrashReport) { 13299 app.crashDialog.dismiss(); 13300 app.crashDialog = null; 13301 } 13302 if (app.anrDialog != null) { 13303 app.anrDialog.dismiss(); 13304 app.anrDialog = null; 13305 } 13306 if (app.waitDialog != null) { 13307 app.waitDialog.dismiss(); 13308 app.waitDialog = null; 13309 } 13310 13311 app.crashing = false; 13312 app.notResponding = false; 13313 13314 app.resetPackageList(mProcessStats); 13315 app.unlinkDeathRecipient(); 13316 app.makeInactive(mProcessStats); 13317 app.waitingToKill = null; 13318 app.forcingToForeground = null; 13319 updateProcessForegroundLocked(app, false, false); 13320 app.foregroundActivities = false; 13321 app.hasShownUi = false; 13322 app.treatLikeActivity = false; 13323 app.hasAboveClient = false; 13324 app.hasClientActivities = false; 13325 13326 mServices.killServicesLocked(app, allowRestart); 13327 13328 boolean restart = false; 13329 13330 // Remove published content providers. 13331 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13332 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13333 final boolean always = app.bad || !allowRestart; 13334 if (removeDyingProviderLocked(app, cpr, always) || always) { 13335 // We left the provider in the launching list, need to 13336 // restart it. 13337 restart = true; 13338 } 13339 13340 cpr.provider = null; 13341 cpr.proc = null; 13342 } 13343 app.pubProviders.clear(); 13344 13345 // Take care of any launching providers waiting for this process. 13346 if (checkAppInLaunchingProvidersLocked(app, false)) { 13347 restart = true; 13348 } 13349 13350 // Unregister from connected content providers. 13351 if (!app.conProviders.isEmpty()) { 13352 for (int i=0; i<app.conProviders.size(); i++) { 13353 ContentProviderConnection conn = app.conProviders.get(i); 13354 conn.provider.connections.remove(conn); 13355 } 13356 app.conProviders.clear(); 13357 } 13358 13359 // At this point there may be remaining entries in mLaunchingProviders 13360 // where we were the only one waiting, so they are no longer of use. 13361 // Look for these and clean up if found. 13362 // XXX Commented out for now. Trying to figure out a way to reproduce 13363 // the actual situation to identify what is actually going on. 13364 if (false) { 13365 for (int i=0; i<mLaunchingProviders.size(); i++) { 13366 ContentProviderRecord cpr = (ContentProviderRecord) 13367 mLaunchingProviders.get(i); 13368 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13369 synchronized (cpr) { 13370 cpr.launchingApp = null; 13371 cpr.notifyAll(); 13372 } 13373 } 13374 } 13375 } 13376 13377 skipCurrentReceiverLocked(app); 13378 13379 // Unregister any receivers. 13380 for (int i=app.receivers.size()-1; i>=0; i--) { 13381 removeReceiverLocked(app.receivers.valueAt(i)); 13382 } 13383 app.receivers.clear(); 13384 13385 // If the app is undergoing backup, tell the backup manager about it 13386 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13387 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13388 + mBackupTarget.appInfo + " died during backup"); 13389 try { 13390 IBackupManager bm = IBackupManager.Stub.asInterface( 13391 ServiceManager.getService(Context.BACKUP_SERVICE)); 13392 bm.agentDisconnected(app.info.packageName); 13393 } catch (RemoteException e) { 13394 // can't happen; backup manager is local 13395 } 13396 } 13397 13398 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13399 ProcessChangeItem item = mPendingProcessChanges.get(i); 13400 if (item.pid == app.pid) { 13401 mPendingProcessChanges.remove(i); 13402 mAvailProcessChanges.add(item); 13403 } 13404 } 13405 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13406 13407 // If the caller is restarting this app, then leave it in its 13408 // current lists and let the caller take care of it. 13409 if (restarting) { 13410 return; 13411 } 13412 13413 if (!app.persistent || app.isolated) { 13414 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13415 "Removing non-persistent process during cleanup: " + app); 13416 mProcessNames.remove(app.processName, app.uid); 13417 mIsolatedProcesses.remove(app.uid); 13418 if (mHeavyWeightProcess == app) { 13419 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13420 mHeavyWeightProcess.userId, 0)); 13421 mHeavyWeightProcess = null; 13422 } 13423 } else if (!app.removed) { 13424 // This app is persistent, so we need to keep its record around. 13425 // If it is not already on the pending app list, add it there 13426 // and start a new process for it. 13427 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13428 mPersistentStartingProcesses.add(app); 13429 restart = true; 13430 } 13431 } 13432 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13433 "Clean-up removing on hold: " + app); 13434 mProcessesOnHold.remove(app); 13435 13436 if (app == mHomeProcess) { 13437 mHomeProcess = null; 13438 } 13439 if (app == mPreviousProcess) { 13440 mPreviousProcess = null; 13441 } 13442 13443 if (restart && !app.isolated) { 13444 // We have components that still need to be running in the 13445 // process, so re-launch it. 13446 mProcessNames.put(app.processName, app.uid, app); 13447 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13448 } else if (app.pid > 0 && app.pid != MY_PID) { 13449 // Goodbye! 13450 boolean removed; 13451 synchronized (mPidsSelfLocked) { 13452 mPidsSelfLocked.remove(app.pid); 13453 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13454 } 13455 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13456 if (app.isolated) { 13457 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13458 } 13459 app.setPid(0); 13460 } 13461 } 13462 13463 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13464 // Look through the content providers we are waiting to have launched, 13465 // and if any run in this process then either schedule a restart of 13466 // the process or kill the client waiting for it if this process has 13467 // gone bad. 13468 int NL = mLaunchingProviders.size(); 13469 boolean restart = false; 13470 for (int i=0; i<NL; i++) { 13471 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13472 if (cpr.launchingApp == app) { 13473 if (!alwaysBad && !app.bad) { 13474 restart = true; 13475 } else { 13476 removeDyingProviderLocked(app, cpr, true); 13477 // cpr should have been removed from mLaunchingProviders 13478 NL = mLaunchingProviders.size(); 13479 i--; 13480 } 13481 } 13482 } 13483 return restart; 13484 } 13485 13486 // ========================================================= 13487 // SERVICES 13488 // ========================================================= 13489 13490 @Override 13491 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13492 int flags) { 13493 enforceNotIsolatedCaller("getServices"); 13494 synchronized (this) { 13495 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13496 } 13497 } 13498 13499 @Override 13500 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13501 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13502 synchronized (this) { 13503 return mServices.getRunningServiceControlPanelLocked(name); 13504 } 13505 } 13506 13507 @Override 13508 public ComponentName startService(IApplicationThread caller, Intent service, 13509 String resolvedType, int userId) { 13510 enforceNotIsolatedCaller("startService"); 13511 // Refuse possible leaked file descriptors 13512 if (service != null && service.hasFileDescriptors() == true) { 13513 throw new IllegalArgumentException("File descriptors passed in Intent"); 13514 } 13515 13516 if (DEBUG_SERVICE) 13517 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13518 synchronized(this) { 13519 final int callingPid = Binder.getCallingPid(); 13520 final int callingUid = Binder.getCallingUid(); 13521 final long origId = Binder.clearCallingIdentity(); 13522 ComponentName res = mServices.startServiceLocked(caller, service, 13523 resolvedType, callingPid, callingUid, userId); 13524 Binder.restoreCallingIdentity(origId); 13525 return res; 13526 } 13527 } 13528 13529 ComponentName startServiceInPackage(int uid, 13530 Intent service, String resolvedType, int userId) { 13531 synchronized(this) { 13532 if (DEBUG_SERVICE) 13533 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13534 final long origId = Binder.clearCallingIdentity(); 13535 ComponentName res = mServices.startServiceLocked(null, service, 13536 resolvedType, -1, uid, userId); 13537 Binder.restoreCallingIdentity(origId); 13538 return res; 13539 } 13540 } 13541 13542 @Override 13543 public int stopService(IApplicationThread caller, Intent service, 13544 String resolvedType, int userId) { 13545 enforceNotIsolatedCaller("stopService"); 13546 // Refuse possible leaked file descriptors 13547 if (service != null && service.hasFileDescriptors() == true) { 13548 throw new IllegalArgumentException("File descriptors passed in Intent"); 13549 } 13550 13551 synchronized(this) { 13552 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13553 } 13554 } 13555 13556 @Override 13557 public IBinder peekService(Intent service, String resolvedType) { 13558 enforceNotIsolatedCaller("peekService"); 13559 // Refuse possible leaked file descriptors 13560 if (service != null && service.hasFileDescriptors() == true) { 13561 throw new IllegalArgumentException("File descriptors passed in Intent"); 13562 } 13563 synchronized(this) { 13564 return mServices.peekServiceLocked(service, resolvedType); 13565 } 13566 } 13567 13568 @Override 13569 public boolean stopServiceToken(ComponentName className, IBinder token, 13570 int startId) { 13571 synchronized(this) { 13572 return mServices.stopServiceTokenLocked(className, token, startId); 13573 } 13574 } 13575 13576 @Override 13577 public void setServiceForeground(ComponentName className, IBinder token, 13578 int id, Notification notification, boolean removeNotification) { 13579 synchronized(this) { 13580 mServices.setServiceForegroundLocked(className, token, id, notification, 13581 removeNotification); 13582 } 13583 } 13584 13585 @Override 13586 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13587 boolean requireFull, String name, String callerPackage) { 13588 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13589 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13590 } 13591 13592 int unsafeConvertIncomingUser(int userId) { 13593 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13594 ? mCurrentUserId : userId; 13595 } 13596 13597 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13598 int allowMode, String name, String callerPackage) { 13599 final int callingUserId = UserHandle.getUserId(callingUid); 13600 if (callingUserId == userId) { 13601 return userId; 13602 } 13603 13604 // Note that we may be accessing mCurrentUserId outside of a lock... 13605 // shouldn't be a big deal, if this is being called outside 13606 // of a locked context there is intrinsically a race with 13607 // the value the caller will receive and someone else changing it. 13608 // We assume that USER_CURRENT_OR_SELF will use the current user; later 13609 // we will switch to the calling user if access to the current user fails. 13610 int targetUserId = unsafeConvertIncomingUser(userId); 13611 13612 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13613 final boolean allow; 13614 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 13615 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 13616 // If the caller has this permission, they always pass go. And collect $200. 13617 allow = true; 13618 } else if (allowMode == ALLOW_FULL_ONLY) { 13619 // We require full access, sucks to be you. 13620 allow = false; 13621 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 13622 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 13623 // If the caller does not have either permission, they are always doomed. 13624 allow = false; 13625 } else if (allowMode == ALLOW_NON_FULL) { 13626 // We are blanket allowing non-full access, you lucky caller! 13627 allow = true; 13628 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 13629 // We may or may not allow this depending on whether the two users are 13630 // in the same profile. 13631 synchronized (mUserProfileGroupIdsSelfLocked) { 13632 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 13633 UserInfo.NO_PROFILE_GROUP_ID); 13634 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 13635 UserInfo.NO_PROFILE_GROUP_ID); 13636 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 13637 && callingProfile == targetProfile; 13638 } 13639 } else { 13640 throw new IllegalArgumentException("Unknown mode: " + allowMode); 13641 } 13642 if (!allow) { 13643 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13644 // In this case, they would like to just execute as their 13645 // owner user instead of failing. 13646 targetUserId = callingUserId; 13647 } else { 13648 StringBuilder builder = new StringBuilder(128); 13649 builder.append("Permission Denial: "); 13650 builder.append(name); 13651 if (callerPackage != null) { 13652 builder.append(" from "); 13653 builder.append(callerPackage); 13654 } 13655 builder.append(" asks to run as user "); 13656 builder.append(userId); 13657 builder.append(" but is calling from user "); 13658 builder.append(UserHandle.getUserId(callingUid)); 13659 builder.append("; this requires "); 13660 builder.append(INTERACT_ACROSS_USERS_FULL); 13661 if (allowMode != ALLOW_FULL_ONLY) { 13662 builder.append(" or "); 13663 builder.append(INTERACT_ACROSS_USERS); 13664 } 13665 String msg = builder.toString(); 13666 Slog.w(TAG, msg); 13667 throw new SecurityException(msg); 13668 } 13669 } 13670 } 13671 if (!allowAll && targetUserId < 0) { 13672 throw new IllegalArgumentException( 13673 "Call does not support special user #" + targetUserId); 13674 } 13675 return targetUserId; 13676 } 13677 13678 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13679 String className, int flags) { 13680 boolean result = false; 13681 // For apps that don't have pre-defined UIDs, check for permission 13682 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13683 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13684 if (ActivityManager.checkUidPermission( 13685 INTERACT_ACROSS_USERS, 13686 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13687 ComponentName comp = new ComponentName(aInfo.packageName, className); 13688 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13689 + " requests FLAG_SINGLE_USER, but app does not hold " 13690 + INTERACT_ACROSS_USERS; 13691 Slog.w(TAG, msg); 13692 throw new SecurityException(msg); 13693 } 13694 // Permission passed 13695 result = true; 13696 } 13697 } else if ("system".equals(componentProcessName)) { 13698 result = true; 13699 } else { 13700 // App with pre-defined UID, check if it's a persistent app 13701 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13702 } 13703 if (DEBUG_MU) { 13704 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13705 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13706 } 13707 return result; 13708 } 13709 13710 /** 13711 * Checks to see if the caller is in the same app as the singleton 13712 * component, or the component is in a special app. It allows special apps 13713 * to export singleton components but prevents exporting singleton 13714 * components for regular apps. 13715 */ 13716 boolean isValidSingletonCall(int callingUid, int componentUid) { 13717 int componentAppId = UserHandle.getAppId(componentUid); 13718 return UserHandle.isSameApp(callingUid, componentUid) 13719 || componentAppId == Process.SYSTEM_UID 13720 || componentAppId == Process.PHONE_UID 13721 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13722 == PackageManager.PERMISSION_GRANTED; 13723 } 13724 13725 public int bindService(IApplicationThread caller, IBinder token, 13726 Intent service, String resolvedType, 13727 IServiceConnection connection, int flags, int userId) { 13728 enforceNotIsolatedCaller("bindService"); 13729 // Refuse possible leaked file descriptors 13730 if (service != null && service.hasFileDescriptors() == true) { 13731 throw new IllegalArgumentException("File descriptors passed in Intent"); 13732 } 13733 13734 synchronized(this) { 13735 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13736 connection, flags, userId); 13737 } 13738 } 13739 13740 public boolean unbindService(IServiceConnection connection) { 13741 synchronized (this) { 13742 return mServices.unbindServiceLocked(connection); 13743 } 13744 } 13745 13746 public void publishService(IBinder token, Intent intent, IBinder service) { 13747 // Refuse possible leaked file descriptors 13748 if (intent != null && intent.hasFileDescriptors() == true) { 13749 throw new IllegalArgumentException("File descriptors passed in Intent"); 13750 } 13751 13752 synchronized(this) { 13753 if (!(token instanceof ServiceRecord)) { 13754 throw new IllegalArgumentException("Invalid service token"); 13755 } 13756 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13757 } 13758 } 13759 13760 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13761 // Refuse possible leaked file descriptors 13762 if (intent != null && intent.hasFileDescriptors() == true) { 13763 throw new IllegalArgumentException("File descriptors passed in Intent"); 13764 } 13765 13766 synchronized(this) { 13767 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13768 } 13769 } 13770 13771 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13772 synchronized(this) { 13773 if (!(token instanceof ServiceRecord)) { 13774 throw new IllegalArgumentException("Invalid service token"); 13775 } 13776 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13777 } 13778 } 13779 13780 // ========================================================= 13781 // BACKUP AND RESTORE 13782 // ========================================================= 13783 13784 // Cause the target app to be launched if necessary and its backup agent 13785 // instantiated. The backup agent will invoke backupAgentCreated() on the 13786 // activity manager to announce its creation. 13787 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13788 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13789 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13790 13791 synchronized(this) { 13792 // !!! TODO: currently no check here that we're already bound 13793 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13794 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13795 synchronized (stats) { 13796 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13797 } 13798 13799 // Backup agent is now in use, its package can't be stopped. 13800 try { 13801 AppGlobals.getPackageManager().setPackageStoppedState( 13802 app.packageName, false, UserHandle.getUserId(app.uid)); 13803 } catch (RemoteException e) { 13804 } catch (IllegalArgumentException e) { 13805 Slog.w(TAG, "Failed trying to unstop package " 13806 + app.packageName + ": " + e); 13807 } 13808 13809 BackupRecord r = new BackupRecord(ss, app, backupMode); 13810 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13811 ? new ComponentName(app.packageName, app.backupAgentName) 13812 : new ComponentName("android", "FullBackupAgent"); 13813 // startProcessLocked() returns existing proc's record if it's already running 13814 ProcessRecord proc = startProcessLocked(app.processName, app, 13815 false, 0, "backup", hostingName, false, false, false); 13816 if (proc == null) { 13817 Slog.e(TAG, "Unable to start backup agent process " + r); 13818 return false; 13819 } 13820 13821 r.app = proc; 13822 mBackupTarget = r; 13823 mBackupAppName = app.packageName; 13824 13825 // Try not to kill the process during backup 13826 updateOomAdjLocked(proc); 13827 13828 // If the process is already attached, schedule the creation of the backup agent now. 13829 // If it is not yet live, this will be done when it attaches to the framework. 13830 if (proc.thread != null) { 13831 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13832 try { 13833 proc.thread.scheduleCreateBackupAgent(app, 13834 compatibilityInfoForPackageLocked(app), backupMode); 13835 } catch (RemoteException e) { 13836 // Will time out on the backup manager side 13837 } 13838 } else { 13839 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13840 } 13841 // Invariants: at this point, the target app process exists and the application 13842 // is either already running or in the process of coming up. mBackupTarget and 13843 // mBackupAppName describe the app, so that when it binds back to the AM we 13844 // know that it's scheduled for a backup-agent operation. 13845 } 13846 13847 return true; 13848 } 13849 13850 @Override 13851 public void clearPendingBackup() { 13852 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13853 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13854 13855 synchronized (this) { 13856 mBackupTarget = null; 13857 mBackupAppName = null; 13858 } 13859 } 13860 13861 // A backup agent has just come up 13862 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13863 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13864 + " = " + agent); 13865 13866 synchronized(this) { 13867 if (!agentPackageName.equals(mBackupAppName)) { 13868 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13869 return; 13870 } 13871 } 13872 13873 long oldIdent = Binder.clearCallingIdentity(); 13874 try { 13875 IBackupManager bm = IBackupManager.Stub.asInterface( 13876 ServiceManager.getService(Context.BACKUP_SERVICE)); 13877 bm.agentConnected(agentPackageName, agent); 13878 } catch (RemoteException e) { 13879 // can't happen; the backup manager service is local 13880 } catch (Exception e) { 13881 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13882 e.printStackTrace(); 13883 } finally { 13884 Binder.restoreCallingIdentity(oldIdent); 13885 } 13886 } 13887 13888 // done with this agent 13889 public void unbindBackupAgent(ApplicationInfo appInfo) { 13890 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13891 if (appInfo == null) { 13892 Slog.w(TAG, "unbind backup agent for null app"); 13893 return; 13894 } 13895 13896 synchronized(this) { 13897 try { 13898 if (mBackupAppName == null) { 13899 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13900 return; 13901 } 13902 13903 if (!mBackupAppName.equals(appInfo.packageName)) { 13904 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13905 return; 13906 } 13907 13908 // Not backing this app up any more; reset its OOM adjustment 13909 final ProcessRecord proc = mBackupTarget.app; 13910 updateOomAdjLocked(proc); 13911 13912 // If the app crashed during backup, 'thread' will be null here 13913 if (proc.thread != null) { 13914 try { 13915 proc.thread.scheduleDestroyBackupAgent(appInfo, 13916 compatibilityInfoForPackageLocked(appInfo)); 13917 } catch (Exception e) { 13918 Slog.e(TAG, "Exception when unbinding backup agent:"); 13919 e.printStackTrace(); 13920 } 13921 } 13922 } finally { 13923 mBackupTarget = null; 13924 mBackupAppName = null; 13925 } 13926 } 13927 } 13928 // ========================================================= 13929 // BROADCASTS 13930 // ========================================================= 13931 13932 private final List getStickiesLocked(String action, IntentFilter filter, 13933 List cur, int userId) { 13934 final ContentResolver resolver = mContext.getContentResolver(); 13935 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13936 if (stickies == null) { 13937 return cur; 13938 } 13939 final ArrayList<Intent> list = stickies.get(action); 13940 if (list == null) { 13941 return cur; 13942 } 13943 int N = list.size(); 13944 for (int i=0; i<N; i++) { 13945 Intent intent = list.get(i); 13946 if (filter.match(resolver, intent, true, TAG) >= 0) { 13947 if (cur == null) { 13948 cur = new ArrayList<Intent>(); 13949 } 13950 cur.add(intent); 13951 } 13952 } 13953 return cur; 13954 } 13955 13956 boolean isPendingBroadcastProcessLocked(int pid) { 13957 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13958 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13959 } 13960 13961 void skipPendingBroadcastLocked(int pid) { 13962 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13963 for (BroadcastQueue queue : mBroadcastQueues) { 13964 queue.skipPendingBroadcastLocked(pid); 13965 } 13966 } 13967 13968 // The app just attached; send any pending broadcasts that it should receive 13969 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13970 boolean didSomething = false; 13971 for (BroadcastQueue queue : mBroadcastQueues) { 13972 didSomething |= queue.sendPendingBroadcastsLocked(app); 13973 } 13974 return didSomething; 13975 } 13976 13977 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13978 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13979 enforceNotIsolatedCaller("registerReceiver"); 13980 int callingUid; 13981 int callingPid; 13982 synchronized(this) { 13983 ProcessRecord callerApp = null; 13984 if (caller != null) { 13985 callerApp = getRecordForAppLocked(caller); 13986 if (callerApp == null) { 13987 throw new SecurityException( 13988 "Unable to find app for caller " + caller 13989 + " (pid=" + Binder.getCallingPid() 13990 + ") when registering receiver " + receiver); 13991 } 13992 if (callerApp.info.uid != Process.SYSTEM_UID && 13993 !callerApp.pkgList.containsKey(callerPackage) && 13994 !"android".equals(callerPackage)) { 13995 throw new SecurityException("Given caller package " + callerPackage 13996 + " is not running in process " + callerApp); 13997 } 13998 callingUid = callerApp.info.uid; 13999 callingPid = callerApp.pid; 14000 } else { 14001 callerPackage = null; 14002 callingUid = Binder.getCallingUid(); 14003 callingPid = Binder.getCallingPid(); 14004 } 14005 14006 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14007 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14008 14009 List allSticky = null; 14010 14011 // Look for any matching sticky broadcasts... 14012 Iterator actions = filter.actionsIterator(); 14013 if (actions != null) { 14014 while (actions.hasNext()) { 14015 String action = (String)actions.next(); 14016 allSticky = getStickiesLocked(action, filter, allSticky, 14017 UserHandle.USER_ALL); 14018 allSticky = getStickiesLocked(action, filter, allSticky, 14019 UserHandle.getUserId(callingUid)); 14020 } 14021 } else { 14022 allSticky = getStickiesLocked(null, filter, allSticky, 14023 UserHandle.USER_ALL); 14024 allSticky = getStickiesLocked(null, filter, allSticky, 14025 UserHandle.getUserId(callingUid)); 14026 } 14027 14028 // The first sticky in the list is returned directly back to 14029 // the client. 14030 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14031 14032 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14033 + ": " + sticky); 14034 14035 if (receiver == null) { 14036 return sticky; 14037 } 14038 14039 ReceiverList rl 14040 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14041 if (rl == null) { 14042 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14043 userId, receiver); 14044 if (rl.app != null) { 14045 rl.app.receivers.add(rl); 14046 } else { 14047 try { 14048 receiver.asBinder().linkToDeath(rl, 0); 14049 } catch (RemoteException e) { 14050 return sticky; 14051 } 14052 rl.linkedToDeath = true; 14053 } 14054 mRegisteredReceivers.put(receiver.asBinder(), rl); 14055 } else if (rl.uid != callingUid) { 14056 throw new IllegalArgumentException( 14057 "Receiver requested to register for uid " + callingUid 14058 + " was previously registered for uid " + rl.uid); 14059 } else if (rl.pid != callingPid) { 14060 throw new IllegalArgumentException( 14061 "Receiver requested to register for pid " + callingPid 14062 + " was previously registered for pid " + rl.pid); 14063 } else if (rl.userId != userId) { 14064 throw new IllegalArgumentException( 14065 "Receiver requested to register for user " + userId 14066 + " was previously registered for user " + rl.userId); 14067 } 14068 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14069 permission, callingUid, userId); 14070 rl.add(bf); 14071 if (!bf.debugCheck()) { 14072 Slog.w(TAG, "==> For Dynamic broadast"); 14073 } 14074 mReceiverResolver.addFilter(bf); 14075 14076 // Enqueue broadcasts for all existing stickies that match 14077 // this filter. 14078 if (allSticky != null) { 14079 ArrayList receivers = new ArrayList(); 14080 receivers.add(bf); 14081 14082 int N = allSticky.size(); 14083 for (int i=0; i<N; i++) { 14084 Intent intent = (Intent)allSticky.get(i); 14085 BroadcastQueue queue = broadcastQueueForIntent(intent); 14086 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14087 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14088 null, null, false, true, true, -1); 14089 queue.enqueueParallelBroadcastLocked(r); 14090 queue.scheduleBroadcastsLocked(); 14091 } 14092 } 14093 14094 return sticky; 14095 } 14096 } 14097 14098 public void unregisterReceiver(IIntentReceiver receiver) { 14099 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14100 14101 final long origId = Binder.clearCallingIdentity(); 14102 try { 14103 boolean doTrim = false; 14104 14105 synchronized(this) { 14106 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14107 if (rl != null) { 14108 if (rl.curBroadcast != null) { 14109 BroadcastRecord r = rl.curBroadcast; 14110 final boolean doNext = finishReceiverLocked( 14111 receiver.asBinder(), r.resultCode, r.resultData, 14112 r.resultExtras, r.resultAbort); 14113 if (doNext) { 14114 doTrim = true; 14115 r.queue.processNextBroadcast(false); 14116 } 14117 } 14118 14119 if (rl.app != null) { 14120 rl.app.receivers.remove(rl); 14121 } 14122 removeReceiverLocked(rl); 14123 if (rl.linkedToDeath) { 14124 rl.linkedToDeath = false; 14125 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14126 } 14127 } 14128 } 14129 14130 // If we actually concluded any broadcasts, we might now be able 14131 // to trim the recipients' apps from our working set 14132 if (doTrim) { 14133 trimApplications(); 14134 return; 14135 } 14136 14137 } finally { 14138 Binder.restoreCallingIdentity(origId); 14139 } 14140 } 14141 14142 void removeReceiverLocked(ReceiverList rl) { 14143 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14144 int N = rl.size(); 14145 for (int i=0; i<N; i++) { 14146 mReceiverResolver.removeFilter(rl.get(i)); 14147 } 14148 } 14149 14150 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14151 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14152 ProcessRecord r = mLruProcesses.get(i); 14153 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14154 try { 14155 r.thread.dispatchPackageBroadcast(cmd, packages); 14156 } catch (RemoteException ex) { 14157 } 14158 } 14159 } 14160 } 14161 14162 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14163 int[] users) { 14164 List<ResolveInfo> receivers = null; 14165 try { 14166 HashSet<ComponentName> singleUserReceivers = null; 14167 boolean scannedFirstReceivers = false; 14168 for (int user : users) { 14169 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14170 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14171 if (user != 0 && newReceivers != null) { 14172 // If this is not the primary user, we need to check for 14173 // any receivers that should be filtered out. 14174 for (int i=0; i<newReceivers.size(); i++) { 14175 ResolveInfo ri = newReceivers.get(i); 14176 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14177 newReceivers.remove(i); 14178 i--; 14179 } 14180 } 14181 } 14182 if (newReceivers != null && newReceivers.size() == 0) { 14183 newReceivers = null; 14184 } 14185 if (receivers == null) { 14186 receivers = newReceivers; 14187 } else if (newReceivers != null) { 14188 // We need to concatenate the additional receivers 14189 // found with what we have do far. This would be easy, 14190 // but we also need to de-dup any receivers that are 14191 // singleUser. 14192 if (!scannedFirstReceivers) { 14193 // Collect any single user receivers we had already retrieved. 14194 scannedFirstReceivers = true; 14195 for (int i=0; i<receivers.size(); i++) { 14196 ResolveInfo ri = receivers.get(i); 14197 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14198 ComponentName cn = new ComponentName( 14199 ri.activityInfo.packageName, ri.activityInfo.name); 14200 if (singleUserReceivers == null) { 14201 singleUserReceivers = new HashSet<ComponentName>(); 14202 } 14203 singleUserReceivers.add(cn); 14204 } 14205 } 14206 } 14207 // Add the new results to the existing results, tracking 14208 // and de-dupping single user receivers. 14209 for (int i=0; i<newReceivers.size(); i++) { 14210 ResolveInfo ri = newReceivers.get(i); 14211 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14212 ComponentName cn = new ComponentName( 14213 ri.activityInfo.packageName, ri.activityInfo.name); 14214 if (singleUserReceivers == null) { 14215 singleUserReceivers = new HashSet<ComponentName>(); 14216 } 14217 if (!singleUserReceivers.contains(cn)) { 14218 singleUserReceivers.add(cn); 14219 receivers.add(ri); 14220 } 14221 } else { 14222 receivers.add(ri); 14223 } 14224 } 14225 } 14226 } 14227 } catch (RemoteException ex) { 14228 // pm is in same process, this will never happen. 14229 } 14230 return receivers; 14231 } 14232 14233 private final int broadcastIntentLocked(ProcessRecord callerApp, 14234 String callerPackage, Intent intent, String resolvedType, 14235 IIntentReceiver resultTo, int resultCode, String resultData, 14236 Bundle map, String requiredPermission, int appOp, 14237 boolean ordered, boolean sticky, int callingPid, int callingUid, 14238 int userId) { 14239 intent = new Intent(intent); 14240 14241 // By default broadcasts do not go to stopped apps. 14242 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14243 14244 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14245 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14246 + " ordered=" + ordered + " userid=" + userId); 14247 if ((resultTo != null) && !ordered) { 14248 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14249 } 14250 14251 userId = handleIncomingUser(callingPid, callingUid, userId, 14252 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14253 14254 // Make sure that the user who is receiving this broadcast is started. 14255 // If not, we will just skip it. 14256 14257 14258 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14259 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14260 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14261 Slog.w(TAG, "Skipping broadcast of " + intent 14262 + ": user " + userId + " is stopped"); 14263 return ActivityManager.BROADCAST_SUCCESS; 14264 } 14265 } 14266 14267 /* 14268 * Prevent non-system code (defined here to be non-persistent 14269 * processes) from sending protected broadcasts. 14270 */ 14271 int callingAppId = UserHandle.getAppId(callingUid); 14272 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14273 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14274 || callingAppId == Process.NFC_UID || callingUid == 0) { 14275 // Always okay. 14276 } else if (callerApp == null || !callerApp.persistent) { 14277 try { 14278 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14279 intent.getAction())) { 14280 String msg = "Permission Denial: not allowed to send broadcast " 14281 + intent.getAction() + " from pid=" 14282 + callingPid + ", uid=" + callingUid; 14283 Slog.w(TAG, msg); 14284 throw new SecurityException(msg); 14285 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14286 // Special case for compatibility: we don't want apps to send this, 14287 // but historically it has not been protected and apps may be using it 14288 // to poke their own app widget. So, instead of making it protected, 14289 // just limit it to the caller. 14290 if (callerApp == null) { 14291 String msg = "Permission Denial: not allowed to send broadcast " 14292 + intent.getAction() + " from unknown caller."; 14293 Slog.w(TAG, msg); 14294 throw new SecurityException(msg); 14295 } else if (intent.getComponent() != null) { 14296 // They are good enough to send to an explicit component... verify 14297 // it is being sent to the calling app. 14298 if (!intent.getComponent().getPackageName().equals( 14299 callerApp.info.packageName)) { 14300 String msg = "Permission Denial: not allowed to send broadcast " 14301 + intent.getAction() + " to " 14302 + intent.getComponent().getPackageName() + " from " 14303 + callerApp.info.packageName; 14304 Slog.w(TAG, msg); 14305 throw new SecurityException(msg); 14306 } 14307 } else { 14308 // Limit broadcast to their own package. 14309 intent.setPackage(callerApp.info.packageName); 14310 } 14311 } 14312 } catch (RemoteException e) { 14313 Slog.w(TAG, "Remote exception", e); 14314 return ActivityManager.BROADCAST_SUCCESS; 14315 } 14316 } 14317 14318 // Handle special intents: if this broadcast is from the package 14319 // manager about a package being removed, we need to remove all of 14320 // its activities from the history stack. 14321 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14322 intent.getAction()); 14323 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14324 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14325 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14326 || uidRemoved) { 14327 if (checkComponentPermission( 14328 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14329 callingPid, callingUid, -1, true) 14330 == PackageManager.PERMISSION_GRANTED) { 14331 if (uidRemoved) { 14332 final Bundle intentExtras = intent.getExtras(); 14333 final int uid = intentExtras != null 14334 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14335 if (uid >= 0) { 14336 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14337 synchronized (bs) { 14338 bs.removeUidStatsLocked(uid); 14339 } 14340 mAppOpsService.uidRemoved(uid); 14341 } 14342 } else { 14343 // If resources are unavailable just force stop all 14344 // those packages and flush the attribute cache as well. 14345 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14346 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14347 if (list != null && (list.length > 0)) { 14348 for (String pkg : list) { 14349 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14350 "storage unmount"); 14351 } 14352 sendPackageBroadcastLocked( 14353 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14354 } 14355 } else { 14356 Uri data = intent.getData(); 14357 String ssp; 14358 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14359 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14360 intent.getAction()); 14361 boolean fullUninstall = removed && 14362 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14363 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14364 forceStopPackageLocked(ssp, UserHandle.getAppId( 14365 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14366 false, fullUninstall, userId, 14367 removed ? "pkg removed" : "pkg changed"); 14368 } 14369 if (removed) { 14370 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14371 new String[] {ssp}, userId); 14372 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14373 mAppOpsService.packageRemoved( 14374 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14375 14376 // Remove all permissions granted from/to this package 14377 removeUriPermissionsForPackageLocked(ssp, userId, true); 14378 } 14379 } 14380 } 14381 } 14382 } 14383 } else { 14384 String msg = "Permission Denial: " + intent.getAction() 14385 + " broadcast from " + callerPackage + " (pid=" + callingPid 14386 + ", uid=" + callingUid + ")" 14387 + " requires " 14388 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14389 Slog.w(TAG, msg); 14390 throw new SecurityException(msg); 14391 } 14392 14393 // Special case for adding a package: by default turn on compatibility 14394 // mode. 14395 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14396 Uri data = intent.getData(); 14397 String ssp; 14398 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14399 mCompatModePackages.handlePackageAddedLocked(ssp, 14400 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14401 } 14402 } 14403 14404 /* 14405 * If this is the time zone changed action, queue up a message that will reset the timezone 14406 * of all currently running processes. This message will get queued up before the broadcast 14407 * happens. 14408 */ 14409 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14410 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14411 } 14412 14413 /* 14414 * If the user set the time, let all running processes know. 14415 */ 14416 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14417 final int is24Hour = intent.getBooleanExtra( 14418 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14419 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14420 } 14421 14422 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14423 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14424 } 14425 14426 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14427 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14428 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14429 } 14430 14431 // Add to the sticky list if requested. 14432 if (sticky) { 14433 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14434 callingPid, callingUid) 14435 != PackageManager.PERMISSION_GRANTED) { 14436 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14437 + callingPid + ", uid=" + callingUid 14438 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14439 Slog.w(TAG, msg); 14440 throw new SecurityException(msg); 14441 } 14442 if (requiredPermission != null) { 14443 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14444 + " and enforce permission " + requiredPermission); 14445 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14446 } 14447 if (intent.getComponent() != null) { 14448 throw new SecurityException( 14449 "Sticky broadcasts can't target a specific component"); 14450 } 14451 // We use userId directly here, since the "all" target is maintained 14452 // as a separate set of sticky broadcasts. 14453 if (userId != UserHandle.USER_ALL) { 14454 // But first, if this is not a broadcast to all users, then 14455 // make sure it doesn't conflict with an existing broadcast to 14456 // all users. 14457 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14458 UserHandle.USER_ALL); 14459 if (stickies != null) { 14460 ArrayList<Intent> list = stickies.get(intent.getAction()); 14461 if (list != null) { 14462 int N = list.size(); 14463 int i; 14464 for (i=0; i<N; i++) { 14465 if (intent.filterEquals(list.get(i))) { 14466 throw new IllegalArgumentException( 14467 "Sticky broadcast " + intent + " for user " 14468 + userId + " conflicts with existing global broadcast"); 14469 } 14470 } 14471 } 14472 } 14473 } 14474 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14475 if (stickies == null) { 14476 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14477 mStickyBroadcasts.put(userId, stickies); 14478 } 14479 ArrayList<Intent> list = stickies.get(intent.getAction()); 14480 if (list == null) { 14481 list = new ArrayList<Intent>(); 14482 stickies.put(intent.getAction(), list); 14483 } 14484 int N = list.size(); 14485 int i; 14486 for (i=0; i<N; i++) { 14487 if (intent.filterEquals(list.get(i))) { 14488 // This sticky already exists, replace it. 14489 list.set(i, new Intent(intent)); 14490 break; 14491 } 14492 } 14493 if (i >= N) { 14494 list.add(new Intent(intent)); 14495 } 14496 } 14497 14498 int[] users; 14499 if (userId == UserHandle.USER_ALL) { 14500 // Caller wants broadcast to go to all started users. 14501 users = mStartedUserArray; 14502 } else { 14503 // Caller wants broadcast to go to one specific user. 14504 users = new int[] {userId}; 14505 } 14506 14507 // Figure out who all will receive this broadcast. 14508 List receivers = null; 14509 List<BroadcastFilter> registeredReceivers = null; 14510 // Need to resolve the intent to interested receivers... 14511 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14512 == 0) { 14513 receivers = collectReceiverComponents(intent, resolvedType, users); 14514 } 14515 if (intent.getComponent() == null) { 14516 registeredReceivers = mReceiverResolver.queryIntent(intent, 14517 resolvedType, false, userId); 14518 } 14519 14520 final boolean replacePending = 14521 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14522 14523 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14524 + " replacePending=" + replacePending); 14525 14526 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14527 if (!ordered && NR > 0) { 14528 // If we are not serializing this broadcast, then send the 14529 // registered receivers separately so they don't wait for the 14530 // components to be launched. 14531 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14532 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14533 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14534 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14535 ordered, sticky, false, userId); 14536 if (DEBUG_BROADCAST) Slog.v( 14537 TAG, "Enqueueing parallel broadcast " + r); 14538 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14539 if (!replaced) { 14540 queue.enqueueParallelBroadcastLocked(r); 14541 queue.scheduleBroadcastsLocked(); 14542 } 14543 registeredReceivers = null; 14544 NR = 0; 14545 } 14546 14547 // Merge into one list. 14548 int ir = 0; 14549 if (receivers != null) { 14550 // A special case for PACKAGE_ADDED: do not allow the package 14551 // being added to see this broadcast. This prevents them from 14552 // using this as a back door to get run as soon as they are 14553 // installed. Maybe in the future we want to have a special install 14554 // broadcast or such for apps, but we'd like to deliberately make 14555 // this decision. 14556 String skipPackages[] = null; 14557 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14558 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14559 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14560 Uri data = intent.getData(); 14561 if (data != null) { 14562 String pkgName = data.getSchemeSpecificPart(); 14563 if (pkgName != null) { 14564 skipPackages = new String[] { pkgName }; 14565 } 14566 } 14567 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14568 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14569 } 14570 if (skipPackages != null && (skipPackages.length > 0)) { 14571 for (String skipPackage : skipPackages) { 14572 if (skipPackage != null) { 14573 int NT = receivers.size(); 14574 for (int it=0; it<NT; it++) { 14575 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14576 if (curt.activityInfo.packageName.equals(skipPackage)) { 14577 receivers.remove(it); 14578 it--; 14579 NT--; 14580 } 14581 } 14582 } 14583 } 14584 } 14585 14586 int NT = receivers != null ? receivers.size() : 0; 14587 int it = 0; 14588 ResolveInfo curt = null; 14589 BroadcastFilter curr = null; 14590 while (it < NT && ir < NR) { 14591 if (curt == null) { 14592 curt = (ResolveInfo)receivers.get(it); 14593 } 14594 if (curr == null) { 14595 curr = registeredReceivers.get(ir); 14596 } 14597 if (curr.getPriority() >= curt.priority) { 14598 // Insert this broadcast record into the final list. 14599 receivers.add(it, curr); 14600 ir++; 14601 curr = null; 14602 it++; 14603 NT++; 14604 } else { 14605 // Skip to the next ResolveInfo in the final list. 14606 it++; 14607 curt = null; 14608 } 14609 } 14610 } 14611 while (ir < NR) { 14612 if (receivers == null) { 14613 receivers = new ArrayList(); 14614 } 14615 receivers.add(registeredReceivers.get(ir)); 14616 ir++; 14617 } 14618 14619 if ((receivers != null && receivers.size() > 0) 14620 || resultTo != null) { 14621 BroadcastQueue queue = broadcastQueueForIntent(intent); 14622 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14623 callerPackage, callingPid, callingUid, resolvedType, 14624 requiredPermission, appOp, receivers, resultTo, resultCode, 14625 resultData, map, ordered, sticky, false, userId); 14626 if (DEBUG_BROADCAST) Slog.v( 14627 TAG, "Enqueueing ordered broadcast " + r 14628 + ": prev had " + queue.mOrderedBroadcasts.size()); 14629 if (DEBUG_BROADCAST) { 14630 int seq = r.intent.getIntExtra("seq", -1); 14631 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14632 } 14633 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14634 if (!replaced) { 14635 queue.enqueueOrderedBroadcastLocked(r); 14636 queue.scheduleBroadcastsLocked(); 14637 } 14638 } 14639 14640 return ActivityManager.BROADCAST_SUCCESS; 14641 } 14642 14643 final Intent verifyBroadcastLocked(Intent intent) { 14644 // Refuse possible leaked file descriptors 14645 if (intent != null && intent.hasFileDescriptors() == true) { 14646 throw new IllegalArgumentException("File descriptors passed in Intent"); 14647 } 14648 14649 int flags = intent.getFlags(); 14650 14651 if (!mProcessesReady) { 14652 // if the caller really truly claims to know what they're doing, go 14653 // ahead and allow the broadcast without launching any receivers 14654 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14655 intent = new Intent(intent); 14656 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14657 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14658 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14659 + " before boot completion"); 14660 throw new IllegalStateException("Cannot broadcast before boot completed"); 14661 } 14662 } 14663 14664 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14665 throw new IllegalArgumentException( 14666 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14667 } 14668 14669 return intent; 14670 } 14671 14672 public final int broadcastIntent(IApplicationThread caller, 14673 Intent intent, String resolvedType, IIntentReceiver resultTo, 14674 int resultCode, String resultData, Bundle map, 14675 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14676 enforceNotIsolatedCaller("broadcastIntent"); 14677 synchronized(this) { 14678 intent = verifyBroadcastLocked(intent); 14679 14680 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14681 final int callingPid = Binder.getCallingPid(); 14682 final int callingUid = Binder.getCallingUid(); 14683 final long origId = Binder.clearCallingIdentity(); 14684 int res = broadcastIntentLocked(callerApp, 14685 callerApp != null ? callerApp.info.packageName : null, 14686 intent, resolvedType, resultTo, 14687 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14688 callingPid, callingUid, userId); 14689 Binder.restoreCallingIdentity(origId); 14690 return res; 14691 } 14692 } 14693 14694 int broadcastIntentInPackage(String packageName, int uid, 14695 Intent intent, String resolvedType, IIntentReceiver resultTo, 14696 int resultCode, String resultData, Bundle map, 14697 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14698 synchronized(this) { 14699 intent = verifyBroadcastLocked(intent); 14700 14701 final long origId = Binder.clearCallingIdentity(); 14702 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14703 resultTo, resultCode, resultData, map, requiredPermission, 14704 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14705 Binder.restoreCallingIdentity(origId); 14706 return res; 14707 } 14708 } 14709 14710 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14711 // Refuse possible leaked file descriptors 14712 if (intent != null && intent.hasFileDescriptors() == true) { 14713 throw new IllegalArgumentException("File descriptors passed in Intent"); 14714 } 14715 14716 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14717 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 14718 14719 synchronized(this) { 14720 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14721 != PackageManager.PERMISSION_GRANTED) { 14722 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14723 + Binder.getCallingPid() 14724 + ", uid=" + Binder.getCallingUid() 14725 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14726 Slog.w(TAG, msg); 14727 throw new SecurityException(msg); 14728 } 14729 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14730 if (stickies != null) { 14731 ArrayList<Intent> list = stickies.get(intent.getAction()); 14732 if (list != null) { 14733 int N = list.size(); 14734 int i; 14735 for (i=0; i<N; i++) { 14736 if (intent.filterEquals(list.get(i))) { 14737 list.remove(i); 14738 break; 14739 } 14740 } 14741 if (list.size() <= 0) { 14742 stickies.remove(intent.getAction()); 14743 } 14744 } 14745 if (stickies.size() <= 0) { 14746 mStickyBroadcasts.remove(userId); 14747 } 14748 } 14749 } 14750 } 14751 14752 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14753 String resultData, Bundle resultExtras, boolean resultAbort) { 14754 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14755 if (r == null) { 14756 Slog.w(TAG, "finishReceiver called but not found on queue"); 14757 return false; 14758 } 14759 14760 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14761 } 14762 14763 void backgroundServicesFinishedLocked(int userId) { 14764 for (BroadcastQueue queue : mBroadcastQueues) { 14765 queue.backgroundServicesFinishedLocked(userId); 14766 } 14767 } 14768 14769 public void finishReceiver(IBinder who, int resultCode, String resultData, 14770 Bundle resultExtras, boolean resultAbort) { 14771 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14772 14773 // Refuse possible leaked file descriptors 14774 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14775 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14776 } 14777 14778 final long origId = Binder.clearCallingIdentity(); 14779 try { 14780 boolean doNext = false; 14781 BroadcastRecord r; 14782 14783 synchronized(this) { 14784 r = broadcastRecordForReceiverLocked(who); 14785 if (r != null) { 14786 doNext = r.queue.finishReceiverLocked(r, resultCode, 14787 resultData, resultExtras, resultAbort, true); 14788 } 14789 } 14790 14791 if (doNext) { 14792 r.queue.processNextBroadcast(false); 14793 } 14794 trimApplications(); 14795 } finally { 14796 Binder.restoreCallingIdentity(origId); 14797 } 14798 } 14799 14800 // ========================================================= 14801 // INSTRUMENTATION 14802 // ========================================================= 14803 14804 public boolean startInstrumentation(ComponentName className, 14805 String profileFile, int flags, Bundle arguments, 14806 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14807 int userId, String abiOverride) { 14808 enforceNotIsolatedCaller("startInstrumentation"); 14809 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14810 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 14811 // Refuse possible leaked file descriptors 14812 if (arguments != null && arguments.hasFileDescriptors()) { 14813 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14814 } 14815 14816 synchronized(this) { 14817 InstrumentationInfo ii = null; 14818 ApplicationInfo ai = null; 14819 try { 14820 ii = mContext.getPackageManager().getInstrumentationInfo( 14821 className, STOCK_PM_FLAGS); 14822 ai = AppGlobals.getPackageManager().getApplicationInfo( 14823 ii.targetPackage, STOCK_PM_FLAGS, userId); 14824 } catch (PackageManager.NameNotFoundException e) { 14825 } catch (RemoteException e) { 14826 } 14827 if (ii == null) { 14828 reportStartInstrumentationFailure(watcher, className, 14829 "Unable to find instrumentation info for: " + className); 14830 return false; 14831 } 14832 if (ai == null) { 14833 reportStartInstrumentationFailure(watcher, className, 14834 "Unable to find instrumentation target package: " + ii.targetPackage); 14835 return false; 14836 } 14837 14838 int match = mContext.getPackageManager().checkSignatures( 14839 ii.targetPackage, ii.packageName); 14840 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14841 String msg = "Permission Denial: starting instrumentation " 14842 + className + " from pid=" 14843 + Binder.getCallingPid() 14844 + ", uid=" + Binder.getCallingPid() 14845 + " not allowed because package " + ii.packageName 14846 + " does not have a signature matching the target " 14847 + ii.targetPackage; 14848 reportStartInstrumentationFailure(watcher, className, msg); 14849 throw new SecurityException(msg); 14850 } 14851 14852 final long origId = Binder.clearCallingIdentity(); 14853 // Instrumentation can kill and relaunch even persistent processes 14854 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14855 "start instr"); 14856 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14857 app.instrumentationClass = className; 14858 app.instrumentationInfo = ai; 14859 app.instrumentationProfileFile = profileFile; 14860 app.instrumentationArguments = arguments; 14861 app.instrumentationWatcher = watcher; 14862 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14863 app.instrumentationResultClass = className; 14864 Binder.restoreCallingIdentity(origId); 14865 } 14866 14867 return true; 14868 } 14869 14870 /** 14871 * Report errors that occur while attempting to start Instrumentation. Always writes the 14872 * error to the logs, but if somebody is watching, send the report there too. This enables 14873 * the "am" command to report errors with more information. 14874 * 14875 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14876 * @param cn The component name of the instrumentation. 14877 * @param report The error report. 14878 */ 14879 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14880 ComponentName cn, String report) { 14881 Slog.w(TAG, report); 14882 try { 14883 if (watcher != null) { 14884 Bundle results = new Bundle(); 14885 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14886 results.putString("Error", report); 14887 watcher.instrumentationStatus(cn, -1, results); 14888 } 14889 } catch (RemoteException e) { 14890 Slog.w(TAG, e); 14891 } 14892 } 14893 14894 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14895 if (app.instrumentationWatcher != null) { 14896 try { 14897 // NOTE: IInstrumentationWatcher *must* be oneway here 14898 app.instrumentationWatcher.instrumentationFinished( 14899 app.instrumentationClass, 14900 resultCode, 14901 results); 14902 } catch (RemoteException e) { 14903 } 14904 } 14905 if (app.instrumentationUiAutomationConnection != null) { 14906 try { 14907 app.instrumentationUiAutomationConnection.shutdown(); 14908 } catch (RemoteException re) { 14909 /* ignore */ 14910 } 14911 // Only a UiAutomation can set this flag and now that 14912 // it is finished we make sure it is reset to its default. 14913 mUserIsMonkey = false; 14914 } 14915 app.instrumentationWatcher = null; 14916 app.instrumentationUiAutomationConnection = null; 14917 app.instrumentationClass = null; 14918 app.instrumentationInfo = null; 14919 app.instrumentationProfileFile = null; 14920 app.instrumentationArguments = null; 14921 14922 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14923 "finished inst"); 14924 } 14925 14926 public void finishInstrumentation(IApplicationThread target, 14927 int resultCode, Bundle results) { 14928 int userId = UserHandle.getCallingUserId(); 14929 // Refuse possible leaked file descriptors 14930 if (results != null && results.hasFileDescriptors()) { 14931 throw new IllegalArgumentException("File descriptors passed in Intent"); 14932 } 14933 14934 synchronized(this) { 14935 ProcessRecord app = getRecordForAppLocked(target); 14936 if (app == null) { 14937 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14938 return; 14939 } 14940 final long origId = Binder.clearCallingIdentity(); 14941 finishInstrumentationLocked(app, resultCode, results); 14942 Binder.restoreCallingIdentity(origId); 14943 } 14944 } 14945 14946 // ========================================================= 14947 // CONFIGURATION 14948 // ========================================================= 14949 14950 public ConfigurationInfo getDeviceConfigurationInfo() { 14951 ConfigurationInfo config = new ConfigurationInfo(); 14952 synchronized (this) { 14953 config.reqTouchScreen = mConfiguration.touchscreen; 14954 config.reqKeyboardType = mConfiguration.keyboard; 14955 config.reqNavigation = mConfiguration.navigation; 14956 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14957 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14958 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14959 } 14960 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14961 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14962 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14963 } 14964 config.reqGlEsVersion = GL_ES_VERSION; 14965 } 14966 return config; 14967 } 14968 14969 ActivityStack getFocusedStack() { 14970 return mStackSupervisor.getFocusedStack(); 14971 } 14972 14973 public Configuration getConfiguration() { 14974 Configuration ci; 14975 synchronized(this) { 14976 ci = new Configuration(mConfiguration); 14977 } 14978 return ci; 14979 } 14980 14981 public void updatePersistentConfiguration(Configuration values) { 14982 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14983 "updateConfiguration()"); 14984 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14985 "updateConfiguration()"); 14986 if (values == null) { 14987 throw new NullPointerException("Configuration must not be null"); 14988 } 14989 14990 synchronized(this) { 14991 final long origId = Binder.clearCallingIdentity(); 14992 updateConfigurationLocked(values, null, true, false); 14993 Binder.restoreCallingIdentity(origId); 14994 } 14995 } 14996 14997 public void updateConfiguration(Configuration values) { 14998 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14999 "updateConfiguration()"); 15000 15001 synchronized(this) { 15002 if (values == null && mWindowManager != null) { 15003 // sentinel: fetch the current configuration from the window manager 15004 values = mWindowManager.computeNewConfiguration(); 15005 } 15006 15007 if (mWindowManager != null) { 15008 mProcessList.applyDisplaySize(mWindowManager); 15009 } 15010 15011 final long origId = Binder.clearCallingIdentity(); 15012 if (values != null) { 15013 Settings.System.clearConfiguration(values); 15014 } 15015 updateConfigurationLocked(values, null, false, false); 15016 Binder.restoreCallingIdentity(origId); 15017 } 15018 } 15019 15020 /** 15021 * Do either or both things: (1) change the current configuration, and (2) 15022 * make sure the given activity is running with the (now) current 15023 * configuration. Returns true if the activity has been left running, or 15024 * false if <var>starting</var> is being destroyed to match the new 15025 * configuration. 15026 * @param persistent TODO 15027 */ 15028 boolean updateConfigurationLocked(Configuration values, 15029 ActivityRecord starting, boolean persistent, boolean initLocale) { 15030 int changes = 0; 15031 15032 if (values != null) { 15033 Configuration newConfig = new Configuration(mConfiguration); 15034 changes = newConfig.updateFrom(values); 15035 if (changes != 0) { 15036 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15037 Slog.i(TAG, "Updating configuration to: " + values); 15038 } 15039 15040 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15041 15042 if (values.locale != null && !initLocale) { 15043 saveLocaleLocked(values.locale, 15044 !values.locale.equals(mConfiguration.locale), 15045 values.userSetLocale); 15046 } 15047 15048 mConfigurationSeq++; 15049 if (mConfigurationSeq <= 0) { 15050 mConfigurationSeq = 1; 15051 } 15052 newConfig.seq = mConfigurationSeq; 15053 mConfiguration = newConfig; 15054 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15055 //mUsageStatsService.noteStartConfig(newConfig); 15056 15057 final Configuration configCopy = new Configuration(mConfiguration); 15058 15059 // TODO: If our config changes, should we auto dismiss any currently 15060 // showing dialogs? 15061 mShowDialogs = shouldShowDialogs(newConfig); 15062 15063 AttributeCache ac = AttributeCache.instance(); 15064 if (ac != null) { 15065 ac.updateConfiguration(configCopy); 15066 } 15067 15068 // Make sure all resources in our process are updated 15069 // right now, so that anyone who is going to retrieve 15070 // resource values after we return will be sure to get 15071 // the new ones. This is especially important during 15072 // boot, where the first config change needs to guarantee 15073 // all resources have that config before following boot 15074 // code is executed. 15075 mSystemThread.applyConfigurationToResources(configCopy); 15076 15077 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15078 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15079 msg.obj = new Configuration(configCopy); 15080 mHandler.sendMessage(msg); 15081 } 15082 15083 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15084 ProcessRecord app = mLruProcesses.get(i); 15085 try { 15086 if (app.thread != null) { 15087 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15088 + app.processName + " new config " + mConfiguration); 15089 app.thread.scheduleConfigurationChanged(configCopy); 15090 } 15091 } catch (Exception e) { 15092 } 15093 } 15094 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15095 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15096 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15097 | Intent.FLAG_RECEIVER_FOREGROUND); 15098 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15099 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15100 Process.SYSTEM_UID, UserHandle.USER_ALL); 15101 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15102 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15103 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15104 broadcastIntentLocked(null, null, intent, 15105 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15106 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15107 } 15108 } 15109 } 15110 15111 boolean kept = true; 15112 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15113 // mainStack is null during startup. 15114 if (mainStack != null) { 15115 if (changes != 0 && starting == null) { 15116 // If the configuration changed, and the caller is not already 15117 // in the process of starting an activity, then find the top 15118 // activity to check if its configuration needs to change. 15119 starting = mainStack.topRunningActivityLocked(null); 15120 } 15121 15122 if (starting != null) { 15123 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15124 // And we need to make sure at this point that all other activities 15125 // are made visible with the correct configuration. 15126 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15127 } 15128 } 15129 15130 if (values != null && mWindowManager != null) { 15131 mWindowManager.setNewConfiguration(mConfiguration); 15132 } 15133 15134 return kept; 15135 } 15136 15137 /** 15138 * Decide based on the configuration whether we should shouw the ANR, 15139 * crash, etc dialogs. The idea is that if there is no affordnace to 15140 * press the on-screen buttons, we shouldn't show the dialog. 15141 * 15142 * A thought: SystemUI might also want to get told about this, the Power 15143 * dialog / global actions also might want different behaviors. 15144 */ 15145 private static final boolean shouldShowDialogs(Configuration config) { 15146 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15147 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15148 } 15149 15150 /** 15151 * Save the locale. You must be inside a synchronized (this) block. 15152 */ 15153 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15154 if(isDiff) { 15155 SystemProperties.set("user.language", l.getLanguage()); 15156 SystemProperties.set("user.region", l.getCountry()); 15157 } 15158 15159 if(isPersist) { 15160 SystemProperties.set("persist.sys.language", l.getLanguage()); 15161 SystemProperties.set("persist.sys.country", l.getCountry()); 15162 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15163 } 15164 } 15165 15166 @Override 15167 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15168 ActivityRecord srec = ActivityRecord.forToken(token); 15169 return srec != null && srec.task.affinity != null && 15170 srec.task.affinity.equals(destAffinity); 15171 } 15172 15173 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15174 Intent resultData) { 15175 15176 synchronized (this) { 15177 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15178 if (stack != null) { 15179 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15180 } 15181 return false; 15182 } 15183 } 15184 15185 public int getLaunchedFromUid(IBinder activityToken) { 15186 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15187 if (srec == null) { 15188 return -1; 15189 } 15190 return srec.launchedFromUid; 15191 } 15192 15193 public String getLaunchedFromPackage(IBinder activityToken) { 15194 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15195 if (srec == null) { 15196 return null; 15197 } 15198 return srec.launchedFromPackage; 15199 } 15200 15201 // ========================================================= 15202 // LIFETIME MANAGEMENT 15203 // ========================================================= 15204 15205 // Returns which broadcast queue the app is the current [or imminent] receiver 15206 // on, or 'null' if the app is not an active broadcast recipient. 15207 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15208 BroadcastRecord r = app.curReceiver; 15209 if (r != null) { 15210 return r.queue; 15211 } 15212 15213 // It's not the current receiver, but it might be starting up to become one 15214 synchronized (this) { 15215 for (BroadcastQueue queue : mBroadcastQueues) { 15216 r = queue.mPendingBroadcast; 15217 if (r != null && r.curApp == app) { 15218 // found it; report which queue it's in 15219 return queue; 15220 } 15221 } 15222 } 15223 15224 return null; 15225 } 15226 15227 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15228 boolean doingAll, long now) { 15229 if (mAdjSeq == app.adjSeq) { 15230 // This adjustment has already been computed. 15231 return app.curRawAdj; 15232 } 15233 15234 if (app.thread == null) { 15235 app.adjSeq = mAdjSeq; 15236 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15237 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15238 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15239 } 15240 15241 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15242 app.adjSource = null; 15243 app.adjTarget = null; 15244 app.empty = false; 15245 app.cached = false; 15246 15247 final int activitiesSize = app.activities.size(); 15248 15249 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15250 // The max adjustment doesn't allow this app to be anything 15251 // below foreground, so it is not worth doing work for it. 15252 app.adjType = "fixed"; 15253 app.adjSeq = mAdjSeq; 15254 app.curRawAdj = app.maxAdj; 15255 app.foregroundActivities = false; 15256 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15257 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15258 // System processes can do UI, and when they do we want to have 15259 // them trim their memory after the user leaves the UI. To 15260 // facilitate this, here we need to determine whether or not it 15261 // is currently showing UI. 15262 app.systemNoUi = true; 15263 if (app == TOP_APP) { 15264 app.systemNoUi = false; 15265 } else if (activitiesSize > 0) { 15266 for (int j = 0; j < activitiesSize; j++) { 15267 final ActivityRecord r = app.activities.get(j); 15268 if (r.visible) { 15269 app.systemNoUi = false; 15270 } 15271 } 15272 } 15273 if (!app.systemNoUi) { 15274 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15275 } 15276 return (app.curAdj=app.maxAdj); 15277 } 15278 15279 app.systemNoUi = false; 15280 15281 // Determine the importance of the process, starting with most 15282 // important to least, and assign an appropriate OOM adjustment. 15283 int adj; 15284 int schedGroup; 15285 int procState; 15286 boolean foregroundActivities = false; 15287 BroadcastQueue queue; 15288 if (app == TOP_APP) { 15289 // The last app on the list is the foreground app. 15290 adj = ProcessList.FOREGROUND_APP_ADJ; 15291 schedGroup = Process.THREAD_GROUP_DEFAULT; 15292 app.adjType = "top-activity"; 15293 foregroundActivities = true; 15294 procState = ActivityManager.PROCESS_STATE_TOP; 15295 } else if (app.instrumentationClass != null) { 15296 // Don't want to kill running instrumentation. 15297 adj = ProcessList.FOREGROUND_APP_ADJ; 15298 schedGroup = Process.THREAD_GROUP_DEFAULT; 15299 app.adjType = "instrumentation"; 15300 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15301 } else if ((queue = isReceivingBroadcast(app)) != null) { 15302 // An app that is currently receiving a broadcast also 15303 // counts as being in the foreground for OOM killer purposes. 15304 // It's placed in a sched group based on the nature of the 15305 // broadcast as reflected by which queue it's active in. 15306 adj = ProcessList.FOREGROUND_APP_ADJ; 15307 schedGroup = (queue == mFgBroadcastQueue) 15308 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15309 app.adjType = "broadcast"; 15310 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15311 } else if (app.executingServices.size() > 0) { 15312 // An app that is currently executing a service callback also 15313 // counts as being in the foreground. 15314 adj = ProcessList.FOREGROUND_APP_ADJ; 15315 schedGroup = app.execServicesFg ? 15316 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15317 app.adjType = "exec-service"; 15318 procState = ActivityManager.PROCESS_STATE_SERVICE; 15319 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15320 } else { 15321 // As far as we know the process is empty. We may change our mind later. 15322 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15323 // At this point we don't actually know the adjustment. Use the cached adj 15324 // value that the caller wants us to. 15325 adj = cachedAdj; 15326 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15327 app.cached = true; 15328 app.empty = true; 15329 app.adjType = "cch-empty"; 15330 } 15331 15332 // Examine all activities if not already foreground. 15333 if (!foregroundActivities && activitiesSize > 0) { 15334 for (int j = 0; j < activitiesSize; j++) { 15335 final ActivityRecord r = app.activities.get(j); 15336 if (r.app != app) { 15337 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15338 + app + "?!?"); 15339 continue; 15340 } 15341 if (r.visible) { 15342 // App has a visible activity; only upgrade adjustment. 15343 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15344 adj = ProcessList.VISIBLE_APP_ADJ; 15345 app.adjType = "visible"; 15346 } 15347 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15348 procState = ActivityManager.PROCESS_STATE_TOP; 15349 } 15350 schedGroup = Process.THREAD_GROUP_DEFAULT; 15351 app.cached = false; 15352 app.empty = false; 15353 foregroundActivities = true; 15354 break; 15355 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15356 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15357 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15358 app.adjType = "pausing"; 15359 } 15360 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15361 procState = ActivityManager.PROCESS_STATE_TOP; 15362 } 15363 schedGroup = Process.THREAD_GROUP_DEFAULT; 15364 app.cached = false; 15365 app.empty = false; 15366 foregroundActivities = true; 15367 } else if (r.state == ActivityState.STOPPING) { 15368 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15369 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15370 app.adjType = "stopping"; 15371 } 15372 // For the process state, we will at this point consider the 15373 // process to be cached. It will be cached either as an activity 15374 // or empty depending on whether the activity is finishing. We do 15375 // this so that we can treat the process as cached for purposes of 15376 // memory trimming (determing current memory level, trim command to 15377 // send to process) since there can be an arbitrary number of stopping 15378 // processes and they should soon all go into the cached state. 15379 if (!r.finishing) { 15380 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15381 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15382 } 15383 } 15384 app.cached = false; 15385 app.empty = false; 15386 foregroundActivities = true; 15387 } else { 15388 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15389 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15390 app.adjType = "cch-act"; 15391 } 15392 } 15393 } 15394 } 15395 15396 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15397 if (app.foregroundServices) { 15398 // The user is aware of this app, so make it visible. 15399 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15400 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15401 app.cached = false; 15402 app.adjType = "fg-service"; 15403 schedGroup = Process.THREAD_GROUP_DEFAULT; 15404 } else if (app.forcingToForeground != null) { 15405 // The user is aware of this app, so make it visible. 15406 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15407 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15408 app.cached = false; 15409 app.adjType = "force-fg"; 15410 app.adjSource = app.forcingToForeground; 15411 schedGroup = Process.THREAD_GROUP_DEFAULT; 15412 } 15413 } 15414 15415 if (app == mHeavyWeightProcess) { 15416 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15417 // We don't want to kill the current heavy-weight process. 15418 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15419 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15420 app.cached = false; 15421 app.adjType = "heavy"; 15422 } 15423 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15424 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15425 } 15426 } 15427 15428 if (app == mHomeProcess) { 15429 if (adj > ProcessList.HOME_APP_ADJ) { 15430 // This process is hosting what we currently consider to be the 15431 // home app, so we don't want to let it go into the background. 15432 adj = ProcessList.HOME_APP_ADJ; 15433 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15434 app.cached = false; 15435 app.adjType = "home"; 15436 } 15437 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15438 procState = ActivityManager.PROCESS_STATE_HOME; 15439 } 15440 } 15441 15442 if (app == mPreviousProcess && app.activities.size() > 0) { 15443 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15444 // This was the previous process that showed UI to the user. 15445 // We want to try to keep it around more aggressively, to give 15446 // a good experience around switching between two apps. 15447 adj = ProcessList.PREVIOUS_APP_ADJ; 15448 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15449 app.cached = false; 15450 app.adjType = "previous"; 15451 } 15452 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15453 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15454 } 15455 } 15456 15457 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15458 + " reason=" + app.adjType); 15459 15460 // By default, we use the computed adjustment. It may be changed if 15461 // there are applications dependent on our services or providers, but 15462 // this gives us a baseline and makes sure we don't get into an 15463 // infinite recursion. 15464 app.adjSeq = mAdjSeq; 15465 app.curRawAdj = adj; 15466 app.hasStartedServices = false; 15467 15468 if (mBackupTarget != null && app == mBackupTarget.app) { 15469 // If possible we want to avoid killing apps while they're being backed up 15470 if (adj > ProcessList.BACKUP_APP_ADJ) { 15471 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15472 adj = ProcessList.BACKUP_APP_ADJ; 15473 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15474 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15475 } 15476 app.adjType = "backup"; 15477 app.cached = false; 15478 } 15479 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15480 procState = ActivityManager.PROCESS_STATE_BACKUP; 15481 } 15482 } 15483 15484 boolean mayBeTop = false; 15485 15486 for (int is = app.services.size()-1; 15487 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15488 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15489 || procState > ActivityManager.PROCESS_STATE_TOP); 15490 is--) { 15491 ServiceRecord s = app.services.valueAt(is); 15492 if (s.startRequested) { 15493 app.hasStartedServices = true; 15494 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15495 procState = ActivityManager.PROCESS_STATE_SERVICE; 15496 } 15497 if (app.hasShownUi && app != mHomeProcess) { 15498 // If this process has shown some UI, let it immediately 15499 // go to the LRU list because it may be pretty heavy with 15500 // UI stuff. We'll tag it with a label just to help 15501 // debug and understand what is going on. 15502 if (adj > ProcessList.SERVICE_ADJ) { 15503 app.adjType = "cch-started-ui-services"; 15504 } 15505 } else { 15506 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15507 // This service has seen some activity within 15508 // recent memory, so we will keep its process ahead 15509 // of the background processes. 15510 if (adj > ProcessList.SERVICE_ADJ) { 15511 adj = ProcessList.SERVICE_ADJ; 15512 app.adjType = "started-services"; 15513 app.cached = false; 15514 } 15515 } 15516 // If we have let the service slide into the background 15517 // state, still have some text describing what it is doing 15518 // even though the service no longer has an impact. 15519 if (adj > ProcessList.SERVICE_ADJ) { 15520 app.adjType = "cch-started-services"; 15521 } 15522 } 15523 } 15524 for (int conni = s.connections.size()-1; 15525 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15526 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15527 || procState > ActivityManager.PROCESS_STATE_TOP); 15528 conni--) { 15529 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15530 for (int i = 0; 15531 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15532 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15533 || procState > ActivityManager.PROCESS_STATE_TOP); 15534 i++) { 15535 // XXX should compute this based on the max of 15536 // all connected clients. 15537 ConnectionRecord cr = clist.get(i); 15538 if (cr.binding.client == app) { 15539 // Binding to ourself is not interesting. 15540 continue; 15541 } 15542 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15543 ProcessRecord client = cr.binding.client; 15544 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15545 TOP_APP, doingAll, now); 15546 int clientProcState = client.curProcState; 15547 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15548 // If the other app is cached for any reason, for purposes here 15549 // we are going to consider it empty. The specific cached state 15550 // doesn't propagate except under certain conditions. 15551 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15552 } 15553 String adjType = null; 15554 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15555 // Not doing bind OOM management, so treat 15556 // this guy more like a started service. 15557 if (app.hasShownUi && app != mHomeProcess) { 15558 // If this process has shown some UI, let it immediately 15559 // go to the LRU list because it may be pretty heavy with 15560 // UI stuff. We'll tag it with a label just to help 15561 // debug and understand what is going on. 15562 if (adj > clientAdj) { 15563 adjType = "cch-bound-ui-services"; 15564 } 15565 app.cached = false; 15566 clientAdj = adj; 15567 clientProcState = procState; 15568 } else { 15569 if (now >= (s.lastActivity 15570 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15571 // This service has not seen activity within 15572 // recent memory, so allow it to drop to the 15573 // LRU list if there is no other reason to keep 15574 // it around. We'll also tag it with a label just 15575 // to help debug and undertand what is going on. 15576 if (adj > clientAdj) { 15577 adjType = "cch-bound-services"; 15578 } 15579 clientAdj = adj; 15580 } 15581 } 15582 } 15583 if (adj > clientAdj) { 15584 // If this process has recently shown UI, and 15585 // the process that is binding to it is less 15586 // important than being visible, then we don't 15587 // care about the binding as much as we care 15588 // about letting this process get into the LRU 15589 // list to be killed and restarted if needed for 15590 // memory. 15591 if (app.hasShownUi && app != mHomeProcess 15592 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15593 adjType = "cch-bound-ui-services"; 15594 } else { 15595 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15596 |Context.BIND_IMPORTANT)) != 0) { 15597 adj = clientAdj; 15598 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15599 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15600 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15601 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15602 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15603 adj = clientAdj; 15604 } else { 15605 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15606 adj = ProcessList.VISIBLE_APP_ADJ; 15607 } 15608 } 15609 if (!client.cached) { 15610 app.cached = false; 15611 } 15612 adjType = "service"; 15613 } 15614 } 15615 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15616 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15617 schedGroup = Process.THREAD_GROUP_DEFAULT; 15618 } 15619 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15620 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15621 // Special handling of clients who are in the top state. 15622 // We *may* want to consider this process to be in the 15623 // top state as well, but only if there is not another 15624 // reason for it to be running. Being on the top is a 15625 // special state, meaning you are specifically running 15626 // for the current top app. If the process is already 15627 // running in the background for some other reason, it 15628 // is more important to continue considering it to be 15629 // in the background state. 15630 mayBeTop = true; 15631 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15632 } else { 15633 // Special handling for above-top states (persistent 15634 // processes). These should not bring the current process 15635 // into the top state, since they are not on top. Instead 15636 // give them the best state after that. 15637 clientProcState = 15638 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15639 } 15640 } 15641 } else { 15642 if (clientProcState < 15643 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15644 clientProcState = 15645 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15646 } 15647 } 15648 if (procState > clientProcState) { 15649 procState = clientProcState; 15650 } 15651 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15652 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15653 app.pendingUiClean = true; 15654 } 15655 if (adjType != null) { 15656 app.adjType = adjType; 15657 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15658 .REASON_SERVICE_IN_USE; 15659 app.adjSource = cr.binding.client; 15660 app.adjSourceProcState = clientProcState; 15661 app.adjTarget = s.name; 15662 } 15663 } 15664 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15665 app.treatLikeActivity = true; 15666 } 15667 final ActivityRecord a = cr.activity; 15668 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15669 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15670 (a.visible || a.state == ActivityState.RESUMED 15671 || a.state == ActivityState.PAUSING)) { 15672 adj = ProcessList.FOREGROUND_APP_ADJ; 15673 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15674 schedGroup = Process.THREAD_GROUP_DEFAULT; 15675 } 15676 app.cached = false; 15677 app.adjType = "service"; 15678 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15679 .REASON_SERVICE_IN_USE; 15680 app.adjSource = a; 15681 app.adjSourceProcState = procState; 15682 app.adjTarget = s.name; 15683 } 15684 } 15685 } 15686 } 15687 } 15688 15689 for (int provi = app.pubProviders.size()-1; 15690 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15691 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15692 || procState > ActivityManager.PROCESS_STATE_TOP); 15693 provi--) { 15694 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15695 for (int i = cpr.connections.size()-1; 15696 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15697 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15698 || procState > ActivityManager.PROCESS_STATE_TOP); 15699 i--) { 15700 ContentProviderConnection conn = cpr.connections.get(i); 15701 ProcessRecord client = conn.client; 15702 if (client == app) { 15703 // Being our own client is not interesting. 15704 continue; 15705 } 15706 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15707 int clientProcState = client.curProcState; 15708 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15709 // If the other app is cached for any reason, for purposes here 15710 // we are going to consider it empty. 15711 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15712 } 15713 if (adj > clientAdj) { 15714 if (app.hasShownUi && app != mHomeProcess 15715 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15716 app.adjType = "cch-ui-provider"; 15717 } else { 15718 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15719 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15720 app.adjType = "provider"; 15721 } 15722 app.cached &= client.cached; 15723 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15724 .REASON_PROVIDER_IN_USE; 15725 app.adjSource = client; 15726 app.adjSourceProcState = clientProcState; 15727 app.adjTarget = cpr.name; 15728 } 15729 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15730 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15731 // Special handling of clients who are in the top state. 15732 // We *may* want to consider this process to be in the 15733 // top state as well, but only if there is not another 15734 // reason for it to be running. Being on the top is a 15735 // special state, meaning you are specifically running 15736 // for the current top app. If the process is already 15737 // running in the background for some other reason, it 15738 // is more important to continue considering it to be 15739 // in the background state. 15740 mayBeTop = true; 15741 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15742 } else { 15743 // Special handling for above-top states (persistent 15744 // processes). These should not bring the current process 15745 // into the top state, since they are not on top. Instead 15746 // give them the best state after that. 15747 clientProcState = 15748 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15749 } 15750 } 15751 if (procState > clientProcState) { 15752 procState = clientProcState; 15753 } 15754 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15755 schedGroup = Process.THREAD_GROUP_DEFAULT; 15756 } 15757 } 15758 // If the provider has external (non-framework) process 15759 // dependencies, ensure that its adjustment is at least 15760 // FOREGROUND_APP_ADJ. 15761 if (cpr.hasExternalProcessHandles()) { 15762 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15763 adj = ProcessList.FOREGROUND_APP_ADJ; 15764 schedGroup = Process.THREAD_GROUP_DEFAULT; 15765 app.cached = false; 15766 app.adjType = "provider"; 15767 app.adjTarget = cpr.name; 15768 } 15769 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15770 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15771 } 15772 } 15773 } 15774 15775 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15776 // A client of one of our services or providers is in the top state. We 15777 // *may* want to be in the top state, but not if we are already running in 15778 // the background for some other reason. For the decision here, we are going 15779 // to pick out a few specific states that we want to remain in when a client 15780 // is top (states that tend to be longer-term) and otherwise allow it to go 15781 // to the top state. 15782 switch (procState) { 15783 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15784 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15785 case ActivityManager.PROCESS_STATE_SERVICE: 15786 // These all are longer-term states, so pull them up to the top 15787 // of the background states, but not all the way to the top state. 15788 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15789 break; 15790 default: 15791 // Otherwise, top is a better choice, so take it. 15792 procState = ActivityManager.PROCESS_STATE_TOP; 15793 break; 15794 } 15795 } 15796 15797 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15798 if (app.hasClientActivities) { 15799 // This is a cached process, but with client activities. Mark it so. 15800 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15801 app.adjType = "cch-client-act"; 15802 } else if (app.treatLikeActivity) { 15803 // This is a cached process, but somebody wants us to treat it like it has 15804 // an activity, okay! 15805 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15806 app.adjType = "cch-as-act"; 15807 } 15808 } 15809 15810 if (adj == ProcessList.SERVICE_ADJ) { 15811 if (doingAll) { 15812 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15813 mNewNumServiceProcs++; 15814 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15815 if (!app.serviceb) { 15816 // This service isn't far enough down on the LRU list to 15817 // normally be a B service, but if we are low on RAM and it 15818 // is large we want to force it down since we would prefer to 15819 // keep launcher over it. 15820 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15821 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15822 app.serviceHighRam = true; 15823 app.serviceb = true; 15824 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15825 } else { 15826 mNewNumAServiceProcs++; 15827 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15828 } 15829 } else { 15830 app.serviceHighRam = false; 15831 } 15832 } 15833 if (app.serviceb) { 15834 adj = ProcessList.SERVICE_B_ADJ; 15835 } 15836 } 15837 15838 app.curRawAdj = adj; 15839 15840 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15841 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15842 if (adj > app.maxAdj) { 15843 adj = app.maxAdj; 15844 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15845 schedGroup = Process.THREAD_GROUP_DEFAULT; 15846 } 15847 } 15848 15849 // Do final modification to adj. Everything we do between here and applying 15850 // the final setAdj must be done in this function, because we will also use 15851 // it when computing the final cached adj later. Note that we don't need to 15852 // worry about this for max adj above, since max adj will always be used to 15853 // keep it out of the cached vaues. 15854 app.curAdj = app.modifyRawOomAdj(adj); 15855 app.curSchedGroup = schedGroup; 15856 app.curProcState = procState; 15857 app.foregroundActivities = foregroundActivities; 15858 15859 return app.curRawAdj; 15860 } 15861 15862 /** 15863 * Schedule PSS collection of a process. 15864 */ 15865 void requestPssLocked(ProcessRecord proc, int procState) { 15866 if (mPendingPssProcesses.contains(proc)) { 15867 return; 15868 } 15869 if (mPendingPssProcesses.size() == 0) { 15870 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15871 } 15872 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15873 proc.pssProcState = procState; 15874 mPendingPssProcesses.add(proc); 15875 } 15876 15877 /** 15878 * Schedule PSS collection of all processes. 15879 */ 15880 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15881 if (!always) { 15882 if (now < (mLastFullPssTime + 15883 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15884 return; 15885 } 15886 } 15887 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15888 mLastFullPssTime = now; 15889 mFullPssPending = true; 15890 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15891 mPendingPssProcesses.clear(); 15892 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15893 ProcessRecord app = mLruProcesses.get(i); 15894 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15895 app.pssProcState = app.setProcState; 15896 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15897 isSleeping(), now); 15898 mPendingPssProcesses.add(app); 15899 } 15900 } 15901 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15902 } 15903 15904 /** 15905 * Ask a given process to GC right now. 15906 */ 15907 final void performAppGcLocked(ProcessRecord app) { 15908 try { 15909 app.lastRequestedGc = SystemClock.uptimeMillis(); 15910 if (app.thread != null) { 15911 if (app.reportLowMemory) { 15912 app.reportLowMemory = false; 15913 app.thread.scheduleLowMemory(); 15914 } else { 15915 app.thread.processInBackground(); 15916 } 15917 } 15918 } catch (Exception e) { 15919 // whatever. 15920 } 15921 } 15922 15923 /** 15924 * Returns true if things are idle enough to perform GCs. 15925 */ 15926 private final boolean canGcNowLocked() { 15927 boolean processingBroadcasts = false; 15928 for (BroadcastQueue q : mBroadcastQueues) { 15929 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15930 processingBroadcasts = true; 15931 } 15932 } 15933 return !processingBroadcasts 15934 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15935 } 15936 15937 /** 15938 * Perform GCs on all processes that are waiting for it, but only 15939 * if things are idle. 15940 */ 15941 final void performAppGcsLocked() { 15942 final int N = mProcessesToGc.size(); 15943 if (N <= 0) { 15944 return; 15945 } 15946 if (canGcNowLocked()) { 15947 while (mProcessesToGc.size() > 0) { 15948 ProcessRecord proc = mProcessesToGc.remove(0); 15949 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15950 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15951 <= SystemClock.uptimeMillis()) { 15952 // To avoid spamming the system, we will GC processes one 15953 // at a time, waiting a few seconds between each. 15954 performAppGcLocked(proc); 15955 scheduleAppGcsLocked(); 15956 return; 15957 } else { 15958 // It hasn't been long enough since we last GCed this 15959 // process... put it in the list to wait for its time. 15960 addProcessToGcListLocked(proc); 15961 break; 15962 } 15963 } 15964 } 15965 15966 scheduleAppGcsLocked(); 15967 } 15968 } 15969 15970 /** 15971 * If all looks good, perform GCs on all processes waiting for them. 15972 */ 15973 final void performAppGcsIfAppropriateLocked() { 15974 if (canGcNowLocked()) { 15975 performAppGcsLocked(); 15976 return; 15977 } 15978 // Still not idle, wait some more. 15979 scheduleAppGcsLocked(); 15980 } 15981 15982 /** 15983 * Schedule the execution of all pending app GCs. 15984 */ 15985 final void scheduleAppGcsLocked() { 15986 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15987 15988 if (mProcessesToGc.size() > 0) { 15989 // Schedule a GC for the time to the next process. 15990 ProcessRecord proc = mProcessesToGc.get(0); 15991 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15992 15993 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15994 long now = SystemClock.uptimeMillis(); 15995 if (when < (now+GC_TIMEOUT)) { 15996 when = now + GC_TIMEOUT; 15997 } 15998 mHandler.sendMessageAtTime(msg, when); 15999 } 16000 } 16001 16002 /** 16003 * Add a process to the array of processes waiting to be GCed. Keeps the 16004 * list in sorted order by the last GC time. The process can't already be 16005 * on the list. 16006 */ 16007 final void addProcessToGcListLocked(ProcessRecord proc) { 16008 boolean added = false; 16009 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16010 if (mProcessesToGc.get(i).lastRequestedGc < 16011 proc.lastRequestedGc) { 16012 added = true; 16013 mProcessesToGc.add(i+1, proc); 16014 break; 16015 } 16016 } 16017 if (!added) { 16018 mProcessesToGc.add(0, proc); 16019 } 16020 } 16021 16022 /** 16023 * Set up to ask a process to GC itself. This will either do it 16024 * immediately, or put it on the list of processes to gc the next 16025 * time things are idle. 16026 */ 16027 final void scheduleAppGcLocked(ProcessRecord app) { 16028 long now = SystemClock.uptimeMillis(); 16029 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16030 return; 16031 } 16032 if (!mProcessesToGc.contains(app)) { 16033 addProcessToGcListLocked(app); 16034 scheduleAppGcsLocked(); 16035 } 16036 } 16037 16038 final void checkExcessivePowerUsageLocked(boolean doKills) { 16039 updateCpuStatsNow(); 16040 16041 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16042 boolean doWakeKills = doKills; 16043 boolean doCpuKills = doKills; 16044 if (mLastPowerCheckRealtime == 0) { 16045 doWakeKills = false; 16046 } 16047 if (mLastPowerCheckUptime == 0) { 16048 doCpuKills = false; 16049 } 16050 if (stats.isScreenOn()) { 16051 doWakeKills = false; 16052 } 16053 final long curRealtime = SystemClock.elapsedRealtime(); 16054 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16055 final long curUptime = SystemClock.uptimeMillis(); 16056 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16057 mLastPowerCheckRealtime = curRealtime; 16058 mLastPowerCheckUptime = curUptime; 16059 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16060 doWakeKills = false; 16061 } 16062 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16063 doCpuKills = false; 16064 } 16065 int i = mLruProcesses.size(); 16066 while (i > 0) { 16067 i--; 16068 ProcessRecord app = mLruProcesses.get(i); 16069 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16070 long wtime; 16071 synchronized (stats) { 16072 wtime = stats.getProcessWakeTime(app.info.uid, 16073 app.pid, curRealtime); 16074 } 16075 long wtimeUsed = wtime - app.lastWakeTime; 16076 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16077 if (DEBUG_POWER) { 16078 StringBuilder sb = new StringBuilder(128); 16079 sb.append("Wake for "); 16080 app.toShortString(sb); 16081 sb.append(": over "); 16082 TimeUtils.formatDuration(realtimeSince, sb); 16083 sb.append(" used "); 16084 TimeUtils.formatDuration(wtimeUsed, sb); 16085 sb.append(" ("); 16086 sb.append((wtimeUsed*100)/realtimeSince); 16087 sb.append("%)"); 16088 Slog.i(TAG, sb.toString()); 16089 sb.setLength(0); 16090 sb.append("CPU for "); 16091 app.toShortString(sb); 16092 sb.append(": over "); 16093 TimeUtils.formatDuration(uptimeSince, sb); 16094 sb.append(" used "); 16095 TimeUtils.formatDuration(cputimeUsed, sb); 16096 sb.append(" ("); 16097 sb.append((cputimeUsed*100)/uptimeSince); 16098 sb.append("%)"); 16099 Slog.i(TAG, sb.toString()); 16100 } 16101 // If a process has held a wake lock for more 16102 // than 50% of the time during this period, 16103 // that sounds bad. Kill! 16104 if (doWakeKills && realtimeSince > 0 16105 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16106 synchronized (stats) { 16107 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16108 realtimeSince, wtimeUsed); 16109 } 16110 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16111 + " during " + realtimeSince); 16112 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16113 } else if (doCpuKills && uptimeSince > 0 16114 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16115 synchronized (stats) { 16116 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16117 uptimeSince, cputimeUsed); 16118 } 16119 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16120 + " during " + uptimeSince); 16121 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16122 } else { 16123 app.lastWakeTime = wtime; 16124 app.lastCpuTime = app.curCpuTime; 16125 } 16126 } 16127 } 16128 } 16129 16130 private final boolean applyOomAdjLocked(ProcessRecord app, 16131 ProcessRecord TOP_APP, boolean doingAll, long now) { 16132 boolean success = true; 16133 16134 if (app.curRawAdj != app.setRawAdj) { 16135 app.setRawAdj = app.curRawAdj; 16136 } 16137 16138 int changes = 0; 16139 16140 if (app.curAdj != app.setAdj) { 16141 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16142 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16143 TAG, "Set " + app.pid + " " + app.processName + 16144 " adj " + app.curAdj + ": " + app.adjType); 16145 app.setAdj = app.curAdj; 16146 } 16147 16148 if (app.setSchedGroup != app.curSchedGroup) { 16149 app.setSchedGroup = app.curSchedGroup; 16150 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16151 "Setting process group of " + app.processName 16152 + " to " + app.curSchedGroup); 16153 if (app.waitingToKill != null && 16154 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16155 killUnneededProcessLocked(app, app.waitingToKill); 16156 success = false; 16157 } else { 16158 if (true) { 16159 long oldId = Binder.clearCallingIdentity(); 16160 try { 16161 Process.setProcessGroup(app.pid, app.curSchedGroup); 16162 } catch (Exception e) { 16163 Slog.w(TAG, "Failed setting process group of " + app.pid 16164 + " to " + app.curSchedGroup); 16165 e.printStackTrace(); 16166 } finally { 16167 Binder.restoreCallingIdentity(oldId); 16168 } 16169 } else { 16170 if (app.thread != null) { 16171 try { 16172 app.thread.setSchedulingGroup(app.curSchedGroup); 16173 } catch (RemoteException e) { 16174 } 16175 } 16176 } 16177 Process.setSwappiness(app.pid, 16178 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16179 } 16180 } 16181 if (app.repForegroundActivities != app.foregroundActivities) { 16182 app.repForegroundActivities = app.foregroundActivities; 16183 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16184 } 16185 if (app.repProcState != app.curProcState) { 16186 app.repProcState = app.curProcState; 16187 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16188 if (app.thread != null) { 16189 try { 16190 if (false) { 16191 //RuntimeException h = new RuntimeException("here"); 16192 Slog.i(TAG, "Sending new process state " + app.repProcState 16193 + " to " + app /*, h*/); 16194 } 16195 app.thread.setProcessState(app.repProcState); 16196 } catch (RemoteException e) { 16197 } 16198 } 16199 } 16200 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16201 app.setProcState)) { 16202 app.lastStateTime = now; 16203 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16204 isSleeping(), now); 16205 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16206 + ProcessList.makeProcStateString(app.setProcState) + " to " 16207 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16208 + (app.nextPssTime-now) + ": " + app); 16209 } else { 16210 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16211 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16212 requestPssLocked(app, app.setProcState); 16213 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16214 isSleeping(), now); 16215 } else if (false && DEBUG_PSS) { 16216 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16217 } 16218 } 16219 if (app.setProcState != app.curProcState) { 16220 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16221 "Proc state change of " + app.processName 16222 + " to " + app.curProcState); 16223 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16224 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16225 if (setImportant && !curImportant) { 16226 // This app is no longer something we consider important enough to allow to 16227 // use arbitrary amounts of battery power. Note 16228 // its current wake lock time to later know to kill it if 16229 // it is not behaving well. 16230 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16231 synchronized (stats) { 16232 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16233 app.pid, SystemClock.elapsedRealtime()); 16234 } 16235 app.lastCpuTime = app.curCpuTime; 16236 16237 } 16238 app.setProcState = app.curProcState; 16239 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16240 app.notCachedSinceIdle = false; 16241 } 16242 if (!doingAll) { 16243 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16244 } else { 16245 app.procStateChanged = true; 16246 } 16247 } 16248 16249 if (changes != 0) { 16250 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16251 int i = mPendingProcessChanges.size()-1; 16252 ProcessChangeItem item = null; 16253 while (i >= 0) { 16254 item = mPendingProcessChanges.get(i); 16255 if (item.pid == app.pid) { 16256 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16257 break; 16258 } 16259 i--; 16260 } 16261 if (i < 0) { 16262 // No existing item in pending changes; need a new one. 16263 final int NA = mAvailProcessChanges.size(); 16264 if (NA > 0) { 16265 item = mAvailProcessChanges.remove(NA-1); 16266 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16267 } else { 16268 item = new ProcessChangeItem(); 16269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16270 } 16271 item.changes = 0; 16272 item.pid = app.pid; 16273 item.uid = app.info.uid; 16274 if (mPendingProcessChanges.size() == 0) { 16275 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16276 "*** Enqueueing dispatch processes changed!"); 16277 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16278 } 16279 mPendingProcessChanges.add(item); 16280 } 16281 item.changes |= changes; 16282 item.processState = app.repProcState; 16283 item.foregroundActivities = app.repForegroundActivities; 16284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16285 + Integer.toHexString(System.identityHashCode(item)) 16286 + " " + app.toShortString() + ": changes=" + item.changes 16287 + " procState=" + item.processState 16288 + " foreground=" + item.foregroundActivities 16289 + " type=" + app.adjType + " source=" + app.adjSource 16290 + " target=" + app.adjTarget); 16291 } 16292 16293 return success; 16294 } 16295 16296 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16297 if (proc.thread != null) { 16298 if (proc.baseProcessTracker != null) { 16299 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16300 } 16301 if (proc.repProcState >= 0) { 16302 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16303 proc.repProcState); 16304 } 16305 } 16306 } 16307 16308 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16309 ProcessRecord TOP_APP, boolean doingAll, long now) { 16310 if (app.thread == null) { 16311 return false; 16312 } 16313 16314 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16315 16316 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16317 } 16318 16319 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16320 boolean oomAdj) { 16321 if (isForeground != proc.foregroundServices) { 16322 proc.foregroundServices = isForeground; 16323 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16324 proc.info.uid); 16325 if (isForeground) { 16326 if (curProcs == null) { 16327 curProcs = new ArrayList<ProcessRecord>(); 16328 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16329 } 16330 if (!curProcs.contains(proc)) { 16331 curProcs.add(proc); 16332 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16333 proc.info.packageName, proc.info.uid); 16334 } 16335 } else { 16336 if (curProcs != null) { 16337 if (curProcs.remove(proc)) { 16338 mBatteryStatsService.noteEvent( 16339 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16340 proc.info.packageName, proc.info.uid); 16341 if (curProcs.size() <= 0) { 16342 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16343 } 16344 } 16345 } 16346 } 16347 if (oomAdj) { 16348 updateOomAdjLocked(); 16349 } 16350 } 16351 } 16352 16353 private final ActivityRecord resumedAppLocked() { 16354 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16355 String pkg; 16356 int uid; 16357 if (act != null) { 16358 pkg = act.packageName; 16359 uid = act.info.applicationInfo.uid; 16360 } else { 16361 pkg = null; 16362 uid = -1; 16363 } 16364 // Has the UID or resumed package name changed? 16365 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16366 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16367 if (mCurResumedPackage != null) { 16368 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16369 mCurResumedPackage, mCurResumedUid); 16370 } 16371 mCurResumedPackage = pkg; 16372 mCurResumedUid = uid; 16373 if (mCurResumedPackage != null) { 16374 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16375 mCurResumedPackage, mCurResumedUid); 16376 } 16377 } 16378 return act; 16379 } 16380 16381 final boolean updateOomAdjLocked(ProcessRecord app) { 16382 final ActivityRecord TOP_ACT = resumedAppLocked(); 16383 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16384 final boolean wasCached = app.cached; 16385 16386 mAdjSeq++; 16387 16388 // This is the desired cached adjusment we want to tell it to use. 16389 // If our app is currently cached, we know it, and that is it. Otherwise, 16390 // we don't know it yet, and it needs to now be cached we will then 16391 // need to do a complete oom adj. 16392 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16393 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16394 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16395 SystemClock.uptimeMillis()); 16396 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16397 // Changed to/from cached state, so apps after it in the LRU 16398 // list may also be changed. 16399 updateOomAdjLocked(); 16400 } 16401 return success; 16402 } 16403 16404 final void updateOomAdjLocked() { 16405 final ActivityRecord TOP_ACT = resumedAppLocked(); 16406 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16407 final long now = SystemClock.uptimeMillis(); 16408 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16409 final int N = mLruProcesses.size(); 16410 16411 if (false) { 16412 RuntimeException e = new RuntimeException(); 16413 e.fillInStackTrace(); 16414 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16415 } 16416 16417 mAdjSeq++; 16418 mNewNumServiceProcs = 0; 16419 mNewNumAServiceProcs = 0; 16420 16421 final int emptyProcessLimit; 16422 final int cachedProcessLimit; 16423 if (mProcessLimit <= 0) { 16424 emptyProcessLimit = cachedProcessLimit = 0; 16425 } else if (mProcessLimit == 1) { 16426 emptyProcessLimit = 1; 16427 cachedProcessLimit = 0; 16428 } else { 16429 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16430 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16431 } 16432 16433 // Let's determine how many processes we have running vs. 16434 // how many slots we have for background processes; we may want 16435 // to put multiple processes in a slot of there are enough of 16436 // them. 16437 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16438 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16439 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16440 if (numEmptyProcs > cachedProcessLimit) { 16441 // If there are more empty processes than our limit on cached 16442 // processes, then use the cached process limit for the factor. 16443 // This ensures that the really old empty processes get pushed 16444 // down to the bottom, so if we are running low on memory we will 16445 // have a better chance at keeping around more cached processes 16446 // instead of a gazillion empty processes. 16447 numEmptyProcs = cachedProcessLimit; 16448 } 16449 int emptyFactor = numEmptyProcs/numSlots; 16450 if (emptyFactor < 1) emptyFactor = 1; 16451 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16452 if (cachedFactor < 1) cachedFactor = 1; 16453 int stepCached = 0; 16454 int stepEmpty = 0; 16455 int numCached = 0; 16456 int numEmpty = 0; 16457 int numTrimming = 0; 16458 16459 mNumNonCachedProcs = 0; 16460 mNumCachedHiddenProcs = 0; 16461 16462 // First update the OOM adjustment for each of the 16463 // application processes based on their current state. 16464 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16465 int nextCachedAdj = curCachedAdj+1; 16466 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16467 int nextEmptyAdj = curEmptyAdj+2; 16468 for (int i=N-1; i>=0; i--) { 16469 ProcessRecord app = mLruProcesses.get(i); 16470 if (!app.killedByAm && app.thread != null) { 16471 app.procStateChanged = false; 16472 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16473 16474 // If we haven't yet assigned the final cached adj 16475 // to the process, do that now. 16476 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16477 switch (app.curProcState) { 16478 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16479 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16480 // This process is a cached process holding activities... 16481 // assign it the next cached value for that type, and then 16482 // step that cached level. 16483 app.curRawAdj = curCachedAdj; 16484 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16485 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16486 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16487 + ")"); 16488 if (curCachedAdj != nextCachedAdj) { 16489 stepCached++; 16490 if (stepCached >= cachedFactor) { 16491 stepCached = 0; 16492 curCachedAdj = nextCachedAdj; 16493 nextCachedAdj += 2; 16494 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16495 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16496 } 16497 } 16498 } 16499 break; 16500 default: 16501 // For everything else, assign next empty cached process 16502 // level and bump that up. Note that this means that 16503 // long-running services that have dropped down to the 16504 // cached level will be treated as empty (since their process 16505 // state is still as a service), which is what we want. 16506 app.curRawAdj = curEmptyAdj; 16507 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16508 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16509 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16510 + ")"); 16511 if (curEmptyAdj != nextEmptyAdj) { 16512 stepEmpty++; 16513 if (stepEmpty >= emptyFactor) { 16514 stepEmpty = 0; 16515 curEmptyAdj = nextEmptyAdj; 16516 nextEmptyAdj += 2; 16517 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16518 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16519 } 16520 } 16521 } 16522 break; 16523 } 16524 } 16525 16526 applyOomAdjLocked(app, TOP_APP, true, now); 16527 16528 // Count the number of process types. 16529 switch (app.curProcState) { 16530 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16531 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16532 mNumCachedHiddenProcs++; 16533 numCached++; 16534 if (numCached > cachedProcessLimit) { 16535 killUnneededProcessLocked(app, "cached #" + numCached); 16536 } 16537 break; 16538 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16539 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16540 && app.lastActivityTime < oldTime) { 16541 killUnneededProcessLocked(app, "empty for " 16542 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16543 / 1000) + "s"); 16544 } else { 16545 numEmpty++; 16546 if (numEmpty > emptyProcessLimit) { 16547 killUnneededProcessLocked(app, "empty #" + numEmpty); 16548 } 16549 } 16550 break; 16551 default: 16552 mNumNonCachedProcs++; 16553 break; 16554 } 16555 16556 if (app.isolated && app.services.size() <= 0) { 16557 // If this is an isolated process, and there are no 16558 // services running in it, then the process is no longer 16559 // needed. We agressively kill these because we can by 16560 // definition not re-use the same process again, and it is 16561 // good to avoid having whatever code was running in them 16562 // left sitting around after no longer needed. 16563 killUnneededProcessLocked(app, "isolated not needed"); 16564 } 16565 16566 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16567 && !app.killedByAm) { 16568 numTrimming++; 16569 } 16570 } 16571 } 16572 16573 mNumServiceProcs = mNewNumServiceProcs; 16574 16575 // Now determine the memory trimming level of background processes. 16576 // Unfortunately we need to start at the back of the list to do this 16577 // properly. We only do this if the number of background apps we 16578 // are managing to keep around is less than half the maximum we desire; 16579 // if we are keeping a good number around, we'll let them use whatever 16580 // memory they want. 16581 final int numCachedAndEmpty = numCached + numEmpty; 16582 int memFactor; 16583 if (numCached <= ProcessList.TRIM_CACHED_APPS 16584 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16585 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16586 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16587 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16588 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16589 } else { 16590 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16591 } 16592 } else { 16593 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16594 } 16595 // We always allow the memory level to go up (better). We only allow it to go 16596 // down if we are in a state where that is allowed, *and* the total number of processes 16597 // has gone down since last time. 16598 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16599 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16600 + " last=" + mLastNumProcesses); 16601 if (memFactor > mLastMemoryLevel) { 16602 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16603 memFactor = mLastMemoryLevel; 16604 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16605 } 16606 } 16607 mLastMemoryLevel = memFactor; 16608 mLastNumProcesses = mLruProcesses.size(); 16609 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16610 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16611 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16612 if (mLowRamStartTime == 0) { 16613 mLowRamStartTime = now; 16614 } 16615 int step = 0; 16616 int fgTrimLevel; 16617 switch (memFactor) { 16618 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16619 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16620 break; 16621 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16622 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16623 break; 16624 default: 16625 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16626 break; 16627 } 16628 int factor = numTrimming/3; 16629 int minFactor = 2; 16630 if (mHomeProcess != null) minFactor++; 16631 if (mPreviousProcess != null) minFactor++; 16632 if (factor < minFactor) factor = minFactor; 16633 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16634 for (int i=N-1; i>=0; i--) { 16635 ProcessRecord app = mLruProcesses.get(i); 16636 if (allChanged || app.procStateChanged) { 16637 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16638 app.procStateChanged = false; 16639 } 16640 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16641 && !app.killedByAm) { 16642 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16643 try { 16644 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16645 "Trimming memory of " + app.processName 16646 + " to " + curLevel); 16647 app.thread.scheduleTrimMemory(curLevel); 16648 } catch (RemoteException e) { 16649 } 16650 if (false) { 16651 // For now we won't do this; our memory trimming seems 16652 // to be good enough at this point that destroying 16653 // activities causes more harm than good. 16654 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16655 && app != mHomeProcess && app != mPreviousProcess) { 16656 // Need to do this on its own message because the stack may not 16657 // be in a consistent state at this point. 16658 // For these apps we will also finish their activities 16659 // to help them free memory. 16660 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16661 } 16662 } 16663 } 16664 app.trimMemoryLevel = curLevel; 16665 step++; 16666 if (step >= factor) { 16667 step = 0; 16668 switch (curLevel) { 16669 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16670 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16671 break; 16672 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16673 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16674 break; 16675 } 16676 } 16677 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16678 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16679 && app.thread != null) { 16680 try { 16681 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16682 "Trimming memory of heavy-weight " + app.processName 16683 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16684 app.thread.scheduleTrimMemory( 16685 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16686 } catch (RemoteException e) { 16687 } 16688 } 16689 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16690 } else { 16691 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16692 || app.systemNoUi) && app.pendingUiClean) { 16693 // If this application is now in the background and it 16694 // had done UI, then give it the special trim level to 16695 // have it free UI resources. 16696 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16697 if (app.trimMemoryLevel < level && app.thread != null) { 16698 try { 16699 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16700 "Trimming memory of bg-ui " + app.processName 16701 + " to " + level); 16702 app.thread.scheduleTrimMemory(level); 16703 } catch (RemoteException e) { 16704 } 16705 } 16706 app.pendingUiClean = false; 16707 } 16708 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16709 try { 16710 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16711 "Trimming memory of fg " + app.processName 16712 + " to " + fgTrimLevel); 16713 app.thread.scheduleTrimMemory(fgTrimLevel); 16714 } catch (RemoteException e) { 16715 } 16716 } 16717 app.trimMemoryLevel = fgTrimLevel; 16718 } 16719 } 16720 } else { 16721 if (mLowRamStartTime != 0) { 16722 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16723 mLowRamStartTime = 0; 16724 } 16725 for (int i=N-1; i>=0; i--) { 16726 ProcessRecord app = mLruProcesses.get(i); 16727 if (allChanged || app.procStateChanged) { 16728 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16729 app.procStateChanged = false; 16730 } 16731 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16732 || app.systemNoUi) && app.pendingUiClean) { 16733 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16734 && app.thread != null) { 16735 try { 16736 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16737 "Trimming memory of ui hidden " + app.processName 16738 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16739 app.thread.scheduleTrimMemory( 16740 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16741 } catch (RemoteException e) { 16742 } 16743 } 16744 app.pendingUiClean = false; 16745 } 16746 app.trimMemoryLevel = 0; 16747 } 16748 } 16749 16750 if (mAlwaysFinishActivities) { 16751 // Need to do this on its own message because the stack may not 16752 // be in a consistent state at this point. 16753 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16754 } 16755 16756 if (allChanged) { 16757 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16758 } 16759 16760 if (mProcessStats.shouldWriteNowLocked(now)) { 16761 mHandler.post(new Runnable() { 16762 @Override public void run() { 16763 synchronized (ActivityManagerService.this) { 16764 mProcessStats.writeStateAsyncLocked(); 16765 } 16766 } 16767 }); 16768 } 16769 16770 if (DEBUG_OOM_ADJ) { 16771 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16772 } 16773 } 16774 16775 final void trimApplications() { 16776 synchronized (this) { 16777 int i; 16778 16779 // First remove any unused application processes whose package 16780 // has been removed. 16781 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16782 final ProcessRecord app = mRemovedProcesses.get(i); 16783 if (app.activities.size() == 0 16784 && app.curReceiver == null && app.services.size() == 0) { 16785 Slog.i( 16786 TAG, "Exiting empty application process " 16787 + app.processName + " (" 16788 + (app.thread != null ? app.thread.asBinder() : null) 16789 + ")\n"); 16790 if (app.pid > 0 && app.pid != MY_PID) { 16791 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16792 app.processName, app.setAdj, "empty"); 16793 app.killedByAm = true; 16794 Process.killProcessQuiet(app.pid); 16795 Process.killProcessGroup(app.info.uid, app.pid); 16796 } else { 16797 try { 16798 app.thread.scheduleExit(); 16799 } catch (Exception e) { 16800 // Ignore exceptions. 16801 } 16802 } 16803 cleanUpApplicationRecordLocked(app, false, true, -1); 16804 mRemovedProcesses.remove(i); 16805 16806 if (app.persistent) { 16807 addAppLocked(app.info, false, null /* ABI override */); 16808 } 16809 } 16810 } 16811 16812 // Now update the oom adj for all processes. 16813 updateOomAdjLocked(); 16814 } 16815 } 16816 16817 /** This method sends the specified signal to each of the persistent apps */ 16818 public void signalPersistentProcesses(int sig) throws RemoteException { 16819 if (sig != Process.SIGNAL_USR1) { 16820 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16821 } 16822 16823 synchronized (this) { 16824 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16825 != PackageManager.PERMISSION_GRANTED) { 16826 throw new SecurityException("Requires permission " 16827 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16828 } 16829 16830 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16831 ProcessRecord r = mLruProcesses.get(i); 16832 if (r.thread != null && r.persistent) { 16833 Process.sendSignal(r.pid, sig); 16834 } 16835 } 16836 } 16837 } 16838 16839 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16840 if (proc == null || proc == mProfileProc) { 16841 proc = mProfileProc; 16842 path = mProfileFile; 16843 profileType = mProfileType; 16844 clearProfilerLocked(); 16845 } 16846 if (proc == null) { 16847 return; 16848 } 16849 try { 16850 proc.thread.profilerControl(false, path, null, profileType); 16851 } catch (RemoteException e) { 16852 throw new IllegalStateException("Process disappeared"); 16853 } 16854 } 16855 16856 private void clearProfilerLocked() { 16857 if (mProfileFd != null) { 16858 try { 16859 mProfileFd.close(); 16860 } catch (IOException e) { 16861 } 16862 } 16863 mProfileApp = null; 16864 mProfileProc = null; 16865 mProfileFile = null; 16866 mProfileType = 0; 16867 mAutoStopProfiler = false; 16868 } 16869 16870 public boolean profileControl(String process, int userId, boolean start, 16871 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16872 16873 try { 16874 synchronized (this) { 16875 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16876 // its own permission. 16877 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16878 != PackageManager.PERMISSION_GRANTED) { 16879 throw new SecurityException("Requires permission " 16880 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16881 } 16882 16883 if (start && fd == null) { 16884 throw new IllegalArgumentException("null fd"); 16885 } 16886 16887 ProcessRecord proc = null; 16888 if (process != null) { 16889 proc = findProcessLocked(process, userId, "profileControl"); 16890 } 16891 16892 if (start && (proc == null || proc.thread == null)) { 16893 throw new IllegalArgumentException("Unknown process: " + process); 16894 } 16895 16896 if (start) { 16897 stopProfilerLocked(null, null, 0); 16898 setProfileApp(proc.info, proc.processName, path, fd, false); 16899 mProfileProc = proc; 16900 mProfileType = profileType; 16901 try { 16902 fd = fd.dup(); 16903 } catch (IOException e) { 16904 fd = null; 16905 } 16906 proc.thread.profilerControl(start, path, fd, profileType); 16907 fd = null; 16908 mProfileFd = null; 16909 } else { 16910 stopProfilerLocked(proc, path, profileType); 16911 if (fd != null) { 16912 try { 16913 fd.close(); 16914 } catch (IOException e) { 16915 } 16916 } 16917 } 16918 16919 return true; 16920 } 16921 } catch (RemoteException e) { 16922 throw new IllegalStateException("Process disappeared"); 16923 } finally { 16924 if (fd != null) { 16925 try { 16926 fd.close(); 16927 } catch (IOException e) { 16928 } 16929 } 16930 } 16931 } 16932 16933 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16934 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16935 userId, true, ALLOW_FULL_ONLY, callName, null); 16936 ProcessRecord proc = null; 16937 try { 16938 int pid = Integer.parseInt(process); 16939 synchronized (mPidsSelfLocked) { 16940 proc = mPidsSelfLocked.get(pid); 16941 } 16942 } catch (NumberFormatException e) { 16943 } 16944 16945 if (proc == null) { 16946 ArrayMap<String, SparseArray<ProcessRecord>> all 16947 = mProcessNames.getMap(); 16948 SparseArray<ProcessRecord> procs = all.get(process); 16949 if (procs != null && procs.size() > 0) { 16950 proc = procs.valueAt(0); 16951 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16952 for (int i=1; i<procs.size(); i++) { 16953 ProcessRecord thisProc = procs.valueAt(i); 16954 if (thisProc.userId == userId) { 16955 proc = thisProc; 16956 break; 16957 } 16958 } 16959 } 16960 } 16961 } 16962 16963 return proc; 16964 } 16965 16966 public boolean dumpHeap(String process, int userId, boolean managed, 16967 String path, ParcelFileDescriptor fd) throws RemoteException { 16968 16969 try { 16970 synchronized (this) { 16971 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16972 // its own permission (same as profileControl). 16973 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16974 != PackageManager.PERMISSION_GRANTED) { 16975 throw new SecurityException("Requires permission " 16976 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16977 } 16978 16979 if (fd == null) { 16980 throw new IllegalArgumentException("null fd"); 16981 } 16982 16983 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16984 if (proc == null || proc.thread == null) { 16985 throw new IllegalArgumentException("Unknown process: " + process); 16986 } 16987 16988 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16989 if (!isDebuggable) { 16990 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16991 throw new SecurityException("Process not debuggable: " + proc); 16992 } 16993 } 16994 16995 proc.thread.dumpHeap(managed, path, fd); 16996 fd = null; 16997 return true; 16998 } 16999 } catch (RemoteException e) { 17000 throw new IllegalStateException("Process disappeared"); 17001 } finally { 17002 if (fd != null) { 17003 try { 17004 fd.close(); 17005 } catch (IOException e) { 17006 } 17007 } 17008 } 17009 } 17010 17011 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17012 public void monitor() { 17013 synchronized (this) { } 17014 } 17015 17016 void onCoreSettingsChange(Bundle settings) { 17017 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17018 ProcessRecord processRecord = mLruProcesses.get(i); 17019 try { 17020 if (processRecord.thread != null) { 17021 processRecord.thread.setCoreSettings(settings); 17022 } 17023 } catch (RemoteException re) { 17024 /* ignore */ 17025 } 17026 } 17027 } 17028 17029 // Multi-user methods 17030 17031 /** 17032 * Start user, if its not already running, but don't bring it to foreground. 17033 */ 17034 @Override 17035 public boolean startUserInBackground(final int userId) { 17036 return startUser(userId, /* foreground */ false); 17037 } 17038 17039 /** 17040 * Refreshes the list of users related to the current user when either a 17041 * user switch happens or when a new related user is started in the 17042 * background. 17043 */ 17044 private void updateCurrentProfileIdsLocked() { 17045 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17046 mCurrentUserId, false /* enabledOnly */); 17047 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17048 for (int i = 0; i < currentProfileIds.length; i++) { 17049 currentProfileIds[i] = profiles.get(i).id; 17050 } 17051 mCurrentProfileIds = currentProfileIds; 17052 17053 synchronized (mUserProfileGroupIdsSelfLocked) { 17054 mUserProfileGroupIdsSelfLocked.clear(); 17055 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17056 for (int i = 0; i < users.size(); i++) { 17057 UserInfo user = users.get(i); 17058 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17059 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17060 } 17061 } 17062 } 17063 } 17064 17065 private Set getProfileIdsLocked(int userId) { 17066 Set userIds = new HashSet<Integer>(); 17067 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17068 userId, false /* enabledOnly */); 17069 for (UserInfo user : profiles) { 17070 userIds.add(Integer.valueOf(user.id)); 17071 } 17072 return userIds; 17073 } 17074 17075 @Override 17076 public boolean switchUser(final int userId) { 17077 return startUser(userId, /* foregound */ true); 17078 } 17079 17080 private boolean startUser(final int userId, boolean foreground) { 17081 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17082 != PackageManager.PERMISSION_GRANTED) { 17083 String msg = "Permission Denial: switchUser() from pid=" 17084 + Binder.getCallingPid() 17085 + ", uid=" + Binder.getCallingUid() 17086 + " requires " + INTERACT_ACROSS_USERS_FULL; 17087 Slog.w(TAG, msg); 17088 throw new SecurityException(msg); 17089 } 17090 17091 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17092 17093 final long ident = Binder.clearCallingIdentity(); 17094 try { 17095 synchronized (this) { 17096 final int oldUserId = mCurrentUserId; 17097 if (oldUserId == userId) { 17098 return true; 17099 } 17100 17101 mStackSupervisor.setLockTaskModeLocked(null, false); 17102 17103 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17104 if (userInfo == null) { 17105 Slog.w(TAG, "No user info for user #" + userId); 17106 return false; 17107 } 17108 17109 if (foreground) { 17110 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17111 R.anim.screen_user_enter); 17112 } 17113 17114 boolean needStart = false; 17115 17116 // If the user we are switching to is not currently started, then 17117 // we need to start it now. 17118 if (mStartedUsers.get(userId) == null) { 17119 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17120 updateStartedUserArrayLocked(); 17121 needStart = true; 17122 } 17123 17124 final Integer userIdInt = Integer.valueOf(userId); 17125 mUserLru.remove(userIdInt); 17126 mUserLru.add(userIdInt); 17127 17128 if (foreground) { 17129 mCurrentUserId = userId; 17130 updateCurrentProfileIdsLocked(); 17131 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17132 // Once the internal notion of the active user has switched, we lock the device 17133 // with the option to show the user switcher on the keyguard. 17134 mWindowManager.lockNow(null); 17135 } else { 17136 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17137 updateCurrentProfileIdsLocked(); 17138 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17139 mUserLru.remove(currentUserIdInt); 17140 mUserLru.add(currentUserIdInt); 17141 } 17142 17143 final UserStartedState uss = mStartedUsers.get(userId); 17144 17145 // Make sure user is in the started state. If it is currently 17146 // stopping, we need to knock that off. 17147 if (uss.mState == UserStartedState.STATE_STOPPING) { 17148 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17149 // so we can just fairly silently bring the user back from 17150 // the almost-dead. 17151 uss.mState = UserStartedState.STATE_RUNNING; 17152 updateStartedUserArrayLocked(); 17153 needStart = true; 17154 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17155 // This means ACTION_SHUTDOWN has been sent, so we will 17156 // need to treat this as a new boot of the user. 17157 uss.mState = UserStartedState.STATE_BOOTING; 17158 updateStartedUserArrayLocked(); 17159 needStart = true; 17160 } 17161 17162 if (uss.mState == UserStartedState.STATE_BOOTING) { 17163 // Booting up a new user, need to tell system services about it. 17164 // Note that this is on the same handler as scheduling of broadcasts, 17165 // which is important because it needs to go first. 17166 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 17167 } 17168 17169 if (foreground) { 17170 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17171 oldUserId)); 17172 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17173 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17174 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17175 oldUserId, userId, uss)); 17176 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17177 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17178 } 17179 17180 if (needStart) { 17181 // Send USER_STARTED broadcast 17182 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17183 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17184 | Intent.FLAG_RECEIVER_FOREGROUND); 17185 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17186 broadcastIntentLocked(null, null, intent, 17187 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17188 false, false, MY_PID, Process.SYSTEM_UID, userId); 17189 } 17190 17191 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17192 if (userId != UserHandle.USER_OWNER) { 17193 // Send PRE_BOOT_COMPLETED broadcasts for this new user 17194 final ArrayList<ComponentName> doneReceivers 17195 = new ArrayList<ComponentName>(); 17196 deliverPreBootCompleted(null, doneReceivers, userId); 17197 17198 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17199 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17200 broadcastIntentLocked(null, null, intent, null, 17201 new IIntentReceiver.Stub() { 17202 public void performReceive(Intent intent, int resultCode, 17203 String data, Bundle extras, boolean ordered, 17204 boolean sticky, int sendingUser) { 17205 userInitialized(uss, userId); 17206 } 17207 }, 0, null, null, null, AppOpsManager.OP_NONE, 17208 true, false, MY_PID, Process.SYSTEM_UID, 17209 userId); 17210 uss.initializing = true; 17211 } else { 17212 getUserManagerLocked().makeInitialized(userInfo.id); 17213 } 17214 } 17215 17216 if (foreground) { 17217 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17218 if (homeInFront) { 17219 startHomeActivityLocked(userId); 17220 } else { 17221 mStackSupervisor.resumeTopActivitiesLocked(); 17222 } 17223 EventLogTags.writeAmSwitchUser(userId); 17224 getUserManagerLocked().userForeground(userId); 17225 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17226 } else { 17227 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17228 } 17229 17230 if (needStart) { 17231 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17232 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17233 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17234 broadcastIntentLocked(null, null, intent, 17235 null, new IIntentReceiver.Stub() { 17236 @Override 17237 public void performReceive(Intent intent, int resultCode, String data, 17238 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17239 throws RemoteException { 17240 } 17241 }, 0, null, null, 17242 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17243 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17244 } 17245 } 17246 } finally { 17247 Binder.restoreCallingIdentity(ident); 17248 } 17249 17250 return true; 17251 } 17252 17253 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17254 long ident = Binder.clearCallingIdentity(); 17255 try { 17256 Intent intent; 17257 if (oldUserId >= 0) { 17258 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17259 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17260 int count = profiles.size(); 17261 for (int i = 0; i < count; i++) { 17262 int profileUserId = profiles.get(i).id; 17263 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17264 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17265 | Intent.FLAG_RECEIVER_FOREGROUND); 17266 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17267 broadcastIntentLocked(null, null, intent, 17268 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17269 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17270 } 17271 } 17272 if (newUserId >= 0) { 17273 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17274 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17275 int count = profiles.size(); 17276 for (int i = 0; i < count; i++) { 17277 int profileUserId = profiles.get(i).id; 17278 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17279 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17280 | Intent.FLAG_RECEIVER_FOREGROUND); 17281 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17282 broadcastIntentLocked(null, null, intent, 17283 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17284 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17285 } 17286 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17287 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17288 | Intent.FLAG_RECEIVER_FOREGROUND); 17289 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17290 broadcastIntentLocked(null, null, intent, 17291 null, null, 0, null, null, 17292 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17293 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17294 } 17295 } finally { 17296 Binder.restoreCallingIdentity(ident); 17297 } 17298 } 17299 17300 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17301 final int newUserId) { 17302 final int N = mUserSwitchObservers.beginBroadcast(); 17303 if (N > 0) { 17304 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17305 int mCount = 0; 17306 @Override 17307 public void sendResult(Bundle data) throws RemoteException { 17308 synchronized (ActivityManagerService.this) { 17309 if (mCurUserSwitchCallback == this) { 17310 mCount++; 17311 if (mCount == N) { 17312 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17313 } 17314 } 17315 } 17316 } 17317 }; 17318 synchronized (this) { 17319 uss.switching = true; 17320 mCurUserSwitchCallback = callback; 17321 } 17322 for (int i=0; i<N; i++) { 17323 try { 17324 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17325 newUserId, callback); 17326 } catch (RemoteException e) { 17327 } 17328 } 17329 } else { 17330 synchronized (this) { 17331 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17332 } 17333 } 17334 mUserSwitchObservers.finishBroadcast(); 17335 } 17336 17337 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17338 synchronized (this) { 17339 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17340 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17341 } 17342 } 17343 17344 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17345 mCurUserSwitchCallback = null; 17346 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17347 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17348 oldUserId, newUserId, uss)); 17349 } 17350 17351 void userInitialized(UserStartedState uss, int newUserId) { 17352 completeSwitchAndInitalize(uss, newUserId, true, false); 17353 } 17354 17355 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17356 completeSwitchAndInitalize(uss, newUserId, false, true); 17357 } 17358 17359 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17360 boolean clearInitializing, boolean clearSwitching) { 17361 boolean unfrozen = false; 17362 synchronized (this) { 17363 if (clearInitializing) { 17364 uss.initializing = false; 17365 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17366 } 17367 if (clearSwitching) { 17368 uss.switching = false; 17369 } 17370 if (!uss.switching && !uss.initializing) { 17371 mWindowManager.stopFreezingScreen(); 17372 unfrozen = true; 17373 } 17374 } 17375 if (unfrozen) { 17376 final int N = mUserSwitchObservers.beginBroadcast(); 17377 for (int i=0; i<N; i++) { 17378 try { 17379 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17380 } catch (RemoteException e) { 17381 } 17382 } 17383 mUserSwitchObservers.finishBroadcast(); 17384 } 17385 } 17386 17387 void scheduleStartProfilesLocked() { 17388 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17389 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17390 DateUtils.SECOND_IN_MILLIS); 17391 } 17392 } 17393 17394 void startProfilesLocked() { 17395 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17396 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17397 mCurrentUserId, false /* enabledOnly */); 17398 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17399 for (UserInfo user : profiles) { 17400 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17401 && user.id != mCurrentUserId) { 17402 toStart.add(user); 17403 } 17404 } 17405 final int n = toStart.size(); 17406 int i = 0; 17407 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17408 startUserInBackground(toStart.get(i).id); 17409 } 17410 if (i < n) { 17411 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17412 } 17413 } 17414 17415 void finishUserBoot(UserStartedState uss) { 17416 synchronized (this) { 17417 if (uss.mState == UserStartedState.STATE_BOOTING 17418 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17419 uss.mState = UserStartedState.STATE_RUNNING; 17420 final int userId = uss.mHandle.getIdentifier(); 17421 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17422 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17423 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17424 broadcastIntentLocked(null, null, intent, 17425 null, null, 0, null, null, 17426 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17427 true, false, MY_PID, Process.SYSTEM_UID, userId); 17428 } 17429 } 17430 } 17431 17432 void finishUserSwitch(UserStartedState uss) { 17433 synchronized (this) { 17434 finishUserBoot(uss); 17435 17436 startProfilesLocked(); 17437 17438 int num = mUserLru.size(); 17439 int i = 0; 17440 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17441 Integer oldUserId = mUserLru.get(i); 17442 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17443 if (oldUss == null) { 17444 // Shouldn't happen, but be sane if it does. 17445 mUserLru.remove(i); 17446 num--; 17447 continue; 17448 } 17449 if (oldUss.mState == UserStartedState.STATE_STOPPING 17450 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17451 // This user is already stopping, doesn't count. 17452 num--; 17453 i++; 17454 continue; 17455 } 17456 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17457 // Owner and current can't be stopped, but count as running. 17458 i++; 17459 continue; 17460 } 17461 // This is a user to be stopped. 17462 stopUserLocked(oldUserId, null); 17463 num--; 17464 i++; 17465 } 17466 } 17467 } 17468 17469 @Override 17470 public int stopUser(final int userId, final IStopUserCallback callback) { 17471 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17472 != PackageManager.PERMISSION_GRANTED) { 17473 String msg = "Permission Denial: switchUser() from pid=" 17474 + Binder.getCallingPid() 17475 + ", uid=" + Binder.getCallingUid() 17476 + " requires " + INTERACT_ACROSS_USERS_FULL; 17477 Slog.w(TAG, msg); 17478 throw new SecurityException(msg); 17479 } 17480 if (userId <= 0) { 17481 throw new IllegalArgumentException("Can't stop primary user " + userId); 17482 } 17483 synchronized (this) { 17484 return stopUserLocked(userId, callback); 17485 } 17486 } 17487 17488 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17489 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17490 if (mCurrentUserId == userId) { 17491 return ActivityManager.USER_OP_IS_CURRENT; 17492 } 17493 17494 final UserStartedState uss = mStartedUsers.get(userId); 17495 if (uss == null) { 17496 // User is not started, nothing to do... but we do need to 17497 // callback if requested. 17498 if (callback != null) { 17499 mHandler.post(new Runnable() { 17500 @Override 17501 public void run() { 17502 try { 17503 callback.userStopped(userId); 17504 } catch (RemoteException e) { 17505 } 17506 } 17507 }); 17508 } 17509 return ActivityManager.USER_OP_SUCCESS; 17510 } 17511 17512 if (callback != null) { 17513 uss.mStopCallbacks.add(callback); 17514 } 17515 17516 if (uss.mState != UserStartedState.STATE_STOPPING 17517 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17518 uss.mState = UserStartedState.STATE_STOPPING; 17519 updateStartedUserArrayLocked(); 17520 17521 long ident = Binder.clearCallingIdentity(); 17522 try { 17523 // We are going to broadcast ACTION_USER_STOPPING and then 17524 // once that is done send a final ACTION_SHUTDOWN and then 17525 // stop the user. 17526 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17527 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17528 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17529 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17530 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17531 // This is the result receiver for the final shutdown broadcast. 17532 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17533 @Override 17534 public void performReceive(Intent intent, int resultCode, String data, 17535 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17536 finishUserStop(uss); 17537 } 17538 }; 17539 // This is the result receiver for the initial stopping broadcast. 17540 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17541 @Override 17542 public void performReceive(Intent intent, int resultCode, String data, 17543 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17544 // On to the next. 17545 synchronized (ActivityManagerService.this) { 17546 if (uss.mState != UserStartedState.STATE_STOPPING) { 17547 // Whoops, we are being started back up. Abort, abort! 17548 return; 17549 } 17550 uss.mState = UserStartedState.STATE_SHUTDOWN; 17551 } 17552 mBatteryStatsService.noteEvent( 17553 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17554 Integer.toString(userId), userId); 17555 mSystemServiceManager.stopUser(userId); 17556 broadcastIntentLocked(null, null, shutdownIntent, 17557 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17558 true, false, MY_PID, Process.SYSTEM_UID, userId); 17559 } 17560 }; 17561 // Kick things off. 17562 broadcastIntentLocked(null, null, stoppingIntent, 17563 null, stoppingReceiver, 0, null, null, 17564 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17565 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17566 } finally { 17567 Binder.restoreCallingIdentity(ident); 17568 } 17569 } 17570 17571 return ActivityManager.USER_OP_SUCCESS; 17572 } 17573 17574 void finishUserStop(UserStartedState uss) { 17575 final int userId = uss.mHandle.getIdentifier(); 17576 boolean stopped; 17577 ArrayList<IStopUserCallback> callbacks; 17578 synchronized (this) { 17579 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17580 if (mStartedUsers.get(userId) != uss) { 17581 stopped = false; 17582 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17583 stopped = false; 17584 } else { 17585 stopped = true; 17586 // User can no longer run. 17587 mStartedUsers.remove(userId); 17588 mUserLru.remove(Integer.valueOf(userId)); 17589 updateStartedUserArrayLocked(); 17590 17591 // Clean up all state and processes associated with the user. 17592 // Kill all the processes for the user. 17593 forceStopUserLocked(userId, "finish user"); 17594 } 17595 } 17596 17597 for (int i=0; i<callbacks.size(); i++) { 17598 try { 17599 if (stopped) callbacks.get(i).userStopped(userId); 17600 else callbacks.get(i).userStopAborted(userId); 17601 } catch (RemoteException e) { 17602 } 17603 } 17604 17605 if (stopped) { 17606 mSystemServiceManager.cleanupUser(userId); 17607 synchronized (this) { 17608 mStackSupervisor.removeUserLocked(userId); 17609 } 17610 } 17611 } 17612 17613 @Override 17614 public UserInfo getCurrentUser() { 17615 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 17616 != PackageManager.PERMISSION_GRANTED) && ( 17617 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17618 != PackageManager.PERMISSION_GRANTED)) { 17619 String msg = "Permission Denial: getCurrentUser() from pid=" 17620 + Binder.getCallingPid() 17621 + ", uid=" + Binder.getCallingUid() 17622 + " requires " + INTERACT_ACROSS_USERS; 17623 Slog.w(TAG, msg); 17624 throw new SecurityException(msg); 17625 } 17626 synchronized (this) { 17627 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17628 } 17629 } 17630 17631 int getCurrentUserIdLocked() { 17632 return mCurrentUserId; 17633 } 17634 17635 @Override 17636 public boolean isUserRunning(int userId, boolean orStopped) { 17637 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17638 != PackageManager.PERMISSION_GRANTED) { 17639 String msg = "Permission Denial: isUserRunning() from pid=" 17640 + Binder.getCallingPid() 17641 + ", uid=" + Binder.getCallingUid() 17642 + " requires " + INTERACT_ACROSS_USERS; 17643 Slog.w(TAG, msg); 17644 throw new SecurityException(msg); 17645 } 17646 synchronized (this) { 17647 return isUserRunningLocked(userId, orStopped); 17648 } 17649 } 17650 17651 boolean isUserRunningLocked(int userId, boolean orStopped) { 17652 UserStartedState state = mStartedUsers.get(userId); 17653 if (state == null) { 17654 return false; 17655 } 17656 if (orStopped) { 17657 return true; 17658 } 17659 return state.mState != UserStartedState.STATE_STOPPING 17660 && state.mState != UserStartedState.STATE_SHUTDOWN; 17661 } 17662 17663 @Override 17664 public int[] getRunningUserIds() { 17665 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17666 != PackageManager.PERMISSION_GRANTED) { 17667 String msg = "Permission Denial: isUserRunning() from pid=" 17668 + Binder.getCallingPid() 17669 + ", uid=" + Binder.getCallingUid() 17670 + " requires " + INTERACT_ACROSS_USERS; 17671 Slog.w(TAG, msg); 17672 throw new SecurityException(msg); 17673 } 17674 synchronized (this) { 17675 return mStartedUserArray; 17676 } 17677 } 17678 17679 private void updateStartedUserArrayLocked() { 17680 int num = 0; 17681 for (int i=0; i<mStartedUsers.size(); i++) { 17682 UserStartedState uss = mStartedUsers.valueAt(i); 17683 // This list does not include stopping users. 17684 if (uss.mState != UserStartedState.STATE_STOPPING 17685 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17686 num++; 17687 } 17688 } 17689 mStartedUserArray = new int[num]; 17690 num = 0; 17691 for (int i=0; i<mStartedUsers.size(); i++) { 17692 UserStartedState uss = mStartedUsers.valueAt(i); 17693 if (uss.mState != UserStartedState.STATE_STOPPING 17694 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17695 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17696 num++; 17697 } 17698 } 17699 } 17700 17701 @Override 17702 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17703 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17704 != PackageManager.PERMISSION_GRANTED) { 17705 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17706 + Binder.getCallingPid() 17707 + ", uid=" + Binder.getCallingUid() 17708 + " requires " + INTERACT_ACROSS_USERS_FULL; 17709 Slog.w(TAG, msg); 17710 throw new SecurityException(msg); 17711 } 17712 17713 mUserSwitchObservers.register(observer); 17714 } 17715 17716 @Override 17717 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17718 mUserSwitchObservers.unregister(observer); 17719 } 17720 17721 private boolean userExists(int userId) { 17722 if (userId == 0) { 17723 return true; 17724 } 17725 UserManagerService ums = getUserManagerLocked(); 17726 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17727 } 17728 17729 int[] getUsersLocked() { 17730 UserManagerService ums = getUserManagerLocked(); 17731 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17732 } 17733 17734 UserManagerService getUserManagerLocked() { 17735 if (mUserManager == null) { 17736 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17737 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17738 } 17739 return mUserManager; 17740 } 17741 17742 private int applyUserId(int uid, int userId) { 17743 return UserHandle.getUid(userId, uid); 17744 } 17745 17746 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17747 if (info == null) return null; 17748 ApplicationInfo newInfo = new ApplicationInfo(info); 17749 newInfo.uid = applyUserId(info.uid, userId); 17750 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17751 + info.packageName; 17752 return newInfo; 17753 } 17754 17755 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17756 if (aInfo == null 17757 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17758 return aInfo; 17759 } 17760 17761 ActivityInfo info = new ActivityInfo(aInfo); 17762 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17763 return info; 17764 } 17765 17766 private final class LocalService extends ActivityManagerInternal { 17767 @Override 17768 public void goingToSleep() { 17769 ActivityManagerService.this.goingToSleep(); 17770 } 17771 17772 @Override 17773 public void wakingUp() { 17774 ActivityManagerService.this.wakingUp(); 17775 } 17776 } 17777 17778 /** 17779 * An implementation of IAppTask, that allows an app to manage its own tasks via 17780 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17781 * only the process that calls getAppTasks() can call the AppTask methods. 17782 */ 17783 class AppTaskImpl extends IAppTask.Stub { 17784 private int mTaskId; 17785 private int mCallingUid; 17786 17787 public AppTaskImpl(int taskId, int callingUid) { 17788 mTaskId = taskId; 17789 mCallingUid = callingUid; 17790 } 17791 17792 @Override 17793 public void finishAndRemoveTask() { 17794 // Ensure that we are called from the same process that created this AppTask 17795 if (mCallingUid != Binder.getCallingUid()) { 17796 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17797 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17798 return; 17799 } 17800 17801 synchronized (ActivityManagerService.this) { 17802 long origId = Binder.clearCallingIdentity(); 17803 try { 17804 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17805 if (tr != null) { 17806 // Only kill the process if we are not a new document 17807 int flags = tr.getBaseIntent().getFlags(); 17808 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17809 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17810 removeTaskByIdLocked(mTaskId, 17811 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17812 } 17813 } finally { 17814 Binder.restoreCallingIdentity(origId); 17815 } 17816 } 17817 } 17818 17819 @Override 17820 public ActivityManager.RecentTaskInfo getTaskInfo() { 17821 // Ensure that we are called from the same process that created this AppTask 17822 if (mCallingUid != Binder.getCallingUid()) { 17823 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17824 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17825 return null; 17826 } 17827 17828 synchronized (ActivityManagerService.this) { 17829 long origId = Binder.clearCallingIdentity(); 17830 try { 17831 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17832 if (tr != null) { 17833 return createRecentTaskInfoFromTaskRecord(tr); 17834 } 17835 } finally { 17836 Binder.restoreCallingIdentity(origId); 17837 } 17838 return null; 17839 } 17840 } 17841 } 17842} 17843