ActivityManagerService.java revision 7805a10c86a2de9fb5ddf41d63075eef342a59ea
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.UsageEvents; 41import android.app.usage.UsageStatsManagerInternal; 42import android.appwidget.AppWidgetManager; 43import android.content.res.Resources; 44import android.graphics.Bitmap; 45import android.graphics.Point; 46import android.graphics.Rect; 47import android.os.BatteryStats; 48import android.os.PersistableBundle; 49import android.service.voice.IVoiceInteractionSession; 50import android.util.ArrayMap; 51import android.util.ArraySet; 52import android.util.SparseIntArray; 53 54import com.android.internal.R; 55import com.android.internal.annotations.GuardedBy; 56import com.android.internal.app.IAppOpsService; 57import com.android.internal.app.IVoiceInteractor; 58import com.android.internal.app.ProcessMap; 59import com.android.internal.app.ProcessStats; 60import com.android.internal.content.PackageMonitor; 61import com.android.internal.os.BackgroundThread; 62import com.android.internal.os.BatteryStatsImpl; 63import com.android.internal.os.ProcessCpuTracker; 64import com.android.internal.os.TransferPipe; 65import com.android.internal.os.Zygote; 66import com.android.internal.util.FastPrintWriter; 67import com.android.internal.util.FastXmlSerializer; 68import com.android.internal.util.MemInfoReader; 69import com.android.internal.util.Preconditions; 70import com.android.server.AppOpsService; 71import com.android.server.AttributeCache; 72import com.android.server.IntentResolver; 73import com.android.server.LocalServices; 74import com.android.server.ServiceThread; 75import com.android.server.SystemService; 76import com.android.server.SystemServiceManager; 77import com.android.server.Watchdog; 78import com.android.server.am.ActivityStack.ActivityState; 79import com.android.server.firewall.IntentFirewall; 80import com.android.server.pm.UserManagerService; 81import com.android.server.wm.AppTransition; 82import com.android.server.wm.WindowManagerService; 83import com.google.android.collect.Lists; 84import com.google.android.collect.Maps; 85 86import libcore.io.IoUtils; 87 88import org.xmlpull.v1.XmlPullParser; 89import org.xmlpull.v1.XmlPullParserException; 90import org.xmlpull.v1.XmlSerializer; 91 92import android.app.Activity; 93import android.app.ActivityManager; 94import android.app.ActivityManager.RunningTaskInfo; 95import android.app.ActivityManager.StackInfo; 96import android.app.ActivityManagerInternal; 97import android.app.ActivityManagerNative; 98import android.app.ActivityOptions; 99import android.app.ActivityThread; 100import android.app.AlertDialog; 101import android.app.AppGlobals; 102import android.app.ApplicationErrorReport; 103import android.app.Dialog; 104import android.app.IActivityController; 105import android.app.IApplicationThread; 106import android.app.IInstrumentationWatcher; 107import android.app.INotificationManager; 108import android.app.IProcessObserver; 109import android.app.IServiceConnection; 110import android.app.IStopUserCallback; 111import android.app.IUiAutomationConnection; 112import android.app.IUserSwitchObserver; 113import android.app.Instrumentation; 114import android.app.Notification; 115import android.app.NotificationManager; 116import android.app.PendingIntent; 117import android.app.backup.IBackupManager; 118import android.content.ActivityNotFoundException; 119import android.content.BroadcastReceiver; 120import android.content.ClipData; 121import android.content.ComponentCallbacks2; 122import android.content.ComponentName; 123import android.content.ContentProvider; 124import android.content.ContentResolver; 125import android.content.Context; 126import android.content.DialogInterface; 127import android.content.IContentProvider; 128import android.content.IIntentReceiver; 129import android.content.IIntentSender; 130import android.content.Intent; 131import android.content.IntentFilter; 132import android.content.IntentSender; 133import android.content.pm.ActivityInfo; 134import android.content.pm.ApplicationInfo; 135import android.content.pm.ConfigurationInfo; 136import android.content.pm.IPackageDataObserver; 137import android.content.pm.IPackageManager; 138import android.content.pm.InstrumentationInfo; 139import android.content.pm.PackageInfo; 140import android.content.pm.PackageManager; 141import android.content.pm.ParceledListSlice; 142import android.content.pm.UserInfo; 143import android.content.pm.PackageManager.NameNotFoundException; 144import android.content.pm.PathPermission; 145import android.content.pm.ProviderInfo; 146import android.content.pm.ResolveInfo; 147import android.content.pm.ServiceInfo; 148import android.content.res.CompatibilityInfo; 149import android.content.res.Configuration; 150import android.net.Proxy; 151import android.net.ProxyInfo; 152import android.net.Uri; 153import android.os.Binder; 154import android.os.Build; 155import android.os.Bundle; 156import android.os.Debug; 157import android.os.DropBoxManager; 158import android.os.Environment; 159import android.os.FactoryTest; 160import android.os.FileObserver; 161import android.os.FileUtils; 162import android.os.Handler; 163import android.os.IBinder; 164import android.os.IPermissionController; 165import android.os.IRemoteCallback; 166import android.os.IUserManager; 167import android.os.Looper; 168import android.os.Message; 169import android.os.Parcel; 170import android.os.ParcelFileDescriptor; 171import android.os.Process; 172import android.os.RemoteCallbackList; 173import android.os.RemoteException; 174import android.os.SELinux; 175import android.os.ServiceManager; 176import android.os.StrictMode; 177import android.os.SystemClock; 178import android.os.SystemProperties; 179import android.os.UpdateLock; 180import android.os.UserHandle; 181import android.provider.Settings; 182import android.text.format.DateUtils; 183import android.text.format.Time; 184import android.util.AtomicFile; 185import android.util.EventLog; 186import android.util.Log; 187import android.util.Pair; 188import android.util.PrintWriterPrinter; 189import android.util.Slog; 190import android.util.SparseArray; 191import android.util.TimeUtils; 192import android.util.Xml; 193import android.view.Gravity; 194import android.view.LayoutInflater; 195import android.view.View; 196import android.view.WindowManager; 197 198import java.io.BufferedInputStream; 199import java.io.BufferedOutputStream; 200import java.io.DataInputStream; 201import java.io.DataOutputStream; 202import java.io.File; 203import java.io.FileDescriptor; 204import java.io.FileInputStream; 205import java.io.FileNotFoundException; 206import java.io.FileOutputStream; 207import java.io.IOException; 208import java.io.InputStreamReader; 209import java.io.PrintWriter; 210import java.io.StringWriter; 211import java.lang.ref.WeakReference; 212import java.util.ArrayList; 213import java.util.Arrays; 214import java.util.Collections; 215import java.util.Comparator; 216import java.util.HashMap; 217import java.util.HashSet; 218import java.util.Iterator; 219import java.util.List; 220import java.util.Locale; 221import java.util.Map; 222import java.util.Set; 223import java.util.concurrent.atomic.AtomicBoolean; 224import java.util.concurrent.atomic.AtomicLong; 225 226public final class ActivityManagerService extends ActivityManagerNative 227 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 228 229 private static final String USER_DATA_DIR = "/data/user/"; 230 // File that stores last updated system version and called preboot receivers 231 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 232 233 static final String TAG = "ActivityManager"; 234 static final String TAG_MU = "ActivityManagerServiceMU"; 235 static final boolean DEBUG = false; 236 static final boolean localLOGV = DEBUG; 237 static final boolean DEBUG_BACKUP = localLOGV || false; 238 static final boolean DEBUG_BROADCAST = localLOGV || false; 239 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 240 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 241 static final boolean DEBUG_CLEANUP = localLOGV || false; 242 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 243 static final boolean DEBUG_FOCUS = false; 244 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 245 static final boolean DEBUG_MU = localLOGV || false; 246 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 247 static final boolean DEBUG_LRU = localLOGV || false; 248 static final boolean DEBUG_PAUSE = localLOGV || false; 249 static final boolean DEBUG_POWER = localLOGV || false; 250 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 251 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 252 static final boolean DEBUG_PROCESSES = localLOGV || false; 253 static final boolean DEBUG_PROVIDER = localLOGV || false; 254 static final boolean DEBUG_RESULTS = localLOGV || false; 255 static final boolean DEBUG_SERVICE = localLOGV || false; 256 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 257 static final boolean DEBUG_STACK = localLOGV || false; 258 static final boolean DEBUG_SWITCH = localLOGV || false; 259 static final boolean DEBUG_TASKS = localLOGV || false; 260 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 261 static final boolean DEBUG_TRANSITION = localLOGV || false; 262 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 263 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 264 static final boolean DEBUG_VISBILITY = localLOGV || false; 265 static final boolean DEBUG_PSS = localLOGV || false; 266 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 267 static final boolean DEBUG_RECENTS = localLOGV || false; 268 static final boolean VALIDATE_TOKENS = false; 269 static final boolean SHOW_ACTIVITY_START_TIME = true; 270 271 // Control over CPU and battery monitoring. 272 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 273 static final boolean MONITOR_CPU_USAGE = true; 274 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 275 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 276 static final boolean MONITOR_THREAD_CPU_USAGE = false; 277 278 // The flags that are set for all calls we make to the package manager. 279 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 280 281 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 282 283 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 284 285 // Maximum number of recent tasks that we can remember. 286 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*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. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mWaitingUpdate = false; 892 boolean mDidUpdate = false; 893 boolean mOnBattery = false; 894 boolean mLaunchWarningShown = false; 895 896 Context mContext; 897 898 int mFactoryTest; 899 900 boolean mCheckedForSetup; 901 902 /** 903 * The time at which we will allow normal application switches again, 904 * after a call to {@link #stopAppSwitches()}. 905 */ 906 long mAppSwitchesAllowedTime; 907 908 /** 909 * This is set to true after the first switch after mAppSwitchesAllowedTime 910 * is set; any switches after that will clear the time. 911 */ 912 boolean mDidAppSwitch; 913 914 /** 915 * Last time (in realtime) at which we checked for power usage. 916 */ 917 long mLastPowerCheckRealtime; 918 919 /** 920 * Last time (in uptime) at which we checked for power usage. 921 */ 922 long mLastPowerCheckUptime; 923 924 /** 925 * Set while we are wanting to sleep, to prevent any 926 * activities from being started/resumed. 927 */ 928 private boolean mSleeping = false; 929 930 /** 931 * Set while we are running a voice interaction. This overrides 932 * sleeping while it is active. 933 */ 934 private boolean mRunningVoice = false; 935 936 /** 937 * State of external calls telling us if the device is asleep. 938 */ 939 private boolean mWentToSleep = false; 940 941 /** 942 * State of external call telling us if the lock screen is shown. 943 */ 944 private boolean mLockScreenShown = false; 945 946 /** 947 * Set if we are shutting down the system, similar to sleeping. 948 */ 949 boolean mShuttingDown = false; 950 951 /** 952 * Current sequence id for oom_adj computation traversal. 953 */ 954 int mAdjSeq = 0; 955 956 /** 957 * Current sequence id for process LRU updating. 958 */ 959 int mLruSeq = 0; 960 961 /** 962 * Keep track of the non-cached/empty process we last found, to help 963 * determine how to distribute cached/empty processes next time. 964 */ 965 int mNumNonCachedProcs = 0; 966 967 /** 968 * Keep track of the number of cached hidden procs, to balance oom adj 969 * distribution between those and empty procs. 970 */ 971 int mNumCachedHiddenProcs = 0; 972 973 /** 974 * Keep track of the number of service processes we last found, to 975 * determine on the next iteration which should be B services. 976 */ 977 int mNumServiceProcs = 0; 978 int mNewNumAServiceProcs = 0; 979 int mNewNumServiceProcs = 0; 980 981 /** 982 * Allow the current computed overall memory level of the system to go down? 983 * This is set to false when we are killing processes for reasons other than 984 * memory management, so that the now smaller process list will not be taken as 985 * an indication that memory is tighter. 986 */ 987 boolean mAllowLowerMemLevel = false; 988 989 /** 990 * The last computed memory level, for holding when we are in a state that 991 * processes are going away for other reasons. 992 */ 993 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 994 995 /** 996 * The last total number of process we have, to determine if changes actually look 997 * like a shrinking number of process due to lower RAM. 998 */ 999 int mLastNumProcesses; 1000 1001 /** 1002 * The uptime of the last time we performed idle maintenance. 1003 */ 1004 long mLastIdleTime = SystemClock.uptimeMillis(); 1005 1006 /** 1007 * Total time spent with RAM that has been added in the past since the last idle time. 1008 */ 1009 long mLowRamTimeSinceLastIdle = 0; 1010 1011 /** 1012 * If RAM is currently low, when that horrible situation started. 1013 */ 1014 long mLowRamStartTime = 0; 1015 1016 /** 1017 * For reporting to battery stats the current top application. 1018 */ 1019 private String mCurResumedPackage = null; 1020 private int mCurResumedUid = -1; 1021 1022 /** 1023 * For reporting to battery stats the apps currently running foreground 1024 * service. The ProcessMap is package/uid tuples; each of these contain 1025 * an array of the currently foreground processes. 1026 */ 1027 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1028 = new ProcessMap<ArrayList<ProcessRecord>>(); 1029 1030 /** 1031 * This is set if we had to do a delayed dexopt of an app before launching 1032 * it, to increase the ANR timeouts in that case. 1033 */ 1034 boolean mDidDexOpt; 1035 1036 /** 1037 * Set if the systemServer made a call to enterSafeMode. 1038 */ 1039 boolean mSafeMode; 1040 1041 String mDebugApp = null; 1042 boolean mWaitForDebugger = false; 1043 boolean mDebugTransient = false; 1044 String mOrigDebugApp = null; 1045 boolean mOrigWaitForDebugger = false; 1046 boolean mAlwaysFinishActivities = false; 1047 IActivityController mController = null; 1048 String mProfileApp = null; 1049 ProcessRecord mProfileProc = null; 1050 String mProfileFile; 1051 ParcelFileDescriptor mProfileFd; 1052 int mProfileType = 0; 1053 boolean mAutoStopProfiler = false; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a recents UI */ 1202 final boolean mHasRecents; 1203 1204 final int mThumbnailWidth; 1205 final int mThumbnailHeight; 1206 1207 final ServiceThread mHandlerThread; 1208 final MainHandler mHandler; 1209 1210 final class MainHandler extends Handler { 1211 public MainHandler(Looper looper) { 1212 super(looper, null, true); 1213 } 1214 1215 @Override 1216 public void handleMessage(Message msg) { 1217 switch (msg.what) { 1218 case SHOW_ERROR_MSG: { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1221 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1222 synchronized (ActivityManagerService.this) { 1223 ProcessRecord proc = (ProcessRecord)data.get("app"); 1224 AppErrorResult res = (AppErrorResult) data.get("result"); 1225 if (proc != null && proc.crashDialog != null) { 1226 Slog.e(TAG, "App already has crash dialog: " + proc); 1227 if (res != null) { 1228 res.set(0); 1229 } 1230 return; 1231 } 1232 boolean isBackground = (UserHandle.getAppId(proc.uid) 1233 >= Process.FIRST_APPLICATION_UID 1234 && proc.pid != MY_PID); 1235 for (int userId : mCurrentProfileIds) { 1236 isBackground &= (proc.userId != userId); 1237 } 1238 if (isBackground && !showBackground) { 1239 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1246 Dialog d = new AppErrorDialog(mContext, 1247 ActivityManagerService.this, res, proc); 1248 d.show(); 1249 proc.crashDialog = d; 1250 } else { 1251 // The device is asleep, so just pretend that the user 1252 // saw a crash dialog and hit "force quit". 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 } 1257 } 1258 1259 ensureBootCompleted(); 1260 } break; 1261 case SHOW_NOT_RESPONDING_MSG: { 1262 synchronized (ActivityManagerService.this) { 1263 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1264 ProcessRecord proc = (ProcessRecord)data.get("app"); 1265 if (proc != null && proc.anrDialog != null) { 1266 Slog.e(TAG, "App already has anr dialog: " + proc); 1267 return; 1268 } 1269 1270 Intent intent = new Intent("android.intent.action.ANR"); 1271 if (!mProcessesReady) { 1272 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1273 | Intent.FLAG_RECEIVER_FOREGROUND); 1274 } 1275 broadcastIntentLocked(null, null, intent, 1276 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1277 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1278 1279 if (mShowDialogs) { 1280 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1281 mContext, proc, (ActivityRecord)data.get("activity"), 1282 msg.arg1 != 0); 1283 d.show(); 1284 proc.anrDialog = d; 1285 } else { 1286 // Just kill the app if there is no dialog to be shown. 1287 killAppAtUsersRequest(proc, null); 1288 } 1289 } 1290 1291 ensureBootCompleted(); 1292 } break; 1293 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1294 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1295 synchronized (ActivityManagerService.this) { 1296 ProcessRecord proc = (ProcessRecord) data.get("app"); 1297 if (proc == null) { 1298 Slog.e(TAG, "App not found when showing strict mode dialog."); 1299 break; 1300 } 1301 if (proc.crashDialog != null) { 1302 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1303 return; 1304 } 1305 AppErrorResult res = (AppErrorResult) data.get("result"); 1306 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1307 Dialog d = new StrictModeViolationDialog(mContext, 1308 ActivityManagerService.this, res, proc); 1309 d.show(); 1310 proc.crashDialog = d; 1311 } else { 1312 // The device is asleep, so just pretend that the user 1313 // saw a crash dialog and hit "force quit". 1314 res.set(0); 1315 } 1316 } 1317 ensureBootCompleted(); 1318 } break; 1319 case SHOW_FACTORY_ERROR_MSG: { 1320 Dialog d = new FactoryErrorDialog( 1321 mContext, msg.getData().getCharSequence("msg")); 1322 d.show(); 1323 ensureBootCompleted(); 1324 } break; 1325 case UPDATE_CONFIGURATION_MSG: { 1326 final ContentResolver resolver = mContext.getContentResolver(); 1327 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1328 } break; 1329 case GC_BACKGROUND_PROCESSES_MSG: { 1330 synchronized (ActivityManagerService.this) { 1331 performAppGcsIfAppropriateLocked(); 1332 } 1333 } break; 1334 case WAIT_FOR_DEBUGGER_MSG: { 1335 synchronized (ActivityManagerService.this) { 1336 ProcessRecord app = (ProcessRecord)msg.obj; 1337 if (msg.arg1 != 0) { 1338 if (!app.waitedForDebugger) { 1339 Dialog d = new AppWaitingForDebuggerDialog( 1340 ActivityManagerService.this, 1341 mContext, app); 1342 app.waitDialog = d; 1343 app.waitedForDebugger = true; 1344 d.show(); 1345 } 1346 } else { 1347 if (app.waitDialog != null) { 1348 app.waitDialog.dismiss(); 1349 app.waitDialog = null; 1350 } 1351 } 1352 } 1353 } break; 1354 case SERVICE_TIMEOUT_MSG: { 1355 if (mDidDexOpt) { 1356 mDidDexOpt = false; 1357 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1358 nmsg.obj = msg.obj; 1359 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1360 return; 1361 } 1362 mServices.serviceTimeout((ProcessRecord)msg.obj); 1363 } break; 1364 case UPDATE_TIME_ZONE: { 1365 synchronized (ActivityManagerService.this) { 1366 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1367 ProcessRecord r = mLruProcesses.get(i); 1368 if (r.thread != null) { 1369 try { 1370 r.thread.updateTimeZone(); 1371 } catch (RemoteException ex) { 1372 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1373 } 1374 } 1375 } 1376 } 1377 } break; 1378 case CLEAR_DNS_CACHE_MSG: { 1379 synchronized (ActivityManagerService.this) { 1380 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1381 ProcessRecord r = mLruProcesses.get(i); 1382 if (r.thread != null) { 1383 try { 1384 r.thread.clearDnsCache(); 1385 } catch (RemoteException ex) { 1386 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1387 } 1388 } 1389 } 1390 } 1391 } break; 1392 case UPDATE_HTTP_PROXY_MSG: { 1393 ProxyInfo proxy = (ProxyInfo)msg.obj; 1394 String host = ""; 1395 String port = ""; 1396 String exclList = ""; 1397 Uri pacFileUrl = Uri.EMPTY; 1398 if (proxy != null) { 1399 host = proxy.getHost(); 1400 port = Integer.toString(proxy.getPort()); 1401 exclList = proxy.getExclusionListAsString(); 1402 pacFileUrl = proxy.getPacFileUrl(); 1403 } 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to update http proxy for: " + 1412 r.info.processName); 1413 } 1414 } 1415 } 1416 } 1417 } break; 1418 case SHOW_UID_ERROR_MSG: { 1419 String title = "System UIDs Inconsistent"; 1420 String text = "UIDs on the system are inconsistent, you need to wipe your" 1421 + " data partition or your device will be unstable."; 1422 Log.e(TAG, title + ": " + text); 1423 if (mShowDialogs) { 1424 // XXX This is a temporary dialog, no need to localize. 1425 AlertDialog d = new BaseErrorDialog(mContext); 1426 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1427 d.setCancelable(false); 1428 d.setTitle(title); 1429 d.setMessage(text); 1430 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1431 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1432 mUidAlert = d; 1433 d.show(); 1434 } 1435 } break; 1436 case IM_FEELING_LUCKY_MSG: { 1437 if (mUidAlert != null) { 1438 mUidAlert.dismiss(); 1439 mUidAlert = null; 1440 } 1441 } break; 1442 case PROC_START_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1448 return; 1449 } 1450 ProcessRecord app = (ProcessRecord)msg.obj; 1451 synchronized (ActivityManagerService.this) { 1452 processStartTimedOutLocked(app); 1453 } 1454 } break; 1455 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1456 synchronized (ActivityManagerService.this) { 1457 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1458 } 1459 } break; 1460 case KILL_APPLICATION_MSG: { 1461 synchronized (ActivityManagerService.this) { 1462 int appid = msg.arg1; 1463 boolean restart = (msg.arg2 == 1); 1464 Bundle bundle = (Bundle)msg.obj; 1465 String pkg = bundle.getString("pkg"); 1466 String reason = bundle.getString("reason"); 1467 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1468 false, UserHandle.USER_ALL, reason); 1469 } 1470 } break; 1471 case FINALIZE_PENDING_INTENT_MSG: { 1472 ((PendingIntentRecord)msg.obj).completeFinalize(); 1473 } break; 1474 case POST_HEAVY_NOTIFICATION_MSG: { 1475 INotificationManager inm = NotificationManager.getService(); 1476 if (inm == null) { 1477 return; 1478 } 1479 1480 ActivityRecord root = (ActivityRecord)msg.obj; 1481 ProcessRecord process = root.app; 1482 if (process == null) { 1483 return; 1484 } 1485 1486 try { 1487 Context context = mContext.createPackageContext(process.info.packageName, 0); 1488 String text = mContext.getString(R.string.heavy_weight_notification, 1489 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1490 Notification notification = new Notification(); 1491 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1492 notification.when = 0; 1493 notification.flags = Notification.FLAG_ONGOING_EVENT; 1494 notification.tickerText = text; 1495 notification.defaults = 0; // please be quiet 1496 notification.sound = null; 1497 notification.vibrate = null; 1498 notification.color = mContext.getResources().getColor( 1499 com.android.internal.R.color.system_notification_accent_color); 1500 notification.setLatestEventInfo(context, text, 1501 mContext.getText(R.string.heavy_weight_notification_detail), 1502 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1503 PendingIntent.FLAG_CANCEL_CURRENT, null, 1504 new UserHandle(root.userId))); 1505 1506 try { 1507 int[] outId = new int[1]; 1508 inm.enqueueNotificationWithTag("android", "android", null, 1509 R.string.heavy_weight_notification, 1510 notification, outId, root.userId); 1511 } catch (RuntimeException e) { 1512 Slog.w(ActivityManagerService.TAG, 1513 "Error showing notification for heavy-weight app", e); 1514 } catch (RemoteException e) { 1515 } 1516 } catch (NameNotFoundException e) { 1517 Slog.w(TAG, "Unable to create context for heavy notification", e); 1518 } 1519 } break; 1520 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 try { 1526 inm.cancelNotificationWithTag("android", null, 1527 R.string.heavy_weight_notification, msg.arg1); 1528 } catch (RuntimeException e) { 1529 Slog.w(ActivityManagerService.TAG, 1530 "Error canceling notification for service", e); 1531 } catch (RemoteException e) { 1532 } 1533 } break; 1534 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1535 synchronized (ActivityManagerService.this) { 1536 checkExcessivePowerUsageLocked(true); 1537 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1538 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1540 } 1541 } break; 1542 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1543 synchronized (ActivityManagerService.this) { 1544 ActivityRecord ar = (ActivityRecord)msg.obj; 1545 if (mCompatModeDialog != null) { 1546 if (mCompatModeDialog.mAppInfo.packageName.equals( 1547 ar.info.applicationInfo.packageName)) { 1548 return; 1549 } 1550 mCompatModeDialog.dismiss(); 1551 mCompatModeDialog = null; 1552 } 1553 if (ar != null && false) { 1554 if (mCompatModePackages.getPackageAskCompatModeLocked( 1555 ar.packageName)) { 1556 int mode = mCompatModePackages.computeCompatModeLocked( 1557 ar.info.applicationInfo); 1558 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1559 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1560 mCompatModeDialog = new CompatModeDialog( 1561 ActivityManagerService.this, mContext, 1562 ar.info.applicationInfo); 1563 mCompatModeDialog.show(); 1564 } 1565 } 1566 } 1567 } 1568 break; 1569 } 1570 case DISPATCH_PROCESSES_CHANGED: { 1571 dispatchProcessesChanged(); 1572 break; 1573 } 1574 case DISPATCH_PROCESS_DIED: { 1575 final int pid = msg.arg1; 1576 final int uid = msg.arg2; 1577 dispatchProcessDied(pid, uid); 1578 break; 1579 } 1580 case REPORT_MEM_USAGE_MSG: { 1581 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1582 Thread thread = new Thread() { 1583 @Override public void run() { 1584 final SparseArray<ProcessMemInfo> infoMap 1585 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1586 for (int i=0, N=memInfos.size(); i<N; i++) { 1587 ProcessMemInfo mi = memInfos.get(i); 1588 infoMap.put(mi.pid, mi); 1589 } 1590 updateCpuStatsNow(); 1591 synchronized (mProcessCpuThread) { 1592 final int N = mProcessCpuTracker.countStats(); 1593 for (int i=0; i<N; i++) { 1594 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1595 if (st.vsize > 0) { 1596 long pss = Debug.getPss(st.pid, null); 1597 if (pss > 0) { 1598 if (infoMap.indexOfKey(st.pid) < 0) { 1599 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1600 ProcessList.NATIVE_ADJ, -1, "native", null); 1601 mi.pss = pss; 1602 memInfos.add(mi); 1603 } 1604 } 1605 } 1606 } 1607 } 1608 1609 long totalPss = 0; 1610 for (int i=0, N=memInfos.size(); i<N; i++) { 1611 ProcessMemInfo mi = memInfos.get(i); 1612 if (mi.pss == 0) { 1613 mi.pss = Debug.getPss(mi.pid, null); 1614 } 1615 totalPss += mi.pss; 1616 } 1617 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1618 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1619 if (lhs.oomAdj != rhs.oomAdj) { 1620 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1621 } 1622 if (lhs.pss != rhs.pss) { 1623 return lhs.pss < rhs.pss ? 1 : -1; 1624 } 1625 return 0; 1626 } 1627 }); 1628 1629 StringBuilder tag = new StringBuilder(128); 1630 StringBuilder stack = new StringBuilder(128); 1631 tag.append("Low on memory -- "); 1632 appendMemBucket(tag, totalPss, "total", false); 1633 appendMemBucket(stack, totalPss, "total", true); 1634 1635 StringBuilder logBuilder = new StringBuilder(1024); 1636 logBuilder.append("Low on memory:\n"); 1637 1638 boolean firstLine = true; 1639 int lastOomAdj = Integer.MIN_VALUE; 1640 for (int i=0, N=memInfos.size(); i<N; i++) { 1641 ProcessMemInfo mi = memInfos.get(i); 1642 1643 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1644 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1645 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1646 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1647 if (lastOomAdj != mi.oomAdj) { 1648 lastOomAdj = mi.oomAdj; 1649 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1650 tag.append(" / "); 1651 } 1652 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1653 if (firstLine) { 1654 stack.append(":"); 1655 firstLine = false; 1656 } 1657 stack.append("\n\t at "); 1658 } else { 1659 stack.append("$"); 1660 } 1661 } else { 1662 tag.append(" "); 1663 stack.append("$"); 1664 } 1665 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1666 appendMemBucket(tag, mi.pss, mi.name, false); 1667 } 1668 appendMemBucket(stack, mi.pss, mi.name, true); 1669 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1670 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1671 stack.append("("); 1672 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1673 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1674 stack.append(DUMP_MEM_OOM_LABEL[k]); 1675 stack.append(":"); 1676 stack.append(DUMP_MEM_OOM_ADJ[k]); 1677 } 1678 } 1679 stack.append(")"); 1680 } 1681 } 1682 1683 logBuilder.append(" "); 1684 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1685 logBuilder.append(' '); 1686 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1687 logBuilder.append(' '); 1688 ProcessList.appendRamKb(logBuilder, mi.pss); 1689 logBuilder.append(" kB: "); 1690 logBuilder.append(mi.name); 1691 logBuilder.append(" ("); 1692 logBuilder.append(mi.pid); 1693 logBuilder.append(") "); 1694 logBuilder.append(mi.adjType); 1695 logBuilder.append('\n'); 1696 if (mi.adjReason != null) { 1697 logBuilder.append(" "); 1698 logBuilder.append(mi.adjReason); 1699 logBuilder.append('\n'); 1700 } 1701 } 1702 1703 logBuilder.append(" "); 1704 ProcessList.appendRamKb(logBuilder, totalPss); 1705 logBuilder.append(" kB: TOTAL\n"); 1706 1707 long[] infos = new long[Debug.MEMINFO_COUNT]; 1708 Debug.getMemInfo(infos); 1709 logBuilder.append(" MemInfo: "); 1710 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1711 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1712 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1713 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1714 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1715 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1716 logBuilder.append(" ZRAM: "); 1717 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1718 logBuilder.append(" kB RAM, "); 1719 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1720 logBuilder.append(" kB swap total, "); 1721 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1722 logBuilder.append(" kB swap free\n"); 1723 } 1724 Slog.i(TAG, logBuilder.toString()); 1725 1726 StringBuilder dropBuilder = new StringBuilder(1024); 1727 /* 1728 StringWriter oomSw = new StringWriter(); 1729 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1730 StringWriter catSw = new StringWriter(); 1731 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1732 String[] emptyArgs = new String[] { }; 1733 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1734 oomPw.flush(); 1735 String oomString = oomSw.toString(); 1736 */ 1737 dropBuilder.append(stack); 1738 dropBuilder.append('\n'); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append(logBuilder); 1741 dropBuilder.append('\n'); 1742 /* 1743 dropBuilder.append(oomString); 1744 dropBuilder.append('\n'); 1745 */ 1746 StringWriter catSw = new StringWriter(); 1747 synchronized (ActivityManagerService.this) { 1748 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1749 String[] emptyArgs = new String[] { }; 1750 catPw.println(); 1751 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1752 catPw.println(); 1753 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1754 false, false, null); 1755 catPw.println(); 1756 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1757 catPw.flush(); 1758 } 1759 dropBuilder.append(catSw.toString()); 1760 addErrorToDropBox("lowmem", null, "system_server", null, 1761 null, tag.toString(), dropBuilder.toString(), null, null); 1762 //Slog.i(TAG, "Sent to dropbox:"); 1763 //Slog.i(TAG, dropBuilder.toString()); 1764 synchronized (ActivityManagerService.this) { 1765 long now = SystemClock.uptimeMillis(); 1766 if (mLastMemUsageReportTime < now) { 1767 mLastMemUsageReportTime = now; 1768 } 1769 } 1770 } 1771 }; 1772 thread.start(); 1773 break; 1774 } 1775 case START_USER_SWITCH_MSG: { 1776 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1777 break; 1778 } 1779 case REPORT_USER_SWITCH_MSG: { 1780 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1781 break; 1782 } 1783 case CONTINUE_USER_SWITCH_MSG: { 1784 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1785 break; 1786 } 1787 case USER_SWITCH_TIMEOUT_MSG: { 1788 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1789 break; 1790 } 1791 case IMMERSIVE_MODE_LOCK_MSG: { 1792 final boolean nextState = (msg.arg1 != 0); 1793 if (mUpdateLock.isHeld() != nextState) { 1794 if (DEBUG_IMMERSIVE) { 1795 final ActivityRecord r = (ActivityRecord) msg.obj; 1796 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1797 } 1798 if (nextState) { 1799 mUpdateLock.acquire(); 1800 } else { 1801 mUpdateLock.release(); 1802 } 1803 } 1804 break; 1805 } 1806 case PERSIST_URI_GRANTS_MSG: { 1807 writeGrantedUriPermissions(); 1808 break; 1809 } 1810 case REQUEST_ALL_PSS_MSG: { 1811 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1812 break; 1813 } 1814 case START_PROFILES_MSG: { 1815 synchronized (ActivityManagerService.this) { 1816 startProfilesLocked(); 1817 } 1818 break; 1819 } 1820 case UPDATE_TIME: { 1821 synchronized (ActivityManagerService.this) { 1822 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1823 ProcessRecord r = mLruProcesses.get(i); 1824 if (r.thread != null) { 1825 try { 1826 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1827 } catch (RemoteException ex) { 1828 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1829 } 1830 } 1831 } 1832 } 1833 break; 1834 } 1835 case SYSTEM_USER_START_MSG: { 1836 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1837 Integer.toString(msg.arg1), msg.arg1); 1838 mSystemServiceManager.startUser(msg.arg1); 1839 break; 1840 } 1841 case SYSTEM_USER_CURRENT_MSG: { 1842 mBatteryStatsService.noteEvent( 1843 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1844 Integer.toString(msg.arg2), msg.arg2); 1845 mBatteryStatsService.noteEvent( 1846 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1847 Integer.toString(msg.arg1), msg.arg1); 1848 mSystemServiceManager.switchUser(msg.arg1); 1849 mLockToAppRequest.clearPrompt(); 1850 break; 1851 } 1852 case ENTER_ANIMATION_COMPLETE_MSG: { 1853 synchronized (ActivityManagerService.this) { 1854 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1855 if (r != null && r.app != null && r.app.thread != null) { 1856 try { 1857 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1858 } catch (RemoteException e) { 1859 } 1860 } 1861 } 1862 break; 1863 } 1864 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1865 enableScreenAfterBoot(); 1866 break; 1867 } 1868 } 1869 } 1870 }; 1871 1872 static final int COLLECT_PSS_BG_MSG = 1; 1873 1874 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1875 @Override 1876 public void handleMessage(Message msg) { 1877 switch (msg.what) { 1878 case COLLECT_PSS_BG_MSG: { 1879 long start = SystemClock.uptimeMillis(); 1880 MemInfoReader memInfo = null; 1881 synchronized (ActivityManagerService.this) { 1882 if (mFullPssPending) { 1883 mFullPssPending = false; 1884 memInfo = new MemInfoReader(); 1885 } 1886 } 1887 if (memInfo != null) { 1888 updateCpuStatsNow(); 1889 long nativeTotalPss = 0; 1890 synchronized (mProcessCpuThread) { 1891 final int N = mProcessCpuTracker.countStats(); 1892 for (int j=0; j<N; j++) { 1893 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1894 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1895 // This is definitely an application process; skip it. 1896 continue; 1897 } 1898 synchronized (mPidsSelfLocked) { 1899 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1900 // This is one of our own processes; skip it. 1901 continue; 1902 } 1903 } 1904 nativeTotalPss += Debug.getPss(st.pid, null); 1905 } 1906 } 1907 memInfo.readMemInfo(); 1908 synchronized (this) { 1909 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1910 + (SystemClock.uptimeMillis()-start) + "ms"); 1911 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1912 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1913 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1914 +memInfo.getSlabSizeKb(), 1915 nativeTotalPss); 1916 } 1917 } 1918 1919 int i=0, num=0; 1920 long[] tmp = new long[1]; 1921 do { 1922 ProcessRecord proc; 1923 int procState; 1924 int pid; 1925 synchronized (ActivityManagerService.this) { 1926 if (i >= mPendingPssProcesses.size()) { 1927 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1928 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1929 mPendingPssProcesses.clear(); 1930 return; 1931 } 1932 proc = mPendingPssProcesses.get(i); 1933 procState = proc.pssProcState; 1934 if (proc.thread != null && procState == proc.setProcState) { 1935 pid = proc.pid; 1936 } else { 1937 proc = null; 1938 pid = 0; 1939 } 1940 i++; 1941 } 1942 if (proc != null) { 1943 long pss = Debug.getPss(pid, tmp); 1944 synchronized (ActivityManagerService.this) { 1945 if (proc.thread != null && proc.setProcState == procState 1946 && proc.pid == pid) { 1947 num++; 1948 proc.lastPssTime = SystemClock.uptimeMillis(); 1949 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1950 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1951 + ": " + pss + " lastPss=" + proc.lastPss 1952 + " state=" + ProcessList.makeProcStateString(procState)); 1953 if (proc.initialIdlePss == 0) { 1954 proc.initialIdlePss = pss; 1955 } 1956 proc.lastPss = pss; 1957 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1958 proc.lastCachedPss = pss; 1959 } 1960 } 1961 } 1962 } 1963 } while (true); 1964 } 1965 } 1966 } 1967 }; 1968 1969 /** 1970 * Monitor for package changes and update our internal state. 1971 */ 1972 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1973 @Override 1974 public void onPackageRemoved(String packageName, int uid) { 1975 // Remove all tasks with activities in the specified package from the list of recent tasks 1976 synchronized (ActivityManagerService.this) { 1977 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1978 TaskRecord tr = mRecentTasks.get(i); 1979 ComponentName cn = tr.intent.getComponent(); 1980 if (cn != null && cn.getPackageName().equals(packageName)) { 1981 // If the package name matches, remove the task and kill the process 1982 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1983 } 1984 } 1985 } 1986 } 1987 1988 @Override 1989 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1990 onPackageModified(packageName); 1991 return true; 1992 } 1993 1994 @Override 1995 public void onPackageModified(String packageName) { 1996 final PackageManager pm = mContext.getPackageManager(); 1997 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1998 new ArrayList<Pair<Intent, Integer>>(); 1999 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2000 // Copy the list of recent tasks so that we don't hold onto the lock on 2001 // ActivityManagerService for long periods while checking if components exist. 2002 synchronized (ActivityManagerService.this) { 2003 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2004 TaskRecord tr = mRecentTasks.get(i); 2005 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2006 } 2007 } 2008 // Check the recent tasks and filter out all tasks with components that no longer exist. 2009 Intent tmpI = new Intent(); 2010 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2011 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2012 ComponentName cn = p.first.getComponent(); 2013 if (cn != null && cn.getPackageName().equals(packageName)) { 2014 try { 2015 // Add the task to the list to remove if the component no longer exists 2016 tmpI.setComponent(cn); 2017 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2018 tasksToRemove.add(p.second); 2019 } 2020 } catch (Exception e) {} 2021 } 2022 } 2023 // Prune all the tasks with removed components from the list of recent tasks 2024 synchronized (ActivityManagerService.this) { 2025 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2026 // Remove the task but don't kill the process (since other components in that 2027 // package may still be running and in the background) 2028 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2035 // Force stop the specified packages 2036 if (packages != null) { 2037 for (String pkg : packages) { 2038 synchronized (ActivityManagerService.this) { 2039 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2040 "finished booting")) { 2041 return true; 2042 } 2043 } 2044 } 2045 } 2046 return false; 2047 } 2048 }; 2049 2050 public void setSystemProcess() { 2051 try { 2052 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2053 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2054 ServiceManager.addService("meminfo", new MemBinder(this)); 2055 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2056 ServiceManager.addService("dbinfo", new DbBinder(this)); 2057 if (MONITOR_CPU_USAGE) { 2058 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2059 } 2060 ServiceManager.addService("permission", new PermissionController(this)); 2061 2062 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2063 "android", STOCK_PM_FLAGS); 2064 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2065 2066 synchronized (this) { 2067 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2068 app.persistent = true; 2069 app.pid = MY_PID; 2070 app.maxAdj = ProcessList.SYSTEM_ADJ; 2071 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2072 mProcessNames.put(app.processName, app.uid, app); 2073 synchronized (mPidsSelfLocked) { 2074 mPidsSelfLocked.put(app.pid, app); 2075 } 2076 updateLruProcessLocked(app, false, null); 2077 updateOomAdjLocked(); 2078 } 2079 } catch (PackageManager.NameNotFoundException e) { 2080 throw new RuntimeException( 2081 "Unable to find android system package", e); 2082 } 2083 } 2084 2085 public void setWindowManager(WindowManagerService wm) { 2086 mWindowManager = wm; 2087 mStackSupervisor.setWindowManager(wm); 2088 } 2089 2090 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2091 mUsageStatsService = usageStatsManager; 2092 } 2093 2094 public void startObservingNativeCrashes() { 2095 final NativeCrashListener ncl = new NativeCrashListener(this); 2096 ncl.start(); 2097 } 2098 2099 public IAppOpsService getAppOpsService() { 2100 return mAppOpsService; 2101 } 2102 2103 static class MemBinder extends Binder { 2104 ActivityManagerService mActivityManagerService; 2105 MemBinder(ActivityManagerService activityManagerService) { 2106 mActivityManagerService = activityManagerService; 2107 } 2108 2109 @Override 2110 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2111 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2112 != PackageManager.PERMISSION_GRANTED) { 2113 pw.println("Permission Denial: can't dump meminfo from from pid=" 2114 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2115 + " without permission " + android.Manifest.permission.DUMP); 2116 return; 2117 } 2118 2119 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2120 } 2121 } 2122 2123 static class GraphicsBinder extends Binder { 2124 ActivityManagerService mActivityManagerService; 2125 GraphicsBinder(ActivityManagerService activityManagerService) { 2126 mActivityManagerService = activityManagerService; 2127 } 2128 2129 @Override 2130 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2131 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2132 != PackageManager.PERMISSION_GRANTED) { 2133 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2134 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2135 + " without permission " + android.Manifest.permission.DUMP); 2136 return; 2137 } 2138 2139 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2140 } 2141 } 2142 2143 static class DbBinder extends Binder { 2144 ActivityManagerService mActivityManagerService; 2145 DbBinder(ActivityManagerService activityManagerService) { 2146 mActivityManagerService = activityManagerService; 2147 } 2148 2149 @Override 2150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2151 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2152 != PackageManager.PERMISSION_GRANTED) { 2153 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2154 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2155 + " without permission " + android.Manifest.permission.DUMP); 2156 return; 2157 } 2158 2159 mActivityManagerService.dumpDbInfo(fd, pw, args); 2160 } 2161 } 2162 2163 static class CpuBinder extends Binder { 2164 ActivityManagerService mActivityManagerService; 2165 CpuBinder(ActivityManagerService activityManagerService) { 2166 mActivityManagerService = activityManagerService; 2167 } 2168 2169 @Override 2170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2171 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2172 != PackageManager.PERMISSION_GRANTED) { 2173 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2174 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2175 + " without permission " + android.Manifest.permission.DUMP); 2176 return; 2177 } 2178 2179 synchronized (mActivityManagerService.mProcessCpuThread) { 2180 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2182 SystemClock.uptimeMillis())); 2183 } 2184 } 2185 } 2186 2187 public static final class Lifecycle extends SystemService { 2188 private final ActivityManagerService mService; 2189 2190 public Lifecycle(Context context) { 2191 super(context); 2192 mService = new ActivityManagerService(context); 2193 } 2194 2195 @Override 2196 public void onStart() { 2197 mService.start(); 2198 } 2199 2200 public ActivityManagerService getService() { 2201 return mService; 2202 } 2203 } 2204 2205 // Note: This method is invoked on the main thread but may need to attach various 2206 // handlers to other threads. So take care to be explicit about the looper. 2207 public ActivityManagerService(Context systemContext) { 2208 mContext = systemContext; 2209 mFactoryTest = FactoryTest.getMode(); 2210 mSystemThread = ActivityThread.currentActivityThread(); 2211 2212 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2213 2214 mHandlerThread = new ServiceThread(TAG, 2215 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2216 mHandlerThread.start(); 2217 mHandler = new MainHandler(mHandlerThread.getLooper()); 2218 2219 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2220 "foreground", BROADCAST_FG_TIMEOUT, false); 2221 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2222 "background", BROADCAST_BG_TIMEOUT, true); 2223 mBroadcastQueues[0] = mFgBroadcastQueue; 2224 mBroadcastQueues[1] = mBgBroadcastQueue; 2225 2226 mServices = new ActiveServices(this); 2227 mProviderMap = new ProviderMap(this); 2228 2229 // TODO: Move creation of battery stats service outside of activity manager service. 2230 File dataDir = Environment.getDataDirectory(); 2231 File systemDir = new File(dataDir, "system"); 2232 systemDir.mkdirs(); 2233 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2234 mBatteryStatsService.getActiveStatistics().readLocked(); 2235 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2236 mOnBattery = DEBUG_POWER ? true 2237 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2238 mBatteryStatsService.getActiveStatistics().setCallback(this); 2239 2240 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2241 2242 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2243 2244 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2245 2246 // User 0 is the first and only user that runs at boot. 2247 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2248 mUserLru.add(Integer.valueOf(0)); 2249 updateStartedUserArrayLocked(); 2250 2251 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2252 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2253 2254 mConfiguration.setToDefaults(); 2255 mConfiguration.setLocale(Locale.getDefault()); 2256 2257 mConfigurationSeq = mConfiguration.seq = 1; 2258 mProcessCpuTracker.init(); 2259 2260 final Resources res = mContext.getResources(); 2261 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 2262 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2263 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2264 2265 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2266 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2267 mStackSupervisor = new ActivityStackSupervisor(this); 2268 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2269 2270 mProcessCpuThread = new Thread("CpuTracker") { 2271 @Override 2272 public void run() { 2273 while (true) { 2274 try { 2275 try { 2276 synchronized(this) { 2277 final long now = SystemClock.uptimeMillis(); 2278 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2279 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2280 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2281 // + ", write delay=" + nextWriteDelay); 2282 if (nextWriteDelay < nextCpuDelay) { 2283 nextCpuDelay = nextWriteDelay; 2284 } 2285 if (nextCpuDelay > 0) { 2286 mProcessCpuMutexFree.set(true); 2287 this.wait(nextCpuDelay); 2288 } 2289 } 2290 } catch (InterruptedException e) { 2291 } 2292 updateCpuStatsNow(); 2293 } catch (Exception e) { 2294 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2295 } 2296 } 2297 } 2298 }; 2299 2300 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2301 2302 Watchdog.getInstance().addMonitor(this); 2303 Watchdog.getInstance().addThread(mHandler); 2304 } 2305 2306 public void setSystemServiceManager(SystemServiceManager mgr) { 2307 mSystemServiceManager = mgr; 2308 } 2309 2310 private void start() { 2311 Process.removeAllProcessGroups(); 2312 mProcessCpuThread.start(); 2313 2314 mBatteryStatsService.publish(mContext); 2315 mAppOpsService.publish(mContext); 2316 Slog.d("AppOps", "AppOpsService published"); 2317 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2318 } 2319 2320 public void initPowerManagement() { 2321 mStackSupervisor.initPowerManagement(); 2322 mBatteryStatsService.initPowerManagement(); 2323 } 2324 2325 @Override 2326 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2327 throws RemoteException { 2328 if (code == SYSPROPS_TRANSACTION) { 2329 // We need to tell all apps about the system property change. 2330 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2331 synchronized(this) { 2332 final int NP = mProcessNames.getMap().size(); 2333 for (int ip=0; ip<NP; ip++) { 2334 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2335 final int NA = apps.size(); 2336 for (int ia=0; ia<NA; ia++) { 2337 ProcessRecord app = apps.valueAt(ia); 2338 if (app.thread != null) { 2339 procs.add(app.thread.asBinder()); 2340 } 2341 } 2342 } 2343 } 2344 2345 int N = procs.size(); 2346 for (int i=0; i<N; i++) { 2347 Parcel data2 = Parcel.obtain(); 2348 try { 2349 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2350 } catch (RemoteException e) { 2351 } 2352 data2.recycle(); 2353 } 2354 } 2355 try { 2356 return super.onTransact(code, data, reply, flags); 2357 } catch (RuntimeException e) { 2358 // The activity manager only throws security exceptions, so let's 2359 // log all others. 2360 if (!(e instanceof SecurityException)) { 2361 Slog.wtf(TAG, "Activity Manager Crash", e); 2362 } 2363 throw e; 2364 } 2365 } 2366 2367 void updateCpuStats() { 2368 final long now = SystemClock.uptimeMillis(); 2369 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2370 return; 2371 } 2372 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2373 synchronized (mProcessCpuThread) { 2374 mProcessCpuThread.notify(); 2375 } 2376 } 2377 } 2378 2379 void updateCpuStatsNow() { 2380 synchronized (mProcessCpuThread) { 2381 mProcessCpuMutexFree.set(false); 2382 final long now = SystemClock.uptimeMillis(); 2383 boolean haveNewCpuStats = false; 2384 2385 if (MONITOR_CPU_USAGE && 2386 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2387 mLastCpuTime.set(now); 2388 haveNewCpuStats = true; 2389 mProcessCpuTracker.update(); 2390 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2391 //Slog.i(TAG, "Total CPU usage: " 2392 // + mProcessCpu.getTotalCpuPercent() + "%"); 2393 2394 // Slog the cpu usage if the property is set. 2395 if ("true".equals(SystemProperties.get("events.cpu"))) { 2396 int user = mProcessCpuTracker.getLastUserTime(); 2397 int system = mProcessCpuTracker.getLastSystemTime(); 2398 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2399 int irq = mProcessCpuTracker.getLastIrqTime(); 2400 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2401 int idle = mProcessCpuTracker.getLastIdleTime(); 2402 2403 int total = user + system + iowait + irq + softIrq + idle; 2404 if (total == 0) total = 1; 2405 2406 EventLog.writeEvent(EventLogTags.CPU, 2407 ((user+system+iowait+irq+softIrq) * 100) / total, 2408 (user * 100) / total, 2409 (system * 100) / total, 2410 (iowait * 100) / total, 2411 (irq * 100) / total, 2412 (softIrq * 100) / total); 2413 } 2414 } 2415 2416 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2417 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2418 synchronized(bstats) { 2419 synchronized(mPidsSelfLocked) { 2420 if (haveNewCpuStats) { 2421 if (mOnBattery) { 2422 int perc = bstats.startAddingCpuLocked(); 2423 int totalUTime = 0; 2424 int totalSTime = 0; 2425 final int N = mProcessCpuTracker.countStats(); 2426 for (int i=0; i<N; i++) { 2427 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2428 if (!st.working) { 2429 continue; 2430 } 2431 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2432 int otherUTime = (st.rel_utime*perc)/100; 2433 int otherSTime = (st.rel_stime*perc)/100; 2434 totalUTime += otherUTime; 2435 totalSTime += otherSTime; 2436 if (pr != null) { 2437 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2438 if (ps == null || !ps.isActive()) { 2439 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2440 pr.info.uid, pr.processName); 2441 } 2442 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2443 st.rel_stime-otherSTime); 2444 ps.addSpeedStepTimes(cpuSpeedTimes); 2445 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2446 } else { 2447 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2448 if (ps == null || !ps.isActive()) { 2449 st.batteryStats = ps = bstats.getProcessStatsLocked( 2450 bstats.mapUid(st.uid), st.name); 2451 } 2452 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2453 st.rel_stime-otherSTime); 2454 ps.addSpeedStepTimes(cpuSpeedTimes); 2455 } 2456 } 2457 bstats.finishAddingCpuLocked(perc, totalUTime, 2458 totalSTime, cpuSpeedTimes); 2459 } 2460 } 2461 } 2462 2463 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2464 mLastWriteTime = now; 2465 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2466 } 2467 } 2468 } 2469 } 2470 2471 @Override 2472 public void batteryNeedsCpuUpdate() { 2473 updateCpuStatsNow(); 2474 } 2475 2476 @Override 2477 public void batteryPowerChanged(boolean onBattery) { 2478 // When plugging in, update the CPU stats first before changing 2479 // the plug state. 2480 updateCpuStatsNow(); 2481 synchronized (this) { 2482 synchronized(mPidsSelfLocked) { 2483 mOnBattery = DEBUG_POWER ? true : onBattery; 2484 } 2485 } 2486 } 2487 2488 /** 2489 * Initialize the application bind args. These are passed to each 2490 * process when the bindApplication() IPC is sent to the process. They're 2491 * lazily setup to make sure the services are running when they're asked for. 2492 */ 2493 private HashMap<String, IBinder> getCommonServicesLocked() { 2494 if (mAppBindArgs == null) { 2495 mAppBindArgs = new HashMap<String, IBinder>(); 2496 2497 // Setup the application init args 2498 mAppBindArgs.put("package", ServiceManager.getService("package")); 2499 mAppBindArgs.put("window", ServiceManager.getService("window")); 2500 mAppBindArgs.put(Context.ALARM_SERVICE, 2501 ServiceManager.getService(Context.ALARM_SERVICE)); 2502 } 2503 return mAppBindArgs; 2504 } 2505 2506 final void setFocusedActivityLocked(ActivityRecord r) { 2507 if (mFocusedActivity != r) { 2508 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2509 mFocusedActivity = r; 2510 if (r.task != null && r.task.voiceInteractor != null) { 2511 startRunningVoiceLocked(); 2512 } else { 2513 finishRunningVoiceLocked(); 2514 } 2515 mStackSupervisor.setFocusedStack(r); 2516 if (r != null) { 2517 mWindowManager.setFocusedApp(r.appToken, true); 2518 } 2519 applyUpdateLockStateLocked(r); 2520 } 2521 } 2522 2523 final void clearFocusedActivity(ActivityRecord r) { 2524 if (mFocusedActivity == r) { 2525 mFocusedActivity = null; 2526 } 2527 } 2528 2529 @Override 2530 public void setFocusedStack(int stackId) { 2531 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2532 synchronized (ActivityManagerService.this) { 2533 ActivityStack stack = mStackSupervisor.getStack(stackId); 2534 if (stack != null) { 2535 ActivityRecord r = stack.topRunningActivityLocked(null); 2536 if (r != null) { 2537 setFocusedActivityLocked(r); 2538 } 2539 } 2540 } 2541 } 2542 2543 @Override 2544 public void notifyActivityDrawn(IBinder token) { 2545 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2546 synchronized (this) { 2547 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2548 if (r != null) { 2549 r.task.stack.notifyActivityDrawnLocked(r); 2550 } 2551 } 2552 } 2553 2554 final void applyUpdateLockStateLocked(ActivityRecord r) { 2555 // Modifications to the UpdateLock state are done on our handler, outside 2556 // the activity manager's locks. The new state is determined based on the 2557 // state *now* of the relevant activity record. The object is passed to 2558 // the handler solely for logging detail, not to be consulted/modified. 2559 final boolean nextState = r != null && r.immersive; 2560 mHandler.sendMessage( 2561 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2562 } 2563 2564 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2565 Message msg = Message.obtain(); 2566 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2567 msg.obj = r.task.askedCompatMode ? null : r; 2568 mHandler.sendMessage(msg); 2569 } 2570 2571 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2572 String what, Object obj, ProcessRecord srcApp) { 2573 app.lastActivityTime = now; 2574 2575 if (app.activities.size() > 0) { 2576 // Don't want to touch dependent processes that are hosting activities. 2577 return index; 2578 } 2579 2580 int lrui = mLruProcesses.lastIndexOf(app); 2581 if (lrui < 0) { 2582 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2583 + what + " " + obj + " from " + srcApp); 2584 return index; 2585 } 2586 2587 if (lrui >= index) { 2588 // Don't want to cause this to move dependent processes *back* in the 2589 // list as if they were less frequently used. 2590 return index; 2591 } 2592 2593 if (lrui >= mLruProcessActivityStart) { 2594 // Don't want to touch dependent processes that are hosting activities. 2595 return index; 2596 } 2597 2598 mLruProcesses.remove(lrui); 2599 if (index > 0) { 2600 index--; 2601 } 2602 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2603 + " in LRU list: " + app); 2604 mLruProcesses.add(index, app); 2605 return index; 2606 } 2607 2608 final void removeLruProcessLocked(ProcessRecord app) { 2609 int lrui = mLruProcesses.lastIndexOf(app); 2610 if (lrui >= 0) { 2611 if (lrui <= mLruProcessActivityStart) { 2612 mLruProcessActivityStart--; 2613 } 2614 if (lrui <= mLruProcessServiceStart) { 2615 mLruProcessServiceStart--; 2616 } 2617 mLruProcesses.remove(lrui); 2618 } 2619 } 2620 2621 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2622 ProcessRecord client) { 2623 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2624 || app.treatLikeActivity; 2625 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2626 if (!activityChange && hasActivity) { 2627 // The process has activities, so we are only allowing activity-based adjustments 2628 // to move it. It should be kept in the front of the list with other 2629 // processes that have activities, and we don't want those to change their 2630 // order except due to activity operations. 2631 return; 2632 } 2633 2634 mLruSeq++; 2635 final long now = SystemClock.uptimeMillis(); 2636 app.lastActivityTime = now; 2637 2638 // First a quick reject: if the app is already at the position we will 2639 // put it, then there is nothing to do. 2640 if (hasActivity) { 2641 final int N = mLruProcesses.size(); 2642 if (N > 0 && mLruProcesses.get(N-1) == app) { 2643 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2644 return; 2645 } 2646 } else { 2647 if (mLruProcessServiceStart > 0 2648 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2649 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2650 return; 2651 } 2652 } 2653 2654 int lrui = mLruProcesses.lastIndexOf(app); 2655 2656 if (app.persistent && lrui >= 0) { 2657 // We don't care about the position of persistent processes, as long as 2658 // they are in the list. 2659 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2660 return; 2661 } 2662 2663 /* In progress: compute new position first, so we can avoid doing work 2664 if the process is not actually going to move. Not yet working. 2665 int addIndex; 2666 int nextIndex; 2667 boolean inActivity = false, inService = false; 2668 if (hasActivity) { 2669 // Process has activities, put it at the very tipsy-top. 2670 addIndex = mLruProcesses.size(); 2671 nextIndex = mLruProcessServiceStart; 2672 inActivity = true; 2673 } else if (hasService) { 2674 // Process has services, put it at the top of the service list. 2675 addIndex = mLruProcessActivityStart; 2676 nextIndex = mLruProcessServiceStart; 2677 inActivity = true; 2678 inService = true; 2679 } else { 2680 // Process not otherwise of interest, it goes to the top of the non-service area. 2681 addIndex = mLruProcessServiceStart; 2682 if (client != null) { 2683 int clientIndex = mLruProcesses.lastIndexOf(client); 2684 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2685 + app); 2686 if (clientIndex >= 0 && addIndex > clientIndex) { 2687 addIndex = clientIndex; 2688 } 2689 } 2690 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2691 } 2692 2693 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2694 + mLruProcessActivityStart + "): " + app); 2695 */ 2696 2697 if (lrui >= 0) { 2698 if (lrui < mLruProcessActivityStart) { 2699 mLruProcessActivityStart--; 2700 } 2701 if (lrui < mLruProcessServiceStart) { 2702 mLruProcessServiceStart--; 2703 } 2704 /* 2705 if (addIndex > lrui) { 2706 addIndex--; 2707 } 2708 if (nextIndex > lrui) { 2709 nextIndex--; 2710 } 2711 */ 2712 mLruProcesses.remove(lrui); 2713 } 2714 2715 /* 2716 mLruProcesses.add(addIndex, app); 2717 if (inActivity) { 2718 mLruProcessActivityStart++; 2719 } 2720 if (inService) { 2721 mLruProcessActivityStart++; 2722 } 2723 */ 2724 2725 int nextIndex; 2726 if (hasActivity) { 2727 final int N = mLruProcesses.size(); 2728 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2729 // Process doesn't have activities, but has clients with 2730 // activities... move it up, but one below the top (the top 2731 // should always have a real activity). 2732 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2733 mLruProcesses.add(N-1, app); 2734 // To keep it from spamming the LRU list (by making a bunch of clients), 2735 // we will push down any other entries owned by the app. 2736 final int uid = app.info.uid; 2737 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2738 ProcessRecord subProc = mLruProcesses.get(i); 2739 if (subProc.info.uid == uid) { 2740 // We want to push this one down the list. If the process after 2741 // it is for the same uid, however, don't do so, because we don't 2742 // want them internally to be re-ordered. 2743 if (mLruProcesses.get(i-1).info.uid != uid) { 2744 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2745 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2746 ProcessRecord tmp = mLruProcesses.get(i); 2747 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2748 mLruProcesses.set(i-1, tmp); 2749 i--; 2750 } 2751 } else { 2752 // A gap, we can stop here. 2753 break; 2754 } 2755 } 2756 } else { 2757 // Process has activities, put it at the very tipsy-top. 2758 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2759 mLruProcesses.add(app); 2760 } 2761 nextIndex = mLruProcessServiceStart; 2762 } else if (hasService) { 2763 // Process has services, put it at the top of the service list. 2764 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2765 mLruProcesses.add(mLruProcessActivityStart, app); 2766 nextIndex = mLruProcessServiceStart; 2767 mLruProcessActivityStart++; 2768 } else { 2769 // Process not otherwise of interest, it goes to the top of the non-service area. 2770 int index = mLruProcessServiceStart; 2771 if (client != null) { 2772 // If there is a client, don't allow the process to be moved up higher 2773 // in the list than that client. 2774 int clientIndex = mLruProcesses.lastIndexOf(client); 2775 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2776 + " when updating " + app); 2777 if (clientIndex <= lrui) { 2778 // Don't allow the client index restriction to push it down farther in the 2779 // list than it already is. 2780 clientIndex = lrui; 2781 } 2782 if (clientIndex >= 0 && index > clientIndex) { 2783 index = clientIndex; 2784 } 2785 } 2786 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2787 mLruProcesses.add(index, app); 2788 nextIndex = index-1; 2789 mLruProcessActivityStart++; 2790 mLruProcessServiceStart++; 2791 } 2792 2793 // If the app is currently using a content provider or service, 2794 // bump those processes as well. 2795 for (int j=app.connections.size()-1; j>=0; j--) { 2796 ConnectionRecord cr = app.connections.valueAt(j); 2797 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2798 && cr.binding.service.app != null 2799 && cr.binding.service.app.lruSeq != mLruSeq 2800 && !cr.binding.service.app.persistent) { 2801 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2802 "service connection", cr, app); 2803 } 2804 } 2805 for (int j=app.conProviders.size()-1; j>=0; j--) { 2806 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2807 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2808 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2809 "provider reference", cpr, app); 2810 } 2811 } 2812 } 2813 2814 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2815 if (uid == Process.SYSTEM_UID) { 2816 // The system gets to run in any process. If there are multiple 2817 // processes with the same uid, just pick the first (this 2818 // should never happen). 2819 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2820 if (procs == null) return null; 2821 final int N = procs.size(); 2822 for (int i = 0; i < N; i++) { 2823 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2824 } 2825 } 2826 ProcessRecord proc = mProcessNames.get(processName, uid); 2827 if (false && proc != null && !keepIfLarge 2828 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2829 && proc.lastCachedPss >= 4000) { 2830 // Turn this condition on to cause killing to happen regularly, for testing. 2831 if (proc.baseProcessTracker != null) { 2832 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2833 } 2834 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2835 + "k from cached"); 2836 } else if (proc != null && !keepIfLarge 2837 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2838 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2839 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2840 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2841 if (proc.baseProcessTracker != null) { 2842 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2843 } 2844 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2845 + "k from cached"); 2846 } 2847 } 2848 return proc; 2849 } 2850 2851 void ensurePackageDexOpt(String packageName) { 2852 IPackageManager pm = AppGlobals.getPackageManager(); 2853 try { 2854 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2855 mDidDexOpt = true; 2856 } 2857 } catch (RemoteException e) { 2858 } 2859 } 2860 2861 boolean isNextTransitionForward() { 2862 int transit = mWindowManager.getPendingAppTransition(); 2863 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_OPEN 2865 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2866 } 2867 2868 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2869 String processName, String abiOverride, int uid, Runnable crashHandler) { 2870 synchronized(this) { 2871 ApplicationInfo info = new ApplicationInfo(); 2872 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2873 // For isolated processes, the former contains the parent's uid and the latter the 2874 // actual uid of the isolated process. 2875 // In the special case introduced by this method (which is, starting an isolated 2876 // process directly from the SystemServer without an actual parent app process) the 2877 // closest thing to a parent's uid is SYSTEM_UID. 2878 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2879 // the |isolated| logic in the ProcessRecord constructor. 2880 info.uid = Process.SYSTEM_UID; 2881 info.processName = processName; 2882 info.className = entryPoint; 2883 info.packageName = "android"; 2884 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2885 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2886 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2887 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2888 crashHandler); 2889 return proc != null ? proc.pid : 0; 2890 } 2891 } 2892 2893 final ProcessRecord startProcessLocked(String processName, 2894 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2895 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2896 boolean isolated, boolean keepIfLarge) { 2897 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2898 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2899 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2900 null /* crashHandler */); 2901 } 2902 2903 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2904 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2905 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2906 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2907 ProcessRecord app; 2908 if (!isolated) { 2909 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2910 } else { 2911 // If this is an isolated process, it can't re-use an existing process. 2912 app = null; 2913 } 2914 // We don't have to do anything more if: 2915 // (1) There is an existing application record; and 2916 // (2) The caller doesn't think it is dead, OR there is no thread 2917 // object attached to it so we know it couldn't have crashed; and 2918 // (3) There is a pid assigned to it, so it is either starting or 2919 // already running. 2920 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2921 + " app=" + app + " knownToBeDead=" + knownToBeDead 2922 + " thread=" + (app != null ? app.thread : null) 2923 + " pid=" + (app != null ? app.pid : -1)); 2924 if (app != null && app.pid > 0) { 2925 if (!knownToBeDead || app.thread == null) { 2926 // We already have the app running, or are waiting for it to 2927 // come up (we have a pid but not yet its thread), so keep it. 2928 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2929 // If this is a new package in the process, add the package to the list 2930 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2931 return app; 2932 } 2933 2934 // An application record is attached to a previous process, 2935 // clean it up now. 2936 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2937 Process.killProcessGroup(app.info.uid, app.pid); 2938 handleAppDiedLocked(app, true, true); 2939 } 2940 2941 String hostingNameStr = hostingName != null 2942 ? hostingName.flattenToShortString() : null; 2943 2944 if (!isolated) { 2945 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2946 // If we are in the background, then check to see if this process 2947 // is bad. If so, we will just silently fail. 2948 if (mBadProcesses.get(info.processName, info.uid) != null) { 2949 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2950 + "/" + info.processName); 2951 return null; 2952 } 2953 } else { 2954 // When the user is explicitly starting a process, then clear its 2955 // crash count so that we won't make it bad until they see at 2956 // least one crash dialog again, and make the process good again 2957 // if it had been bad. 2958 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2959 + "/" + info.processName); 2960 mProcessCrashTimes.remove(info.processName, info.uid); 2961 if (mBadProcesses.get(info.processName, info.uid) != null) { 2962 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2963 UserHandle.getUserId(info.uid), info.uid, 2964 info.processName); 2965 mBadProcesses.remove(info.processName, info.uid); 2966 if (app != null) { 2967 app.bad = false; 2968 } 2969 } 2970 } 2971 } 2972 2973 if (app == null) { 2974 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2975 app.crashHandler = crashHandler; 2976 if (app == null) { 2977 Slog.w(TAG, "Failed making new process record for " 2978 + processName + "/" + info.uid + " isolated=" + isolated); 2979 return null; 2980 } 2981 mProcessNames.put(processName, app.uid, app); 2982 if (isolated) { 2983 mIsolatedProcesses.put(app.uid, app); 2984 } 2985 } else { 2986 // If this is a new package in the process, add the package to the list 2987 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2988 } 2989 2990 // If the system is not ready yet, then hold off on starting this 2991 // process until it is. 2992 if (!mProcessesReady 2993 && !isAllowedWhileBooting(info) 2994 && !allowWhileBooting) { 2995 if (!mProcessesOnHold.contains(app)) { 2996 mProcessesOnHold.add(app); 2997 } 2998 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2999 return app; 3000 } 3001 3002 startProcessLocked( 3003 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3004 return (app.pid != 0) ? app : null; 3005 } 3006 3007 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3008 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3009 } 3010 3011 private final void startProcessLocked(ProcessRecord app, 3012 String hostingType, String hostingNameStr) { 3013 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3014 null /* entryPoint */, null /* entryPointArgs */); 3015 } 3016 3017 private final void startProcessLocked(ProcessRecord app, String hostingType, 3018 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3019 if (app.pid > 0 && app.pid != MY_PID) { 3020 synchronized (mPidsSelfLocked) { 3021 mPidsSelfLocked.remove(app.pid); 3022 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3023 } 3024 app.setPid(0); 3025 } 3026 3027 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3028 "startProcessLocked removing on hold: " + app); 3029 mProcessesOnHold.remove(app); 3030 3031 updateCpuStats(); 3032 3033 try { 3034 int uid = app.uid; 3035 3036 int[] gids = null; 3037 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3038 if (!app.isolated) { 3039 int[] permGids = null; 3040 try { 3041 final PackageManager pm = mContext.getPackageManager(); 3042 permGids = pm.getPackageGids(app.info.packageName); 3043 3044 if (Environment.isExternalStorageEmulated()) { 3045 if (pm.checkPermission( 3046 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3047 app.info.packageName) == PERMISSION_GRANTED) { 3048 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3049 } else { 3050 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3051 } 3052 } 3053 } catch (PackageManager.NameNotFoundException e) { 3054 Slog.w(TAG, "Unable to retrieve gids", e); 3055 } 3056 3057 /* 3058 * Add shared application and profile GIDs so applications can share some 3059 * resources like shared libraries and access user-wide resources 3060 */ 3061 if (permGids == null) { 3062 gids = new int[2]; 3063 } else { 3064 gids = new int[permGids.length + 2]; 3065 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3066 } 3067 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3068 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3069 } 3070 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3071 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3072 && mTopComponent != null 3073 && app.processName.equals(mTopComponent.getPackageName())) { 3074 uid = 0; 3075 } 3076 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3077 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3078 uid = 0; 3079 } 3080 } 3081 int debugFlags = 0; 3082 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3083 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3084 // Also turn on CheckJNI for debuggable apps. It's quite 3085 // awkward to turn on otherwise. 3086 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3087 } 3088 // Run the app in safe mode if its manifest requests so or the 3089 // system is booted in safe mode. 3090 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3091 mSafeMode == true) { 3092 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3093 } 3094 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3095 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3096 } 3097 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3098 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3099 } 3100 if ("1".equals(SystemProperties.get("debug.assert"))) { 3101 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3102 } 3103 3104 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3105 if (requiredAbi == null) { 3106 requiredAbi = Build.SUPPORTED_ABIS[0]; 3107 } 3108 3109 // Start the process. It will either succeed and return a result containing 3110 // the PID of the new process, or else throw a RuntimeException. 3111 boolean isActivityProcess = (entryPoint == null); 3112 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3113 Process.ProcessStartResult startResult = Process.start(entryPoint, 3114 app.processName, uid, uid, gids, debugFlags, mountExternal, 3115 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3116 3117 if (app.isolated) { 3118 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3119 } 3120 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3121 3122 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3123 UserHandle.getUserId(uid), startResult.pid, uid, 3124 app.processName, hostingType, 3125 hostingNameStr != null ? hostingNameStr : ""); 3126 3127 if (app.persistent) { 3128 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3129 } 3130 3131 StringBuilder buf = mStringBuilder; 3132 buf.setLength(0); 3133 buf.append("Start proc "); 3134 buf.append(app.processName); 3135 if (!isActivityProcess) { 3136 buf.append(" ["); 3137 buf.append(entryPoint); 3138 buf.append("]"); 3139 } 3140 buf.append(" for "); 3141 buf.append(hostingType); 3142 if (hostingNameStr != null) { 3143 buf.append(" "); 3144 buf.append(hostingNameStr); 3145 } 3146 buf.append(": pid="); 3147 buf.append(startResult.pid); 3148 buf.append(" uid="); 3149 buf.append(uid); 3150 buf.append(" gids={"); 3151 if (gids != null) { 3152 for (int gi=0; gi<gids.length; gi++) { 3153 if (gi != 0) buf.append(", "); 3154 buf.append(gids[gi]); 3155 3156 } 3157 } 3158 buf.append("}"); 3159 if (requiredAbi != null) { 3160 buf.append(" abi="); 3161 buf.append(requiredAbi); 3162 } 3163 Slog.i(TAG, buf.toString()); 3164 app.setPid(startResult.pid); 3165 app.usingWrapper = startResult.usingWrapper; 3166 app.removed = false; 3167 app.killedByAm = false; 3168 synchronized (mPidsSelfLocked) { 3169 this.mPidsSelfLocked.put(startResult.pid, app); 3170 if (isActivityProcess) { 3171 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3172 msg.obj = app; 3173 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3174 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3175 } 3176 } 3177 } catch (RuntimeException e) { 3178 // XXX do better error recovery. 3179 app.setPid(0); 3180 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3181 if (app.isolated) { 3182 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3183 } 3184 Slog.e(TAG, "Failure starting process " + app.processName, e); 3185 } 3186 } 3187 3188 void updateUsageStats(ActivityRecord component, boolean resumed) { 3189 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3190 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3191 if (resumed) { 3192 if (mUsageStatsService != null) { 3193 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3194 System.currentTimeMillis(), 3195 UsageEvents.Event.MOVE_TO_FOREGROUND); 3196 } 3197 synchronized (stats) { 3198 stats.noteActivityResumedLocked(component.app.uid); 3199 } 3200 } else { 3201 if (mUsageStatsService != null) { 3202 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3203 System.currentTimeMillis(), 3204 UsageEvents.Event.MOVE_TO_BACKGROUND); 3205 } 3206 synchronized (stats) { 3207 stats.noteActivityPausedLocked(component.app.uid); 3208 } 3209 } 3210 } 3211 3212 Intent getHomeIntent() { 3213 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3214 intent.setComponent(mTopComponent); 3215 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3216 intent.addCategory(Intent.CATEGORY_HOME); 3217 } 3218 return intent; 3219 } 3220 3221 boolean startHomeActivityLocked(int userId) { 3222 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3223 && mTopAction == null) { 3224 // We are running in factory test mode, but unable to find 3225 // the factory test app, so just sit around displaying the 3226 // error message and don't try to start anything. 3227 return false; 3228 } 3229 Intent intent = getHomeIntent(); 3230 ActivityInfo aInfo = 3231 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3232 if (aInfo != null) { 3233 intent.setComponent(new ComponentName( 3234 aInfo.applicationInfo.packageName, aInfo.name)); 3235 // Don't do this if the home app is currently being 3236 // instrumented. 3237 aInfo = new ActivityInfo(aInfo); 3238 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3239 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3240 aInfo.applicationInfo.uid, true); 3241 if (app == null || app.instrumentationClass == null) { 3242 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3243 mStackSupervisor.startHomeActivity(intent, aInfo); 3244 } 3245 } 3246 3247 return true; 3248 } 3249 3250 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3251 ActivityInfo ai = null; 3252 ComponentName comp = intent.getComponent(); 3253 try { 3254 if (comp != null) { 3255 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3256 } else { 3257 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3258 intent, 3259 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3260 flags, userId); 3261 3262 if (info != null) { 3263 ai = info.activityInfo; 3264 } 3265 } 3266 } catch (RemoteException e) { 3267 // ignore 3268 } 3269 3270 return ai; 3271 } 3272 3273 /** 3274 * Starts the "new version setup screen" if appropriate. 3275 */ 3276 void startSetupActivityLocked() { 3277 // Only do this once per boot. 3278 if (mCheckedForSetup) { 3279 return; 3280 } 3281 3282 // We will show this screen if the current one is a different 3283 // version than the last one shown, and we are not running in 3284 // low-level factory test mode. 3285 final ContentResolver resolver = mContext.getContentResolver(); 3286 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3287 Settings.Global.getInt(resolver, 3288 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3289 mCheckedForSetup = true; 3290 3291 // See if we should be showing the platform update setup UI. 3292 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3293 List<ResolveInfo> ris = mContext.getPackageManager() 3294 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3295 3296 // We don't allow third party apps to replace this. 3297 ResolveInfo ri = null; 3298 for (int i=0; ris != null && i<ris.size(); i++) { 3299 if ((ris.get(i).activityInfo.applicationInfo.flags 3300 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3301 ri = ris.get(i); 3302 break; 3303 } 3304 } 3305 3306 if (ri != null) { 3307 String vers = ri.activityInfo.metaData != null 3308 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3309 : null; 3310 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3311 vers = ri.activityInfo.applicationInfo.metaData.getString( 3312 Intent.METADATA_SETUP_VERSION); 3313 } 3314 String lastVers = Settings.Secure.getString( 3315 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3316 if (vers != null && !vers.equals(lastVers)) { 3317 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3318 intent.setComponent(new ComponentName( 3319 ri.activityInfo.packageName, ri.activityInfo.name)); 3320 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3321 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3322 } 3323 } 3324 } 3325 } 3326 3327 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3328 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3329 } 3330 3331 void enforceNotIsolatedCaller(String caller) { 3332 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3333 throw new SecurityException("Isolated process not allowed to call " + caller); 3334 } 3335 } 3336 3337 @Override 3338 public int getFrontActivityScreenCompatMode() { 3339 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3340 synchronized (this) { 3341 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3342 } 3343 } 3344 3345 @Override 3346 public void setFrontActivityScreenCompatMode(int mode) { 3347 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3348 "setFrontActivityScreenCompatMode"); 3349 synchronized (this) { 3350 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3351 } 3352 } 3353 3354 @Override 3355 public int getPackageScreenCompatMode(String packageName) { 3356 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3357 synchronized (this) { 3358 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3359 } 3360 } 3361 3362 @Override 3363 public void setPackageScreenCompatMode(String packageName, int mode) { 3364 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3365 "setPackageScreenCompatMode"); 3366 synchronized (this) { 3367 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3368 } 3369 } 3370 3371 @Override 3372 public boolean getPackageAskScreenCompat(String packageName) { 3373 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3374 synchronized (this) { 3375 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3376 } 3377 } 3378 3379 @Override 3380 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3381 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3382 "setPackageAskScreenCompat"); 3383 synchronized (this) { 3384 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3385 } 3386 } 3387 3388 private void dispatchProcessesChanged() { 3389 int N; 3390 synchronized (this) { 3391 N = mPendingProcessChanges.size(); 3392 if (mActiveProcessChanges.length < N) { 3393 mActiveProcessChanges = new ProcessChangeItem[N]; 3394 } 3395 mPendingProcessChanges.toArray(mActiveProcessChanges); 3396 mAvailProcessChanges.addAll(mPendingProcessChanges); 3397 mPendingProcessChanges.clear(); 3398 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3399 } 3400 3401 int i = mProcessObservers.beginBroadcast(); 3402 while (i > 0) { 3403 i--; 3404 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3405 if (observer != null) { 3406 try { 3407 for (int j=0; j<N; j++) { 3408 ProcessChangeItem item = mActiveProcessChanges[j]; 3409 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3410 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3411 + item.pid + " uid=" + item.uid + ": " 3412 + item.foregroundActivities); 3413 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3414 item.foregroundActivities); 3415 } 3416 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3417 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3418 + item.pid + " uid=" + item.uid + ": " + item.processState); 3419 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3420 } 3421 } 3422 } catch (RemoteException e) { 3423 } 3424 } 3425 } 3426 mProcessObservers.finishBroadcast(); 3427 } 3428 3429 private void dispatchProcessDied(int pid, int uid) { 3430 int i = mProcessObservers.beginBroadcast(); 3431 while (i > 0) { 3432 i--; 3433 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3434 if (observer != null) { 3435 try { 3436 observer.onProcessDied(pid, uid); 3437 } catch (RemoteException e) { 3438 } 3439 } 3440 } 3441 mProcessObservers.finishBroadcast(); 3442 } 3443 3444 @Override 3445 public final int startActivity(IApplicationThread caller, String callingPackage, 3446 Intent intent, String resolvedType, IBinder resultTo, 3447 String resultWho, int requestCode, int startFlags, 3448 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3449 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3450 resultWho, requestCode, 3451 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3452 } 3453 3454 @Override 3455 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3456 Intent intent, String resolvedType, IBinder resultTo, 3457 String resultWho, int requestCode, int startFlags, 3458 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3459 enforceNotIsolatedCaller("startActivity"); 3460 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3461 false, ALLOW_FULL_ONLY, "startActivity", null); 3462 // TODO: Switch to user app stacks here. 3463 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3464 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3465 null, null, options, userId, null); 3466 } 3467 3468 @Override 3469 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3470 Intent intent, String resolvedType, IBinder resultTo, 3471 String resultWho, int requestCode, int startFlags, 3472 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3473 3474 // This is very dangerous -- it allows you to perform a start activity (including 3475 // permission grants) as any app that may launch one of your own activities. So 3476 // we will only allow this to be done from activities that are part of the core framework, 3477 // and then only when they are running as the system. 3478 final ActivityRecord sourceRecord; 3479 final int targetUid; 3480 final String targetPackage; 3481 synchronized (this) { 3482 if (resultTo == null) { 3483 throw new SecurityException("Must be called from an activity"); 3484 } 3485 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3486 if (sourceRecord == null) { 3487 throw new SecurityException("Called with bad activity token: " + resultTo); 3488 } 3489 if (!sourceRecord.info.packageName.equals("android")) { 3490 throw new SecurityException( 3491 "Must be called from an activity that is declared in the android package"); 3492 } 3493 if (sourceRecord.app == null) { 3494 throw new SecurityException("Called without a process attached to activity"); 3495 } 3496 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3497 // This is still okay, as long as this activity is running under the 3498 // uid of the original calling activity. 3499 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3500 throw new SecurityException( 3501 "Calling activity in uid " + sourceRecord.app.uid 3502 + " must be system uid or original calling uid " 3503 + sourceRecord.launchedFromUid); 3504 } 3505 } 3506 targetUid = sourceRecord.launchedFromUid; 3507 targetPackage = sourceRecord.launchedFromPackage; 3508 } 3509 3510 // TODO: Switch to user app stacks here. 3511 try { 3512 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3513 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3514 null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid), 3515 null); 3516 return ret; 3517 } catch (SecurityException e) { 3518 // XXX need to figure out how to propagate to original app. 3519 // A SecurityException here is generally actually a fault of the original 3520 // calling activity (such as a fairly granting permissions), so propagate it 3521 // back to them. 3522 /* 3523 StringBuilder msg = new StringBuilder(); 3524 msg.append("While launching"); 3525 msg.append(intent.toString()); 3526 msg.append(": "); 3527 msg.append(e.getMessage()); 3528 */ 3529 throw e; 3530 } 3531 } 3532 3533 @Override 3534 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3535 Intent intent, String resolvedType, IBinder resultTo, 3536 String resultWho, int requestCode, int startFlags, String profileFile, 3537 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3538 enforceNotIsolatedCaller("startActivityAndWait"); 3539 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3540 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3541 WaitResult res = new WaitResult(); 3542 // TODO: Switch to user app stacks here. 3543 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3544 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3545 res, null, options, userId, null); 3546 return res; 3547 } 3548 3549 @Override 3550 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3551 Intent intent, String resolvedType, IBinder resultTo, 3552 String resultWho, int requestCode, int startFlags, Configuration config, 3553 Bundle options, int userId) { 3554 enforceNotIsolatedCaller("startActivityWithConfig"); 3555 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3556 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3557 // TODO: Switch to user app stacks here. 3558 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3559 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3560 null, null, null, config, options, userId, null); 3561 return ret; 3562 } 3563 3564 @Override 3565 public int startActivityIntentSender(IApplicationThread caller, 3566 IntentSender intent, Intent fillInIntent, String resolvedType, 3567 IBinder resultTo, String resultWho, int requestCode, 3568 int flagsMask, int flagsValues, Bundle options) { 3569 enforceNotIsolatedCaller("startActivityIntentSender"); 3570 // Refuse possible leaked file descriptors 3571 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3572 throw new IllegalArgumentException("File descriptors passed in Intent"); 3573 } 3574 3575 IIntentSender sender = intent.getTarget(); 3576 if (!(sender instanceof PendingIntentRecord)) { 3577 throw new IllegalArgumentException("Bad PendingIntent object"); 3578 } 3579 3580 PendingIntentRecord pir = (PendingIntentRecord)sender; 3581 3582 synchronized (this) { 3583 // If this is coming from the currently resumed activity, it is 3584 // effectively saying that app switches are allowed at this point. 3585 final ActivityStack stack = getFocusedStack(); 3586 if (stack.mResumedActivity != null && 3587 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3588 mAppSwitchesAllowedTime = 0; 3589 } 3590 } 3591 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3592 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3593 return ret; 3594 } 3595 3596 @Override 3597 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3598 Intent intent, String resolvedType, IVoiceInteractionSession session, 3599 IVoiceInteractor interactor, int startFlags, String profileFile, 3600 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3601 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3602 != PackageManager.PERMISSION_GRANTED) { 3603 String msg = "Permission Denial: startVoiceActivity() from pid=" 3604 + Binder.getCallingPid() 3605 + ", uid=" + Binder.getCallingUid() 3606 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3607 Slog.w(TAG, msg); 3608 throw new SecurityException(msg); 3609 } 3610 if (session == null || interactor == null) { 3611 throw new NullPointerException("null session or interactor"); 3612 } 3613 userId = handleIncomingUser(callingPid, callingUid, userId, 3614 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3615 // TODO: Switch to user app stacks here. 3616 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3617 resolvedType, session, interactor, null, null, 0, startFlags, 3618 profileFile, profileFd, null, null, options, userId, null); 3619 } 3620 3621 @Override 3622 public boolean startNextMatchingActivity(IBinder callingActivity, 3623 Intent intent, Bundle options) { 3624 // Refuse possible leaked file descriptors 3625 if (intent != null && intent.hasFileDescriptors() == true) { 3626 throw new IllegalArgumentException("File descriptors passed in Intent"); 3627 } 3628 3629 synchronized (this) { 3630 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3631 if (r == null) { 3632 ActivityOptions.abort(options); 3633 return false; 3634 } 3635 if (r.app == null || r.app.thread == null) { 3636 // The caller is not running... d'oh! 3637 ActivityOptions.abort(options); 3638 return false; 3639 } 3640 intent = new Intent(intent); 3641 // The caller is not allowed to change the data. 3642 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3643 // And we are resetting to find the next component... 3644 intent.setComponent(null); 3645 3646 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3647 3648 ActivityInfo aInfo = null; 3649 try { 3650 List<ResolveInfo> resolves = 3651 AppGlobals.getPackageManager().queryIntentActivities( 3652 intent, r.resolvedType, 3653 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3654 UserHandle.getCallingUserId()); 3655 3656 // Look for the original activity in the list... 3657 final int N = resolves != null ? resolves.size() : 0; 3658 for (int i=0; i<N; i++) { 3659 ResolveInfo rInfo = resolves.get(i); 3660 if (rInfo.activityInfo.packageName.equals(r.packageName) 3661 && rInfo.activityInfo.name.equals(r.info.name)) { 3662 // We found the current one... the next matching is 3663 // after it. 3664 i++; 3665 if (i<N) { 3666 aInfo = resolves.get(i).activityInfo; 3667 } 3668 if (debug) { 3669 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3670 + "/" + r.info.name); 3671 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3672 + "/" + aInfo.name); 3673 } 3674 break; 3675 } 3676 } 3677 } catch (RemoteException e) { 3678 } 3679 3680 if (aInfo == null) { 3681 // Nobody who is next! 3682 ActivityOptions.abort(options); 3683 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3684 return false; 3685 } 3686 3687 intent.setComponent(new ComponentName( 3688 aInfo.applicationInfo.packageName, aInfo.name)); 3689 intent.setFlags(intent.getFlags()&~( 3690 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3691 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3692 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3693 Intent.FLAG_ACTIVITY_NEW_TASK)); 3694 3695 // Okay now we need to start the new activity, replacing the 3696 // currently running activity. This is a little tricky because 3697 // we want to start the new one as if the current one is finished, 3698 // but not finish the current one first so that there is no flicker. 3699 // And thus... 3700 final boolean wasFinishing = r.finishing; 3701 r.finishing = true; 3702 3703 // Propagate reply information over to the new activity. 3704 final ActivityRecord resultTo = r.resultTo; 3705 final String resultWho = r.resultWho; 3706 final int requestCode = r.requestCode; 3707 r.resultTo = null; 3708 if (resultTo != null) { 3709 resultTo.removeResultsLocked(r, resultWho, requestCode); 3710 } 3711 3712 final long origId = Binder.clearCallingIdentity(); 3713 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3714 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3715 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3716 options, false, null, null); 3717 Binder.restoreCallingIdentity(origId); 3718 3719 r.finishing = wasFinishing; 3720 if (res != ActivityManager.START_SUCCESS) { 3721 return false; 3722 } 3723 return true; 3724 } 3725 } 3726 3727 @Override 3728 public final int startActivityFromRecents(int taskId, Bundle options) { 3729 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3730 String msg = "Permission Denial: startActivityFromRecents called without " + 3731 START_TASKS_FROM_RECENTS; 3732 Slog.w(TAG, msg); 3733 throw new SecurityException(msg); 3734 } 3735 final int callingUid; 3736 final String callingPackage; 3737 final Intent intent; 3738 final int userId; 3739 synchronized (this) { 3740 final TaskRecord task = recentTaskForIdLocked(taskId); 3741 if (task == null) { 3742 throw new ActivityNotFoundException("Task " + taskId + " not found."); 3743 } 3744 callingUid = task.mCallingUid; 3745 callingPackage = task.mCallingPackage; 3746 intent = task.intent; 3747 userId = task.userId; 3748 } 3749 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3750 options, userId, null); 3751 } 3752 3753 final int startActivityInPackage(int uid, String callingPackage, 3754 Intent intent, String resolvedType, IBinder resultTo, 3755 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3756 IActivityContainer container) { 3757 3758 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3759 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3760 3761 // TODO: Switch to user app stacks here. 3762 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3763 null, null, resultTo, resultWho, requestCode, startFlags, 3764 null, null, null, null, options, userId, container); 3765 return ret; 3766 } 3767 3768 @Override 3769 public final int startActivities(IApplicationThread caller, String callingPackage, 3770 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3771 int userId) { 3772 enforceNotIsolatedCaller("startActivities"); 3773 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3774 false, ALLOW_FULL_ONLY, "startActivity", null); 3775 // TODO: Switch to user app stacks here. 3776 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3777 resolvedTypes, resultTo, options, userId); 3778 return ret; 3779 } 3780 3781 final int startActivitiesInPackage(int uid, String callingPackage, 3782 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3783 Bundle options, int userId) { 3784 3785 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3786 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3787 // TODO: Switch to user app stacks here. 3788 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3789 resultTo, options, userId); 3790 return ret; 3791 } 3792 3793 //explicitly remove thd old information in mRecentTasks when removing existing user. 3794 private void removeRecentTasksForUserLocked(int userId) { 3795 if(userId <= 0) { 3796 Slog.i(TAG, "Can't remove recent task on user " + userId); 3797 return; 3798 } 3799 3800 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3801 TaskRecord tr = mRecentTasks.get(i); 3802 if (tr.userId == userId) { 3803 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3804 + " when finishing user" + userId); 3805 tr.disposeThumbnail(); 3806 mRecentTasks.remove(i); 3807 } 3808 } 3809 3810 // Remove tasks from persistent storage. 3811 mTaskPersister.wakeup(null, true); 3812 } 3813 3814 final void addRecentTaskLocked(TaskRecord task) { 3815 final int N = mRecentTasks.size(); 3816 // Quick case: check if the top-most recent task is the same. 3817 if (N > 0 && mRecentTasks.get(0) == task) { 3818 return; 3819 } 3820 // Another quick case: never add voice sessions. 3821 if (task.voiceSession != null) { 3822 return; 3823 } 3824 3825 trimRecentsForTask(task, true); 3826 3827 if (N >= MAX_RECENT_TASKS) { 3828 final TaskRecord tr = mRecentTasks.remove(N - 1); 3829 tr.disposeThumbnail(); 3830 tr.closeRecentsChain(); 3831 } 3832 mRecentTasks.add(0, task); 3833 } 3834 3835 /** 3836 * If needed, remove oldest existing entries in recents that are for the same kind 3837 * of task as the given one. 3838 */ 3839 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 3840 int N = mRecentTasks.size(); 3841 final Intent intent = task.intent; 3842 final boolean document = intent != null && intent.isDocument(); 3843 3844 int maxRecents = task.maxRecents - 1; 3845 for (int i=0; i<N; i++) { 3846 final TaskRecord tr = mRecentTasks.get(i); 3847 if (task != tr) { 3848 if (task.userId != tr.userId) { 3849 continue; 3850 } 3851 if (i > MAX_RECENT_BITMAPS) { 3852 tr.freeLastThumbnail(); 3853 } 3854 final Intent trIntent = tr.intent; 3855 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3856 (intent == null || !intent.filterEquals(trIntent))) { 3857 continue; 3858 } 3859 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3860 if (document && trIsDocument) { 3861 // These are the same document activity (not necessarily the same doc). 3862 if (maxRecents > 0) { 3863 --maxRecents; 3864 continue; 3865 } 3866 // Hit the maximum number of documents for this task. Fall through 3867 // and remove this document from recents. 3868 } else if (document || trIsDocument) { 3869 // Only one of these is a document. Not the droid we're looking for. 3870 continue; 3871 } 3872 } 3873 3874 if (!doTrim) { 3875 // If the caller is not actually asking for a trim, just tell them we reached 3876 // a point where the trim would happen. 3877 return i; 3878 } 3879 3880 // Either task and tr are the same or, their affinities match or their intents match 3881 // and neither of them is a document, or they are documents using the same activity 3882 // and their maxRecents has been reached. 3883 tr.disposeThumbnail(); 3884 mRecentTasks.remove(i); 3885 if (task != tr) { 3886 tr.closeRecentsChain(); 3887 } 3888 i--; 3889 N--; 3890 if (task.intent == null) { 3891 // If the new recent task we are adding is not fully 3892 // specified, then replace it with the existing recent task. 3893 task = tr; 3894 } 3895 notifyTaskPersisterLocked(tr, false); 3896 } 3897 3898 return -1; 3899 } 3900 3901 @Override 3902 public void reportActivityFullyDrawn(IBinder token) { 3903 synchronized (this) { 3904 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3905 if (r == null) { 3906 return; 3907 } 3908 r.reportFullyDrawnLocked(); 3909 } 3910 } 3911 3912 @Override 3913 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3914 synchronized (this) { 3915 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3916 if (r == null) { 3917 return; 3918 } 3919 final long origId = Binder.clearCallingIdentity(); 3920 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3921 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3922 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3923 if (config != null) { 3924 r.frozenBeforeDestroy = true; 3925 if (!updateConfigurationLocked(config, r, false, false)) { 3926 mStackSupervisor.resumeTopActivitiesLocked(); 3927 } 3928 } 3929 Binder.restoreCallingIdentity(origId); 3930 } 3931 } 3932 3933 @Override 3934 public int getRequestedOrientation(IBinder token) { 3935 synchronized (this) { 3936 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3937 if (r == null) { 3938 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3939 } 3940 return mWindowManager.getAppOrientation(r.appToken); 3941 } 3942 } 3943 3944 /** 3945 * This is the internal entry point for handling Activity.finish(). 3946 * 3947 * @param token The Binder token referencing the Activity we want to finish. 3948 * @param resultCode Result code, if any, from this Activity. 3949 * @param resultData Result data (Intent), if any, from this Activity. 3950 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3951 * the root Activity in the task. 3952 * 3953 * @return Returns true if the activity successfully finished, or false if it is still running. 3954 */ 3955 @Override 3956 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3957 boolean finishTask) { 3958 // Refuse possible leaked file descriptors 3959 if (resultData != null && resultData.hasFileDescriptors() == true) { 3960 throw new IllegalArgumentException("File descriptors passed in Intent"); 3961 } 3962 3963 synchronized(this) { 3964 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3965 if (r == null) { 3966 return true; 3967 } 3968 // Keep track of the root activity of the task before we finish it 3969 TaskRecord tr = r.task; 3970 ActivityRecord rootR = tr.getRootActivity(); 3971 // Do not allow task to finish in Lock Task mode. 3972 if (tr == mStackSupervisor.mLockTaskModeTask) { 3973 if (rootR == r) { 3974 mStackSupervisor.showLockTaskToast(); 3975 return false; 3976 } 3977 } 3978 if (mController != null) { 3979 // Find the first activity that is not finishing. 3980 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3981 if (next != null) { 3982 // ask watcher if this is allowed 3983 boolean resumeOK = true; 3984 try { 3985 resumeOK = mController.activityResuming(next.packageName); 3986 } catch (RemoteException e) { 3987 mController = null; 3988 Watchdog.getInstance().setActivityController(null); 3989 } 3990 3991 if (!resumeOK) { 3992 return false; 3993 } 3994 } 3995 } 3996 final long origId = Binder.clearCallingIdentity(); 3997 try { 3998 boolean res; 3999 if (finishTask && r == rootR) { 4000 // If requested, remove the task that is associated to this activity only if it 4001 // was the root activity in the task. The result code and data is ignored because 4002 // we don't support returning them across task boundaries. 4003 res = removeTaskByIdLocked(tr.taskId, 0); 4004 } else { 4005 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4006 resultData, "app-request", true); 4007 } 4008 return res; 4009 } finally { 4010 Binder.restoreCallingIdentity(origId); 4011 } 4012 } 4013 } 4014 4015 @Override 4016 public final void finishHeavyWeightApp() { 4017 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4018 != PackageManager.PERMISSION_GRANTED) { 4019 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4020 + Binder.getCallingPid() 4021 + ", uid=" + Binder.getCallingUid() 4022 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4023 Slog.w(TAG, msg); 4024 throw new SecurityException(msg); 4025 } 4026 4027 synchronized(this) { 4028 if (mHeavyWeightProcess == null) { 4029 return; 4030 } 4031 4032 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4033 mHeavyWeightProcess.activities); 4034 for (int i=0; i<activities.size(); i++) { 4035 ActivityRecord r = activities.get(i); 4036 if (!r.finishing) { 4037 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4038 null, "finish-heavy", true); 4039 } 4040 } 4041 4042 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4043 mHeavyWeightProcess.userId, 0)); 4044 mHeavyWeightProcess = null; 4045 } 4046 } 4047 4048 @Override 4049 public void crashApplication(int uid, int initialPid, String packageName, 4050 String message) { 4051 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4052 != PackageManager.PERMISSION_GRANTED) { 4053 String msg = "Permission Denial: crashApplication() from pid=" 4054 + Binder.getCallingPid() 4055 + ", uid=" + Binder.getCallingUid() 4056 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4057 Slog.w(TAG, msg); 4058 throw new SecurityException(msg); 4059 } 4060 4061 synchronized(this) { 4062 ProcessRecord proc = null; 4063 4064 // Figure out which process to kill. We don't trust that initialPid 4065 // still has any relation to current pids, so must scan through the 4066 // list. 4067 synchronized (mPidsSelfLocked) { 4068 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4069 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4070 if (p.uid != uid) { 4071 continue; 4072 } 4073 if (p.pid == initialPid) { 4074 proc = p; 4075 break; 4076 } 4077 if (p.pkgList.containsKey(packageName)) { 4078 proc = p; 4079 } 4080 } 4081 } 4082 4083 if (proc == null) { 4084 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4085 + " initialPid=" + initialPid 4086 + " packageName=" + packageName); 4087 return; 4088 } 4089 4090 if (proc.thread != null) { 4091 if (proc.pid == Process.myPid()) { 4092 Log.w(TAG, "crashApplication: trying to crash self!"); 4093 return; 4094 } 4095 long ident = Binder.clearCallingIdentity(); 4096 try { 4097 proc.thread.scheduleCrash(message); 4098 } catch (RemoteException e) { 4099 } 4100 Binder.restoreCallingIdentity(ident); 4101 } 4102 } 4103 } 4104 4105 @Override 4106 public final void finishSubActivity(IBinder token, String resultWho, 4107 int requestCode) { 4108 synchronized(this) { 4109 final long origId = Binder.clearCallingIdentity(); 4110 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4111 if (r != null) { 4112 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4113 } 4114 Binder.restoreCallingIdentity(origId); 4115 } 4116 } 4117 4118 @Override 4119 public boolean finishActivityAffinity(IBinder token) { 4120 synchronized(this) { 4121 final long origId = Binder.clearCallingIdentity(); 4122 try { 4123 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4124 4125 ActivityRecord rootR = r.task.getRootActivity(); 4126 // Do not allow task to finish in Lock Task mode. 4127 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4128 if (rootR == r) { 4129 mStackSupervisor.showLockTaskToast(); 4130 return false; 4131 } 4132 } 4133 boolean res = false; 4134 if (r != null) { 4135 res = r.task.stack.finishActivityAffinityLocked(r); 4136 } 4137 return res; 4138 } finally { 4139 Binder.restoreCallingIdentity(origId); 4140 } 4141 } 4142 } 4143 4144 @Override 4145 public void finishVoiceTask(IVoiceInteractionSession session) { 4146 synchronized(this) { 4147 final long origId = Binder.clearCallingIdentity(); 4148 try { 4149 mStackSupervisor.finishVoiceTask(session); 4150 } finally { 4151 Binder.restoreCallingIdentity(origId); 4152 } 4153 } 4154 4155 } 4156 4157 @Override 4158 public boolean willActivityBeVisible(IBinder token) { 4159 synchronized(this) { 4160 ActivityStack stack = ActivityRecord.getStackLocked(token); 4161 if (stack != null) { 4162 return stack.willActivityBeVisibleLocked(token); 4163 } 4164 return false; 4165 } 4166 } 4167 4168 @Override 4169 public void overridePendingTransition(IBinder token, String packageName, 4170 int enterAnim, int exitAnim) { 4171 synchronized(this) { 4172 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4173 if (self == null) { 4174 return; 4175 } 4176 4177 final long origId = Binder.clearCallingIdentity(); 4178 4179 if (self.state == ActivityState.RESUMED 4180 || self.state == ActivityState.PAUSING) { 4181 mWindowManager.overridePendingAppTransition(packageName, 4182 enterAnim, exitAnim, null); 4183 } 4184 4185 Binder.restoreCallingIdentity(origId); 4186 } 4187 } 4188 4189 /** 4190 * Main function for removing an existing process from the activity manager 4191 * as a result of that process going away. Clears out all connections 4192 * to the process. 4193 */ 4194 private final void handleAppDiedLocked(ProcessRecord app, 4195 boolean restarting, boolean allowRestart) { 4196 int pid = app.pid; 4197 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4198 if (!restarting) { 4199 removeLruProcessLocked(app); 4200 if (pid > 0) { 4201 ProcessList.remove(pid); 4202 } 4203 } 4204 4205 if (mProfileProc == app) { 4206 clearProfilerLocked(); 4207 } 4208 4209 // Remove this application's activities from active lists. 4210 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4211 4212 app.activities.clear(); 4213 4214 if (app.instrumentationClass != null) { 4215 Slog.w(TAG, "Crash of app " + app.processName 4216 + " running instrumentation " + app.instrumentationClass); 4217 Bundle info = new Bundle(); 4218 info.putString("shortMsg", "Process crashed."); 4219 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4220 } 4221 4222 if (!restarting) { 4223 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4224 // If there was nothing to resume, and we are not already 4225 // restarting this process, but there is a visible activity that 4226 // is hosted by the process... then make sure all visible 4227 // activities are running, taking care of restarting this 4228 // process. 4229 if (hasVisibleActivities) { 4230 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4231 } 4232 } 4233 } 4234 } 4235 4236 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4237 IBinder threadBinder = thread.asBinder(); 4238 // Find the application record. 4239 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4240 ProcessRecord rec = mLruProcesses.get(i); 4241 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4242 return i; 4243 } 4244 } 4245 return -1; 4246 } 4247 4248 final ProcessRecord getRecordForAppLocked( 4249 IApplicationThread thread) { 4250 if (thread == null) { 4251 return null; 4252 } 4253 4254 int appIndex = getLRURecordIndexForAppLocked(thread); 4255 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4256 } 4257 4258 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4259 // If there are no longer any background processes running, 4260 // and the app that died was not running instrumentation, 4261 // then tell everyone we are now low on memory. 4262 boolean haveBg = false; 4263 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4264 ProcessRecord rec = mLruProcesses.get(i); 4265 if (rec.thread != null 4266 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4267 haveBg = true; 4268 break; 4269 } 4270 } 4271 4272 if (!haveBg) { 4273 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4274 if (doReport) { 4275 long now = SystemClock.uptimeMillis(); 4276 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4277 doReport = false; 4278 } else { 4279 mLastMemUsageReportTime = now; 4280 } 4281 } 4282 final ArrayList<ProcessMemInfo> memInfos 4283 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4284 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4285 long now = SystemClock.uptimeMillis(); 4286 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4287 ProcessRecord rec = mLruProcesses.get(i); 4288 if (rec == dyingProc || rec.thread == null) { 4289 continue; 4290 } 4291 if (doReport) { 4292 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4293 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4294 } 4295 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4296 // The low memory report is overriding any current 4297 // state for a GC request. Make sure to do 4298 // heavy/important/visible/foreground processes first. 4299 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4300 rec.lastRequestedGc = 0; 4301 } else { 4302 rec.lastRequestedGc = rec.lastLowMemory; 4303 } 4304 rec.reportLowMemory = true; 4305 rec.lastLowMemory = now; 4306 mProcessesToGc.remove(rec); 4307 addProcessToGcListLocked(rec); 4308 } 4309 } 4310 if (doReport) { 4311 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4312 mHandler.sendMessage(msg); 4313 } 4314 scheduleAppGcsLocked(); 4315 } 4316 } 4317 4318 final void appDiedLocked(ProcessRecord app) { 4319 appDiedLocked(app, app.pid, app.thread); 4320 } 4321 4322 final void appDiedLocked(ProcessRecord app, int pid, 4323 IApplicationThread thread) { 4324 4325 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4326 synchronized (stats) { 4327 stats.noteProcessDiedLocked(app.info.uid, pid); 4328 } 4329 4330 Process.killProcessGroup(app.info.uid, pid); 4331 4332 // Clean up already done if the process has been re-started. 4333 if (app.pid == pid && app.thread != null && 4334 app.thread.asBinder() == thread.asBinder()) { 4335 boolean doLowMem = app.instrumentationClass == null; 4336 boolean doOomAdj = doLowMem; 4337 if (!app.killedByAm) { 4338 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4339 + ") has died."); 4340 mAllowLowerMemLevel = true; 4341 } else { 4342 // Note that we always want to do oom adj to update our state with the 4343 // new number of procs. 4344 mAllowLowerMemLevel = false; 4345 doLowMem = false; 4346 } 4347 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4348 if (DEBUG_CLEANUP) Slog.v( 4349 TAG, "Dying app: " + app + ", pid: " + pid 4350 + ", thread: " + thread.asBinder()); 4351 handleAppDiedLocked(app, false, true); 4352 4353 if (doOomAdj) { 4354 updateOomAdjLocked(); 4355 } 4356 if (doLowMem) { 4357 doLowMemReportIfNeededLocked(app); 4358 } 4359 } else if (app.pid != pid) { 4360 // A new process has already been started. 4361 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4362 + ") has died and restarted (pid " + app.pid + ")."); 4363 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4364 } else if (DEBUG_PROCESSES) { 4365 Slog.d(TAG, "Received spurious death notification for thread " 4366 + thread.asBinder()); 4367 } 4368 } 4369 4370 /** 4371 * If a stack trace dump file is configured, dump process stack traces. 4372 * @param clearTraces causes the dump file to be erased prior to the new 4373 * traces being written, if true; when false, the new traces will be 4374 * appended to any existing file content. 4375 * @param firstPids of dalvik VM processes to dump stack traces for first 4376 * @param lastPids of dalvik VM processes to dump stack traces for last 4377 * @param nativeProcs optional list of native process names to dump stack crawls 4378 * @return file containing stack traces, or null if no dump file is configured 4379 */ 4380 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4381 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4382 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4383 if (tracesPath == null || tracesPath.length() == 0) { 4384 return null; 4385 } 4386 4387 File tracesFile = new File(tracesPath); 4388 try { 4389 File tracesDir = tracesFile.getParentFile(); 4390 if (!tracesDir.exists()) { 4391 tracesFile.mkdirs(); 4392 if (!SELinux.restorecon(tracesDir)) { 4393 return null; 4394 } 4395 } 4396 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4397 4398 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4399 tracesFile.createNewFile(); 4400 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4401 } catch (IOException e) { 4402 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4403 return null; 4404 } 4405 4406 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4407 return tracesFile; 4408 } 4409 4410 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4411 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4412 // Use a FileObserver to detect when traces finish writing. 4413 // The order of traces is considered important to maintain for legibility. 4414 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4415 @Override 4416 public synchronized void onEvent(int event, String path) { notify(); } 4417 }; 4418 4419 try { 4420 observer.startWatching(); 4421 4422 // First collect all of the stacks of the most important pids. 4423 if (firstPids != null) { 4424 try { 4425 int num = firstPids.size(); 4426 for (int i = 0; i < num; i++) { 4427 synchronized (observer) { 4428 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4429 observer.wait(200); // Wait for write-close, give up after 200msec 4430 } 4431 } 4432 } catch (InterruptedException e) { 4433 Log.wtf(TAG, e); 4434 } 4435 } 4436 4437 // Next collect the stacks of the native pids 4438 if (nativeProcs != null) { 4439 int[] pids = Process.getPidsForCommands(nativeProcs); 4440 if (pids != null) { 4441 for (int pid : pids) { 4442 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4443 } 4444 } 4445 } 4446 4447 // Lastly, measure CPU usage. 4448 if (processCpuTracker != null) { 4449 processCpuTracker.init(); 4450 System.gc(); 4451 processCpuTracker.update(); 4452 try { 4453 synchronized (processCpuTracker) { 4454 processCpuTracker.wait(500); // measure over 1/2 second. 4455 } 4456 } catch (InterruptedException e) { 4457 } 4458 processCpuTracker.update(); 4459 4460 // We'll take the stack crawls of just the top apps using CPU. 4461 final int N = processCpuTracker.countWorkingStats(); 4462 int numProcs = 0; 4463 for (int i=0; i<N && numProcs<5; i++) { 4464 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4465 if (lastPids.indexOfKey(stats.pid) >= 0) { 4466 numProcs++; 4467 try { 4468 synchronized (observer) { 4469 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4470 observer.wait(200); // Wait for write-close, give up after 200msec 4471 } 4472 } catch (InterruptedException e) { 4473 Log.wtf(TAG, e); 4474 } 4475 4476 } 4477 } 4478 } 4479 } finally { 4480 observer.stopWatching(); 4481 } 4482 } 4483 4484 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4485 if (true || IS_USER_BUILD) { 4486 return; 4487 } 4488 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4489 if (tracesPath == null || tracesPath.length() == 0) { 4490 return; 4491 } 4492 4493 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4494 StrictMode.allowThreadDiskWrites(); 4495 try { 4496 final File tracesFile = new File(tracesPath); 4497 final File tracesDir = tracesFile.getParentFile(); 4498 final File tracesTmp = new File(tracesDir, "__tmp__"); 4499 try { 4500 if (!tracesDir.exists()) { 4501 tracesFile.mkdirs(); 4502 if (!SELinux.restorecon(tracesDir.getPath())) { 4503 return; 4504 } 4505 } 4506 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4507 4508 if (tracesFile.exists()) { 4509 tracesTmp.delete(); 4510 tracesFile.renameTo(tracesTmp); 4511 } 4512 StringBuilder sb = new StringBuilder(); 4513 Time tobj = new Time(); 4514 tobj.set(System.currentTimeMillis()); 4515 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4516 sb.append(": "); 4517 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4518 sb.append(" since "); 4519 sb.append(msg); 4520 FileOutputStream fos = new FileOutputStream(tracesFile); 4521 fos.write(sb.toString().getBytes()); 4522 if (app == null) { 4523 fos.write("\n*** No application process!".getBytes()); 4524 } 4525 fos.close(); 4526 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4527 } catch (IOException e) { 4528 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4529 return; 4530 } 4531 4532 if (app != null) { 4533 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4534 firstPids.add(app.pid); 4535 dumpStackTraces(tracesPath, firstPids, null, null, null); 4536 } 4537 4538 File lastTracesFile = null; 4539 File curTracesFile = null; 4540 for (int i=9; i>=0; i--) { 4541 String name = String.format(Locale.US, "slow%02d.txt", i); 4542 curTracesFile = new File(tracesDir, name); 4543 if (curTracesFile.exists()) { 4544 if (lastTracesFile != null) { 4545 curTracesFile.renameTo(lastTracesFile); 4546 } else { 4547 curTracesFile.delete(); 4548 } 4549 } 4550 lastTracesFile = curTracesFile; 4551 } 4552 tracesFile.renameTo(curTracesFile); 4553 if (tracesTmp.exists()) { 4554 tracesTmp.renameTo(tracesFile); 4555 } 4556 } finally { 4557 StrictMode.setThreadPolicy(oldPolicy); 4558 } 4559 } 4560 4561 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4562 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4563 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4564 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4565 4566 if (mController != null) { 4567 try { 4568 // 0 == continue, -1 = kill process immediately 4569 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4570 if (res < 0 && app.pid != MY_PID) { 4571 Process.killProcess(app.pid); 4572 Process.killProcessGroup(app.info.uid, app.pid); 4573 } 4574 } catch (RemoteException e) { 4575 mController = null; 4576 Watchdog.getInstance().setActivityController(null); 4577 } 4578 } 4579 4580 long anrTime = SystemClock.uptimeMillis(); 4581 if (MONITOR_CPU_USAGE) { 4582 updateCpuStatsNow(); 4583 } 4584 4585 synchronized (this) { 4586 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4587 if (mShuttingDown) { 4588 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4589 return; 4590 } else if (app.notResponding) { 4591 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4592 return; 4593 } else if (app.crashing) { 4594 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4595 return; 4596 } 4597 4598 // In case we come through here for the same app before completing 4599 // this one, mark as anring now so we will bail out. 4600 app.notResponding = true; 4601 4602 // Log the ANR to the event log. 4603 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4604 app.processName, app.info.flags, annotation); 4605 4606 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4607 firstPids.add(app.pid); 4608 4609 int parentPid = app.pid; 4610 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4611 if (parentPid != app.pid) firstPids.add(parentPid); 4612 4613 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4614 4615 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4616 ProcessRecord r = mLruProcesses.get(i); 4617 if (r != null && r.thread != null) { 4618 int pid = r.pid; 4619 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4620 if (r.persistent) { 4621 firstPids.add(pid); 4622 } else { 4623 lastPids.put(pid, Boolean.TRUE); 4624 } 4625 } 4626 } 4627 } 4628 } 4629 4630 // Log the ANR to the main log. 4631 StringBuilder info = new StringBuilder(); 4632 info.setLength(0); 4633 info.append("ANR in ").append(app.processName); 4634 if (activity != null && activity.shortComponentName != null) { 4635 info.append(" (").append(activity.shortComponentName).append(")"); 4636 } 4637 info.append("\n"); 4638 info.append("PID: ").append(app.pid).append("\n"); 4639 if (annotation != null) { 4640 info.append("Reason: ").append(annotation).append("\n"); 4641 } 4642 if (parent != null && parent != activity) { 4643 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4644 } 4645 4646 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4647 4648 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4649 NATIVE_STACKS_OF_INTEREST); 4650 4651 String cpuInfo = null; 4652 if (MONITOR_CPU_USAGE) { 4653 updateCpuStatsNow(); 4654 synchronized (mProcessCpuThread) { 4655 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4656 } 4657 info.append(processCpuTracker.printCurrentLoad()); 4658 info.append(cpuInfo); 4659 } 4660 4661 info.append(processCpuTracker.printCurrentState(anrTime)); 4662 4663 Slog.e(TAG, info.toString()); 4664 if (tracesFile == null) { 4665 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4666 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4667 } 4668 4669 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4670 cpuInfo, tracesFile, null); 4671 4672 if (mController != null) { 4673 try { 4674 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4675 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4676 if (res != 0) { 4677 if (res < 0 && app.pid != MY_PID) { 4678 Process.killProcess(app.pid); 4679 Process.killProcessGroup(app.info.uid, app.pid); 4680 } else { 4681 synchronized (this) { 4682 mServices.scheduleServiceTimeoutLocked(app); 4683 } 4684 } 4685 return; 4686 } 4687 } catch (RemoteException e) { 4688 mController = null; 4689 Watchdog.getInstance().setActivityController(null); 4690 } 4691 } 4692 4693 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4694 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4695 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4696 4697 synchronized (this) { 4698 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4699 killUnneededProcessLocked(app, "background ANR"); 4700 return; 4701 } 4702 4703 // Set the app's notResponding state, and look up the errorReportReceiver 4704 makeAppNotRespondingLocked(app, 4705 activity != null ? activity.shortComponentName : null, 4706 annotation != null ? "ANR " + annotation : "ANR", 4707 info.toString()); 4708 4709 // Bring up the infamous App Not Responding dialog 4710 Message msg = Message.obtain(); 4711 HashMap<String, Object> map = new HashMap<String, Object>(); 4712 msg.what = SHOW_NOT_RESPONDING_MSG; 4713 msg.obj = map; 4714 msg.arg1 = aboveSystem ? 1 : 0; 4715 map.put("app", app); 4716 if (activity != null) { 4717 map.put("activity", activity); 4718 } 4719 4720 mHandler.sendMessage(msg); 4721 } 4722 } 4723 4724 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4725 if (!mLaunchWarningShown) { 4726 mLaunchWarningShown = true; 4727 mHandler.post(new Runnable() { 4728 @Override 4729 public void run() { 4730 synchronized (ActivityManagerService.this) { 4731 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4732 d.show(); 4733 mHandler.postDelayed(new Runnable() { 4734 @Override 4735 public void run() { 4736 synchronized (ActivityManagerService.this) { 4737 d.dismiss(); 4738 mLaunchWarningShown = false; 4739 } 4740 } 4741 }, 4000); 4742 } 4743 } 4744 }); 4745 } 4746 } 4747 4748 @Override 4749 public boolean clearApplicationUserData(final String packageName, 4750 final IPackageDataObserver observer, int userId) { 4751 enforceNotIsolatedCaller("clearApplicationUserData"); 4752 int uid = Binder.getCallingUid(); 4753 int pid = Binder.getCallingPid(); 4754 userId = handleIncomingUser(pid, uid, 4755 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4756 long callingId = Binder.clearCallingIdentity(); 4757 try { 4758 IPackageManager pm = AppGlobals.getPackageManager(); 4759 int pkgUid = -1; 4760 synchronized(this) { 4761 try { 4762 pkgUid = pm.getPackageUid(packageName, userId); 4763 } catch (RemoteException e) { 4764 } 4765 if (pkgUid == -1) { 4766 Slog.w(TAG, "Invalid packageName: " + packageName); 4767 if (observer != null) { 4768 try { 4769 observer.onRemoveCompleted(packageName, false); 4770 } catch (RemoteException e) { 4771 Slog.i(TAG, "Observer no longer exists."); 4772 } 4773 } 4774 return false; 4775 } 4776 if (uid == pkgUid || checkComponentPermission( 4777 android.Manifest.permission.CLEAR_APP_USER_DATA, 4778 pid, uid, -1, true) 4779 == PackageManager.PERMISSION_GRANTED) { 4780 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4781 } else { 4782 throw new SecurityException("PID " + pid + " does not have permission " 4783 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4784 + " of package " + packageName); 4785 } 4786 4787 // Remove all tasks match the cleared application package and user 4788 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 4789 final TaskRecord tr = mRecentTasks.get(i); 4790 final String taskPackageName = 4791 tr.getBaseIntent().getComponent().getPackageName(); 4792 if (tr.userId != userId) continue; 4793 if (!taskPackageName.equals(packageName)) continue; 4794 removeTaskByIdLocked(tr.taskId, 0); 4795 } 4796 } 4797 4798 try { 4799 // Clear application user data 4800 pm.clearApplicationUserData(packageName, observer, userId); 4801 4802 synchronized(this) { 4803 // Remove all permissions granted from/to this package 4804 removeUriPermissionsForPackageLocked(packageName, userId, true); 4805 } 4806 4807 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4808 Uri.fromParts("package", packageName, null)); 4809 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4810 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4811 null, null, 0, null, null, null, false, false, userId); 4812 } catch (RemoteException e) { 4813 } 4814 } finally { 4815 Binder.restoreCallingIdentity(callingId); 4816 } 4817 return true; 4818 } 4819 4820 @Override 4821 public void killBackgroundProcesses(final String packageName, int userId) { 4822 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4823 != PackageManager.PERMISSION_GRANTED && 4824 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4825 != PackageManager.PERMISSION_GRANTED) { 4826 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4827 + Binder.getCallingPid() 4828 + ", uid=" + Binder.getCallingUid() 4829 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4830 Slog.w(TAG, msg); 4831 throw new SecurityException(msg); 4832 } 4833 4834 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4835 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4836 long callingId = Binder.clearCallingIdentity(); 4837 try { 4838 IPackageManager pm = AppGlobals.getPackageManager(); 4839 synchronized(this) { 4840 int appId = -1; 4841 try { 4842 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4843 } catch (RemoteException e) { 4844 } 4845 if (appId == -1) { 4846 Slog.w(TAG, "Invalid packageName: " + packageName); 4847 return; 4848 } 4849 killPackageProcessesLocked(packageName, appId, userId, 4850 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4851 } 4852 } finally { 4853 Binder.restoreCallingIdentity(callingId); 4854 } 4855 } 4856 4857 @Override 4858 public void killAllBackgroundProcesses() { 4859 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4860 != PackageManager.PERMISSION_GRANTED) { 4861 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4862 + Binder.getCallingPid() 4863 + ", uid=" + Binder.getCallingUid() 4864 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4865 Slog.w(TAG, msg); 4866 throw new SecurityException(msg); 4867 } 4868 4869 long callingId = Binder.clearCallingIdentity(); 4870 try { 4871 synchronized(this) { 4872 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4873 final int NP = mProcessNames.getMap().size(); 4874 for (int ip=0; ip<NP; ip++) { 4875 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4876 final int NA = apps.size(); 4877 for (int ia=0; ia<NA; ia++) { 4878 ProcessRecord app = apps.valueAt(ia); 4879 if (app.persistent) { 4880 // we don't kill persistent processes 4881 continue; 4882 } 4883 if (app.removed) { 4884 procs.add(app); 4885 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4886 app.removed = true; 4887 procs.add(app); 4888 } 4889 } 4890 } 4891 4892 int N = procs.size(); 4893 for (int i=0; i<N; i++) { 4894 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4895 } 4896 mAllowLowerMemLevel = true; 4897 updateOomAdjLocked(); 4898 doLowMemReportIfNeededLocked(null); 4899 } 4900 } finally { 4901 Binder.restoreCallingIdentity(callingId); 4902 } 4903 } 4904 4905 @Override 4906 public void forceStopPackage(final String packageName, int userId) { 4907 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4908 != PackageManager.PERMISSION_GRANTED) { 4909 String msg = "Permission Denial: forceStopPackage() from pid=" 4910 + Binder.getCallingPid() 4911 + ", uid=" + Binder.getCallingUid() 4912 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4913 Slog.w(TAG, msg); 4914 throw new SecurityException(msg); 4915 } 4916 final int callingPid = Binder.getCallingPid(); 4917 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4918 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4919 long callingId = Binder.clearCallingIdentity(); 4920 try { 4921 IPackageManager pm = AppGlobals.getPackageManager(); 4922 synchronized(this) { 4923 int[] users = userId == UserHandle.USER_ALL 4924 ? getUsersLocked() : new int[] { userId }; 4925 for (int user : users) { 4926 int pkgUid = -1; 4927 try { 4928 pkgUid = pm.getPackageUid(packageName, user); 4929 } catch (RemoteException e) { 4930 } 4931 if (pkgUid == -1) { 4932 Slog.w(TAG, "Invalid packageName: " + packageName); 4933 continue; 4934 } 4935 try { 4936 pm.setPackageStoppedState(packageName, true, user); 4937 } catch (RemoteException e) { 4938 } catch (IllegalArgumentException e) { 4939 Slog.w(TAG, "Failed trying to unstop package " 4940 + packageName + ": " + e); 4941 } 4942 if (isUserRunningLocked(user, false)) { 4943 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4944 } 4945 } 4946 } 4947 } finally { 4948 Binder.restoreCallingIdentity(callingId); 4949 } 4950 } 4951 4952 @Override 4953 public void addPackageDependency(String packageName) { 4954 synchronized (this) { 4955 int callingPid = Binder.getCallingPid(); 4956 if (callingPid == Process.myPid()) { 4957 // Yeah, um, no. 4958 Slog.w(TAG, "Can't addPackageDependency on system process"); 4959 return; 4960 } 4961 ProcessRecord proc; 4962 synchronized (mPidsSelfLocked) { 4963 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4964 } 4965 if (proc != null) { 4966 if (proc.pkgDeps == null) { 4967 proc.pkgDeps = new ArraySet<String>(1); 4968 } 4969 proc.pkgDeps.add(packageName); 4970 } 4971 } 4972 } 4973 4974 /* 4975 * The pkg name and app id have to be specified. 4976 */ 4977 @Override 4978 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4979 if (pkg == null) { 4980 return; 4981 } 4982 // Make sure the uid is valid. 4983 if (appid < 0) { 4984 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4985 return; 4986 } 4987 int callerUid = Binder.getCallingUid(); 4988 // Only the system server can kill an application 4989 if (callerUid == Process.SYSTEM_UID) { 4990 // Post an aysnc message to kill the application 4991 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4992 msg.arg1 = appid; 4993 msg.arg2 = 0; 4994 Bundle bundle = new Bundle(); 4995 bundle.putString("pkg", pkg); 4996 bundle.putString("reason", reason); 4997 msg.obj = bundle; 4998 mHandler.sendMessage(msg); 4999 } else { 5000 throw new SecurityException(callerUid + " cannot kill pkg: " + 5001 pkg); 5002 } 5003 } 5004 5005 @Override 5006 public void closeSystemDialogs(String reason) { 5007 enforceNotIsolatedCaller("closeSystemDialogs"); 5008 5009 final int pid = Binder.getCallingPid(); 5010 final int uid = Binder.getCallingUid(); 5011 final long origId = Binder.clearCallingIdentity(); 5012 try { 5013 synchronized (this) { 5014 // Only allow this from foreground processes, so that background 5015 // applications can't abuse it to prevent system UI from being shown. 5016 if (uid >= Process.FIRST_APPLICATION_UID) { 5017 ProcessRecord proc; 5018 synchronized (mPidsSelfLocked) { 5019 proc = mPidsSelfLocked.get(pid); 5020 } 5021 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5022 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5023 + " from background process " + proc); 5024 return; 5025 } 5026 } 5027 closeSystemDialogsLocked(reason); 5028 } 5029 } finally { 5030 Binder.restoreCallingIdentity(origId); 5031 } 5032 } 5033 5034 void closeSystemDialogsLocked(String reason) { 5035 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5036 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5037 | Intent.FLAG_RECEIVER_FOREGROUND); 5038 if (reason != null) { 5039 intent.putExtra("reason", reason); 5040 } 5041 mWindowManager.closeSystemDialogs(reason); 5042 5043 mStackSupervisor.closeSystemDialogsLocked(); 5044 5045 broadcastIntentLocked(null, null, intent, null, 5046 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5047 Process.SYSTEM_UID, UserHandle.USER_ALL); 5048 } 5049 5050 @Override 5051 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5052 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5053 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5054 for (int i=pids.length-1; i>=0; i--) { 5055 ProcessRecord proc; 5056 int oomAdj; 5057 synchronized (this) { 5058 synchronized (mPidsSelfLocked) { 5059 proc = mPidsSelfLocked.get(pids[i]); 5060 oomAdj = proc != null ? proc.setAdj : 0; 5061 } 5062 } 5063 infos[i] = new Debug.MemoryInfo(); 5064 Debug.getMemoryInfo(pids[i], infos[i]); 5065 if (proc != null) { 5066 synchronized (this) { 5067 if (proc.thread != null && proc.setAdj == oomAdj) { 5068 // Record this for posterity if the process has been stable. 5069 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5070 infos[i].getTotalUss(), false, proc.pkgList); 5071 } 5072 } 5073 } 5074 } 5075 return infos; 5076 } 5077 5078 @Override 5079 public long[] getProcessPss(int[] pids) { 5080 enforceNotIsolatedCaller("getProcessPss"); 5081 long[] pss = new long[pids.length]; 5082 for (int i=pids.length-1; i>=0; i--) { 5083 ProcessRecord proc; 5084 int oomAdj; 5085 synchronized (this) { 5086 synchronized (mPidsSelfLocked) { 5087 proc = mPidsSelfLocked.get(pids[i]); 5088 oomAdj = proc != null ? proc.setAdj : 0; 5089 } 5090 } 5091 long[] tmpUss = new long[1]; 5092 pss[i] = Debug.getPss(pids[i], tmpUss); 5093 if (proc != null) { 5094 synchronized (this) { 5095 if (proc.thread != null && proc.setAdj == oomAdj) { 5096 // Record this for posterity if the process has been stable. 5097 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5098 } 5099 } 5100 } 5101 } 5102 return pss; 5103 } 5104 5105 @Override 5106 public void killApplicationProcess(String processName, int uid) { 5107 if (processName == null) { 5108 return; 5109 } 5110 5111 int callerUid = Binder.getCallingUid(); 5112 // Only the system server can kill an application 5113 if (callerUid == Process.SYSTEM_UID) { 5114 synchronized (this) { 5115 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5116 if (app != null && app.thread != null) { 5117 try { 5118 app.thread.scheduleSuicide(); 5119 } catch (RemoteException e) { 5120 // If the other end already died, then our work here is done. 5121 } 5122 } else { 5123 Slog.w(TAG, "Process/uid not found attempting kill of " 5124 + processName + " / " + uid); 5125 } 5126 } 5127 } else { 5128 throw new SecurityException(callerUid + " cannot kill app process: " + 5129 processName); 5130 } 5131 } 5132 5133 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5134 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5135 false, true, false, false, UserHandle.getUserId(uid), reason); 5136 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5137 Uri.fromParts("package", packageName, null)); 5138 if (!mProcessesReady) { 5139 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5140 | Intent.FLAG_RECEIVER_FOREGROUND); 5141 } 5142 intent.putExtra(Intent.EXTRA_UID, uid); 5143 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5144 broadcastIntentLocked(null, null, intent, 5145 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5146 false, false, 5147 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5148 } 5149 5150 private void forceStopUserLocked(int userId, String reason) { 5151 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5152 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5154 | Intent.FLAG_RECEIVER_FOREGROUND); 5155 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5156 broadcastIntentLocked(null, null, intent, 5157 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5158 false, false, 5159 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5160 } 5161 5162 private final boolean killPackageProcessesLocked(String packageName, int appId, 5163 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5164 boolean doit, boolean evenPersistent, String reason) { 5165 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5166 5167 // Remove all processes this package may have touched: all with the 5168 // same UID (except for the system or root user), and all whose name 5169 // matches the package name. 5170 final int NP = mProcessNames.getMap().size(); 5171 for (int ip=0; ip<NP; ip++) { 5172 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5173 final int NA = apps.size(); 5174 for (int ia=0; ia<NA; ia++) { 5175 ProcessRecord app = apps.valueAt(ia); 5176 if (app.persistent && !evenPersistent) { 5177 // we don't kill persistent processes 5178 continue; 5179 } 5180 if (app.removed) { 5181 if (doit) { 5182 procs.add(app); 5183 } 5184 continue; 5185 } 5186 5187 // Skip process if it doesn't meet our oom adj requirement. 5188 if (app.setAdj < minOomAdj) { 5189 continue; 5190 } 5191 5192 // If no package is specified, we call all processes under the 5193 // give user id. 5194 if (packageName == null) { 5195 if (app.userId != userId) { 5196 continue; 5197 } 5198 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5199 continue; 5200 } 5201 // Package has been specified, we want to hit all processes 5202 // that match it. We need to qualify this by the processes 5203 // that are running under the specified app and user ID. 5204 } else { 5205 final boolean isDep = app.pkgDeps != null 5206 && app.pkgDeps.contains(packageName); 5207 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5208 continue; 5209 } 5210 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5211 continue; 5212 } 5213 if (!app.pkgList.containsKey(packageName) && !isDep) { 5214 continue; 5215 } 5216 } 5217 5218 // Process has passed all conditions, kill it! 5219 if (!doit) { 5220 return true; 5221 } 5222 app.removed = true; 5223 procs.add(app); 5224 } 5225 } 5226 5227 int N = procs.size(); 5228 for (int i=0; i<N; i++) { 5229 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5230 } 5231 updateOomAdjLocked(); 5232 return N > 0; 5233 } 5234 5235 private final boolean forceStopPackageLocked(String name, int appId, 5236 boolean callerWillRestart, boolean purgeCache, boolean doit, 5237 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5238 int i; 5239 int N; 5240 5241 if (userId == UserHandle.USER_ALL && name == null) { 5242 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5243 } 5244 5245 if (appId < 0 && name != null) { 5246 try { 5247 appId = UserHandle.getAppId( 5248 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5249 } catch (RemoteException e) { 5250 } 5251 } 5252 5253 if (doit) { 5254 if (name != null) { 5255 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5256 + " user=" + userId + ": " + reason); 5257 } else { 5258 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5259 } 5260 5261 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5262 for (int ip=pmap.size()-1; ip>=0; ip--) { 5263 SparseArray<Long> ba = pmap.valueAt(ip); 5264 for (i=ba.size()-1; i>=0; i--) { 5265 boolean remove = false; 5266 final int entUid = ba.keyAt(i); 5267 if (name != null) { 5268 if (userId == UserHandle.USER_ALL) { 5269 if (UserHandle.getAppId(entUid) == appId) { 5270 remove = true; 5271 } 5272 } else { 5273 if (entUid == UserHandle.getUid(userId, appId)) { 5274 remove = true; 5275 } 5276 } 5277 } else if (UserHandle.getUserId(entUid) == userId) { 5278 remove = true; 5279 } 5280 if (remove) { 5281 ba.removeAt(i); 5282 } 5283 } 5284 if (ba.size() == 0) { 5285 pmap.removeAt(ip); 5286 } 5287 } 5288 } 5289 5290 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5291 -100, callerWillRestart, true, doit, evenPersistent, 5292 name == null ? ("stop user " + userId) : ("stop " + name)); 5293 5294 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5295 if (!doit) { 5296 return true; 5297 } 5298 didSomething = true; 5299 } 5300 5301 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5302 if (!doit) { 5303 return true; 5304 } 5305 didSomething = true; 5306 } 5307 5308 if (name == null) { 5309 // Remove all sticky broadcasts from this user. 5310 mStickyBroadcasts.remove(userId); 5311 } 5312 5313 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5314 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5315 userId, providers)) { 5316 if (!doit) { 5317 return true; 5318 } 5319 didSomething = true; 5320 } 5321 N = providers.size(); 5322 for (i=0; i<N; i++) { 5323 removeDyingProviderLocked(null, providers.get(i), true); 5324 } 5325 5326 // Remove transient permissions granted from/to this package/user 5327 removeUriPermissionsForPackageLocked(name, userId, false); 5328 5329 if (name == null || uninstalling) { 5330 // Remove pending intents. For now we only do this when force 5331 // stopping users, because we have some problems when doing this 5332 // for packages -- app widgets are not currently cleaned up for 5333 // such packages, so they can be left with bad pending intents. 5334 if (mIntentSenderRecords.size() > 0) { 5335 Iterator<WeakReference<PendingIntentRecord>> it 5336 = mIntentSenderRecords.values().iterator(); 5337 while (it.hasNext()) { 5338 WeakReference<PendingIntentRecord> wpir = it.next(); 5339 if (wpir == null) { 5340 it.remove(); 5341 continue; 5342 } 5343 PendingIntentRecord pir = wpir.get(); 5344 if (pir == null) { 5345 it.remove(); 5346 continue; 5347 } 5348 if (name == null) { 5349 // Stopping user, remove all objects for the user. 5350 if (pir.key.userId != userId) { 5351 // Not the same user, skip it. 5352 continue; 5353 } 5354 } else { 5355 if (UserHandle.getAppId(pir.uid) != appId) { 5356 // Different app id, skip it. 5357 continue; 5358 } 5359 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5360 // Different user, skip it. 5361 continue; 5362 } 5363 if (!pir.key.packageName.equals(name)) { 5364 // Different package, skip it. 5365 continue; 5366 } 5367 } 5368 if (!doit) { 5369 return true; 5370 } 5371 didSomething = true; 5372 it.remove(); 5373 pir.canceled = true; 5374 if (pir.key.activity != null) { 5375 pir.key.activity.pendingResults.remove(pir.ref); 5376 } 5377 } 5378 } 5379 } 5380 5381 if (doit) { 5382 if (purgeCache && name != null) { 5383 AttributeCache ac = AttributeCache.instance(); 5384 if (ac != null) { 5385 ac.removePackage(name); 5386 } 5387 } 5388 if (mBooted) { 5389 mStackSupervisor.resumeTopActivitiesLocked(); 5390 mStackSupervisor.scheduleIdleLocked(); 5391 } 5392 } 5393 5394 return didSomething; 5395 } 5396 5397 private final boolean removeProcessLocked(ProcessRecord app, 5398 boolean callerWillRestart, boolean allowRestart, String reason) { 5399 final String name = app.processName; 5400 final int uid = app.uid; 5401 if (DEBUG_PROCESSES) Slog.d( 5402 TAG, "Force removing proc " + app.toShortString() + " (" + name 5403 + "/" + uid + ")"); 5404 5405 mProcessNames.remove(name, uid); 5406 mIsolatedProcesses.remove(app.uid); 5407 if (mHeavyWeightProcess == app) { 5408 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5409 mHeavyWeightProcess.userId, 0)); 5410 mHeavyWeightProcess = null; 5411 } 5412 boolean needRestart = false; 5413 if (app.pid > 0 && app.pid != MY_PID) { 5414 int pid = app.pid; 5415 synchronized (mPidsSelfLocked) { 5416 mPidsSelfLocked.remove(pid); 5417 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5418 } 5419 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5420 if (app.isolated) { 5421 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5422 } 5423 killUnneededProcessLocked(app, reason); 5424 Process.killProcessGroup(app.info.uid, app.pid); 5425 handleAppDiedLocked(app, true, allowRestart); 5426 removeLruProcessLocked(app); 5427 5428 if (app.persistent && !app.isolated) { 5429 if (!callerWillRestart) { 5430 addAppLocked(app.info, false, null /* ABI override */); 5431 } else { 5432 needRestart = true; 5433 } 5434 } 5435 } else { 5436 mRemovedProcesses.add(app); 5437 } 5438 5439 return needRestart; 5440 } 5441 5442 private final void processStartTimedOutLocked(ProcessRecord app) { 5443 final int pid = app.pid; 5444 boolean gone = false; 5445 synchronized (mPidsSelfLocked) { 5446 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5447 if (knownApp != null && knownApp.thread == null) { 5448 mPidsSelfLocked.remove(pid); 5449 gone = true; 5450 } 5451 } 5452 5453 if (gone) { 5454 Slog.w(TAG, "Process " + app + " failed to attach"); 5455 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5456 pid, app.uid, app.processName); 5457 mProcessNames.remove(app.processName, app.uid); 5458 mIsolatedProcesses.remove(app.uid); 5459 if (mHeavyWeightProcess == app) { 5460 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5461 mHeavyWeightProcess.userId, 0)); 5462 mHeavyWeightProcess = null; 5463 } 5464 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5465 if (app.isolated) { 5466 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5467 } 5468 // Take care of any launching providers waiting for this process. 5469 checkAppInLaunchingProvidersLocked(app, true); 5470 // Take care of any services that are waiting for the process. 5471 mServices.processStartTimedOutLocked(app); 5472 killUnneededProcessLocked(app, "start timeout"); 5473 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5474 Slog.w(TAG, "Unattached app died before backup, skipping"); 5475 try { 5476 IBackupManager bm = IBackupManager.Stub.asInterface( 5477 ServiceManager.getService(Context.BACKUP_SERVICE)); 5478 bm.agentDisconnected(app.info.packageName); 5479 } catch (RemoteException e) { 5480 // Can't happen; the backup manager is local 5481 } 5482 } 5483 if (isPendingBroadcastProcessLocked(pid)) { 5484 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5485 skipPendingBroadcastLocked(pid); 5486 } 5487 } else { 5488 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5489 } 5490 } 5491 5492 private final boolean attachApplicationLocked(IApplicationThread thread, 5493 int pid) { 5494 5495 // Find the application record that is being attached... either via 5496 // the pid if we are running in multiple processes, or just pull the 5497 // next app record if we are emulating process with anonymous threads. 5498 ProcessRecord app; 5499 if (pid != MY_PID && pid >= 0) { 5500 synchronized (mPidsSelfLocked) { 5501 app = mPidsSelfLocked.get(pid); 5502 } 5503 } else { 5504 app = null; 5505 } 5506 5507 if (app == null) { 5508 Slog.w(TAG, "No pending application record for pid " + pid 5509 + " (IApplicationThread " + thread + "); dropping process"); 5510 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5511 if (pid > 0 && pid != MY_PID) { 5512 Process.killProcessQuiet(pid); 5513 //TODO: Process.killProcessGroup(app.info.uid, pid); 5514 } else { 5515 try { 5516 thread.scheduleExit(); 5517 } catch (Exception e) { 5518 // Ignore exceptions. 5519 } 5520 } 5521 return false; 5522 } 5523 5524 // If this application record is still attached to a previous 5525 // process, clean it up now. 5526 if (app.thread != null) { 5527 handleAppDiedLocked(app, true, true); 5528 } 5529 5530 // Tell the process all about itself. 5531 5532 if (localLOGV) Slog.v( 5533 TAG, "Binding process pid " + pid + " to record " + app); 5534 5535 final String processName = app.processName; 5536 try { 5537 AppDeathRecipient adr = new AppDeathRecipient( 5538 app, pid, thread); 5539 thread.asBinder().linkToDeath(adr, 0); 5540 app.deathRecipient = adr; 5541 } catch (RemoteException e) { 5542 app.resetPackageList(mProcessStats); 5543 startProcessLocked(app, "link fail", processName); 5544 return false; 5545 } 5546 5547 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5548 5549 app.makeActive(thread, mProcessStats); 5550 app.curAdj = app.setAdj = -100; 5551 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5552 app.forcingToForeground = null; 5553 updateProcessForegroundLocked(app, false, false); 5554 app.hasShownUi = false; 5555 app.debugging = false; 5556 app.cached = false; 5557 5558 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5559 5560 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5561 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5562 5563 if (!normalMode) { 5564 Slog.i(TAG, "Launching preboot mode app: " + app); 5565 } 5566 5567 if (localLOGV) Slog.v( 5568 TAG, "New app record " + app 5569 + " thread=" + thread.asBinder() + " pid=" + pid); 5570 try { 5571 int testMode = IApplicationThread.DEBUG_OFF; 5572 if (mDebugApp != null && mDebugApp.equals(processName)) { 5573 testMode = mWaitForDebugger 5574 ? IApplicationThread.DEBUG_WAIT 5575 : IApplicationThread.DEBUG_ON; 5576 app.debugging = true; 5577 if (mDebugTransient) { 5578 mDebugApp = mOrigDebugApp; 5579 mWaitForDebugger = mOrigWaitForDebugger; 5580 } 5581 } 5582 String profileFile = app.instrumentationProfileFile; 5583 ParcelFileDescriptor profileFd = null; 5584 boolean profileAutoStop = false; 5585 if (mProfileApp != null && mProfileApp.equals(processName)) { 5586 mProfileProc = app; 5587 profileFile = mProfileFile; 5588 profileFd = mProfileFd; 5589 profileAutoStop = mAutoStopProfiler; 5590 } 5591 boolean enableOpenGlTrace = false; 5592 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5593 enableOpenGlTrace = true; 5594 mOpenGlTraceApp = null; 5595 } 5596 5597 // If the app is being launched for restore or full backup, set it up specially 5598 boolean isRestrictedBackupMode = false; 5599 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5600 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5601 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5602 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5603 } 5604 5605 ensurePackageDexOpt(app.instrumentationInfo != null 5606 ? app.instrumentationInfo.packageName 5607 : app.info.packageName); 5608 if (app.instrumentationClass != null) { 5609 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5610 } 5611 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5612 + processName + " with config " + mConfiguration); 5613 ApplicationInfo appInfo = app.instrumentationInfo != null 5614 ? app.instrumentationInfo : app.info; 5615 app.compat = compatibilityInfoForPackageLocked(appInfo); 5616 if (profileFd != null) { 5617 profileFd = profileFd.dup(); 5618 } 5619 thread.bindApplication(processName, appInfo, providers, 5620 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5621 app.instrumentationArguments, app.instrumentationWatcher, 5622 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5623 isRestrictedBackupMode || !normalMode, app.persistent, 5624 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5625 mCoreSettingsObserver.getCoreSettingsLocked()); 5626 updateLruProcessLocked(app, false, null); 5627 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5628 } catch (Exception e) { 5629 // todo: Yikes! What should we do? For now we will try to 5630 // start another process, but that could easily get us in 5631 // an infinite loop of restarting processes... 5632 Slog.w(TAG, "Exception thrown during bind!", e); 5633 5634 app.resetPackageList(mProcessStats); 5635 app.unlinkDeathRecipient(); 5636 startProcessLocked(app, "bind fail", processName); 5637 return false; 5638 } 5639 5640 // Remove this record from the list of starting applications. 5641 mPersistentStartingProcesses.remove(app); 5642 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5643 "Attach application locked removing on hold: " + app); 5644 mProcessesOnHold.remove(app); 5645 5646 boolean badApp = false; 5647 boolean didSomething = false; 5648 5649 // See if the top visible activity is waiting to run in this process... 5650 if (normalMode) { 5651 try { 5652 if (mStackSupervisor.attachApplicationLocked(app)) { 5653 didSomething = true; 5654 } 5655 } catch (Exception e) { 5656 badApp = true; 5657 } 5658 } 5659 5660 // Find any services that should be running in this process... 5661 if (!badApp) { 5662 try { 5663 didSomething |= mServices.attachApplicationLocked(app, processName); 5664 } catch (Exception e) { 5665 badApp = true; 5666 } 5667 } 5668 5669 // Check if a next-broadcast receiver is in this process... 5670 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5671 try { 5672 didSomething |= sendPendingBroadcastsLocked(app); 5673 } catch (Exception e) { 5674 // If the app died trying to launch the receiver we declare it 'bad' 5675 badApp = true; 5676 } 5677 } 5678 5679 // Check whether the next backup agent is in this process... 5680 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5681 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5682 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5683 try { 5684 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5685 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5686 mBackupTarget.backupMode); 5687 } catch (Exception e) { 5688 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5689 e.printStackTrace(); 5690 } 5691 } 5692 5693 if (badApp) { 5694 // todo: Also need to kill application to deal with all 5695 // kinds of exceptions. 5696 handleAppDiedLocked(app, false, true); 5697 return false; 5698 } 5699 5700 if (!didSomething) { 5701 updateOomAdjLocked(); 5702 } 5703 5704 return true; 5705 } 5706 5707 @Override 5708 public final void attachApplication(IApplicationThread thread) { 5709 synchronized (this) { 5710 int callingPid = Binder.getCallingPid(); 5711 final long origId = Binder.clearCallingIdentity(); 5712 attachApplicationLocked(thread, callingPid); 5713 Binder.restoreCallingIdentity(origId); 5714 } 5715 } 5716 5717 @Override 5718 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5719 final long origId = Binder.clearCallingIdentity(); 5720 synchronized (this) { 5721 ActivityStack stack = ActivityRecord.getStackLocked(token); 5722 if (stack != null) { 5723 ActivityRecord r = 5724 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5725 if (stopProfiling) { 5726 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5727 try { 5728 mProfileFd.close(); 5729 } catch (IOException e) { 5730 } 5731 clearProfilerLocked(); 5732 } 5733 } 5734 } 5735 } 5736 Binder.restoreCallingIdentity(origId); 5737 } 5738 5739 void postEnableScreenAfterBootLocked() { 5740 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 5741 } 5742 5743 void enableScreenAfterBoot() { 5744 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5745 SystemClock.uptimeMillis()); 5746 mWindowManager.enableScreenAfterBoot(); 5747 5748 synchronized (this) { 5749 updateEventDispatchingLocked(); 5750 } 5751 } 5752 5753 @Override 5754 public void showBootMessage(final CharSequence msg, final boolean always) { 5755 enforceNotIsolatedCaller("showBootMessage"); 5756 mWindowManager.showBootMessage(msg, always); 5757 } 5758 5759 @Override 5760 public void keyguardWaitingForActivityDrawn() { 5761 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 5762 final long token = Binder.clearCallingIdentity(); 5763 try { 5764 synchronized (this) { 5765 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5766 mWindowManager.keyguardWaitingForActivityDrawn(); 5767 } 5768 } finally { 5769 Binder.restoreCallingIdentity(token); 5770 } 5771 } 5772 5773 final void finishBooting() { 5774 // Register receivers to handle package update events 5775 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5776 5777 // Let system services know. 5778 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 5779 5780 synchronized (this) { 5781 // Ensure that any processes we had put on hold are now started 5782 // up. 5783 final int NP = mProcessesOnHold.size(); 5784 if (NP > 0) { 5785 ArrayList<ProcessRecord> procs = 5786 new ArrayList<ProcessRecord>(mProcessesOnHold); 5787 for (int ip=0; ip<NP; ip++) { 5788 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5789 + procs.get(ip)); 5790 startProcessLocked(procs.get(ip), "on-hold", null); 5791 } 5792 } 5793 5794 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5795 // Start looking for apps that are abusing wake locks. 5796 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5797 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5798 // Tell anyone interested that we are done booting! 5799 SystemProperties.set("sys.boot_completed", "1"); 5800 SystemProperties.set("dev.bootcomplete", "1"); 5801 for (int i=0; i<mStartedUsers.size(); i++) { 5802 UserStartedState uss = mStartedUsers.valueAt(i); 5803 if (uss.mState == UserStartedState.STATE_BOOTING) { 5804 uss.mState = UserStartedState.STATE_RUNNING; 5805 final int userId = mStartedUsers.keyAt(i); 5806 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5807 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5808 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5809 broadcastIntentLocked(null, null, intent, null, 5810 new IIntentReceiver.Stub() { 5811 @Override 5812 public void performReceive(Intent intent, int resultCode, 5813 String data, Bundle extras, boolean ordered, 5814 boolean sticky, int sendingUser) { 5815 synchronized (ActivityManagerService.this) { 5816 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5817 true, false); 5818 } 5819 } 5820 }, 5821 0, null, null, 5822 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5823 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5824 userId); 5825 } 5826 } 5827 scheduleStartProfilesLocked(); 5828 } 5829 } 5830 } 5831 5832 final void ensureBootCompleted() { 5833 boolean booting; 5834 boolean enableScreen; 5835 synchronized (this) { 5836 booting = mBooting; 5837 mBooting = false; 5838 enableScreen = !mBooted; 5839 mBooted = true; 5840 } 5841 5842 if (booting) { 5843 finishBooting(); 5844 } 5845 5846 if (enableScreen) { 5847 enableScreenAfterBoot(); 5848 } 5849 } 5850 5851 @Override 5852 public final void activityResumed(IBinder token) { 5853 final long origId = Binder.clearCallingIdentity(); 5854 synchronized(this) { 5855 ActivityStack stack = ActivityRecord.getStackLocked(token); 5856 if (stack != null) { 5857 ActivityRecord.activityResumedLocked(token); 5858 } 5859 } 5860 Binder.restoreCallingIdentity(origId); 5861 } 5862 5863 @Override 5864 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5865 final long origId = Binder.clearCallingIdentity(); 5866 synchronized(this) { 5867 ActivityStack stack = ActivityRecord.getStackLocked(token); 5868 if (stack != null) { 5869 stack.activityPausedLocked(token, false, persistentState); 5870 } 5871 } 5872 Binder.restoreCallingIdentity(origId); 5873 } 5874 5875 @Override 5876 public final void activityStopped(IBinder token, Bundle icicle, 5877 PersistableBundle persistentState, CharSequence description) { 5878 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5879 5880 // Refuse possible leaked file descriptors 5881 if (icicle != null && icicle.hasFileDescriptors()) { 5882 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5883 } 5884 5885 final long origId = Binder.clearCallingIdentity(); 5886 5887 synchronized (this) { 5888 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5889 if (r != null) { 5890 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5891 } 5892 } 5893 5894 trimApplications(); 5895 5896 Binder.restoreCallingIdentity(origId); 5897 } 5898 5899 @Override 5900 public final void activityDestroyed(IBinder token) { 5901 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5902 synchronized (this) { 5903 ActivityStack stack = ActivityRecord.getStackLocked(token); 5904 if (stack != null) { 5905 stack.activityDestroyedLocked(token); 5906 } 5907 } 5908 } 5909 5910 @Override 5911 public final void backgroundResourcesReleased(IBinder token) { 5912 final long origId = Binder.clearCallingIdentity(); 5913 try { 5914 synchronized (this) { 5915 ActivityStack stack = ActivityRecord.getStackLocked(token); 5916 if (stack != null) { 5917 stack.backgroundResourcesReleased(token); 5918 } 5919 } 5920 } finally { 5921 Binder.restoreCallingIdentity(origId); 5922 } 5923 } 5924 5925 @Override 5926 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5927 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5928 } 5929 5930 @Override 5931 public final void notifyEnterAnimationComplete(IBinder token) { 5932 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 5933 } 5934 5935 @Override 5936 public String getCallingPackage(IBinder token) { 5937 synchronized (this) { 5938 ActivityRecord r = getCallingRecordLocked(token); 5939 return r != null ? r.info.packageName : null; 5940 } 5941 } 5942 5943 @Override 5944 public ComponentName getCallingActivity(IBinder token) { 5945 synchronized (this) { 5946 ActivityRecord r = getCallingRecordLocked(token); 5947 return r != null ? r.intent.getComponent() : null; 5948 } 5949 } 5950 5951 private ActivityRecord getCallingRecordLocked(IBinder token) { 5952 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5953 if (r == null) { 5954 return null; 5955 } 5956 return r.resultTo; 5957 } 5958 5959 @Override 5960 public ComponentName getActivityClassForToken(IBinder token) { 5961 synchronized(this) { 5962 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5963 if (r == null) { 5964 return null; 5965 } 5966 return r.intent.getComponent(); 5967 } 5968 } 5969 5970 @Override 5971 public String getPackageForToken(IBinder token) { 5972 synchronized(this) { 5973 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5974 if (r == null) { 5975 return null; 5976 } 5977 return r.packageName; 5978 } 5979 } 5980 5981 @Override 5982 public IIntentSender getIntentSender(int type, 5983 String packageName, IBinder token, String resultWho, 5984 int requestCode, Intent[] intents, String[] resolvedTypes, 5985 int flags, Bundle options, int userId) { 5986 enforceNotIsolatedCaller("getIntentSender"); 5987 // Refuse possible leaked file descriptors 5988 if (intents != null) { 5989 if (intents.length < 1) { 5990 throw new IllegalArgumentException("Intents array length must be >= 1"); 5991 } 5992 for (int i=0; i<intents.length; i++) { 5993 Intent intent = intents[i]; 5994 if (intent != null) { 5995 if (intent.hasFileDescriptors()) { 5996 throw new IllegalArgumentException("File descriptors passed in Intent"); 5997 } 5998 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5999 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6000 throw new IllegalArgumentException( 6001 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6002 } 6003 intents[i] = new Intent(intent); 6004 } 6005 } 6006 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6007 throw new IllegalArgumentException( 6008 "Intent array length does not match resolvedTypes length"); 6009 } 6010 } 6011 if (options != null) { 6012 if (options.hasFileDescriptors()) { 6013 throw new IllegalArgumentException("File descriptors passed in options"); 6014 } 6015 } 6016 6017 synchronized(this) { 6018 int callingUid = Binder.getCallingUid(); 6019 int origUserId = userId; 6020 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6021 type == ActivityManager.INTENT_SENDER_BROADCAST, 6022 ALLOW_NON_FULL, "getIntentSender", null); 6023 if (origUserId == UserHandle.USER_CURRENT) { 6024 // We don't want to evaluate this until the pending intent is 6025 // actually executed. However, we do want to always do the 6026 // security checking for it above. 6027 userId = UserHandle.USER_CURRENT; 6028 } 6029 try { 6030 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6031 int uid = AppGlobals.getPackageManager() 6032 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6033 if (!UserHandle.isSameApp(callingUid, uid)) { 6034 String msg = "Permission Denial: getIntentSender() from pid=" 6035 + Binder.getCallingPid() 6036 + ", uid=" + Binder.getCallingUid() 6037 + ", (need uid=" + uid + ")" 6038 + " is not allowed to send as package " + packageName; 6039 Slog.w(TAG, msg); 6040 throw new SecurityException(msg); 6041 } 6042 } 6043 6044 return getIntentSenderLocked(type, packageName, callingUid, userId, 6045 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6046 6047 } catch (RemoteException e) { 6048 throw new SecurityException(e); 6049 } 6050 } 6051 } 6052 6053 IIntentSender getIntentSenderLocked(int type, String packageName, 6054 int callingUid, int userId, IBinder token, String resultWho, 6055 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6056 Bundle options) { 6057 if (DEBUG_MU) 6058 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6059 ActivityRecord activity = null; 6060 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6061 activity = ActivityRecord.isInStackLocked(token); 6062 if (activity == null) { 6063 return null; 6064 } 6065 if (activity.finishing) { 6066 return null; 6067 } 6068 } 6069 6070 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6071 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6072 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6073 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6074 |PendingIntent.FLAG_UPDATE_CURRENT); 6075 6076 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6077 type, packageName, activity, resultWho, 6078 requestCode, intents, resolvedTypes, flags, options, userId); 6079 WeakReference<PendingIntentRecord> ref; 6080 ref = mIntentSenderRecords.get(key); 6081 PendingIntentRecord rec = ref != null ? ref.get() : null; 6082 if (rec != null) { 6083 if (!cancelCurrent) { 6084 if (updateCurrent) { 6085 if (rec.key.requestIntent != null) { 6086 rec.key.requestIntent.replaceExtras(intents != null ? 6087 intents[intents.length - 1] : null); 6088 } 6089 if (intents != null) { 6090 intents[intents.length-1] = rec.key.requestIntent; 6091 rec.key.allIntents = intents; 6092 rec.key.allResolvedTypes = resolvedTypes; 6093 } else { 6094 rec.key.allIntents = null; 6095 rec.key.allResolvedTypes = null; 6096 } 6097 } 6098 return rec; 6099 } 6100 rec.canceled = true; 6101 mIntentSenderRecords.remove(key); 6102 } 6103 if (noCreate) { 6104 return rec; 6105 } 6106 rec = new PendingIntentRecord(this, key, callingUid); 6107 mIntentSenderRecords.put(key, rec.ref); 6108 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6109 if (activity.pendingResults == null) { 6110 activity.pendingResults 6111 = new HashSet<WeakReference<PendingIntentRecord>>(); 6112 } 6113 activity.pendingResults.add(rec.ref); 6114 } 6115 return rec; 6116 } 6117 6118 @Override 6119 public void cancelIntentSender(IIntentSender sender) { 6120 if (!(sender instanceof PendingIntentRecord)) { 6121 return; 6122 } 6123 synchronized(this) { 6124 PendingIntentRecord rec = (PendingIntentRecord)sender; 6125 try { 6126 int uid = AppGlobals.getPackageManager() 6127 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6128 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6129 String msg = "Permission Denial: cancelIntentSender() from pid=" 6130 + Binder.getCallingPid() 6131 + ", uid=" + Binder.getCallingUid() 6132 + " is not allowed to cancel packges " 6133 + rec.key.packageName; 6134 Slog.w(TAG, msg); 6135 throw new SecurityException(msg); 6136 } 6137 } catch (RemoteException e) { 6138 throw new SecurityException(e); 6139 } 6140 cancelIntentSenderLocked(rec, true); 6141 } 6142 } 6143 6144 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6145 rec.canceled = true; 6146 mIntentSenderRecords.remove(rec.key); 6147 if (cleanActivity && rec.key.activity != null) { 6148 rec.key.activity.pendingResults.remove(rec.ref); 6149 } 6150 } 6151 6152 @Override 6153 public String getPackageForIntentSender(IIntentSender pendingResult) { 6154 if (!(pendingResult instanceof PendingIntentRecord)) { 6155 return null; 6156 } 6157 try { 6158 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6159 return res.key.packageName; 6160 } catch (ClassCastException e) { 6161 } 6162 return null; 6163 } 6164 6165 @Override 6166 public int getUidForIntentSender(IIntentSender sender) { 6167 if (sender instanceof PendingIntentRecord) { 6168 try { 6169 PendingIntentRecord res = (PendingIntentRecord)sender; 6170 return res.uid; 6171 } catch (ClassCastException e) { 6172 } 6173 } 6174 return -1; 6175 } 6176 6177 @Override 6178 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6179 if (!(pendingResult instanceof PendingIntentRecord)) { 6180 return false; 6181 } 6182 try { 6183 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6184 if (res.key.allIntents == null) { 6185 return false; 6186 } 6187 for (int i=0; i<res.key.allIntents.length; i++) { 6188 Intent intent = res.key.allIntents[i]; 6189 if (intent.getPackage() != null && intent.getComponent() != null) { 6190 return false; 6191 } 6192 } 6193 return true; 6194 } catch (ClassCastException e) { 6195 } 6196 return false; 6197 } 6198 6199 @Override 6200 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6201 if (!(pendingResult instanceof PendingIntentRecord)) { 6202 return false; 6203 } 6204 try { 6205 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6206 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6207 return true; 6208 } 6209 return false; 6210 } catch (ClassCastException e) { 6211 } 6212 return false; 6213 } 6214 6215 @Override 6216 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6217 if (!(pendingResult instanceof PendingIntentRecord)) { 6218 return null; 6219 } 6220 try { 6221 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6222 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6223 } catch (ClassCastException e) { 6224 } 6225 return null; 6226 } 6227 6228 @Override 6229 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6230 if (!(pendingResult instanceof PendingIntentRecord)) { 6231 return null; 6232 } 6233 try { 6234 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6235 Intent intent = res.key.requestIntent; 6236 if (intent != null) { 6237 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6238 || res.lastTagPrefix.equals(prefix))) { 6239 return res.lastTag; 6240 } 6241 res.lastTagPrefix = prefix; 6242 StringBuilder sb = new StringBuilder(128); 6243 if (prefix != null) { 6244 sb.append(prefix); 6245 } 6246 if (intent.getAction() != null) { 6247 sb.append(intent.getAction()); 6248 } else if (intent.getComponent() != null) { 6249 intent.getComponent().appendShortString(sb); 6250 } else { 6251 sb.append("?"); 6252 } 6253 return res.lastTag = sb.toString(); 6254 } 6255 } catch (ClassCastException e) { 6256 } 6257 return null; 6258 } 6259 6260 @Override 6261 public void setProcessLimit(int max) { 6262 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6263 "setProcessLimit()"); 6264 synchronized (this) { 6265 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6266 mProcessLimitOverride = max; 6267 } 6268 trimApplications(); 6269 } 6270 6271 @Override 6272 public int getProcessLimit() { 6273 synchronized (this) { 6274 return mProcessLimitOverride; 6275 } 6276 } 6277 6278 void foregroundTokenDied(ForegroundToken token) { 6279 synchronized (ActivityManagerService.this) { 6280 synchronized (mPidsSelfLocked) { 6281 ForegroundToken cur 6282 = mForegroundProcesses.get(token.pid); 6283 if (cur != token) { 6284 return; 6285 } 6286 mForegroundProcesses.remove(token.pid); 6287 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6288 if (pr == null) { 6289 return; 6290 } 6291 pr.forcingToForeground = null; 6292 updateProcessForegroundLocked(pr, false, false); 6293 } 6294 updateOomAdjLocked(); 6295 } 6296 } 6297 6298 @Override 6299 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6300 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6301 "setProcessForeground()"); 6302 synchronized(this) { 6303 boolean changed = false; 6304 6305 synchronized (mPidsSelfLocked) { 6306 ProcessRecord pr = mPidsSelfLocked.get(pid); 6307 if (pr == null && isForeground) { 6308 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6309 return; 6310 } 6311 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6312 if (oldToken != null) { 6313 oldToken.token.unlinkToDeath(oldToken, 0); 6314 mForegroundProcesses.remove(pid); 6315 if (pr != null) { 6316 pr.forcingToForeground = null; 6317 } 6318 changed = true; 6319 } 6320 if (isForeground && token != null) { 6321 ForegroundToken newToken = new ForegroundToken() { 6322 @Override 6323 public void binderDied() { 6324 foregroundTokenDied(this); 6325 } 6326 }; 6327 newToken.pid = pid; 6328 newToken.token = token; 6329 try { 6330 token.linkToDeath(newToken, 0); 6331 mForegroundProcesses.put(pid, newToken); 6332 pr.forcingToForeground = token; 6333 changed = true; 6334 } catch (RemoteException e) { 6335 // If the process died while doing this, we will later 6336 // do the cleanup with the process death link. 6337 } 6338 } 6339 } 6340 6341 if (changed) { 6342 updateOomAdjLocked(); 6343 } 6344 } 6345 } 6346 6347 // ========================================================= 6348 // PERMISSIONS 6349 // ========================================================= 6350 6351 static class PermissionController extends IPermissionController.Stub { 6352 ActivityManagerService mActivityManagerService; 6353 PermissionController(ActivityManagerService activityManagerService) { 6354 mActivityManagerService = activityManagerService; 6355 } 6356 6357 @Override 6358 public boolean checkPermission(String permission, int pid, int uid) { 6359 return mActivityManagerService.checkPermission(permission, pid, 6360 uid) == PackageManager.PERMISSION_GRANTED; 6361 } 6362 } 6363 6364 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6365 @Override 6366 public int checkComponentPermission(String permission, int pid, int uid, 6367 int owningUid, boolean exported) { 6368 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6369 owningUid, exported); 6370 } 6371 6372 @Override 6373 public Object getAMSLock() { 6374 return ActivityManagerService.this; 6375 } 6376 } 6377 6378 /** 6379 * This can be called with or without the global lock held. 6380 */ 6381 int checkComponentPermission(String permission, int pid, int uid, 6382 int owningUid, boolean exported) { 6383 // We might be performing an operation on behalf of an indirect binder 6384 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6385 // client identity accordingly before proceeding. 6386 Identity tlsIdentity = sCallerIdentity.get(); 6387 if (tlsIdentity != null) { 6388 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6389 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6390 uid = tlsIdentity.uid; 6391 pid = tlsIdentity.pid; 6392 } 6393 6394 if (pid == MY_PID) { 6395 return PackageManager.PERMISSION_GRANTED; 6396 } 6397 6398 return ActivityManager.checkComponentPermission(permission, uid, 6399 owningUid, exported); 6400 } 6401 6402 /** 6403 * As the only public entry point for permissions checking, this method 6404 * can enforce the semantic that requesting a check on a null global 6405 * permission is automatically denied. (Internally a null permission 6406 * string is used when calling {@link #checkComponentPermission} in cases 6407 * when only uid-based security is needed.) 6408 * 6409 * This can be called with or without the global lock held. 6410 */ 6411 @Override 6412 public int checkPermission(String permission, int pid, int uid) { 6413 if (permission == null) { 6414 return PackageManager.PERMISSION_DENIED; 6415 } 6416 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6417 } 6418 6419 /** 6420 * Binder IPC calls go through the public entry point. 6421 * This can be called with or without the global lock held. 6422 */ 6423 int checkCallingPermission(String permission) { 6424 return checkPermission(permission, 6425 Binder.getCallingPid(), 6426 UserHandle.getAppId(Binder.getCallingUid())); 6427 } 6428 6429 /** 6430 * This can be called with or without the global lock held. 6431 */ 6432 void enforceCallingPermission(String permission, String func) { 6433 if (checkCallingPermission(permission) 6434 == PackageManager.PERMISSION_GRANTED) { 6435 return; 6436 } 6437 6438 String msg = "Permission Denial: " + func + " from pid=" 6439 + Binder.getCallingPid() 6440 + ", uid=" + Binder.getCallingUid() 6441 + " requires " + permission; 6442 Slog.w(TAG, msg); 6443 throw new SecurityException(msg); 6444 } 6445 6446 /** 6447 * Determine if UID is holding permissions required to access {@link Uri} in 6448 * the given {@link ProviderInfo}. Final permission checking is always done 6449 * in {@link ContentProvider}. 6450 */ 6451 private final boolean checkHoldingPermissionsLocked( 6452 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6453 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6454 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6455 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6456 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6457 != PERMISSION_GRANTED) { 6458 return false; 6459 } 6460 } 6461 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6462 } 6463 6464 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6465 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6466 if (pi.applicationInfo.uid == uid) { 6467 return true; 6468 } else if (!pi.exported) { 6469 return false; 6470 } 6471 6472 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6473 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6474 try { 6475 // check if target holds top-level <provider> permissions 6476 if (!readMet && pi.readPermission != null && considerUidPermissions 6477 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6478 readMet = true; 6479 } 6480 if (!writeMet && pi.writePermission != null && considerUidPermissions 6481 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6482 writeMet = true; 6483 } 6484 6485 // track if unprotected read/write is allowed; any denied 6486 // <path-permission> below removes this ability 6487 boolean allowDefaultRead = pi.readPermission == null; 6488 boolean allowDefaultWrite = pi.writePermission == null; 6489 6490 // check if target holds any <path-permission> that match uri 6491 final PathPermission[] pps = pi.pathPermissions; 6492 if (pps != null) { 6493 final String path = grantUri.uri.getPath(); 6494 int i = pps.length; 6495 while (i > 0 && (!readMet || !writeMet)) { 6496 i--; 6497 PathPermission pp = pps[i]; 6498 if (pp.match(path)) { 6499 if (!readMet) { 6500 final String pprperm = pp.getReadPermission(); 6501 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6502 + pprperm + " for " + pp.getPath() 6503 + ": match=" + pp.match(path) 6504 + " check=" + pm.checkUidPermission(pprperm, uid)); 6505 if (pprperm != null) { 6506 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6507 == PERMISSION_GRANTED) { 6508 readMet = true; 6509 } else { 6510 allowDefaultRead = false; 6511 } 6512 } 6513 } 6514 if (!writeMet) { 6515 final String ppwperm = pp.getWritePermission(); 6516 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6517 + ppwperm + " for " + pp.getPath() 6518 + ": match=" + pp.match(path) 6519 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6520 if (ppwperm != null) { 6521 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6522 == PERMISSION_GRANTED) { 6523 writeMet = true; 6524 } else { 6525 allowDefaultWrite = false; 6526 } 6527 } 6528 } 6529 } 6530 } 6531 } 6532 6533 // grant unprotected <provider> read/write, if not blocked by 6534 // <path-permission> above 6535 if (allowDefaultRead) readMet = true; 6536 if (allowDefaultWrite) writeMet = true; 6537 6538 } catch (RemoteException e) { 6539 return false; 6540 } 6541 6542 return readMet && writeMet; 6543 } 6544 6545 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6546 ProviderInfo pi = null; 6547 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6548 if (cpr != null) { 6549 pi = cpr.info; 6550 } else { 6551 try { 6552 pi = AppGlobals.getPackageManager().resolveContentProvider( 6553 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6554 } catch (RemoteException ex) { 6555 } 6556 } 6557 return pi; 6558 } 6559 6560 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6561 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6562 if (targetUris != null) { 6563 return targetUris.get(grantUri); 6564 } 6565 return null; 6566 } 6567 6568 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6569 String targetPkg, int targetUid, GrantUri grantUri) { 6570 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6571 if (targetUris == null) { 6572 targetUris = Maps.newArrayMap(); 6573 mGrantedUriPermissions.put(targetUid, targetUris); 6574 } 6575 6576 UriPermission perm = targetUris.get(grantUri); 6577 if (perm == null) { 6578 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6579 targetUris.put(grantUri, perm); 6580 } 6581 6582 return perm; 6583 } 6584 6585 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6586 final int modeFlags) { 6587 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6588 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6589 : UriPermission.STRENGTH_OWNED; 6590 6591 // Root gets to do everything. 6592 if (uid == 0) { 6593 return true; 6594 } 6595 6596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6597 if (perms == null) return false; 6598 6599 // First look for exact match 6600 final UriPermission exactPerm = perms.get(grantUri); 6601 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6602 return true; 6603 } 6604 6605 // No exact match, look for prefixes 6606 final int N = perms.size(); 6607 for (int i = 0; i < N; i++) { 6608 final UriPermission perm = perms.valueAt(i); 6609 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6610 && perm.getStrength(modeFlags) >= minStrength) { 6611 return true; 6612 } 6613 } 6614 6615 return false; 6616 } 6617 6618 @Override 6619 public int checkUriPermission(Uri uri, int pid, int uid, 6620 final int modeFlags, int userId) { 6621 enforceNotIsolatedCaller("checkUriPermission"); 6622 6623 // Another redirected-binder-call permissions check as in 6624 // {@link checkComponentPermission}. 6625 Identity tlsIdentity = sCallerIdentity.get(); 6626 if (tlsIdentity != null) { 6627 uid = tlsIdentity.uid; 6628 pid = tlsIdentity.pid; 6629 } 6630 6631 // Our own process gets to do everything. 6632 if (pid == MY_PID) { 6633 return PackageManager.PERMISSION_GRANTED; 6634 } 6635 synchronized (this) { 6636 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6637 ? PackageManager.PERMISSION_GRANTED 6638 : PackageManager.PERMISSION_DENIED; 6639 } 6640 } 6641 6642 /** 6643 * Check if the targetPkg can be granted permission to access uri by 6644 * the callingUid using the given modeFlags. Throws a security exception 6645 * if callingUid is not allowed to do this. Returns the uid of the target 6646 * if the URI permission grant should be performed; returns -1 if it is not 6647 * needed (for example targetPkg already has permission to access the URI). 6648 * If you already know the uid of the target, you can supply it in 6649 * lastTargetUid else set that to -1. 6650 */ 6651 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6652 final int modeFlags, int lastTargetUid) { 6653 if (!Intent.isAccessUriMode(modeFlags)) { 6654 return -1; 6655 } 6656 6657 if (targetPkg != null) { 6658 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6659 "Checking grant " + targetPkg + " permission to " + grantUri); 6660 } 6661 6662 final IPackageManager pm = AppGlobals.getPackageManager(); 6663 6664 // If this is not a content: uri, we can't do anything with it. 6665 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6666 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6667 "Can't grant URI permission for non-content URI: " + grantUri); 6668 return -1; 6669 } 6670 6671 final String authority = grantUri.uri.getAuthority(); 6672 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6673 if (pi == null) { 6674 Slog.w(TAG, "No content provider found for permission check: " + 6675 grantUri.uri.toSafeString()); 6676 return -1; 6677 } 6678 6679 int targetUid = lastTargetUid; 6680 if (targetUid < 0 && targetPkg != null) { 6681 try { 6682 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6683 if (targetUid < 0) { 6684 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6685 "Can't grant URI permission no uid for: " + targetPkg); 6686 return -1; 6687 } 6688 } catch (RemoteException ex) { 6689 return -1; 6690 } 6691 } 6692 6693 if (targetUid >= 0) { 6694 // First... does the target actually need this permission? 6695 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6696 // No need to grant the target this permission. 6697 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6698 "Target " + targetPkg + " already has full permission to " + grantUri); 6699 return -1; 6700 } 6701 } else { 6702 // First... there is no target package, so can anyone access it? 6703 boolean allowed = pi.exported; 6704 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6705 if (pi.readPermission != null) { 6706 allowed = false; 6707 } 6708 } 6709 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6710 if (pi.writePermission != null) { 6711 allowed = false; 6712 } 6713 } 6714 if (allowed) { 6715 return -1; 6716 } 6717 } 6718 6719 /* There is a special cross user grant if: 6720 * - The target is on another user. 6721 * - Apps on the current user can access the uri without any uid permissions. 6722 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6723 * grant uri permissions. 6724 */ 6725 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6726 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6727 modeFlags, false /*without considering the uid permissions*/); 6728 6729 // Second... is the provider allowing granting of URI permissions? 6730 if (!specialCrossUserGrant) { 6731 if (!pi.grantUriPermissions) { 6732 throw new SecurityException("Provider " + pi.packageName 6733 + "/" + pi.name 6734 + " does not allow granting of Uri permissions (uri " 6735 + grantUri + ")"); 6736 } 6737 if (pi.uriPermissionPatterns != null) { 6738 final int N = pi.uriPermissionPatterns.length; 6739 boolean allowed = false; 6740 for (int i=0; i<N; i++) { 6741 if (pi.uriPermissionPatterns[i] != null 6742 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6743 allowed = true; 6744 break; 6745 } 6746 } 6747 if (!allowed) { 6748 throw new SecurityException("Provider " + pi.packageName 6749 + "/" + pi.name 6750 + " does not allow granting of permission to path of Uri " 6751 + grantUri); 6752 } 6753 } 6754 } 6755 6756 // Third... does the caller itself have permission to access 6757 // this uri? 6758 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6759 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6760 // Require they hold a strong enough Uri permission 6761 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6762 throw new SecurityException("Uid " + callingUid 6763 + " does not have permission to uri " + grantUri); 6764 } 6765 } 6766 } 6767 return targetUid; 6768 } 6769 6770 @Override 6771 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6772 final int modeFlags, int userId) { 6773 enforceNotIsolatedCaller("checkGrantUriPermission"); 6774 synchronized(this) { 6775 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6776 new GrantUri(userId, uri, false), modeFlags, -1); 6777 } 6778 } 6779 6780 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6781 final int modeFlags, UriPermissionOwner owner) { 6782 if (!Intent.isAccessUriMode(modeFlags)) { 6783 return; 6784 } 6785 6786 // So here we are: the caller has the assumed permission 6787 // to the uri, and the target doesn't. Let's now give this to 6788 // the target. 6789 6790 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6791 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6792 6793 final String authority = grantUri.uri.getAuthority(); 6794 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6795 if (pi == null) { 6796 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6797 return; 6798 } 6799 6800 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6801 grantUri.prefix = true; 6802 } 6803 final UriPermission perm = findOrCreateUriPermissionLocked( 6804 pi.packageName, targetPkg, targetUid, grantUri); 6805 perm.grantModes(modeFlags, owner); 6806 } 6807 6808 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6809 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 6810 if (targetPkg == null) { 6811 throw new NullPointerException("targetPkg"); 6812 } 6813 int targetUid; 6814 final IPackageManager pm = AppGlobals.getPackageManager(); 6815 try { 6816 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6817 } catch (RemoteException ex) { 6818 return; 6819 } 6820 6821 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6822 targetUid); 6823 if (targetUid < 0) { 6824 return; 6825 } 6826 6827 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6828 owner); 6829 } 6830 6831 static class NeededUriGrants extends ArrayList<GrantUri> { 6832 final String targetPkg; 6833 final int targetUid; 6834 final int flags; 6835 6836 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6837 this.targetPkg = targetPkg; 6838 this.targetUid = targetUid; 6839 this.flags = flags; 6840 } 6841 } 6842 6843 /** 6844 * Like checkGrantUriPermissionLocked, but takes an Intent. 6845 */ 6846 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6847 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6848 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6849 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6850 + " clip=" + (intent != null ? intent.getClipData() : null) 6851 + " from " + intent + "; flags=0x" 6852 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6853 6854 if (targetPkg == null) { 6855 throw new NullPointerException("targetPkg"); 6856 } 6857 6858 if (intent == null) { 6859 return null; 6860 } 6861 Uri data = intent.getData(); 6862 ClipData clip = intent.getClipData(); 6863 if (data == null && clip == null) { 6864 return null; 6865 } 6866 // Default userId for uris in the intent (if they don't specify it themselves) 6867 int contentUserHint = intent.getContentUserHint(); 6868 if (contentUserHint == UserHandle.USER_CURRENT) { 6869 contentUserHint = UserHandle.getUserId(callingUid); 6870 } 6871 final IPackageManager pm = AppGlobals.getPackageManager(); 6872 int targetUid; 6873 if (needed != null) { 6874 targetUid = needed.targetUid; 6875 } else { 6876 try { 6877 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6878 } catch (RemoteException ex) { 6879 return null; 6880 } 6881 if (targetUid < 0) { 6882 if (DEBUG_URI_PERMISSION) { 6883 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6884 + " on user " + targetUserId); 6885 } 6886 return null; 6887 } 6888 } 6889 if (data != null) { 6890 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 6891 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6892 targetUid); 6893 if (targetUid > 0) { 6894 if (needed == null) { 6895 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6896 } 6897 needed.add(grantUri); 6898 } 6899 } 6900 if (clip != null) { 6901 for (int i=0; i<clip.getItemCount(); i++) { 6902 Uri uri = clip.getItemAt(i).getUri(); 6903 if (uri != null) { 6904 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 6905 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6906 targetUid); 6907 if (targetUid > 0) { 6908 if (needed == null) { 6909 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6910 } 6911 needed.add(grantUri); 6912 } 6913 } else { 6914 Intent clipIntent = clip.getItemAt(i).getIntent(); 6915 if (clipIntent != null) { 6916 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6917 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6918 if (newNeeded != null) { 6919 needed = newNeeded; 6920 } 6921 } 6922 } 6923 } 6924 } 6925 6926 return needed; 6927 } 6928 6929 /** 6930 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6931 */ 6932 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6933 UriPermissionOwner owner) { 6934 if (needed != null) { 6935 for (int i=0; i<needed.size(); i++) { 6936 GrantUri grantUri = needed.get(i); 6937 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6938 grantUri, needed.flags, owner); 6939 } 6940 } 6941 } 6942 6943 void grantUriPermissionFromIntentLocked(int callingUid, 6944 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6945 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6946 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6947 if (needed == null) { 6948 return; 6949 } 6950 6951 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6952 } 6953 6954 @Override 6955 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6956 final int modeFlags, int userId) { 6957 enforceNotIsolatedCaller("grantUriPermission"); 6958 GrantUri grantUri = new GrantUri(userId, uri, false); 6959 synchronized(this) { 6960 final ProcessRecord r = getRecordForAppLocked(caller); 6961 if (r == null) { 6962 throw new SecurityException("Unable to find app for caller " 6963 + caller 6964 + " when granting permission to uri " + grantUri); 6965 } 6966 if (targetPkg == null) { 6967 throw new IllegalArgumentException("null target"); 6968 } 6969 if (grantUri == null) { 6970 throw new IllegalArgumentException("null uri"); 6971 } 6972 6973 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6974 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6975 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6976 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6977 6978 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 6979 UserHandle.getUserId(r.uid)); 6980 } 6981 } 6982 6983 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6984 if (perm.modeFlags == 0) { 6985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6986 perm.targetUid); 6987 if (perms != null) { 6988 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6989 "Removing " + perm.targetUid + " permission to " + perm.uri); 6990 6991 perms.remove(perm.uri); 6992 if (perms.isEmpty()) { 6993 mGrantedUriPermissions.remove(perm.targetUid); 6994 } 6995 } 6996 } 6997 } 6998 6999 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7000 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7001 7002 final IPackageManager pm = AppGlobals.getPackageManager(); 7003 final String authority = grantUri.uri.getAuthority(); 7004 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7005 if (pi == null) { 7006 Slog.w(TAG, "No content provider found for permission revoke: " 7007 + grantUri.toSafeString()); 7008 return; 7009 } 7010 7011 // Does the caller have this permission on the URI? 7012 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7013 // Right now, if you are not the original owner of the permission, 7014 // you are not allowed to revoke it. 7015 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7016 throw new SecurityException("Uid " + callingUid 7017 + " does not have permission to uri " + grantUri); 7018 //} 7019 } 7020 7021 boolean persistChanged = false; 7022 7023 // Go through all of the permissions and remove any that match. 7024 int N = mGrantedUriPermissions.size(); 7025 for (int i = 0; i < N; i++) { 7026 final int targetUid = mGrantedUriPermissions.keyAt(i); 7027 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7028 7029 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7030 final UriPermission perm = it.next(); 7031 if (perm.uri.sourceUserId == grantUri.sourceUserId 7032 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7033 if (DEBUG_URI_PERMISSION) 7034 Slog.v(TAG, 7035 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7036 persistChanged |= perm.revokeModes( 7037 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7038 if (perm.modeFlags == 0) { 7039 it.remove(); 7040 } 7041 } 7042 } 7043 7044 if (perms.isEmpty()) { 7045 mGrantedUriPermissions.remove(targetUid); 7046 N--; 7047 i--; 7048 } 7049 } 7050 7051 if (persistChanged) { 7052 schedulePersistUriGrants(); 7053 } 7054 } 7055 7056 @Override 7057 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7058 int userId) { 7059 enforceNotIsolatedCaller("revokeUriPermission"); 7060 synchronized(this) { 7061 final ProcessRecord r = getRecordForAppLocked(caller); 7062 if (r == null) { 7063 throw new SecurityException("Unable to find app for caller " 7064 + caller 7065 + " when revoking permission to uri " + uri); 7066 } 7067 if (uri == null) { 7068 Slog.w(TAG, "revokeUriPermission: null uri"); 7069 return; 7070 } 7071 7072 if (!Intent.isAccessUriMode(modeFlags)) { 7073 return; 7074 } 7075 7076 final IPackageManager pm = AppGlobals.getPackageManager(); 7077 final String authority = uri.getAuthority(); 7078 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7079 if (pi == null) { 7080 Slog.w(TAG, "No content provider found for permission revoke: " 7081 + uri.toSafeString()); 7082 return; 7083 } 7084 7085 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7086 } 7087 } 7088 7089 /** 7090 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7091 * given package. 7092 * 7093 * @param packageName Package name to match, or {@code null} to apply to all 7094 * packages. 7095 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7096 * to all users. 7097 * @param persistable If persistable grants should be removed. 7098 */ 7099 private void removeUriPermissionsForPackageLocked( 7100 String packageName, int userHandle, boolean persistable) { 7101 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7102 throw new IllegalArgumentException("Must narrow by either package or user"); 7103 } 7104 7105 boolean persistChanged = false; 7106 7107 int N = mGrantedUriPermissions.size(); 7108 for (int i = 0; i < N; i++) { 7109 final int targetUid = mGrantedUriPermissions.keyAt(i); 7110 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7111 7112 // Only inspect grants matching user 7113 if (userHandle == UserHandle.USER_ALL 7114 || userHandle == UserHandle.getUserId(targetUid)) { 7115 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7116 final UriPermission perm = it.next(); 7117 7118 // Only inspect grants matching package 7119 if (packageName == null || perm.sourcePkg.equals(packageName) 7120 || perm.targetPkg.equals(packageName)) { 7121 persistChanged |= perm.revokeModes( 7122 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7123 7124 // Only remove when no modes remain; any persisted grants 7125 // will keep this alive. 7126 if (perm.modeFlags == 0) { 7127 it.remove(); 7128 } 7129 } 7130 } 7131 7132 if (perms.isEmpty()) { 7133 mGrantedUriPermissions.remove(targetUid); 7134 N--; 7135 i--; 7136 } 7137 } 7138 } 7139 7140 if (persistChanged) { 7141 schedulePersistUriGrants(); 7142 } 7143 } 7144 7145 @Override 7146 public IBinder newUriPermissionOwner(String name) { 7147 enforceNotIsolatedCaller("newUriPermissionOwner"); 7148 synchronized(this) { 7149 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7150 return owner.getExternalTokenLocked(); 7151 } 7152 } 7153 7154 @Override 7155 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7156 final int modeFlags, int sourceUserId, int targetUserId) { 7157 synchronized(this) { 7158 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7159 if (owner == null) { 7160 throw new IllegalArgumentException("Unknown owner: " + token); 7161 } 7162 if (fromUid != Binder.getCallingUid()) { 7163 if (Binder.getCallingUid() != Process.myUid()) { 7164 // Only system code can grant URI permissions on behalf 7165 // of other users. 7166 throw new SecurityException("nice try"); 7167 } 7168 } 7169 if (targetPkg == null) { 7170 throw new IllegalArgumentException("null target"); 7171 } 7172 if (uri == null) { 7173 throw new IllegalArgumentException("null uri"); 7174 } 7175 7176 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7177 modeFlags, owner, targetUserId); 7178 } 7179 } 7180 7181 @Override 7182 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7183 synchronized(this) { 7184 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7185 if (owner == null) { 7186 throw new IllegalArgumentException("Unknown owner: " + token); 7187 } 7188 7189 if (uri == null) { 7190 owner.removeUriPermissionsLocked(mode); 7191 } else { 7192 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7193 } 7194 } 7195 } 7196 7197 private void schedulePersistUriGrants() { 7198 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7199 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7200 10 * DateUtils.SECOND_IN_MILLIS); 7201 } 7202 } 7203 7204 private void writeGrantedUriPermissions() { 7205 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7206 7207 // Snapshot permissions so we can persist without lock 7208 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7209 synchronized (this) { 7210 final int size = mGrantedUriPermissions.size(); 7211 for (int i = 0; i < size; i++) { 7212 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7213 for (UriPermission perm : perms.values()) { 7214 if (perm.persistedModeFlags != 0) { 7215 persist.add(perm.snapshot()); 7216 } 7217 } 7218 } 7219 } 7220 7221 FileOutputStream fos = null; 7222 try { 7223 fos = mGrantFile.startWrite(); 7224 7225 XmlSerializer out = new FastXmlSerializer(); 7226 out.setOutput(fos, "utf-8"); 7227 out.startDocument(null, true); 7228 out.startTag(null, TAG_URI_GRANTS); 7229 for (UriPermission.Snapshot perm : persist) { 7230 out.startTag(null, TAG_URI_GRANT); 7231 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7232 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7233 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7234 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7235 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7236 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7237 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7238 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7239 out.endTag(null, TAG_URI_GRANT); 7240 } 7241 out.endTag(null, TAG_URI_GRANTS); 7242 out.endDocument(); 7243 7244 mGrantFile.finishWrite(fos); 7245 } catch (IOException e) { 7246 if (fos != null) { 7247 mGrantFile.failWrite(fos); 7248 } 7249 } 7250 } 7251 7252 private void readGrantedUriPermissionsLocked() { 7253 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7254 7255 final long now = System.currentTimeMillis(); 7256 7257 FileInputStream fis = null; 7258 try { 7259 fis = mGrantFile.openRead(); 7260 final XmlPullParser in = Xml.newPullParser(); 7261 in.setInput(fis, null); 7262 7263 int type; 7264 while ((type = in.next()) != END_DOCUMENT) { 7265 final String tag = in.getName(); 7266 if (type == START_TAG) { 7267 if (TAG_URI_GRANT.equals(tag)) { 7268 final int sourceUserId; 7269 final int targetUserId; 7270 final int userHandle = readIntAttribute(in, 7271 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7272 if (userHandle != UserHandle.USER_NULL) { 7273 // For backwards compatibility. 7274 sourceUserId = userHandle; 7275 targetUserId = userHandle; 7276 } else { 7277 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7278 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7279 } 7280 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7281 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7282 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7283 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7284 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7285 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7286 7287 // Sanity check that provider still belongs to source package 7288 final ProviderInfo pi = getProviderInfoLocked( 7289 uri.getAuthority(), sourceUserId); 7290 if (pi != null && sourcePkg.equals(pi.packageName)) { 7291 int targetUid = -1; 7292 try { 7293 targetUid = AppGlobals.getPackageManager() 7294 .getPackageUid(targetPkg, targetUserId); 7295 } catch (RemoteException e) { 7296 } 7297 if (targetUid != -1) { 7298 final UriPermission perm = findOrCreateUriPermissionLocked( 7299 sourcePkg, targetPkg, targetUid, 7300 new GrantUri(sourceUserId, uri, prefix)); 7301 perm.initPersistedModes(modeFlags, createdTime); 7302 } 7303 } else { 7304 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7305 + " but instead found " + pi); 7306 } 7307 } 7308 } 7309 } 7310 } catch (FileNotFoundException e) { 7311 // Missing grants is okay 7312 } catch (IOException e) { 7313 Log.wtf(TAG, "Failed reading Uri grants", e); 7314 } catch (XmlPullParserException e) { 7315 Log.wtf(TAG, "Failed reading Uri grants", e); 7316 } finally { 7317 IoUtils.closeQuietly(fis); 7318 } 7319 } 7320 7321 @Override 7322 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7323 enforceNotIsolatedCaller("takePersistableUriPermission"); 7324 7325 Preconditions.checkFlagsArgument(modeFlags, 7326 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7327 7328 synchronized (this) { 7329 final int callingUid = Binder.getCallingUid(); 7330 boolean persistChanged = false; 7331 GrantUri grantUri = new GrantUri(userId, uri, false); 7332 7333 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7334 new GrantUri(userId, uri, false)); 7335 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7336 new GrantUri(userId, uri, true)); 7337 7338 final boolean exactValid = (exactPerm != null) 7339 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7340 final boolean prefixValid = (prefixPerm != null) 7341 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7342 7343 if (!(exactValid || prefixValid)) { 7344 throw new SecurityException("No persistable permission grants found for UID " 7345 + callingUid + " and Uri " + grantUri.toSafeString()); 7346 } 7347 7348 if (exactValid) { 7349 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7350 } 7351 if (prefixValid) { 7352 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7353 } 7354 7355 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7356 7357 if (persistChanged) { 7358 schedulePersistUriGrants(); 7359 } 7360 } 7361 } 7362 7363 @Override 7364 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7365 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7366 7367 Preconditions.checkFlagsArgument(modeFlags, 7368 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7369 7370 synchronized (this) { 7371 final int callingUid = Binder.getCallingUid(); 7372 boolean persistChanged = false; 7373 7374 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7375 new GrantUri(userId, uri, false)); 7376 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7377 new GrantUri(userId, uri, true)); 7378 if (exactPerm == null && prefixPerm == null) { 7379 throw new SecurityException("No permission grants found for UID " + callingUid 7380 + " and Uri " + uri.toSafeString()); 7381 } 7382 7383 if (exactPerm != null) { 7384 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7385 removeUriPermissionIfNeededLocked(exactPerm); 7386 } 7387 if (prefixPerm != null) { 7388 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7389 removeUriPermissionIfNeededLocked(prefixPerm); 7390 } 7391 7392 if (persistChanged) { 7393 schedulePersistUriGrants(); 7394 } 7395 } 7396 } 7397 7398 /** 7399 * Prune any older {@link UriPermission} for the given UID until outstanding 7400 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7401 * 7402 * @return if any mutations occured that require persisting. 7403 */ 7404 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7405 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7406 if (perms == null) return false; 7407 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7408 7409 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7410 for (UriPermission perm : perms.values()) { 7411 if (perm.persistedModeFlags != 0) { 7412 persisted.add(perm); 7413 } 7414 } 7415 7416 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7417 if (trimCount <= 0) return false; 7418 7419 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7420 for (int i = 0; i < trimCount; i++) { 7421 final UriPermission perm = persisted.get(i); 7422 7423 if (DEBUG_URI_PERMISSION) { 7424 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7425 } 7426 7427 perm.releasePersistableModes(~0); 7428 removeUriPermissionIfNeededLocked(perm); 7429 } 7430 7431 return true; 7432 } 7433 7434 @Override 7435 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7436 String packageName, boolean incoming) { 7437 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7438 Preconditions.checkNotNull(packageName, "packageName"); 7439 7440 final int callingUid = Binder.getCallingUid(); 7441 final IPackageManager pm = AppGlobals.getPackageManager(); 7442 try { 7443 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7444 if (packageUid != callingUid) { 7445 throw new SecurityException( 7446 "Package " + packageName + " does not belong to calling UID " + callingUid); 7447 } 7448 } catch (RemoteException e) { 7449 throw new SecurityException("Failed to verify package name ownership"); 7450 } 7451 7452 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7453 synchronized (this) { 7454 if (incoming) { 7455 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7456 callingUid); 7457 if (perms == null) { 7458 Slog.w(TAG, "No permission grants found for " + packageName); 7459 } else { 7460 for (UriPermission perm : perms.values()) { 7461 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7462 result.add(perm.buildPersistedPublicApiObject()); 7463 } 7464 } 7465 } 7466 } else { 7467 final int size = mGrantedUriPermissions.size(); 7468 for (int i = 0; i < size; i++) { 7469 final ArrayMap<GrantUri, UriPermission> perms = 7470 mGrantedUriPermissions.valueAt(i); 7471 for (UriPermission perm : perms.values()) { 7472 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7473 result.add(perm.buildPersistedPublicApiObject()); 7474 } 7475 } 7476 } 7477 } 7478 } 7479 return new ParceledListSlice<android.content.UriPermission>(result); 7480 } 7481 7482 @Override 7483 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7484 synchronized (this) { 7485 ProcessRecord app = 7486 who != null ? getRecordForAppLocked(who) : null; 7487 if (app == null) return; 7488 7489 Message msg = Message.obtain(); 7490 msg.what = WAIT_FOR_DEBUGGER_MSG; 7491 msg.obj = app; 7492 msg.arg1 = waiting ? 1 : 0; 7493 mHandler.sendMessage(msg); 7494 } 7495 } 7496 7497 @Override 7498 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7499 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7500 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7501 outInfo.availMem = Process.getFreeMemory(); 7502 outInfo.totalMem = Process.getTotalMemory(); 7503 outInfo.threshold = homeAppMem; 7504 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7505 outInfo.hiddenAppThreshold = cachedAppMem; 7506 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7507 ProcessList.SERVICE_ADJ); 7508 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7509 ProcessList.VISIBLE_APP_ADJ); 7510 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7511 ProcessList.FOREGROUND_APP_ADJ); 7512 } 7513 7514 // ========================================================= 7515 // TASK MANAGEMENT 7516 // ========================================================= 7517 7518 @Override 7519 public List<IAppTask> getAppTasks() { 7520 final PackageManager pm = mContext.getPackageManager(); 7521 int callingUid = Binder.getCallingUid(); 7522 long ident = Binder.clearCallingIdentity(); 7523 7524 // Compose the list of packages for this id to test against 7525 HashSet<String> packages = new HashSet<String>(); 7526 String[] uidPackages = pm.getPackagesForUid(callingUid); 7527 for (int i = 0; i < uidPackages.length; i++) { 7528 packages.add(uidPackages[i]); 7529 } 7530 7531 synchronized(this) { 7532 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7533 try { 7534 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7535 7536 final int N = mRecentTasks.size(); 7537 for (int i = 0; i < N; i++) { 7538 TaskRecord tr = mRecentTasks.get(i); 7539 // Skip tasks that do not match the package name 7540 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7541 ActivityManager.RecentTaskInfo taskInfo = 7542 createRecentTaskInfoFromTaskRecord(tr); 7543 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7544 list.add(taskImpl); 7545 } 7546 } 7547 } finally { 7548 Binder.restoreCallingIdentity(ident); 7549 } 7550 return list; 7551 } 7552 } 7553 7554 @Override 7555 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7556 final int callingUid = Binder.getCallingUid(); 7557 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7558 7559 synchronized(this) { 7560 if (localLOGV) Slog.v( 7561 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7562 7563 final boolean allowed = checkCallingPermission( 7564 android.Manifest.permission.GET_TASKS) 7565 == PackageManager.PERMISSION_GRANTED; 7566 if (!allowed) { 7567 Slog.w(TAG, "getTasks: caller " + callingUid 7568 + " does not hold GET_TASKS; limiting output"); 7569 } 7570 7571 // TODO: Improve with MRU list from all ActivityStacks. 7572 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7573 } 7574 7575 return list; 7576 } 7577 7578 TaskRecord getMostRecentTask() { 7579 return mRecentTasks.get(0); 7580 } 7581 7582 /** 7583 * Creates a new RecentTaskInfo from a TaskRecord. 7584 */ 7585 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7586 // Update the task description to reflect any changes in the task stack 7587 tr.updateTaskDescription(); 7588 7589 // Compose the recent task info 7590 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7591 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7592 rti.persistentId = tr.taskId; 7593 rti.baseIntent = new Intent(tr.getBaseIntent()); 7594 rti.origActivity = tr.origActivity; 7595 rti.description = tr.lastDescription; 7596 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7597 rti.userId = tr.userId; 7598 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7599 rti.firstActiveTime = tr.firstActiveTime; 7600 rti.lastActiveTime = tr.lastActiveTime; 7601 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7602 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 7603 return rti; 7604 } 7605 7606 @Override 7607 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7608 final int callingUid = Binder.getCallingUid(); 7609 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7610 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7611 7612 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7613 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7614 synchronized (this) { 7615 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7616 == PackageManager.PERMISSION_GRANTED; 7617 if (!allowed) { 7618 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7619 + " does not hold GET_TASKS; limiting output"); 7620 } 7621 final boolean detailed = checkCallingPermission( 7622 android.Manifest.permission.GET_DETAILED_TASKS) 7623 == PackageManager.PERMISSION_GRANTED; 7624 7625 IPackageManager pm = AppGlobals.getPackageManager(); 7626 7627 final int N = mRecentTasks.size(); 7628 ArrayList<ActivityManager.RecentTaskInfo> res 7629 = new ArrayList<ActivityManager.RecentTaskInfo>( 7630 maxNum < N ? maxNum : N); 7631 7632 final Set<Integer> includedUsers; 7633 if (includeProfiles) { 7634 includedUsers = getProfileIdsLocked(userId); 7635 } else { 7636 includedUsers = new HashSet<Integer>(); 7637 } 7638 includedUsers.add(Integer.valueOf(userId)); 7639 7640 // Regroup affiliated tasks together. 7641 for (int i = 0; i < N; ) { 7642 TaskRecord task = mRecentTasks.remove(i); 7643 if (mTmpRecents.contains(task)) { 7644 continue; 7645 } 7646 int affiliatedTaskId = task.mAffiliatedTaskId; 7647 while (true) { 7648 TaskRecord next = task.mNextAffiliate; 7649 if (next == null) { 7650 break; 7651 } 7652 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7653 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7654 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7655 task.setNextAffiliate(null); 7656 if (next.mPrevAffiliate == task) { 7657 next.setPrevAffiliate(null); 7658 } 7659 break; 7660 } 7661 if (next.mPrevAffiliate != task) { 7662 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7663 next.mPrevAffiliate + " task=" + task); 7664 next.setPrevAffiliate(null); 7665 break; 7666 } 7667 if (!mRecentTasks.contains(next)) { 7668 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7669 task.setNextAffiliate(null); 7670 if (next.mPrevAffiliate == task) { 7671 next.setPrevAffiliate(null); 7672 } 7673 break; 7674 } 7675 task = next; 7676 } 7677 // task is now the end of the list 7678 do { 7679 mRecentTasks.remove(task); 7680 mRecentTasks.add(i++, task); 7681 mTmpRecents.add(task); 7682 } while ((task = task.mPrevAffiliate) != null); 7683 } 7684 mTmpRecents.clear(); 7685 // mRecentTasks is now in sorted, affiliated order. 7686 7687 for (int i=0; i<N && maxNum > 0; i++) { 7688 TaskRecord tr = mRecentTasks.get(i); 7689 // Only add calling user or related users recent tasks 7690 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 7691 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 7692 continue; 7693 } 7694 7695 // Return the entry if desired by the caller. We always return 7696 // the first entry, because callers always expect this to be the 7697 // foreground app. We may filter others if the caller has 7698 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7699 // we should exclude the entry. 7700 7701 if (i == 0 7702 || withExcluded 7703 || (tr.intent == null) 7704 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7705 == 0)) { 7706 if (!allowed) { 7707 // If the caller doesn't have the GET_TASKS permission, then only 7708 // allow them to see a small subset of tasks -- their own and home. 7709 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7710 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 7711 continue; 7712 } 7713 } 7714 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7715 // Don't include auto remove tasks that are finished or finishing. 7716 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 7717 + tr); 7718 continue; 7719 } 7720 7721 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7722 if (!detailed) { 7723 rti.baseIntent.replaceExtras((Bundle)null); 7724 } 7725 7726 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7727 // Check whether this activity is currently available. 7728 try { 7729 if (rti.origActivity != null) { 7730 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7731 == null) { 7732 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: " 7733 + tr); 7734 continue; 7735 } 7736 } else if (rti.baseIntent != null) { 7737 if (pm.queryIntentActivities(rti.baseIntent, 7738 null, 0, userId) == null) { 7739 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: " 7740 + tr); 7741 continue; 7742 } 7743 } 7744 } catch (RemoteException e) { 7745 // Will never happen. 7746 } 7747 } 7748 7749 res.add(rti); 7750 maxNum--; 7751 } 7752 } 7753 return res; 7754 } 7755 } 7756 7757 private TaskRecord recentTaskForIdLocked(int id) { 7758 final int N = mRecentTasks.size(); 7759 for (int i=0; i<N; i++) { 7760 TaskRecord tr = mRecentTasks.get(i); 7761 if (tr.taskId == id) { 7762 return tr; 7763 } 7764 } 7765 return null; 7766 } 7767 7768 @Override 7769 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7770 synchronized (this) { 7771 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7772 "getTaskThumbnail()"); 7773 TaskRecord tr = recentTaskForIdLocked(id); 7774 if (tr != null) { 7775 return tr.getTaskThumbnailLocked(); 7776 } 7777 } 7778 return null; 7779 } 7780 7781 @Override 7782 public int addAppTask(IBinder activityToken, Intent intent, 7783 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 7784 final int callingUid = Binder.getCallingUid(); 7785 final long callingIdent = Binder.clearCallingIdentity(); 7786 7787 try { 7788 synchronized (this) { 7789 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 7790 if (r == null) { 7791 throw new IllegalArgumentException("Activity does not exist; token=" 7792 + activityToken); 7793 } 7794 ComponentName comp = intent.getComponent(); 7795 if (comp == null) { 7796 throw new IllegalArgumentException("Intent " + intent 7797 + " must specify explicit component"); 7798 } 7799 if (thumbnail.getWidth() != mThumbnailWidth 7800 || thumbnail.getHeight() != mThumbnailHeight) { 7801 throw new IllegalArgumentException("Bad thumbnail size: got " 7802 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 7803 + mThumbnailWidth + "x" + mThumbnailHeight); 7804 } 7805 if (intent.getSelector() != null) { 7806 intent.setSelector(null); 7807 } 7808 if (intent.getSourceBounds() != null) { 7809 intent.setSourceBounds(null); 7810 } 7811 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 7812 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 7813 // The caller has added this as an auto-remove task... that makes no 7814 // sense, so turn off auto-remove. 7815 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 7816 } 7817 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 7818 // Must be a new task. 7819 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7820 } 7821 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 7822 mLastAddedTaskActivity = null; 7823 } 7824 ActivityInfo ainfo = mLastAddedTaskActivity; 7825 if (ainfo == null) { 7826 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 7827 comp, 0, UserHandle.getUserId(callingUid)); 7828 if (ainfo.applicationInfo.uid != callingUid) { 7829 throw new SecurityException( 7830 "Can't add task for another application: target uid=" 7831 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 7832 } 7833 } 7834 7835 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 7836 intent, description); 7837 7838 int trimIdx = trimRecentsForTask(task, false); 7839 if (trimIdx >= 0) { 7840 // If this would have caused a trim, then we'll abort because that 7841 // means it would be added at the end of the list but then just removed. 7842 return -1; 7843 } 7844 7845 final int N = mRecentTasks.size(); 7846 if (N >= (MAX_RECENT_TASKS-1)) { 7847 final TaskRecord tr = mRecentTasks.remove(N - 1); 7848 tr.disposeThumbnail(); 7849 tr.closeRecentsChain(); 7850 } 7851 7852 mRecentTasks.add(task); 7853 r.task.stack.addTask(task, false, false); 7854 7855 task.setLastThumbnail(thumbnail); 7856 task.freeLastThumbnail(); 7857 7858 return task.taskId; 7859 } 7860 } finally { 7861 Binder.restoreCallingIdentity(callingIdent); 7862 } 7863 } 7864 7865 @Override 7866 public Point getAppTaskThumbnailSize() { 7867 synchronized (this) { 7868 return new Point(mThumbnailWidth, mThumbnailHeight); 7869 } 7870 } 7871 7872 @Override 7873 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7874 synchronized (this) { 7875 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7876 if (r != null) { 7877 r.taskDescription = td; 7878 r.task.updateTaskDescription(); 7879 } 7880 } 7881 } 7882 7883 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7884 if (!pr.killedByAm) { 7885 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7886 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7887 pr.processName, pr.setAdj, reason); 7888 pr.killedByAm = true; 7889 Process.killProcessQuiet(pr.pid); 7890 Process.killProcessGroup(pr.info.uid, pr.pid); 7891 } 7892 } 7893 7894 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7895 tr.disposeThumbnail(); 7896 mRecentTasks.remove(tr); 7897 tr.closeRecentsChain(); 7898 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7899 Intent baseIntent = new Intent( 7900 tr.intent != null ? tr.intent : tr.affinityIntent); 7901 ComponentName component = baseIntent.getComponent(); 7902 if (component == null) { 7903 Slog.w(TAG, "Now component for base intent of task: " + tr); 7904 return; 7905 } 7906 7907 // Find any running services associated with this app. 7908 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7909 7910 if (killProcesses) { 7911 // Find any running processes associated with this app. 7912 final String pkg = component.getPackageName(); 7913 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7914 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7915 for (int i=0; i<pmap.size(); i++) { 7916 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7917 for (int j=0; j<uids.size(); j++) { 7918 ProcessRecord proc = uids.valueAt(j); 7919 if (proc.userId != tr.userId) { 7920 continue; 7921 } 7922 if (!proc.pkgList.containsKey(pkg)) { 7923 continue; 7924 } 7925 procs.add(proc); 7926 } 7927 } 7928 7929 // Kill the running processes. 7930 for (int i=0; i<procs.size(); i++) { 7931 ProcessRecord pr = procs.get(i); 7932 if (pr == mHomeProcess) { 7933 // Don't kill the home process along with tasks from the same package. 7934 continue; 7935 } 7936 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7937 killUnneededProcessLocked(pr, "remove task"); 7938 } else { 7939 pr.waitingToKill = "remove task"; 7940 } 7941 } 7942 } 7943 } 7944 7945 /** 7946 * Removes the task with the specified task id. 7947 * 7948 * @param taskId Identifier of the task to be removed. 7949 * @param flags Additional operational flags. May be 0 or 7950 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7951 * @return Returns true if the given task was found and removed. 7952 */ 7953 private boolean removeTaskByIdLocked(int taskId, int flags) { 7954 TaskRecord tr = recentTaskForIdLocked(taskId); 7955 if (tr != null) { 7956 tr.removeTaskActivitiesLocked(); 7957 cleanUpRemovedTaskLocked(tr, flags); 7958 if (tr.isPersistable) { 7959 notifyTaskPersisterLocked(null, true); 7960 } 7961 return true; 7962 } 7963 return false; 7964 } 7965 7966 @Override 7967 public boolean removeTask(int taskId, int flags) { 7968 synchronized (this) { 7969 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7970 "removeTask()"); 7971 long ident = Binder.clearCallingIdentity(); 7972 try { 7973 return removeTaskByIdLocked(taskId, flags); 7974 } finally { 7975 Binder.restoreCallingIdentity(ident); 7976 } 7977 } 7978 } 7979 7980 /** 7981 * TODO: Add mController hook 7982 */ 7983 @Override 7984 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7985 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7986 "moveTaskToFront()"); 7987 7988 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7989 synchronized(this) { 7990 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7991 Binder.getCallingUid(), "Task to front")) { 7992 ActivityOptions.abort(options); 7993 return; 7994 } 7995 final long origId = Binder.clearCallingIdentity(); 7996 try { 7997 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7998 if (task == null) { 7999 return; 8000 } 8001 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8002 mStackSupervisor.showLockTaskToast(); 8003 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8004 return; 8005 } 8006 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8007 if (prev != null && prev.isRecentsActivity()) { 8008 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8009 } 8010 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8011 } finally { 8012 Binder.restoreCallingIdentity(origId); 8013 } 8014 ActivityOptions.abort(options); 8015 } 8016 } 8017 8018 @Override 8019 public void moveTaskToBack(int taskId) { 8020 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8021 "moveTaskToBack()"); 8022 8023 synchronized(this) { 8024 TaskRecord tr = recentTaskForIdLocked(taskId); 8025 if (tr != null) { 8026 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8027 ActivityStack stack = tr.stack; 8028 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8029 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8030 Binder.getCallingUid(), "Task to back")) { 8031 return; 8032 } 8033 } 8034 final long origId = Binder.clearCallingIdentity(); 8035 try { 8036 stack.moveTaskToBackLocked(taskId, null); 8037 } finally { 8038 Binder.restoreCallingIdentity(origId); 8039 } 8040 } 8041 } 8042 } 8043 8044 /** 8045 * Moves an activity, and all of the other activities within the same task, to the bottom 8046 * of the history stack. The activity's order within the task is unchanged. 8047 * 8048 * @param token A reference to the activity we wish to move 8049 * @param nonRoot If false then this only works if the activity is the root 8050 * of a task; if true it will work for any activity in a task. 8051 * @return Returns true if the move completed, false if not. 8052 */ 8053 @Override 8054 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8055 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8056 synchronized(this) { 8057 final long origId = Binder.clearCallingIdentity(); 8058 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8059 if (taskId >= 0) { 8060 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8061 } 8062 Binder.restoreCallingIdentity(origId); 8063 } 8064 return false; 8065 } 8066 8067 @Override 8068 public void moveTaskBackwards(int task) { 8069 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8070 "moveTaskBackwards()"); 8071 8072 synchronized(this) { 8073 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8074 Binder.getCallingUid(), "Task backwards")) { 8075 return; 8076 } 8077 final long origId = Binder.clearCallingIdentity(); 8078 moveTaskBackwardsLocked(task); 8079 Binder.restoreCallingIdentity(origId); 8080 } 8081 } 8082 8083 private final void moveTaskBackwardsLocked(int task) { 8084 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8085 } 8086 8087 @Override 8088 public IBinder getHomeActivityToken() throws RemoteException { 8089 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8090 "getHomeActivityToken()"); 8091 synchronized (this) { 8092 return mStackSupervisor.getHomeActivityToken(); 8093 } 8094 } 8095 8096 @Override 8097 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8098 IActivityContainerCallback callback) throws RemoteException { 8099 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8100 "createActivityContainer()"); 8101 synchronized (this) { 8102 if (parentActivityToken == null) { 8103 throw new IllegalArgumentException("parent token must not be null"); 8104 } 8105 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8106 if (r == null) { 8107 return null; 8108 } 8109 if (callback == null) { 8110 throw new IllegalArgumentException("callback must not be null"); 8111 } 8112 return mStackSupervisor.createActivityContainer(r, callback); 8113 } 8114 } 8115 8116 @Override 8117 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8118 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8119 "deleteActivityContainer()"); 8120 synchronized (this) { 8121 mStackSupervisor.deleteActivityContainer(container); 8122 } 8123 } 8124 8125 @Override 8126 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8127 throws RemoteException { 8128 synchronized (this) { 8129 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8130 if (stack != null) { 8131 return stack.mActivityContainer; 8132 } 8133 return null; 8134 } 8135 } 8136 8137 @Override 8138 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8139 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8140 "moveTaskToStack()"); 8141 if (stackId == HOME_STACK_ID) { 8142 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8143 new RuntimeException("here").fillInStackTrace()); 8144 } 8145 synchronized (this) { 8146 long ident = Binder.clearCallingIdentity(); 8147 try { 8148 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8149 + stackId + " toTop=" + toTop); 8150 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8151 } finally { 8152 Binder.restoreCallingIdentity(ident); 8153 } 8154 } 8155 } 8156 8157 @Override 8158 public void resizeStack(int stackBoxId, Rect bounds) { 8159 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8160 "resizeStackBox()"); 8161 long ident = Binder.clearCallingIdentity(); 8162 try { 8163 mWindowManager.resizeStack(stackBoxId, bounds); 8164 } finally { 8165 Binder.restoreCallingIdentity(ident); 8166 } 8167 } 8168 8169 @Override 8170 public List<StackInfo> getAllStackInfos() { 8171 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8172 "getAllStackInfos()"); 8173 long ident = Binder.clearCallingIdentity(); 8174 try { 8175 synchronized (this) { 8176 return mStackSupervisor.getAllStackInfosLocked(); 8177 } 8178 } finally { 8179 Binder.restoreCallingIdentity(ident); 8180 } 8181 } 8182 8183 @Override 8184 public StackInfo getStackInfo(int stackId) { 8185 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8186 "getStackInfo()"); 8187 long ident = Binder.clearCallingIdentity(); 8188 try { 8189 synchronized (this) { 8190 return mStackSupervisor.getStackInfoLocked(stackId); 8191 } 8192 } finally { 8193 Binder.restoreCallingIdentity(ident); 8194 } 8195 } 8196 8197 @Override 8198 public boolean isInHomeStack(int taskId) { 8199 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8200 "getStackInfo()"); 8201 long ident = Binder.clearCallingIdentity(); 8202 try { 8203 synchronized (this) { 8204 TaskRecord tr = recentTaskForIdLocked(taskId); 8205 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8206 } 8207 } finally { 8208 Binder.restoreCallingIdentity(ident); 8209 } 8210 } 8211 8212 @Override 8213 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8214 synchronized(this) { 8215 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8216 } 8217 } 8218 8219 private boolean isLockTaskAuthorized(String pkg) { 8220 final DevicePolicyManager dpm = (DevicePolicyManager) 8221 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8222 try { 8223 int uid = mContext.getPackageManager().getPackageUid(pkg, 8224 Binder.getCallingUserHandle().getIdentifier()); 8225 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8226 } catch (NameNotFoundException e) { 8227 return false; 8228 } 8229 } 8230 8231 void startLockTaskMode(TaskRecord task) { 8232 final String pkg; 8233 synchronized (this) { 8234 pkg = task.intent.getComponent().getPackageName(); 8235 } 8236 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8237 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8238 final TaskRecord taskRecord = task; 8239 mHandler.post(new Runnable() { 8240 @Override 8241 public void run() { 8242 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8243 } 8244 }); 8245 return; 8246 } 8247 long ident = Binder.clearCallingIdentity(); 8248 try { 8249 synchronized (this) { 8250 // Since we lost lock on task, make sure it is still there. 8251 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8252 if (task != null) { 8253 if (!isSystemInitiated 8254 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8255 throw new IllegalArgumentException("Invalid task, not in foreground"); 8256 } 8257 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8258 } 8259 } 8260 } finally { 8261 Binder.restoreCallingIdentity(ident); 8262 } 8263 } 8264 8265 @Override 8266 public void startLockTaskMode(int taskId) { 8267 final TaskRecord task; 8268 long ident = Binder.clearCallingIdentity(); 8269 try { 8270 synchronized (this) { 8271 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8272 } 8273 } finally { 8274 Binder.restoreCallingIdentity(ident); 8275 } 8276 if (task != null) { 8277 startLockTaskMode(task); 8278 } 8279 } 8280 8281 @Override 8282 public void startLockTaskMode(IBinder token) { 8283 final TaskRecord task; 8284 long ident = Binder.clearCallingIdentity(); 8285 try { 8286 synchronized (this) { 8287 final ActivityRecord r = ActivityRecord.forToken(token); 8288 if (r == null) { 8289 return; 8290 } 8291 task = r.task; 8292 } 8293 } finally { 8294 Binder.restoreCallingIdentity(ident); 8295 } 8296 if (task != null) { 8297 startLockTaskMode(task); 8298 } 8299 } 8300 8301 @Override 8302 public void startLockTaskModeOnCurrent() throws RemoteException { 8303 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8304 ActivityRecord r = null; 8305 synchronized (this) { 8306 r = mStackSupervisor.topRunningActivityLocked(); 8307 } 8308 startLockTaskMode(r.task); 8309 } 8310 8311 @Override 8312 public void stopLockTaskMode() { 8313 // Verify that the user matches the package of the intent for the TaskRecord 8314 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8315 // and stopLockTaskMode. 8316 final int callingUid = Binder.getCallingUid(); 8317 if (callingUid != Process.SYSTEM_UID) { 8318 try { 8319 String pkg = 8320 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8321 int uid = mContext.getPackageManager().getPackageUid(pkg, 8322 Binder.getCallingUserHandle().getIdentifier()); 8323 if (uid != callingUid) { 8324 throw new SecurityException("Invalid uid, expected " + uid); 8325 } 8326 } catch (NameNotFoundException e) { 8327 Log.d(TAG, "stopLockTaskMode " + e); 8328 return; 8329 } 8330 } 8331 long ident = Binder.clearCallingIdentity(); 8332 try { 8333 Log.d(TAG, "stopLockTaskMode"); 8334 // Stop lock task 8335 synchronized (this) { 8336 mStackSupervisor.setLockTaskModeLocked(null, false); 8337 } 8338 } finally { 8339 Binder.restoreCallingIdentity(ident); 8340 } 8341 } 8342 8343 @Override 8344 public void stopLockTaskModeOnCurrent() throws RemoteException { 8345 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8346 long ident = Binder.clearCallingIdentity(); 8347 try { 8348 stopLockTaskMode(); 8349 } finally { 8350 Binder.restoreCallingIdentity(ident); 8351 } 8352 } 8353 8354 @Override 8355 public boolean isInLockTaskMode() { 8356 synchronized (this) { 8357 return mStackSupervisor.isInLockTaskMode(); 8358 } 8359 } 8360 8361 // ========================================================= 8362 // CONTENT PROVIDERS 8363 // ========================================================= 8364 8365 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8366 List<ProviderInfo> providers = null; 8367 try { 8368 providers = AppGlobals.getPackageManager(). 8369 queryContentProviders(app.processName, app.uid, 8370 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8371 } catch (RemoteException ex) { 8372 } 8373 if (DEBUG_MU) 8374 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8375 int userId = app.userId; 8376 if (providers != null) { 8377 int N = providers.size(); 8378 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8379 for (int i=0; i<N; i++) { 8380 ProviderInfo cpi = 8381 (ProviderInfo)providers.get(i); 8382 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8383 cpi.name, cpi.flags); 8384 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8385 // This is a singleton provider, but a user besides the 8386 // default user is asking to initialize a process it runs 8387 // in... well, no, it doesn't actually run in this process, 8388 // it runs in the process of the default user. Get rid of it. 8389 providers.remove(i); 8390 N--; 8391 i--; 8392 continue; 8393 } 8394 8395 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8396 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8397 if (cpr == null) { 8398 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8399 mProviderMap.putProviderByClass(comp, cpr); 8400 } 8401 if (DEBUG_MU) 8402 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8403 app.pubProviders.put(cpi.name, cpr); 8404 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8405 // Don't add this if it is a platform component that is marked 8406 // to run in multiple processes, because this is actually 8407 // part of the framework so doesn't make sense to track as a 8408 // separate apk in the process. 8409 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8410 mProcessStats); 8411 } 8412 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8413 } 8414 } 8415 return providers; 8416 } 8417 8418 /** 8419 * Check if {@link ProcessRecord} has a possible chance at accessing the 8420 * given {@link ProviderInfo}. Final permission checking is always done 8421 * in {@link ContentProvider}. 8422 */ 8423 private final String checkContentProviderPermissionLocked( 8424 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8425 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8426 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8427 boolean checkedGrants = false; 8428 if (checkUser) { 8429 // Looking for cross-user grants before enforcing the typical cross-users permissions 8430 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8431 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8432 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8433 return null; 8434 } 8435 checkedGrants = true; 8436 } 8437 userId = handleIncomingUser(callingPid, callingUid, userId, 8438 false, ALLOW_NON_FULL, 8439 "checkContentProviderPermissionLocked " + cpi.authority, null); 8440 if (userId != tmpTargetUserId) { 8441 // When we actually went to determine the final targer user ID, this ended 8442 // up different than our initial check for the authority. This is because 8443 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8444 // SELF. So we need to re-check the grants again. 8445 checkedGrants = false; 8446 } 8447 } 8448 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8449 cpi.applicationInfo.uid, cpi.exported) 8450 == PackageManager.PERMISSION_GRANTED) { 8451 return null; 8452 } 8453 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8454 cpi.applicationInfo.uid, cpi.exported) 8455 == PackageManager.PERMISSION_GRANTED) { 8456 return null; 8457 } 8458 8459 PathPermission[] pps = cpi.pathPermissions; 8460 if (pps != null) { 8461 int i = pps.length; 8462 while (i > 0) { 8463 i--; 8464 PathPermission pp = pps[i]; 8465 String pprperm = pp.getReadPermission(); 8466 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8467 cpi.applicationInfo.uid, cpi.exported) 8468 == PackageManager.PERMISSION_GRANTED) { 8469 return null; 8470 } 8471 String ppwperm = pp.getWritePermission(); 8472 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8473 cpi.applicationInfo.uid, cpi.exported) 8474 == PackageManager.PERMISSION_GRANTED) { 8475 return null; 8476 } 8477 } 8478 } 8479 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8480 return null; 8481 } 8482 8483 String msg; 8484 if (!cpi.exported) { 8485 msg = "Permission Denial: opening provider " + cpi.name 8486 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8487 + ", uid=" + callingUid + ") that is not exported from uid " 8488 + cpi.applicationInfo.uid; 8489 } else { 8490 msg = "Permission Denial: opening provider " + cpi.name 8491 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8492 + ", uid=" + callingUid + ") requires " 8493 + cpi.readPermission + " or " + cpi.writePermission; 8494 } 8495 Slog.w(TAG, msg); 8496 return msg; 8497 } 8498 8499 /** 8500 * Returns if the ContentProvider has granted a uri to callingUid 8501 */ 8502 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8503 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8504 if (perms != null) { 8505 for (int i=perms.size()-1; i>=0; i--) { 8506 GrantUri grantUri = perms.keyAt(i); 8507 if (grantUri.sourceUserId == userId || !checkUser) { 8508 if (matchesProvider(grantUri.uri, cpi)) { 8509 return true; 8510 } 8511 } 8512 } 8513 } 8514 return false; 8515 } 8516 8517 /** 8518 * Returns true if the uri authority is one of the authorities specified in the provider. 8519 */ 8520 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8521 String uriAuth = uri.getAuthority(); 8522 String cpiAuth = cpi.authority; 8523 if (cpiAuth.indexOf(';') == -1) { 8524 return cpiAuth.equals(uriAuth); 8525 } 8526 String[] cpiAuths = cpiAuth.split(";"); 8527 int length = cpiAuths.length; 8528 for (int i = 0; i < length; i++) { 8529 if (cpiAuths[i].equals(uriAuth)) return true; 8530 } 8531 return false; 8532 } 8533 8534 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8535 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8536 if (r != null) { 8537 for (int i=0; i<r.conProviders.size(); i++) { 8538 ContentProviderConnection conn = r.conProviders.get(i); 8539 if (conn.provider == cpr) { 8540 if (DEBUG_PROVIDER) Slog.v(TAG, 8541 "Adding provider requested by " 8542 + r.processName + " from process " 8543 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8544 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8545 if (stable) { 8546 conn.stableCount++; 8547 conn.numStableIncs++; 8548 } else { 8549 conn.unstableCount++; 8550 conn.numUnstableIncs++; 8551 } 8552 return conn; 8553 } 8554 } 8555 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8556 if (stable) { 8557 conn.stableCount = 1; 8558 conn.numStableIncs = 1; 8559 } else { 8560 conn.unstableCount = 1; 8561 conn.numUnstableIncs = 1; 8562 } 8563 cpr.connections.add(conn); 8564 r.conProviders.add(conn); 8565 return conn; 8566 } 8567 cpr.addExternalProcessHandleLocked(externalProcessToken); 8568 return null; 8569 } 8570 8571 boolean decProviderCountLocked(ContentProviderConnection conn, 8572 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8573 if (conn != null) { 8574 cpr = conn.provider; 8575 if (DEBUG_PROVIDER) Slog.v(TAG, 8576 "Removing provider requested by " 8577 + conn.client.processName + " from process " 8578 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8579 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8580 if (stable) { 8581 conn.stableCount--; 8582 } else { 8583 conn.unstableCount--; 8584 } 8585 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8586 cpr.connections.remove(conn); 8587 conn.client.conProviders.remove(conn); 8588 return true; 8589 } 8590 return false; 8591 } 8592 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8593 return false; 8594 } 8595 8596 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8597 String name, IBinder token, boolean stable, int userId) { 8598 ContentProviderRecord cpr; 8599 ContentProviderConnection conn = null; 8600 ProviderInfo cpi = null; 8601 8602 synchronized(this) { 8603 ProcessRecord r = null; 8604 if (caller != null) { 8605 r = getRecordForAppLocked(caller); 8606 if (r == null) { 8607 throw new SecurityException( 8608 "Unable to find app for caller " + caller 8609 + " (pid=" + Binder.getCallingPid() 8610 + ") when getting content provider " + name); 8611 } 8612 } 8613 8614 boolean checkCrossUser = true; 8615 8616 // First check if this content provider has been published... 8617 cpr = mProviderMap.getProviderByName(name, userId); 8618 // If that didn't work, check if it exists for user 0 and then 8619 // verify that it's a singleton provider before using it. 8620 if (cpr == null && userId != UserHandle.USER_OWNER) { 8621 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8622 if (cpr != null) { 8623 cpi = cpr.info; 8624 if (isSingleton(cpi.processName, cpi.applicationInfo, 8625 cpi.name, cpi.flags) 8626 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8627 userId = UserHandle.USER_OWNER; 8628 checkCrossUser = false; 8629 } else { 8630 cpr = null; 8631 cpi = null; 8632 } 8633 } 8634 } 8635 8636 boolean providerRunning = cpr != null; 8637 if (providerRunning) { 8638 cpi = cpr.info; 8639 String msg; 8640 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8641 != null) { 8642 throw new SecurityException(msg); 8643 } 8644 8645 if (r != null && cpr.canRunHere(r)) { 8646 // This provider has been published or is in the process 8647 // of being published... but it is also allowed to run 8648 // in the caller's process, so don't make a connection 8649 // and just let the caller instantiate its own instance. 8650 ContentProviderHolder holder = cpr.newHolder(null); 8651 // don't give caller the provider object, it needs 8652 // to make its own. 8653 holder.provider = null; 8654 return holder; 8655 } 8656 8657 final long origId = Binder.clearCallingIdentity(); 8658 8659 // In this case the provider instance already exists, so we can 8660 // return it right away. 8661 conn = incProviderCountLocked(r, cpr, token, stable); 8662 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8663 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8664 // If this is a perceptible app accessing the provider, 8665 // make sure to count it as being accessed and thus 8666 // back up on the LRU list. This is good because 8667 // content providers are often expensive to start. 8668 updateLruProcessLocked(cpr.proc, false, null); 8669 } 8670 } 8671 8672 if (cpr.proc != null) { 8673 if (false) { 8674 if (cpr.name.flattenToShortString().equals( 8675 "com.android.providers.calendar/.CalendarProvider2")) { 8676 Slog.v(TAG, "****************** KILLING " 8677 + cpr.name.flattenToShortString()); 8678 Process.killProcess(cpr.proc.pid); 8679 } 8680 } 8681 boolean success = updateOomAdjLocked(cpr.proc); 8682 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8683 // NOTE: there is still a race here where a signal could be 8684 // pending on the process even though we managed to update its 8685 // adj level. Not sure what to do about this, but at least 8686 // the race is now smaller. 8687 if (!success) { 8688 // Uh oh... it looks like the provider's process 8689 // has been killed on us. We need to wait for a new 8690 // process to be started, and make sure its death 8691 // doesn't kill our process. 8692 Slog.i(TAG, 8693 "Existing provider " + cpr.name.flattenToShortString() 8694 + " is crashing; detaching " + r); 8695 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8696 appDiedLocked(cpr.proc); 8697 if (!lastRef) { 8698 // This wasn't the last ref our process had on 8699 // the provider... we have now been killed, bail. 8700 return null; 8701 } 8702 providerRunning = false; 8703 conn = null; 8704 } 8705 } 8706 8707 Binder.restoreCallingIdentity(origId); 8708 } 8709 8710 boolean singleton; 8711 if (!providerRunning) { 8712 try { 8713 cpi = AppGlobals.getPackageManager(). 8714 resolveContentProvider(name, 8715 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8716 } catch (RemoteException ex) { 8717 } 8718 if (cpi == null) { 8719 return null; 8720 } 8721 // If the provider is a singleton AND 8722 // (it's a call within the same user || the provider is a 8723 // privileged app) 8724 // Then allow connecting to the singleton provider 8725 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8726 cpi.name, cpi.flags) 8727 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8728 if (singleton) { 8729 userId = UserHandle.USER_OWNER; 8730 } 8731 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8732 8733 String msg; 8734 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8735 != null) { 8736 throw new SecurityException(msg); 8737 } 8738 8739 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8740 && !cpi.processName.equals("system")) { 8741 // If this content provider does not run in the system 8742 // process, and the system is not yet ready to run other 8743 // processes, then fail fast instead of hanging. 8744 throw new IllegalArgumentException( 8745 "Attempt to launch content provider before system ready"); 8746 } 8747 8748 // Make sure that the user who owns this provider is started. If not, 8749 // we don't want to allow it to run. 8750 if (mStartedUsers.get(userId) == null) { 8751 Slog.w(TAG, "Unable to launch app " 8752 + cpi.applicationInfo.packageName + "/" 8753 + cpi.applicationInfo.uid + " for provider " 8754 + name + ": user " + userId + " is stopped"); 8755 return null; 8756 } 8757 8758 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8759 cpr = mProviderMap.getProviderByClass(comp, userId); 8760 final boolean firstClass = cpr == null; 8761 if (firstClass) { 8762 try { 8763 ApplicationInfo ai = 8764 AppGlobals.getPackageManager(). 8765 getApplicationInfo( 8766 cpi.applicationInfo.packageName, 8767 STOCK_PM_FLAGS, userId); 8768 if (ai == null) { 8769 Slog.w(TAG, "No package info for content provider " 8770 + cpi.name); 8771 return null; 8772 } 8773 ai = getAppInfoForUser(ai, userId); 8774 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8775 } catch (RemoteException ex) { 8776 // pm is in same process, this will never happen. 8777 } 8778 } 8779 8780 if (r != null && cpr.canRunHere(r)) { 8781 // If this is a multiprocess provider, then just return its 8782 // info and allow the caller to instantiate it. Only do 8783 // this if the provider is the same user as the caller's 8784 // process, or can run as root (so can be in any process). 8785 return cpr.newHolder(null); 8786 } 8787 8788 if (DEBUG_PROVIDER) { 8789 RuntimeException e = new RuntimeException("here"); 8790 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8791 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8792 } 8793 8794 // This is single process, and our app is now connecting to it. 8795 // See if we are already in the process of launching this 8796 // provider. 8797 final int N = mLaunchingProviders.size(); 8798 int i; 8799 for (i=0; i<N; i++) { 8800 if (mLaunchingProviders.get(i) == cpr) { 8801 break; 8802 } 8803 } 8804 8805 // If the provider is not already being launched, then get it 8806 // started. 8807 if (i >= N) { 8808 final long origId = Binder.clearCallingIdentity(); 8809 8810 try { 8811 // Content provider is now in use, its package can't be stopped. 8812 try { 8813 AppGlobals.getPackageManager().setPackageStoppedState( 8814 cpr.appInfo.packageName, false, userId); 8815 } catch (RemoteException e) { 8816 } catch (IllegalArgumentException e) { 8817 Slog.w(TAG, "Failed trying to unstop package " 8818 + cpr.appInfo.packageName + ": " + e); 8819 } 8820 8821 // Use existing process if already started 8822 ProcessRecord proc = getProcessRecordLocked( 8823 cpi.processName, cpr.appInfo.uid, false); 8824 if (proc != null && proc.thread != null) { 8825 if (DEBUG_PROVIDER) { 8826 Slog.d(TAG, "Installing in existing process " + proc); 8827 } 8828 proc.pubProviders.put(cpi.name, cpr); 8829 try { 8830 proc.thread.scheduleInstallProvider(cpi); 8831 } catch (RemoteException e) { 8832 } 8833 } else { 8834 proc = startProcessLocked(cpi.processName, 8835 cpr.appInfo, false, 0, "content provider", 8836 new ComponentName(cpi.applicationInfo.packageName, 8837 cpi.name), false, false, false); 8838 if (proc == null) { 8839 Slog.w(TAG, "Unable to launch app " 8840 + cpi.applicationInfo.packageName + "/" 8841 + cpi.applicationInfo.uid + " for provider " 8842 + name + ": process is bad"); 8843 return null; 8844 } 8845 } 8846 cpr.launchingApp = proc; 8847 mLaunchingProviders.add(cpr); 8848 } finally { 8849 Binder.restoreCallingIdentity(origId); 8850 } 8851 } 8852 8853 // Make sure the provider is published (the same provider class 8854 // may be published under multiple names). 8855 if (firstClass) { 8856 mProviderMap.putProviderByClass(comp, cpr); 8857 } 8858 8859 mProviderMap.putProviderByName(name, cpr); 8860 conn = incProviderCountLocked(r, cpr, token, stable); 8861 if (conn != null) { 8862 conn.waiting = true; 8863 } 8864 } 8865 } 8866 8867 // Wait for the provider to be published... 8868 synchronized (cpr) { 8869 while (cpr.provider == null) { 8870 if (cpr.launchingApp == null) { 8871 Slog.w(TAG, "Unable to launch app " 8872 + cpi.applicationInfo.packageName + "/" 8873 + cpi.applicationInfo.uid + " for provider " 8874 + name + ": launching app became null"); 8875 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8876 UserHandle.getUserId(cpi.applicationInfo.uid), 8877 cpi.applicationInfo.packageName, 8878 cpi.applicationInfo.uid, name); 8879 return null; 8880 } 8881 try { 8882 if (DEBUG_MU) { 8883 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8884 + cpr.launchingApp); 8885 } 8886 if (conn != null) { 8887 conn.waiting = true; 8888 } 8889 cpr.wait(); 8890 } catch (InterruptedException ex) { 8891 } finally { 8892 if (conn != null) { 8893 conn.waiting = false; 8894 } 8895 } 8896 } 8897 } 8898 return cpr != null ? cpr.newHolder(conn) : null; 8899 } 8900 8901 @Override 8902 public final ContentProviderHolder getContentProvider( 8903 IApplicationThread caller, String name, int userId, boolean stable) { 8904 enforceNotIsolatedCaller("getContentProvider"); 8905 if (caller == null) { 8906 String msg = "null IApplicationThread when getting content provider " 8907 + name; 8908 Slog.w(TAG, msg); 8909 throw new SecurityException(msg); 8910 } 8911 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8912 // with cross-user grant. 8913 return getContentProviderImpl(caller, name, null, stable, userId); 8914 } 8915 8916 public ContentProviderHolder getContentProviderExternal( 8917 String name, int userId, IBinder token) { 8918 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8919 "Do not have permission in call getContentProviderExternal()"); 8920 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8921 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8922 return getContentProviderExternalUnchecked(name, token, userId); 8923 } 8924 8925 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8926 IBinder token, int userId) { 8927 return getContentProviderImpl(null, name, token, true, userId); 8928 } 8929 8930 /** 8931 * Drop a content provider from a ProcessRecord's bookkeeping 8932 */ 8933 public void removeContentProvider(IBinder connection, boolean stable) { 8934 enforceNotIsolatedCaller("removeContentProvider"); 8935 long ident = Binder.clearCallingIdentity(); 8936 try { 8937 synchronized (this) { 8938 ContentProviderConnection conn; 8939 try { 8940 conn = (ContentProviderConnection)connection; 8941 } catch (ClassCastException e) { 8942 String msg ="removeContentProvider: " + connection 8943 + " not a ContentProviderConnection"; 8944 Slog.w(TAG, msg); 8945 throw new IllegalArgumentException(msg); 8946 } 8947 if (conn == null) { 8948 throw new NullPointerException("connection is null"); 8949 } 8950 if (decProviderCountLocked(conn, null, null, stable)) { 8951 updateOomAdjLocked(); 8952 } 8953 } 8954 } finally { 8955 Binder.restoreCallingIdentity(ident); 8956 } 8957 } 8958 8959 public void removeContentProviderExternal(String name, IBinder token) { 8960 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8961 "Do not have permission in call removeContentProviderExternal()"); 8962 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8963 } 8964 8965 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8966 synchronized (this) { 8967 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8968 if(cpr == null) { 8969 //remove from mProvidersByClass 8970 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8971 return; 8972 } 8973 8974 //update content provider record entry info 8975 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8976 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8977 if (localCpr.hasExternalProcessHandles()) { 8978 if (localCpr.removeExternalProcessHandleLocked(token)) { 8979 updateOomAdjLocked(); 8980 } else { 8981 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8982 + " with no external reference for token: " 8983 + token + "."); 8984 } 8985 } else { 8986 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8987 + " with no external references."); 8988 } 8989 } 8990 } 8991 8992 public final void publishContentProviders(IApplicationThread caller, 8993 List<ContentProviderHolder> providers) { 8994 if (providers == null) { 8995 return; 8996 } 8997 8998 enforceNotIsolatedCaller("publishContentProviders"); 8999 synchronized (this) { 9000 final ProcessRecord r = getRecordForAppLocked(caller); 9001 if (DEBUG_MU) 9002 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9003 if (r == null) { 9004 throw new SecurityException( 9005 "Unable to find app for caller " + caller 9006 + " (pid=" + Binder.getCallingPid() 9007 + ") when publishing content providers"); 9008 } 9009 9010 final long origId = Binder.clearCallingIdentity(); 9011 9012 final int N = providers.size(); 9013 for (int i=0; i<N; i++) { 9014 ContentProviderHolder src = providers.get(i); 9015 if (src == null || src.info == null || src.provider == null) { 9016 continue; 9017 } 9018 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9019 if (DEBUG_MU) 9020 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9021 if (dst != null) { 9022 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9023 mProviderMap.putProviderByClass(comp, dst); 9024 String names[] = dst.info.authority.split(";"); 9025 for (int j = 0; j < names.length; j++) { 9026 mProviderMap.putProviderByName(names[j], dst); 9027 } 9028 9029 int NL = mLaunchingProviders.size(); 9030 int j; 9031 for (j=0; j<NL; j++) { 9032 if (mLaunchingProviders.get(j) == dst) { 9033 mLaunchingProviders.remove(j); 9034 j--; 9035 NL--; 9036 } 9037 } 9038 synchronized (dst) { 9039 dst.provider = src.provider; 9040 dst.proc = r; 9041 dst.notifyAll(); 9042 } 9043 updateOomAdjLocked(r); 9044 } 9045 } 9046 9047 Binder.restoreCallingIdentity(origId); 9048 } 9049 } 9050 9051 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9052 ContentProviderConnection conn; 9053 try { 9054 conn = (ContentProviderConnection)connection; 9055 } catch (ClassCastException e) { 9056 String msg ="refContentProvider: " + connection 9057 + " not a ContentProviderConnection"; 9058 Slog.w(TAG, msg); 9059 throw new IllegalArgumentException(msg); 9060 } 9061 if (conn == null) { 9062 throw new NullPointerException("connection is null"); 9063 } 9064 9065 synchronized (this) { 9066 if (stable > 0) { 9067 conn.numStableIncs += stable; 9068 } 9069 stable = conn.stableCount + stable; 9070 if (stable < 0) { 9071 throw new IllegalStateException("stableCount < 0: " + stable); 9072 } 9073 9074 if (unstable > 0) { 9075 conn.numUnstableIncs += unstable; 9076 } 9077 unstable = conn.unstableCount + unstable; 9078 if (unstable < 0) { 9079 throw new IllegalStateException("unstableCount < 0: " + unstable); 9080 } 9081 9082 if ((stable+unstable) <= 0) { 9083 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9084 + stable + " unstable=" + unstable); 9085 } 9086 conn.stableCount = stable; 9087 conn.unstableCount = unstable; 9088 return !conn.dead; 9089 } 9090 } 9091 9092 public void unstableProviderDied(IBinder connection) { 9093 ContentProviderConnection conn; 9094 try { 9095 conn = (ContentProviderConnection)connection; 9096 } catch (ClassCastException e) { 9097 String msg ="refContentProvider: " + connection 9098 + " not a ContentProviderConnection"; 9099 Slog.w(TAG, msg); 9100 throw new IllegalArgumentException(msg); 9101 } 9102 if (conn == null) { 9103 throw new NullPointerException("connection is null"); 9104 } 9105 9106 // Safely retrieve the content provider associated with the connection. 9107 IContentProvider provider; 9108 synchronized (this) { 9109 provider = conn.provider.provider; 9110 } 9111 9112 if (provider == null) { 9113 // Um, yeah, we're way ahead of you. 9114 return; 9115 } 9116 9117 // Make sure the caller is being honest with us. 9118 if (provider.asBinder().pingBinder()) { 9119 // Er, no, still looks good to us. 9120 synchronized (this) { 9121 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9122 + " says " + conn + " died, but we don't agree"); 9123 return; 9124 } 9125 } 9126 9127 // Well look at that! It's dead! 9128 synchronized (this) { 9129 if (conn.provider.provider != provider) { 9130 // But something changed... good enough. 9131 return; 9132 } 9133 9134 ProcessRecord proc = conn.provider.proc; 9135 if (proc == null || proc.thread == null) { 9136 // Seems like the process is already cleaned up. 9137 return; 9138 } 9139 9140 // As far as we're concerned, this is just like receiving a 9141 // death notification... just a bit prematurely. 9142 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9143 + ") early provider death"); 9144 final long ident = Binder.clearCallingIdentity(); 9145 try { 9146 appDiedLocked(proc); 9147 } finally { 9148 Binder.restoreCallingIdentity(ident); 9149 } 9150 } 9151 } 9152 9153 @Override 9154 public void appNotRespondingViaProvider(IBinder connection) { 9155 enforceCallingPermission( 9156 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9157 9158 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9159 if (conn == null) { 9160 Slog.w(TAG, "ContentProviderConnection is null"); 9161 return; 9162 } 9163 9164 final ProcessRecord host = conn.provider.proc; 9165 if (host == null) { 9166 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9167 return; 9168 } 9169 9170 final long token = Binder.clearCallingIdentity(); 9171 try { 9172 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9173 } finally { 9174 Binder.restoreCallingIdentity(token); 9175 } 9176 } 9177 9178 public final void installSystemProviders() { 9179 List<ProviderInfo> providers; 9180 synchronized (this) { 9181 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9182 providers = generateApplicationProvidersLocked(app); 9183 if (providers != null) { 9184 for (int i=providers.size()-1; i>=0; i--) { 9185 ProviderInfo pi = (ProviderInfo)providers.get(i); 9186 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9187 Slog.w(TAG, "Not installing system proc provider " + pi.name 9188 + ": not system .apk"); 9189 providers.remove(i); 9190 } 9191 } 9192 } 9193 } 9194 if (providers != null) { 9195 mSystemThread.installSystemProviders(providers); 9196 } 9197 9198 mCoreSettingsObserver = new CoreSettingsObserver(this); 9199 9200 //mUsageStatsService.monitorPackages(); 9201 } 9202 9203 /** 9204 * Allows apps to retrieve the MIME type of a URI. 9205 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9206 * users, then it does not need permission to access the ContentProvider. 9207 * Either, it needs cross-user uri grants. 9208 * 9209 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9210 * 9211 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9212 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9213 */ 9214 public String getProviderMimeType(Uri uri, int userId) { 9215 enforceNotIsolatedCaller("getProviderMimeType"); 9216 final String name = uri.getAuthority(); 9217 int callingUid = Binder.getCallingUid(); 9218 int callingPid = Binder.getCallingPid(); 9219 long ident = 0; 9220 boolean clearedIdentity = false; 9221 userId = unsafeConvertIncomingUser(userId); 9222 if (UserHandle.getUserId(callingUid) != userId) { 9223 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9224 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9225 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9226 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9227 clearedIdentity = true; 9228 ident = Binder.clearCallingIdentity(); 9229 } 9230 } 9231 ContentProviderHolder holder = null; 9232 try { 9233 holder = getContentProviderExternalUnchecked(name, null, userId); 9234 if (holder != null) { 9235 return holder.provider.getType(uri); 9236 } 9237 } catch (RemoteException e) { 9238 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9239 return null; 9240 } finally { 9241 // We need to clear the identity to call removeContentProviderExternalUnchecked 9242 if (!clearedIdentity) { 9243 ident = Binder.clearCallingIdentity(); 9244 } 9245 try { 9246 if (holder != null) { 9247 removeContentProviderExternalUnchecked(name, null, userId); 9248 } 9249 } finally { 9250 Binder.restoreCallingIdentity(ident); 9251 } 9252 } 9253 9254 return null; 9255 } 9256 9257 // ========================================================= 9258 // GLOBAL MANAGEMENT 9259 // ========================================================= 9260 9261 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9262 boolean isolated, int isolatedUid) { 9263 String proc = customProcess != null ? customProcess : info.processName; 9264 BatteryStatsImpl.Uid.Proc ps = null; 9265 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9266 int uid = info.uid; 9267 if (isolated) { 9268 if (isolatedUid == 0) { 9269 int userId = UserHandle.getUserId(uid); 9270 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9271 while (true) { 9272 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9273 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9274 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9275 } 9276 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9277 mNextIsolatedProcessUid++; 9278 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9279 // No process for this uid, use it. 9280 break; 9281 } 9282 stepsLeft--; 9283 if (stepsLeft <= 0) { 9284 return null; 9285 } 9286 } 9287 } else { 9288 // Special case for startIsolatedProcess (internal only), where 9289 // the uid of the isolated process is specified by the caller. 9290 uid = isolatedUid; 9291 } 9292 } 9293 return new ProcessRecord(stats, info, proc, uid); 9294 } 9295 9296 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9297 String abiOverride) { 9298 ProcessRecord app; 9299 if (!isolated) { 9300 app = getProcessRecordLocked(info.processName, info.uid, true); 9301 } else { 9302 app = null; 9303 } 9304 9305 if (app == null) { 9306 app = newProcessRecordLocked(info, null, isolated, 0); 9307 mProcessNames.put(info.processName, app.uid, app); 9308 if (isolated) { 9309 mIsolatedProcesses.put(app.uid, app); 9310 } 9311 updateLruProcessLocked(app, false, null); 9312 updateOomAdjLocked(); 9313 } 9314 9315 // This package really, really can not be stopped. 9316 try { 9317 AppGlobals.getPackageManager().setPackageStoppedState( 9318 info.packageName, false, UserHandle.getUserId(app.uid)); 9319 } catch (RemoteException e) { 9320 } catch (IllegalArgumentException e) { 9321 Slog.w(TAG, "Failed trying to unstop package " 9322 + info.packageName + ": " + e); 9323 } 9324 9325 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9326 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9327 app.persistent = true; 9328 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9329 } 9330 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9331 mPersistentStartingProcesses.add(app); 9332 startProcessLocked(app, "added application", app.processName, abiOverride, 9333 null /* entryPoint */, null /* entryPointArgs */); 9334 } 9335 9336 return app; 9337 } 9338 9339 public void unhandledBack() { 9340 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9341 "unhandledBack()"); 9342 9343 synchronized(this) { 9344 final long origId = Binder.clearCallingIdentity(); 9345 try { 9346 getFocusedStack().unhandledBackLocked(); 9347 } finally { 9348 Binder.restoreCallingIdentity(origId); 9349 } 9350 } 9351 } 9352 9353 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9354 enforceNotIsolatedCaller("openContentUri"); 9355 final int userId = UserHandle.getCallingUserId(); 9356 String name = uri.getAuthority(); 9357 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9358 ParcelFileDescriptor pfd = null; 9359 if (cph != null) { 9360 // We record the binder invoker's uid in thread-local storage before 9361 // going to the content provider to open the file. Later, in the code 9362 // that handles all permissions checks, we look for this uid and use 9363 // that rather than the Activity Manager's own uid. The effect is that 9364 // we do the check against the caller's permissions even though it looks 9365 // to the content provider like the Activity Manager itself is making 9366 // the request. 9367 sCallerIdentity.set(new Identity( 9368 Binder.getCallingPid(), Binder.getCallingUid())); 9369 try { 9370 pfd = cph.provider.openFile(null, uri, "r", null); 9371 } catch (FileNotFoundException e) { 9372 // do nothing; pfd will be returned null 9373 } finally { 9374 // Ensure that whatever happens, we clean up the identity state 9375 sCallerIdentity.remove(); 9376 } 9377 9378 // We've got the fd now, so we're done with the provider. 9379 removeContentProviderExternalUnchecked(name, null, userId); 9380 } else { 9381 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9382 } 9383 return pfd; 9384 } 9385 9386 // Actually is sleeping or shutting down or whatever else in the future 9387 // is an inactive state. 9388 public boolean isSleepingOrShuttingDown() { 9389 return mSleeping || mShuttingDown; 9390 } 9391 9392 public boolean isSleeping() { 9393 return mSleeping; 9394 } 9395 9396 void goingToSleep() { 9397 synchronized(this) { 9398 mWentToSleep = true; 9399 updateEventDispatchingLocked(); 9400 goToSleepIfNeededLocked(); 9401 } 9402 } 9403 9404 void finishRunningVoiceLocked() { 9405 if (mRunningVoice) { 9406 mRunningVoice = false; 9407 goToSleepIfNeededLocked(); 9408 } 9409 } 9410 9411 void goToSleepIfNeededLocked() { 9412 if (mWentToSleep && !mRunningVoice) { 9413 if (!mSleeping) { 9414 mSleeping = true; 9415 mStackSupervisor.goingToSleepLocked(); 9416 9417 // Initialize the wake times of all processes. 9418 checkExcessivePowerUsageLocked(false); 9419 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9420 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9421 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9422 } 9423 } 9424 } 9425 9426 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9427 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9428 // Never persist the home stack. 9429 return; 9430 } 9431 mTaskPersister.wakeup(task, flush); 9432 } 9433 9434 @Override 9435 public boolean shutdown(int timeout) { 9436 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9437 != PackageManager.PERMISSION_GRANTED) { 9438 throw new SecurityException("Requires permission " 9439 + android.Manifest.permission.SHUTDOWN); 9440 } 9441 9442 boolean timedout = false; 9443 9444 synchronized(this) { 9445 mShuttingDown = true; 9446 updateEventDispatchingLocked(); 9447 timedout = mStackSupervisor.shutdownLocked(timeout); 9448 } 9449 9450 mAppOpsService.shutdown(); 9451 if (mUsageStatsService != null) { 9452 mUsageStatsService.prepareShutdown(); 9453 } 9454 mBatteryStatsService.shutdown(); 9455 synchronized (this) { 9456 mProcessStats.shutdownLocked(); 9457 } 9458 notifyTaskPersisterLocked(null, true); 9459 9460 return timedout; 9461 } 9462 9463 public final void activitySlept(IBinder token) { 9464 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9465 9466 final long origId = Binder.clearCallingIdentity(); 9467 9468 synchronized (this) { 9469 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9470 if (r != null) { 9471 mStackSupervisor.activitySleptLocked(r); 9472 } 9473 } 9474 9475 Binder.restoreCallingIdentity(origId); 9476 } 9477 9478 void logLockScreen(String msg) { 9479 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9480 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9481 mWentToSleep + " mSleeping=" + mSleeping); 9482 } 9483 9484 private void comeOutOfSleepIfNeededLocked() { 9485 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9486 if (mSleeping) { 9487 mSleeping = false; 9488 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9489 } 9490 } 9491 } 9492 9493 void wakingUp() { 9494 synchronized(this) { 9495 mWentToSleep = false; 9496 updateEventDispatchingLocked(); 9497 comeOutOfSleepIfNeededLocked(); 9498 } 9499 } 9500 9501 void startRunningVoiceLocked() { 9502 if (!mRunningVoice) { 9503 mRunningVoice = true; 9504 comeOutOfSleepIfNeededLocked(); 9505 } 9506 } 9507 9508 private void updateEventDispatchingLocked() { 9509 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9510 } 9511 9512 public void setLockScreenShown(boolean shown) { 9513 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9514 != PackageManager.PERMISSION_GRANTED) { 9515 throw new SecurityException("Requires permission " 9516 + android.Manifest.permission.DEVICE_POWER); 9517 } 9518 9519 synchronized(this) { 9520 long ident = Binder.clearCallingIdentity(); 9521 try { 9522 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9523 mLockScreenShown = shown; 9524 comeOutOfSleepIfNeededLocked(); 9525 } finally { 9526 Binder.restoreCallingIdentity(ident); 9527 } 9528 } 9529 } 9530 9531 @Override 9532 public void stopAppSwitches() { 9533 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9534 != PackageManager.PERMISSION_GRANTED) { 9535 throw new SecurityException("Requires permission " 9536 + android.Manifest.permission.STOP_APP_SWITCHES); 9537 } 9538 9539 synchronized(this) { 9540 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9541 + APP_SWITCH_DELAY_TIME; 9542 mDidAppSwitch = false; 9543 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9544 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9545 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9546 } 9547 } 9548 9549 public void resumeAppSwitches() { 9550 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9551 != PackageManager.PERMISSION_GRANTED) { 9552 throw new SecurityException("Requires permission " 9553 + android.Manifest.permission.STOP_APP_SWITCHES); 9554 } 9555 9556 synchronized(this) { 9557 // Note that we don't execute any pending app switches... we will 9558 // let those wait until either the timeout, or the next start 9559 // activity request. 9560 mAppSwitchesAllowedTime = 0; 9561 } 9562 } 9563 9564 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9565 String name) { 9566 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9567 return true; 9568 } 9569 9570 final int perm = checkComponentPermission( 9571 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9572 callingUid, -1, true); 9573 if (perm == PackageManager.PERMISSION_GRANTED) { 9574 return true; 9575 } 9576 9577 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9578 return false; 9579 } 9580 9581 public void setDebugApp(String packageName, boolean waitForDebugger, 9582 boolean persistent) { 9583 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9584 "setDebugApp()"); 9585 9586 long ident = Binder.clearCallingIdentity(); 9587 try { 9588 // Note that this is not really thread safe if there are multiple 9589 // callers into it at the same time, but that's not a situation we 9590 // care about. 9591 if (persistent) { 9592 final ContentResolver resolver = mContext.getContentResolver(); 9593 Settings.Global.putString( 9594 resolver, Settings.Global.DEBUG_APP, 9595 packageName); 9596 Settings.Global.putInt( 9597 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9598 waitForDebugger ? 1 : 0); 9599 } 9600 9601 synchronized (this) { 9602 if (!persistent) { 9603 mOrigDebugApp = mDebugApp; 9604 mOrigWaitForDebugger = mWaitForDebugger; 9605 } 9606 mDebugApp = packageName; 9607 mWaitForDebugger = waitForDebugger; 9608 mDebugTransient = !persistent; 9609 if (packageName != null) { 9610 forceStopPackageLocked(packageName, -1, false, false, true, true, 9611 false, UserHandle.USER_ALL, "set debug app"); 9612 } 9613 } 9614 } finally { 9615 Binder.restoreCallingIdentity(ident); 9616 } 9617 } 9618 9619 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9620 synchronized (this) { 9621 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9622 if (!isDebuggable) { 9623 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9624 throw new SecurityException("Process not debuggable: " + app.packageName); 9625 } 9626 } 9627 9628 mOpenGlTraceApp = processName; 9629 } 9630 } 9631 9632 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9633 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9634 synchronized (this) { 9635 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9636 if (!isDebuggable) { 9637 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9638 throw new SecurityException("Process not debuggable: " + app.packageName); 9639 } 9640 } 9641 mProfileApp = processName; 9642 mProfileFile = profileFile; 9643 if (mProfileFd != null) { 9644 try { 9645 mProfileFd.close(); 9646 } catch (IOException e) { 9647 } 9648 mProfileFd = null; 9649 } 9650 mProfileFd = profileFd; 9651 mProfileType = 0; 9652 mAutoStopProfiler = autoStopProfiler; 9653 } 9654 } 9655 9656 @Override 9657 public void setAlwaysFinish(boolean enabled) { 9658 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9659 "setAlwaysFinish()"); 9660 9661 Settings.Global.putInt( 9662 mContext.getContentResolver(), 9663 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9664 9665 synchronized (this) { 9666 mAlwaysFinishActivities = enabled; 9667 } 9668 } 9669 9670 @Override 9671 public void setActivityController(IActivityController controller) { 9672 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9673 "setActivityController()"); 9674 synchronized (this) { 9675 mController = controller; 9676 Watchdog.getInstance().setActivityController(controller); 9677 } 9678 } 9679 9680 @Override 9681 public void setUserIsMonkey(boolean userIsMonkey) { 9682 synchronized (this) { 9683 synchronized (mPidsSelfLocked) { 9684 final int callingPid = Binder.getCallingPid(); 9685 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9686 if (precessRecord == null) { 9687 throw new SecurityException("Unknown process: " + callingPid); 9688 } 9689 if (precessRecord.instrumentationUiAutomationConnection == null) { 9690 throw new SecurityException("Only an instrumentation process " 9691 + "with a UiAutomation can call setUserIsMonkey"); 9692 } 9693 } 9694 mUserIsMonkey = userIsMonkey; 9695 } 9696 } 9697 9698 @Override 9699 public boolean isUserAMonkey() { 9700 synchronized (this) { 9701 // If there is a controller also implies the user is a monkey. 9702 return (mUserIsMonkey || mController != null); 9703 } 9704 } 9705 9706 public void requestBugReport() { 9707 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9708 SystemProperties.set("ctl.start", "bugreport"); 9709 } 9710 9711 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9712 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9713 } 9714 9715 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9716 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9717 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9718 } 9719 return KEY_DISPATCHING_TIMEOUT; 9720 } 9721 9722 @Override 9723 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9724 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9725 != PackageManager.PERMISSION_GRANTED) { 9726 throw new SecurityException("Requires permission " 9727 + android.Manifest.permission.FILTER_EVENTS); 9728 } 9729 ProcessRecord proc; 9730 long timeout; 9731 synchronized (this) { 9732 synchronized (mPidsSelfLocked) { 9733 proc = mPidsSelfLocked.get(pid); 9734 } 9735 timeout = getInputDispatchingTimeoutLocked(proc); 9736 } 9737 9738 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9739 return -1; 9740 } 9741 9742 return timeout; 9743 } 9744 9745 /** 9746 * Handle input dispatching timeouts. 9747 * Returns whether input dispatching should be aborted or not. 9748 */ 9749 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9750 final ActivityRecord activity, final ActivityRecord parent, 9751 final boolean aboveSystem, String reason) { 9752 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9753 != PackageManager.PERMISSION_GRANTED) { 9754 throw new SecurityException("Requires permission " 9755 + android.Manifest.permission.FILTER_EVENTS); 9756 } 9757 9758 final String annotation; 9759 if (reason == null) { 9760 annotation = "Input dispatching timed out"; 9761 } else { 9762 annotation = "Input dispatching timed out (" + reason + ")"; 9763 } 9764 9765 if (proc != null) { 9766 synchronized (this) { 9767 if (proc.debugging) { 9768 return false; 9769 } 9770 9771 if (mDidDexOpt) { 9772 // Give more time since we were dexopting. 9773 mDidDexOpt = false; 9774 return false; 9775 } 9776 9777 if (proc.instrumentationClass != null) { 9778 Bundle info = new Bundle(); 9779 info.putString("shortMsg", "keyDispatchingTimedOut"); 9780 info.putString("longMsg", annotation); 9781 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9782 return true; 9783 } 9784 } 9785 mHandler.post(new Runnable() { 9786 @Override 9787 public void run() { 9788 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9789 } 9790 }); 9791 } 9792 9793 return true; 9794 } 9795 9796 public Bundle getAssistContextExtras(int requestType) { 9797 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9798 "getAssistContextExtras()"); 9799 PendingAssistExtras pae; 9800 Bundle extras = new Bundle(); 9801 synchronized (this) { 9802 ActivityRecord activity = getFocusedStack().mResumedActivity; 9803 if (activity == null) { 9804 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9805 return null; 9806 } 9807 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9808 if (activity.app == null || activity.app.thread == null) { 9809 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9810 return extras; 9811 } 9812 if (activity.app.pid == Binder.getCallingPid()) { 9813 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9814 return extras; 9815 } 9816 pae = new PendingAssistExtras(activity); 9817 try { 9818 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9819 requestType); 9820 mPendingAssistExtras.add(pae); 9821 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9822 } catch (RemoteException e) { 9823 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9824 return extras; 9825 } 9826 } 9827 synchronized (pae) { 9828 while (!pae.haveResult) { 9829 try { 9830 pae.wait(); 9831 } catch (InterruptedException e) { 9832 } 9833 } 9834 if (pae.result != null) { 9835 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9836 } 9837 } 9838 synchronized (this) { 9839 mPendingAssistExtras.remove(pae); 9840 mHandler.removeCallbacks(pae); 9841 } 9842 return extras; 9843 } 9844 9845 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9846 PendingAssistExtras pae = (PendingAssistExtras)token; 9847 synchronized (pae) { 9848 pae.result = extras; 9849 pae.haveResult = true; 9850 pae.notifyAll(); 9851 } 9852 } 9853 9854 public void registerProcessObserver(IProcessObserver observer) { 9855 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9856 "registerProcessObserver()"); 9857 synchronized (this) { 9858 mProcessObservers.register(observer); 9859 } 9860 } 9861 9862 @Override 9863 public void unregisterProcessObserver(IProcessObserver observer) { 9864 synchronized (this) { 9865 mProcessObservers.unregister(observer); 9866 } 9867 } 9868 9869 @Override 9870 public boolean convertFromTranslucent(IBinder token) { 9871 final long origId = Binder.clearCallingIdentity(); 9872 try { 9873 synchronized (this) { 9874 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9875 if (r == null) { 9876 return false; 9877 } 9878 if (r.changeWindowTranslucency(true)) { 9879 mWindowManager.setAppFullscreen(token, true); 9880 r.task.stack.releaseBackgroundResources(); 9881 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9882 return true; 9883 } 9884 return false; 9885 } 9886 } finally { 9887 Binder.restoreCallingIdentity(origId); 9888 } 9889 } 9890 9891 @Override 9892 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9893 final long origId = Binder.clearCallingIdentity(); 9894 try { 9895 synchronized (this) { 9896 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9897 if (r == null) { 9898 return false; 9899 } 9900 int index = r.task.mActivities.lastIndexOf(r); 9901 if (index > 0) { 9902 ActivityRecord under = r.task.mActivities.get(index - 1); 9903 under.returningOptions = options; 9904 } 9905 if (r.changeWindowTranslucency(false)) { 9906 r.task.stack.convertToTranslucent(r); 9907 mWindowManager.setAppFullscreen(token, false); 9908 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9909 return true; 9910 } else { 9911 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9912 return false; 9913 } 9914 } 9915 } finally { 9916 Binder.restoreCallingIdentity(origId); 9917 } 9918 } 9919 9920 @Override 9921 public boolean requestVisibleBehind(IBinder token, boolean visible) { 9922 final long origId = Binder.clearCallingIdentity(); 9923 try { 9924 synchronized (this) { 9925 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9926 if (r != null) { 9927 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 9928 } 9929 } 9930 return false; 9931 } finally { 9932 Binder.restoreCallingIdentity(origId); 9933 } 9934 } 9935 9936 @Override 9937 public boolean isBackgroundVisibleBehind(IBinder token) { 9938 final long origId = Binder.clearCallingIdentity(); 9939 try { 9940 synchronized (this) { 9941 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9942 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 9943 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 9944 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 9945 return visible; 9946 } 9947 } finally { 9948 Binder.restoreCallingIdentity(origId); 9949 } 9950 } 9951 9952 @Override 9953 public ActivityOptions getActivityOptions(IBinder token) { 9954 final long origId = Binder.clearCallingIdentity(); 9955 try { 9956 synchronized (this) { 9957 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9958 if (r != null) { 9959 final ActivityOptions activityOptions = r.pendingOptions; 9960 r.pendingOptions = null; 9961 return activityOptions; 9962 } 9963 return null; 9964 } 9965 } finally { 9966 Binder.restoreCallingIdentity(origId); 9967 } 9968 } 9969 9970 @Override 9971 public void setImmersive(IBinder token, boolean immersive) { 9972 synchronized(this) { 9973 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9974 if (r == null) { 9975 throw new IllegalArgumentException(); 9976 } 9977 r.immersive = immersive; 9978 9979 // update associated state if we're frontmost 9980 if (r == mFocusedActivity) { 9981 if (DEBUG_IMMERSIVE) { 9982 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9983 } 9984 applyUpdateLockStateLocked(r); 9985 } 9986 } 9987 } 9988 9989 @Override 9990 public boolean isImmersive(IBinder token) { 9991 synchronized (this) { 9992 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9993 if (r == null) { 9994 throw new IllegalArgumentException(); 9995 } 9996 return r.immersive; 9997 } 9998 } 9999 10000 public boolean isTopActivityImmersive() { 10001 enforceNotIsolatedCaller("startActivity"); 10002 synchronized (this) { 10003 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10004 return (r != null) ? r.immersive : false; 10005 } 10006 } 10007 10008 @Override 10009 public boolean isTopOfTask(IBinder token) { 10010 synchronized (this) { 10011 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10012 if (r == null) { 10013 throw new IllegalArgumentException(); 10014 } 10015 return r.task.getTopActivity() == r; 10016 } 10017 } 10018 10019 public final void enterSafeMode() { 10020 synchronized(this) { 10021 // It only makes sense to do this before the system is ready 10022 // and started launching other packages. 10023 if (!mSystemReady) { 10024 try { 10025 AppGlobals.getPackageManager().enterSafeMode(); 10026 } catch (RemoteException e) { 10027 } 10028 } 10029 10030 mSafeMode = true; 10031 } 10032 } 10033 10034 public final void showSafeModeOverlay() { 10035 View v = LayoutInflater.from(mContext).inflate( 10036 com.android.internal.R.layout.safe_mode, null); 10037 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10038 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10039 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10040 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10041 lp.gravity = Gravity.BOTTOM | Gravity.START; 10042 lp.format = v.getBackground().getOpacity(); 10043 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10044 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10045 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10046 ((WindowManager)mContext.getSystemService( 10047 Context.WINDOW_SERVICE)).addView(v, lp); 10048 } 10049 10050 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10051 if (!(sender instanceof PendingIntentRecord)) { 10052 return; 10053 } 10054 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10055 synchronized (stats) { 10056 if (mBatteryStatsService.isOnBattery()) { 10057 mBatteryStatsService.enforceCallingPermission(); 10058 PendingIntentRecord rec = (PendingIntentRecord)sender; 10059 int MY_UID = Binder.getCallingUid(); 10060 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10061 BatteryStatsImpl.Uid.Pkg pkg = 10062 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10063 sourcePkg != null ? sourcePkg : rec.key.packageName); 10064 pkg.incWakeupsLocked(); 10065 } 10066 } 10067 } 10068 10069 public boolean killPids(int[] pids, String pReason, boolean secure) { 10070 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10071 throw new SecurityException("killPids only available to the system"); 10072 } 10073 String reason = (pReason == null) ? "Unknown" : pReason; 10074 // XXX Note: don't acquire main activity lock here, because the window 10075 // manager calls in with its locks held. 10076 10077 boolean killed = false; 10078 synchronized (mPidsSelfLocked) { 10079 int[] types = new int[pids.length]; 10080 int worstType = 0; 10081 for (int i=0; i<pids.length; i++) { 10082 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10083 if (proc != null) { 10084 int type = proc.setAdj; 10085 types[i] = type; 10086 if (type > worstType) { 10087 worstType = type; 10088 } 10089 } 10090 } 10091 10092 // If the worst oom_adj is somewhere in the cached proc LRU range, 10093 // then constrain it so we will kill all cached procs. 10094 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10095 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10096 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10097 } 10098 10099 // If this is not a secure call, don't let it kill processes that 10100 // are important. 10101 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10102 worstType = ProcessList.SERVICE_ADJ; 10103 } 10104 10105 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10106 for (int i=0; i<pids.length; i++) { 10107 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10108 if (proc == null) { 10109 continue; 10110 } 10111 int adj = proc.setAdj; 10112 if (adj >= worstType && !proc.killedByAm) { 10113 killUnneededProcessLocked(proc, reason); 10114 killed = true; 10115 } 10116 } 10117 } 10118 return killed; 10119 } 10120 10121 @Override 10122 public void killUid(int uid, String reason) { 10123 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10124 throw new SecurityException("killUid only available to the system"); 10125 } 10126 synchronized (this) { 10127 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10128 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10129 reason != null ? reason : "kill uid"); 10130 } 10131 } 10132 10133 @Override 10134 public boolean killProcessesBelowForeground(String reason) { 10135 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10136 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10137 } 10138 10139 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10140 } 10141 10142 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10143 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10144 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10145 } 10146 10147 boolean killed = false; 10148 synchronized (mPidsSelfLocked) { 10149 final int size = mPidsSelfLocked.size(); 10150 for (int i = 0; i < size; i++) { 10151 final int pid = mPidsSelfLocked.keyAt(i); 10152 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10153 if (proc == null) continue; 10154 10155 final int adj = proc.setAdj; 10156 if (adj > belowAdj && !proc.killedByAm) { 10157 killUnneededProcessLocked(proc, reason); 10158 killed = true; 10159 } 10160 } 10161 } 10162 return killed; 10163 } 10164 10165 @Override 10166 public void hang(final IBinder who, boolean allowRestart) { 10167 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10168 != PackageManager.PERMISSION_GRANTED) { 10169 throw new SecurityException("Requires permission " 10170 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10171 } 10172 10173 final IBinder.DeathRecipient death = new DeathRecipient() { 10174 @Override 10175 public void binderDied() { 10176 synchronized (this) { 10177 notifyAll(); 10178 } 10179 } 10180 }; 10181 10182 try { 10183 who.linkToDeath(death, 0); 10184 } catch (RemoteException e) { 10185 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10186 return; 10187 } 10188 10189 synchronized (this) { 10190 Watchdog.getInstance().setAllowRestart(allowRestart); 10191 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10192 synchronized (death) { 10193 while (who.isBinderAlive()) { 10194 try { 10195 death.wait(); 10196 } catch (InterruptedException e) { 10197 } 10198 } 10199 } 10200 Watchdog.getInstance().setAllowRestart(true); 10201 } 10202 } 10203 10204 @Override 10205 public void restart() { 10206 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10207 != PackageManager.PERMISSION_GRANTED) { 10208 throw new SecurityException("Requires permission " 10209 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10210 } 10211 10212 Log.i(TAG, "Sending shutdown broadcast..."); 10213 10214 BroadcastReceiver br = new BroadcastReceiver() { 10215 @Override public void onReceive(Context context, Intent intent) { 10216 // Now the broadcast is done, finish up the low-level shutdown. 10217 Log.i(TAG, "Shutting down activity manager..."); 10218 shutdown(10000); 10219 Log.i(TAG, "Shutdown complete, restarting!"); 10220 Process.killProcess(Process.myPid()); 10221 System.exit(10); 10222 } 10223 }; 10224 10225 // First send the high-level shut down broadcast. 10226 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10227 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10228 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10229 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10230 mContext.sendOrderedBroadcastAsUser(intent, 10231 UserHandle.ALL, null, br, mHandler, 0, null, null); 10232 */ 10233 br.onReceive(mContext, intent); 10234 } 10235 10236 private long getLowRamTimeSinceIdle(long now) { 10237 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10238 } 10239 10240 @Override 10241 public void performIdleMaintenance() { 10242 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10243 != PackageManager.PERMISSION_GRANTED) { 10244 throw new SecurityException("Requires permission " 10245 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10246 } 10247 10248 synchronized (this) { 10249 final long now = SystemClock.uptimeMillis(); 10250 final long timeSinceLastIdle = now - mLastIdleTime; 10251 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10252 mLastIdleTime = now; 10253 mLowRamTimeSinceLastIdle = 0; 10254 if (mLowRamStartTime != 0) { 10255 mLowRamStartTime = now; 10256 } 10257 10258 StringBuilder sb = new StringBuilder(128); 10259 sb.append("Idle maintenance over "); 10260 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10261 sb.append(" low RAM for "); 10262 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10263 Slog.i(TAG, sb.toString()); 10264 10265 // If at least 1/3 of our time since the last idle period has been spent 10266 // with RAM low, then we want to kill processes. 10267 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10268 10269 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10270 ProcessRecord proc = mLruProcesses.get(i); 10271 if (proc.notCachedSinceIdle) { 10272 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10273 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10274 if (doKilling && proc.initialIdlePss != 0 10275 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10276 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 10277 + " from " + proc.initialIdlePss + ")"); 10278 } 10279 } 10280 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10281 proc.notCachedSinceIdle = true; 10282 proc.initialIdlePss = 0; 10283 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10284 isSleeping(), now); 10285 } 10286 } 10287 10288 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10289 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10290 } 10291 } 10292 10293 private void retrieveSettings() { 10294 final ContentResolver resolver = mContext.getContentResolver(); 10295 String debugApp = Settings.Global.getString( 10296 resolver, Settings.Global.DEBUG_APP); 10297 boolean waitForDebugger = Settings.Global.getInt( 10298 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10299 boolean alwaysFinishActivities = Settings.Global.getInt( 10300 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10301 boolean forceRtl = Settings.Global.getInt( 10302 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10303 // Transfer any global setting for forcing RTL layout, into a System Property 10304 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10305 10306 Configuration configuration = new Configuration(); 10307 Settings.System.getConfiguration(resolver, configuration); 10308 if (forceRtl) { 10309 // This will take care of setting the correct layout direction flags 10310 configuration.setLayoutDirection(configuration.locale); 10311 } 10312 10313 synchronized (this) { 10314 mDebugApp = mOrigDebugApp = debugApp; 10315 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10316 mAlwaysFinishActivities = alwaysFinishActivities; 10317 // This happens before any activities are started, so we can 10318 // change mConfiguration in-place. 10319 updateConfigurationLocked(configuration, null, false, true); 10320 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10321 } 10322 } 10323 10324 public boolean testIsSystemReady() { 10325 // no need to synchronize(this) just to read & return the value 10326 return mSystemReady; 10327 } 10328 10329 private static File getCalledPreBootReceiversFile() { 10330 File dataDir = Environment.getDataDirectory(); 10331 File systemDir = new File(dataDir, "system"); 10332 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10333 return fname; 10334 } 10335 10336 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10337 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10338 File file = getCalledPreBootReceiversFile(); 10339 FileInputStream fis = null; 10340 try { 10341 fis = new FileInputStream(file); 10342 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10343 int fvers = dis.readInt(); 10344 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10345 String vers = dis.readUTF(); 10346 String codename = dis.readUTF(); 10347 String build = dis.readUTF(); 10348 if (android.os.Build.VERSION.RELEASE.equals(vers) 10349 && android.os.Build.VERSION.CODENAME.equals(codename) 10350 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10351 int num = dis.readInt(); 10352 while (num > 0) { 10353 num--; 10354 String pkg = dis.readUTF(); 10355 String cls = dis.readUTF(); 10356 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10357 } 10358 } 10359 } 10360 } catch (FileNotFoundException e) { 10361 } catch (IOException e) { 10362 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10363 } finally { 10364 if (fis != null) { 10365 try { 10366 fis.close(); 10367 } catch (IOException e) { 10368 } 10369 } 10370 } 10371 return lastDoneReceivers; 10372 } 10373 10374 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10375 File file = getCalledPreBootReceiversFile(); 10376 FileOutputStream fos = null; 10377 DataOutputStream dos = null; 10378 try { 10379 fos = new FileOutputStream(file); 10380 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10381 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10382 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10383 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10384 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10385 dos.writeInt(list.size()); 10386 for (int i=0; i<list.size(); i++) { 10387 dos.writeUTF(list.get(i).getPackageName()); 10388 dos.writeUTF(list.get(i).getClassName()); 10389 } 10390 } catch (IOException e) { 10391 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10392 file.delete(); 10393 } finally { 10394 FileUtils.sync(fos); 10395 if (dos != null) { 10396 try { 10397 dos.close(); 10398 } catch (IOException e) { 10399 // TODO Auto-generated catch block 10400 e.printStackTrace(); 10401 } 10402 } 10403 } 10404 } 10405 10406 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10407 ArrayList<ComponentName> doneReceivers, int userId) { 10408 boolean waitingUpdate = false; 10409 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10410 List<ResolveInfo> ris = null; 10411 try { 10412 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10413 intent, null, 0, userId); 10414 } catch (RemoteException e) { 10415 } 10416 if (ris != null) { 10417 for (int i=ris.size()-1; i>=0; i--) { 10418 if ((ris.get(i).activityInfo.applicationInfo.flags 10419 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10420 ris.remove(i); 10421 } 10422 } 10423 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10424 10425 // For User 0, load the version number. When delivering to a new user, deliver 10426 // to all receivers. 10427 if (userId == UserHandle.USER_OWNER) { 10428 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10429 for (int i=0; i<ris.size(); i++) { 10430 ActivityInfo ai = ris.get(i).activityInfo; 10431 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10432 if (lastDoneReceivers.contains(comp)) { 10433 // We already did the pre boot receiver for this app with the current 10434 // platform version, so don't do it again... 10435 ris.remove(i); 10436 i--; 10437 // ...however, do keep it as one that has been done, so we don't 10438 // forget about it when rewriting the file of last done receivers. 10439 doneReceivers.add(comp); 10440 } 10441 } 10442 } 10443 10444 // If primary user, send broadcast to all available users, else just to userId 10445 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10446 : new int[] { userId }; 10447 for (int i = 0; i < ris.size(); i++) { 10448 ActivityInfo ai = ris.get(i).activityInfo; 10449 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10450 doneReceivers.add(comp); 10451 intent.setComponent(comp); 10452 for (int j=0; j<users.length; j++) { 10453 IIntentReceiver finisher = null; 10454 // On last receiver and user, set up a completion callback 10455 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10456 finisher = new IIntentReceiver.Stub() { 10457 public void performReceive(Intent intent, int resultCode, 10458 String data, Bundle extras, boolean ordered, 10459 boolean sticky, int sendingUser) { 10460 // The raw IIntentReceiver interface is called 10461 // with the AM lock held, so redispatch to 10462 // execute our code without the lock. 10463 mHandler.post(onFinishCallback); 10464 } 10465 }; 10466 } 10467 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10468 + " for user " + users[j]); 10469 broadcastIntentLocked(null, null, intent, null, finisher, 10470 0, null, null, null, AppOpsManager.OP_NONE, 10471 true, false, MY_PID, Process.SYSTEM_UID, 10472 users[j]); 10473 if (finisher != null) { 10474 waitingUpdate = true; 10475 } 10476 } 10477 } 10478 } 10479 10480 return waitingUpdate; 10481 } 10482 10483 public void systemReady(final Runnable goingCallback) { 10484 synchronized(this) { 10485 if (mSystemReady) { 10486 // If we're done calling all the receivers, run the next "boot phase" passed in 10487 // by the SystemServer 10488 if (goingCallback != null) { 10489 goingCallback.run(); 10490 } 10491 return; 10492 } 10493 10494 // Make sure we have the current profile info, since it is needed for 10495 // security checks. 10496 updateCurrentProfileIdsLocked(); 10497 10498 if (mRecentTasks == null) { 10499 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10500 if (!mRecentTasks.isEmpty()) { 10501 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10502 } 10503 mTaskPersister.startPersisting(); 10504 } 10505 10506 // Check to see if there are any update receivers to run. 10507 if (!mDidUpdate) { 10508 if (mWaitingUpdate) { 10509 return; 10510 } 10511 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10512 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10513 public void run() { 10514 synchronized (ActivityManagerService.this) { 10515 mDidUpdate = true; 10516 } 10517 writeLastDonePreBootReceivers(doneReceivers); 10518 showBootMessage(mContext.getText( 10519 R.string.android_upgrading_complete), 10520 false); 10521 systemReady(goingCallback); 10522 } 10523 }, doneReceivers, UserHandle.USER_OWNER); 10524 10525 if (mWaitingUpdate) { 10526 return; 10527 } 10528 mDidUpdate = true; 10529 } 10530 10531 mAppOpsService.systemReady(); 10532 mSystemReady = true; 10533 } 10534 10535 ArrayList<ProcessRecord> procsToKill = null; 10536 synchronized(mPidsSelfLocked) { 10537 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10538 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10539 if (!isAllowedWhileBooting(proc.info)){ 10540 if (procsToKill == null) { 10541 procsToKill = new ArrayList<ProcessRecord>(); 10542 } 10543 procsToKill.add(proc); 10544 } 10545 } 10546 } 10547 10548 synchronized(this) { 10549 if (procsToKill != null) { 10550 for (int i=procsToKill.size()-1; i>=0; i--) { 10551 ProcessRecord proc = procsToKill.get(i); 10552 Slog.i(TAG, "Removing system update proc: " + proc); 10553 removeProcessLocked(proc, true, false, "system update done"); 10554 } 10555 } 10556 10557 // Now that we have cleaned up any update processes, we 10558 // are ready to start launching real processes and know that 10559 // we won't trample on them any more. 10560 mProcessesReady = true; 10561 } 10562 10563 Slog.i(TAG, "System now ready"); 10564 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10565 SystemClock.uptimeMillis()); 10566 10567 synchronized(this) { 10568 // Make sure we have no pre-ready processes sitting around. 10569 10570 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10571 ResolveInfo ri = mContext.getPackageManager() 10572 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10573 STOCK_PM_FLAGS); 10574 CharSequence errorMsg = null; 10575 if (ri != null) { 10576 ActivityInfo ai = ri.activityInfo; 10577 ApplicationInfo app = ai.applicationInfo; 10578 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10579 mTopAction = Intent.ACTION_FACTORY_TEST; 10580 mTopData = null; 10581 mTopComponent = new ComponentName(app.packageName, 10582 ai.name); 10583 } else { 10584 errorMsg = mContext.getResources().getText( 10585 com.android.internal.R.string.factorytest_not_system); 10586 } 10587 } else { 10588 errorMsg = mContext.getResources().getText( 10589 com.android.internal.R.string.factorytest_no_action); 10590 } 10591 if (errorMsg != null) { 10592 mTopAction = null; 10593 mTopData = null; 10594 mTopComponent = null; 10595 Message msg = Message.obtain(); 10596 msg.what = SHOW_FACTORY_ERROR_MSG; 10597 msg.getData().putCharSequence("msg", errorMsg); 10598 mHandler.sendMessage(msg); 10599 } 10600 } 10601 } 10602 10603 retrieveSettings(); 10604 10605 synchronized (this) { 10606 readGrantedUriPermissionsLocked(); 10607 } 10608 10609 if (goingCallback != null) goingCallback.run(); 10610 10611 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10612 Integer.toString(mCurrentUserId), mCurrentUserId); 10613 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10614 Integer.toString(mCurrentUserId), mCurrentUserId); 10615 mSystemServiceManager.startUser(mCurrentUserId); 10616 10617 synchronized (this) { 10618 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10619 try { 10620 List apps = AppGlobals.getPackageManager(). 10621 getPersistentApplications(STOCK_PM_FLAGS); 10622 if (apps != null) { 10623 int N = apps.size(); 10624 int i; 10625 for (i=0; i<N; i++) { 10626 ApplicationInfo info 10627 = (ApplicationInfo)apps.get(i); 10628 if (info != null && 10629 !info.packageName.equals("android")) { 10630 addAppLocked(info, false, null /* ABI override */); 10631 } 10632 } 10633 } 10634 } catch (RemoteException ex) { 10635 // pm is in same process, this will never happen. 10636 } 10637 } 10638 10639 // Start up initial activity. 10640 mBooting = true; 10641 10642 try { 10643 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10644 Message msg = Message.obtain(); 10645 msg.what = SHOW_UID_ERROR_MSG; 10646 mHandler.sendMessage(msg); 10647 } 10648 } catch (RemoteException e) { 10649 } 10650 10651 long ident = Binder.clearCallingIdentity(); 10652 try { 10653 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10655 | Intent.FLAG_RECEIVER_FOREGROUND); 10656 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10657 broadcastIntentLocked(null, null, intent, 10658 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10659 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10660 intent = new Intent(Intent.ACTION_USER_STARTING); 10661 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10662 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10663 broadcastIntentLocked(null, null, intent, 10664 null, new IIntentReceiver.Stub() { 10665 @Override 10666 public void performReceive(Intent intent, int resultCode, String data, 10667 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10668 throws RemoteException { 10669 } 10670 }, 0, null, null, 10671 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10672 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10673 } catch (Throwable t) { 10674 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10675 } finally { 10676 Binder.restoreCallingIdentity(ident); 10677 } 10678 mStackSupervisor.resumeTopActivitiesLocked(); 10679 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10680 } 10681 } 10682 10683 private boolean makeAppCrashingLocked(ProcessRecord app, 10684 String shortMsg, String longMsg, String stackTrace) { 10685 app.crashing = true; 10686 app.crashingReport = generateProcessError(app, 10687 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10688 startAppProblemLocked(app); 10689 app.stopFreezingAllLocked(); 10690 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10691 } 10692 10693 private void makeAppNotRespondingLocked(ProcessRecord app, 10694 String activity, String shortMsg, String longMsg) { 10695 app.notResponding = true; 10696 app.notRespondingReport = generateProcessError(app, 10697 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10698 activity, shortMsg, longMsg, null); 10699 startAppProblemLocked(app); 10700 app.stopFreezingAllLocked(); 10701 } 10702 10703 /** 10704 * Generate a process error record, suitable for attachment to a ProcessRecord. 10705 * 10706 * @param app The ProcessRecord in which the error occurred. 10707 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10708 * ActivityManager.AppErrorStateInfo 10709 * @param activity The activity associated with the crash, if known. 10710 * @param shortMsg Short message describing the crash. 10711 * @param longMsg Long message describing the crash. 10712 * @param stackTrace Full crash stack trace, may be null. 10713 * 10714 * @return Returns a fully-formed AppErrorStateInfo record. 10715 */ 10716 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10717 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10718 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10719 10720 report.condition = condition; 10721 report.processName = app.processName; 10722 report.pid = app.pid; 10723 report.uid = app.info.uid; 10724 report.tag = activity; 10725 report.shortMsg = shortMsg; 10726 report.longMsg = longMsg; 10727 report.stackTrace = stackTrace; 10728 10729 return report; 10730 } 10731 10732 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10733 synchronized (this) { 10734 app.crashing = false; 10735 app.crashingReport = null; 10736 app.notResponding = false; 10737 app.notRespondingReport = null; 10738 if (app.anrDialog == fromDialog) { 10739 app.anrDialog = null; 10740 } 10741 if (app.waitDialog == fromDialog) { 10742 app.waitDialog = null; 10743 } 10744 if (app.pid > 0 && app.pid != MY_PID) { 10745 handleAppCrashLocked(app, null, null, null); 10746 killUnneededProcessLocked(app, "user request after error"); 10747 } 10748 } 10749 } 10750 10751 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10752 String stackTrace) { 10753 long now = SystemClock.uptimeMillis(); 10754 10755 Long crashTime; 10756 if (!app.isolated) { 10757 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10758 } else { 10759 crashTime = null; 10760 } 10761 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10762 // This process loses! 10763 Slog.w(TAG, "Process " + app.info.processName 10764 + " has crashed too many times: killing!"); 10765 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10766 app.userId, app.info.processName, app.uid); 10767 mStackSupervisor.handleAppCrashLocked(app); 10768 if (!app.persistent) { 10769 // We don't want to start this process again until the user 10770 // explicitly does so... but for persistent process, we really 10771 // need to keep it running. If a persistent process is actually 10772 // repeatedly crashing, then badness for everyone. 10773 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10774 app.info.processName); 10775 if (!app.isolated) { 10776 // XXX We don't have a way to mark isolated processes 10777 // as bad, since they don't have a peristent identity. 10778 mBadProcesses.put(app.info.processName, app.uid, 10779 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10780 mProcessCrashTimes.remove(app.info.processName, app.uid); 10781 } 10782 app.bad = true; 10783 app.removed = true; 10784 // Don't let services in this process be restarted and potentially 10785 // annoy the user repeatedly. Unless it is persistent, since those 10786 // processes run critical code. 10787 removeProcessLocked(app, false, false, "crash"); 10788 mStackSupervisor.resumeTopActivitiesLocked(); 10789 return false; 10790 } 10791 mStackSupervisor.resumeTopActivitiesLocked(); 10792 } else { 10793 mStackSupervisor.finishTopRunningActivityLocked(app); 10794 } 10795 10796 // Bump up the crash count of any services currently running in the proc. 10797 for (int i=app.services.size()-1; i>=0; i--) { 10798 // Any services running in the application need to be placed 10799 // back in the pending list. 10800 ServiceRecord sr = app.services.valueAt(i); 10801 sr.crashCount++; 10802 } 10803 10804 // If the crashing process is what we consider to be the "home process" and it has been 10805 // replaced by a third-party app, clear the package preferred activities from packages 10806 // with a home activity running in the process to prevent a repeatedly crashing app 10807 // from blocking the user to manually clear the list. 10808 final ArrayList<ActivityRecord> activities = app.activities; 10809 if (app == mHomeProcess && activities.size() > 0 10810 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10811 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10812 final ActivityRecord r = activities.get(activityNdx); 10813 if (r.isHomeActivity()) { 10814 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10815 try { 10816 ActivityThread.getPackageManager() 10817 .clearPackagePreferredActivities(r.packageName); 10818 } catch (RemoteException c) { 10819 // pm is in same process, this will never happen. 10820 } 10821 } 10822 } 10823 } 10824 10825 if (!app.isolated) { 10826 // XXX Can't keep track of crash times for isolated processes, 10827 // because they don't have a perisistent identity. 10828 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10829 } 10830 10831 if (app.crashHandler != null) mHandler.post(app.crashHandler); 10832 return true; 10833 } 10834 10835 void startAppProblemLocked(ProcessRecord app) { 10836 // If this app is not running under the current user, then we 10837 // can't give it a report button because that would require 10838 // launching the report UI under a different user. 10839 app.errorReportReceiver = null; 10840 10841 for (int userId : mCurrentProfileIds) { 10842 if (app.userId == userId) { 10843 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10844 mContext, app.info.packageName, app.info.flags); 10845 } 10846 } 10847 skipCurrentReceiverLocked(app); 10848 } 10849 10850 void skipCurrentReceiverLocked(ProcessRecord app) { 10851 for (BroadcastQueue queue : mBroadcastQueues) { 10852 queue.skipCurrentReceiverLocked(app); 10853 } 10854 } 10855 10856 /** 10857 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10858 * The application process will exit immediately after this call returns. 10859 * @param app object of the crashing app, null for the system server 10860 * @param crashInfo describing the exception 10861 */ 10862 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10863 ProcessRecord r = findAppProcess(app, "Crash"); 10864 final String processName = app == null ? "system_server" 10865 : (r == null ? "unknown" : r.processName); 10866 10867 handleApplicationCrashInner("crash", r, processName, crashInfo); 10868 } 10869 10870 /* Native crash reporting uses this inner version because it needs to be somewhat 10871 * decoupled from the AM-managed cleanup lifecycle 10872 */ 10873 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10874 ApplicationErrorReport.CrashInfo crashInfo) { 10875 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10876 UserHandle.getUserId(Binder.getCallingUid()), processName, 10877 r == null ? -1 : r.info.flags, 10878 crashInfo.exceptionClassName, 10879 crashInfo.exceptionMessage, 10880 crashInfo.throwFileName, 10881 crashInfo.throwLineNumber); 10882 10883 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10884 10885 crashApplication(r, crashInfo); 10886 } 10887 10888 public void handleApplicationStrictModeViolation( 10889 IBinder app, 10890 int violationMask, 10891 StrictMode.ViolationInfo info) { 10892 ProcessRecord r = findAppProcess(app, "StrictMode"); 10893 if (r == null) { 10894 return; 10895 } 10896 10897 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10898 Integer stackFingerprint = info.hashCode(); 10899 boolean logIt = true; 10900 synchronized (mAlreadyLoggedViolatedStacks) { 10901 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10902 logIt = false; 10903 // TODO: sub-sample into EventLog for these, with 10904 // the info.durationMillis? Then we'd get 10905 // the relative pain numbers, without logging all 10906 // the stack traces repeatedly. We'd want to do 10907 // likewise in the client code, which also does 10908 // dup suppression, before the Binder call. 10909 } else { 10910 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10911 mAlreadyLoggedViolatedStacks.clear(); 10912 } 10913 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10914 } 10915 } 10916 if (logIt) { 10917 logStrictModeViolationToDropBox(r, info); 10918 } 10919 } 10920 10921 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10922 AppErrorResult result = new AppErrorResult(); 10923 synchronized (this) { 10924 final long origId = Binder.clearCallingIdentity(); 10925 10926 Message msg = Message.obtain(); 10927 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10928 HashMap<String, Object> data = new HashMap<String, Object>(); 10929 data.put("result", result); 10930 data.put("app", r); 10931 data.put("violationMask", violationMask); 10932 data.put("info", info); 10933 msg.obj = data; 10934 mHandler.sendMessage(msg); 10935 10936 Binder.restoreCallingIdentity(origId); 10937 } 10938 int res = result.get(); 10939 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10940 } 10941 } 10942 10943 // Depending on the policy in effect, there could be a bunch of 10944 // these in quick succession so we try to batch these together to 10945 // minimize disk writes, number of dropbox entries, and maximize 10946 // compression, by having more fewer, larger records. 10947 private void logStrictModeViolationToDropBox( 10948 ProcessRecord process, 10949 StrictMode.ViolationInfo info) { 10950 if (info == null) { 10951 return; 10952 } 10953 final boolean isSystemApp = process == null || 10954 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10955 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10956 final String processName = process == null ? "unknown" : process.processName; 10957 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10958 final DropBoxManager dbox = (DropBoxManager) 10959 mContext.getSystemService(Context.DROPBOX_SERVICE); 10960 10961 // Exit early if the dropbox isn't configured to accept this report type. 10962 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10963 10964 boolean bufferWasEmpty; 10965 boolean needsFlush; 10966 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10967 synchronized (sb) { 10968 bufferWasEmpty = sb.length() == 0; 10969 appendDropBoxProcessHeaders(process, processName, sb); 10970 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10971 sb.append("System-App: ").append(isSystemApp).append("\n"); 10972 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10973 if (info.violationNumThisLoop != 0) { 10974 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10975 } 10976 if (info.numAnimationsRunning != 0) { 10977 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10978 } 10979 if (info.broadcastIntentAction != null) { 10980 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10981 } 10982 if (info.durationMillis != -1) { 10983 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10984 } 10985 if (info.numInstances != -1) { 10986 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10987 } 10988 if (info.tags != null) { 10989 for (String tag : info.tags) { 10990 sb.append("Span-Tag: ").append(tag).append("\n"); 10991 } 10992 } 10993 sb.append("\n"); 10994 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10995 sb.append(info.crashInfo.stackTrace); 10996 } 10997 sb.append("\n"); 10998 10999 // Only buffer up to ~64k. Various logging bits truncate 11000 // things at 128k. 11001 needsFlush = (sb.length() > 64 * 1024); 11002 } 11003 11004 // Flush immediately if the buffer's grown too large, or this 11005 // is a non-system app. Non-system apps are isolated with a 11006 // different tag & policy and not batched. 11007 // 11008 // Batching is useful during internal testing with 11009 // StrictMode settings turned up high. Without batching, 11010 // thousands of separate files could be created on boot. 11011 if (!isSystemApp || needsFlush) { 11012 new Thread("Error dump: " + dropboxTag) { 11013 @Override 11014 public void run() { 11015 String report; 11016 synchronized (sb) { 11017 report = sb.toString(); 11018 sb.delete(0, sb.length()); 11019 sb.trimToSize(); 11020 } 11021 if (report.length() != 0) { 11022 dbox.addText(dropboxTag, report); 11023 } 11024 } 11025 }.start(); 11026 return; 11027 } 11028 11029 // System app batching: 11030 if (!bufferWasEmpty) { 11031 // An existing dropbox-writing thread is outstanding, so 11032 // we don't need to start it up. The existing thread will 11033 // catch the buffer appends we just did. 11034 return; 11035 } 11036 11037 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11038 // (After this point, we shouldn't access AMS internal data structures.) 11039 new Thread("Error dump: " + dropboxTag) { 11040 @Override 11041 public void run() { 11042 // 5 second sleep to let stacks arrive and be batched together 11043 try { 11044 Thread.sleep(5000); // 5 seconds 11045 } catch (InterruptedException e) {} 11046 11047 String errorReport; 11048 synchronized (mStrictModeBuffer) { 11049 errorReport = mStrictModeBuffer.toString(); 11050 if (errorReport.length() == 0) { 11051 return; 11052 } 11053 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11054 mStrictModeBuffer.trimToSize(); 11055 } 11056 dbox.addText(dropboxTag, errorReport); 11057 } 11058 }.start(); 11059 } 11060 11061 /** 11062 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11063 * @param app object of the crashing app, null for the system server 11064 * @param tag reported by the caller 11065 * @param crashInfo describing the context of the error 11066 * @return true if the process should exit immediately (WTF is fatal) 11067 */ 11068 public boolean handleApplicationWtf(IBinder app, String tag, 11069 ApplicationErrorReport.CrashInfo crashInfo) { 11070 ProcessRecord r = findAppProcess(app, "WTF"); 11071 final String processName = app == null ? "system_server" 11072 : (r == null ? "unknown" : r.processName); 11073 11074 EventLog.writeEvent(EventLogTags.AM_WTF, 11075 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11076 processName, 11077 r == null ? -1 : r.info.flags, 11078 tag, crashInfo.exceptionMessage); 11079 11080 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11081 11082 if (r != null && r.pid != Process.myPid() && 11083 Settings.Global.getInt(mContext.getContentResolver(), 11084 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11085 crashApplication(r, crashInfo); 11086 return true; 11087 } else { 11088 return false; 11089 } 11090 } 11091 11092 /** 11093 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11094 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11095 */ 11096 private ProcessRecord findAppProcess(IBinder app, String reason) { 11097 if (app == null) { 11098 return null; 11099 } 11100 11101 synchronized (this) { 11102 final int NP = mProcessNames.getMap().size(); 11103 for (int ip=0; ip<NP; ip++) { 11104 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11105 final int NA = apps.size(); 11106 for (int ia=0; ia<NA; ia++) { 11107 ProcessRecord p = apps.valueAt(ia); 11108 if (p.thread != null && p.thread.asBinder() == app) { 11109 return p; 11110 } 11111 } 11112 } 11113 11114 Slog.w(TAG, "Can't find mystery application for " + reason 11115 + " from pid=" + Binder.getCallingPid() 11116 + " uid=" + Binder.getCallingUid() + ": " + app); 11117 return null; 11118 } 11119 } 11120 11121 /** 11122 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11123 * to append various headers to the dropbox log text. 11124 */ 11125 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11126 StringBuilder sb) { 11127 // Watchdog thread ends up invoking this function (with 11128 // a null ProcessRecord) to add the stack file to dropbox. 11129 // Do not acquire a lock on this (am) in such cases, as it 11130 // could cause a potential deadlock, if and when watchdog 11131 // is invoked due to unavailability of lock on am and it 11132 // would prevent watchdog from killing system_server. 11133 if (process == null) { 11134 sb.append("Process: ").append(processName).append("\n"); 11135 return; 11136 } 11137 // Note: ProcessRecord 'process' is guarded by the service 11138 // instance. (notably process.pkgList, which could otherwise change 11139 // concurrently during execution of this method) 11140 synchronized (this) { 11141 sb.append("Process: ").append(processName).append("\n"); 11142 int flags = process.info.flags; 11143 IPackageManager pm = AppGlobals.getPackageManager(); 11144 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11145 for (int ip=0; ip<process.pkgList.size(); ip++) { 11146 String pkg = process.pkgList.keyAt(ip); 11147 sb.append("Package: ").append(pkg); 11148 try { 11149 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11150 if (pi != null) { 11151 sb.append(" v").append(pi.versionCode); 11152 if (pi.versionName != null) { 11153 sb.append(" (").append(pi.versionName).append(")"); 11154 } 11155 } 11156 } catch (RemoteException e) { 11157 Slog.e(TAG, "Error getting package info: " + pkg, e); 11158 } 11159 sb.append("\n"); 11160 } 11161 } 11162 } 11163 11164 private static String processClass(ProcessRecord process) { 11165 if (process == null || process.pid == MY_PID) { 11166 return "system_server"; 11167 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11168 return "system_app"; 11169 } else { 11170 return "data_app"; 11171 } 11172 } 11173 11174 /** 11175 * Write a description of an error (crash, WTF, ANR) to the drop box. 11176 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11177 * @param process which caused the error, null means the system server 11178 * @param activity which triggered the error, null if unknown 11179 * @param parent activity related to the error, null if unknown 11180 * @param subject line related to the error, null if absent 11181 * @param report in long form describing the error, null if absent 11182 * @param logFile to include in the report, null if none 11183 * @param crashInfo giving an application stack trace, null if absent 11184 */ 11185 public void addErrorToDropBox(String eventType, 11186 ProcessRecord process, String processName, ActivityRecord activity, 11187 ActivityRecord parent, String subject, 11188 final String report, final File logFile, 11189 final ApplicationErrorReport.CrashInfo crashInfo) { 11190 // NOTE -- this must never acquire the ActivityManagerService lock, 11191 // otherwise the watchdog may be prevented from resetting the system. 11192 11193 final String dropboxTag = processClass(process) + "_" + eventType; 11194 final DropBoxManager dbox = (DropBoxManager) 11195 mContext.getSystemService(Context.DROPBOX_SERVICE); 11196 11197 // Exit early if the dropbox isn't configured to accept this report type. 11198 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11199 11200 final StringBuilder sb = new StringBuilder(1024); 11201 appendDropBoxProcessHeaders(process, processName, sb); 11202 if (activity != null) { 11203 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11204 } 11205 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11206 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11207 } 11208 if (parent != null && parent != activity) { 11209 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11210 } 11211 if (subject != null) { 11212 sb.append("Subject: ").append(subject).append("\n"); 11213 } 11214 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11215 if (Debug.isDebuggerConnected()) { 11216 sb.append("Debugger: Connected\n"); 11217 } 11218 sb.append("\n"); 11219 11220 // Do the rest in a worker thread to avoid blocking the caller on I/O 11221 // (After this point, we shouldn't access AMS internal data structures.) 11222 Thread worker = new Thread("Error dump: " + dropboxTag) { 11223 @Override 11224 public void run() { 11225 if (report != null) { 11226 sb.append(report); 11227 } 11228 if (logFile != null) { 11229 try { 11230 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11231 "\n\n[[TRUNCATED]]")); 11232 } catch (IOException e) { 11233 Slog.e(TAG, "Error reading " + logFile, e); 11234 } 11235 } 11236 if (crashInfo != null && crashInfo.stackTrace != null) { 11237 sb.append(crashInfo.stackTrace); 11238 } 11239 11240 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11241 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11242 if (lines > 0) { 11243 sb.append("\n"); 11244 11245 // Merge several logcat streams, and take the last N lines 11246 InputStreamReader input = null; 11247 try { 11248 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11249 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11250 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11251 11252 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11253 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11254 input = new InputStreamReader(logcat.getInputStream()); 11255 11256 int num; 11257 char[] buf = new char[8192]; 11258 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11259 } catch (IOException e) { 11260 Slog.e(TAG, "Error running logcat", e); 11261 } finally { 11262 if (input != null) try { input.close(); } catch (IOException e) {} 11263 } 11264 } 11265 11266 dbox.addText(dropboxTag, sb.toString()); 11267 } 11268 }; 11269 11270 if (process == null) { 11271 // If process is null, we are being called from some internal code 11272 // and may be about to die -- run this synchronously. 11273 worker.run(); 11274 } else { 11275 worker.start(); 11276 } 11277 } 11278 11279 /** 11280 * Bring up the "unexpected error" dialog box for a crashing app. 11281 * Deal with edge cases (intercepts from instrumented applications, 11282 * ActivityController, error intent receivers, that sort of thing). 11283 * @param r the application crashing 11284 * @param crashInfo describing the failure 11285 */ 11286 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11287 long timeMillis = System.currentTimeMillis(); 11288 String shortMsg = crashInfo.exceptionClassName; 11289 String longMsg = crashInfo.exceptionMessage; 11290 String stackTrace = crashInfo.stackTrace; 11291 if (shortMsg != null && longMsg != null) { 11292 longMsg = shortMsg + ": " + longMsg; 11293 } else if (shortMsg != null) { 11294 longMsg = shortMsg; 11295 } 11296 11297 AppErrorResult result = new AppErrorResult(); 11298 synchronized (this) { 11299 if (mController != null) { 11300 try { 11301 String name = r != null ? r.processName : null; 11302 int pid = r != null ? r.pid : Binder.getCallingPid(); 11303 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11304 if (!mController.appCrashed(name, pid, 11305 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11306 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11307 && "Native crash".equals(crashInfo.exceptionClassName)) { 11308 Slog.w(TAG, "Skip killing native crashed app " + name 11309 + "(" + pid + ") during testing"); 11310 } else { 11311 Slog.w(TAG, "Force-killing crashed app " + name 11312 + " at watcher's request"); 11313 Process.killProcess(pid); 11314 if (r != null) { 11315 Process.killProcessGroup(uid, pid); 11316 } 11317 } 11318 return; 11319 } 11320 } catch (RemoteException e) { 11321 mController = null; 11322 Watchdog.getInstance().setActivityController(null); 11323 } 11324 } 11325 11326 final long origId = Binder.clearCallingIdentity(); 11327 11328 // If this process is running instrumentation, finish it. 11329 if (r != null && r.instrumentationClass != null) { 11330 Slog.w(TAG, "Error in app " + r.processName 11331 + " running instrumentation " + r.instrumentationClass + ":"); 11332 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11333 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11334 Bundle info = new Bundle(); 11335 info.putString("shortMsg", shortMsg); 11336 info.putString("longMsg", longMsg); 11337 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11338 Binder.restoreCallingIdentity(origId); 11339 return; 11340 } 11341 11342 // If we can't identify the process or it's already exceeded its crash quota, 11343 // quit right away without showing a crash dialog. 11344 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11345 Binder.restoreCallingIdentity(origId); 11346 return; 11347 } 11348 11349 Message msg = Message.obtain(); 11350 msg.what = SHOW_ERROR_MSG; 11351 HashMap data = new HashMap(); 11352 data.put("result", result); 11353 data.put("app", r); 11354 msg.obj = data; 11355 mHandler.sendMessage(msg); 11356 11357 Binder.restoreCallingIdentity(origId); 11358 } 11359 11360 int res = result.get(); 11361 11362 Intent appErrorIntent = null; 11363 synchronized (this) { 11364 if (r != null && !r.isolated) { 11365 // XXX Can't keep track of crash time for isolated processes, 11366 // since they don't have a persistent identity. 11367 mProcessCrashTimes.put(r.info.processName, r.uid, 11368 SystemClock.uptimeMillis()); 11369 } 11370 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11371 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11372 } 11373 } 11374 11375 if (appErrorIntent != null) { 11376 try { 11377 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11378 } catch (ActivityNotFoundException e) { 11379 Slog.w(TAG, "bug report receiver dissappeared", e); 11380 } 11381 } 11382 } 11383 11384 Intent createAppErrorIntentLocked(ProcessRecord r, 11385 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11386 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11387 if (report == null) { 11388 return null; 11389 } 11390 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11391 result.setComponent(r.errorReportReceiver); 11392 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11393 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11394 return result; 11395 } 11396 11397 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11398 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11399 if (r.errorReportReceiver == null) { 11400 return null; 11401 } 11402 11403 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11404 return null; 11405 } 11406 11407 ApplicationErrorReport report = new ApplicationErrorReport(); 11408 report.packageName = r.info.packageName; 11409 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11410 report.processName = r.processName; 11411 report.time = timeMillis; 11412 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11413 11414 if (r.crashing || r.forceCrashReport) { 11415 report.type = ApplicationErrorReport.TYPE_CRASH; 11416 report.crashInfo = crashInfo; 11417 } else if (r.notResponding) { 11418 report.type = ApplicationErrorReport.TYPE_ANR; 11419 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11420 11421 report.anrInfo.activity = r.notRespondingReport.tag; 11422 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11423 report.anrInfo.info = r.notRespondingReport.longMsg; 11424 } 11425 11426 return report; 11427 } 11428 11429 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11430 enforceNotIsolatedCaller("getProcessesInErrorState"); 11431 // assume our apps are happy - lazy create the list 11432 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11433 11434 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11435 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11436 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11437 11438 synchronized (this) { 11439 11440 // iterate across all processes 11441 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11442 ProcessRecord app = mLruProcesses.get(i); 11443 if (!allUsers && app.userId != userId) { 11444 continue; 11445 } 11446 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11447 // This one's in trouble, so we'll generate a report for it 11448 // crashes are higher priority (in case there's a crash *and* an anr) 11449 ActivityManager.ProcessErrorStateInfo report = null; 11450 if (app.crashing) { 11451 report = app.crashingReport; 11452 } else if (app.notResponding) { 11453 report = app.notRespondingReport; 11454 } 11455 11456 if (report != null) { 11457 if (errList == null) { 11458 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11459 } 11460 errList.add(report); 11461 } else { 11462 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11463 " crashing = " + app.crashing + 11464 " notResponding = " + app.notResponding); 11465 } 11466 } 11467 } 11468 } 11469 11470 return errList; 11471 } 11472 11473 static int procStateToImportance(int procState, int memAdj, 11474 ActivityManager.RunningAppProcessInfo currApp) { 11475 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11476 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11477 currApp.lru = memAdj; 11478 } else { 11479 currApp.lru = 0; 11480 } 11481 return imp; 11482 } 11483 11484 private void fillInProcMemInfo(ProcessRecord app, 11485 ActivityManager.RunningAppProcessInfo outInfo) { 11486 outInfo.pid = app.pid; 11487 outInfo.uid = app.info.uid; 11488 if (mHeavyWeightProcess == app) { 11489 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11490 } 11491 if (app.persistent) { 11492 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11493 } 11494 if (app.activities.size() > 0) { 11495 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11496 } 11497 outInfo.lastTrimLevel = app.trimMemoryLevel; 11498 int adj = app.curAdj; 11499 int procState = app.curProcState; 11500 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11501 outInfo.importanceReasonCode = app.adjTypeCode; 11502 outInfo.processState = app.curProcState; 11503 } 11504 11505 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11506 enforceNotIsolatedCaller("getRunningAppProcesses"); 11507 // Lazy instantiation of list 11508 List<ActivityManager.RunningAppProcessInfo> runList = null; 11509 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11510 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11511 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11512 synchronized (this) { 11513 // Iterate across all processes 11514 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11515 ProcessRecord app = mLruProcesses.get(i); 11516 if (!allUsers && app.userId != userId) { 11517 continue; 11518 } 11519 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11520 // Generate process state info for running application 11521 ActivityManager.RunningAppProcessInfo currApp = 11522 new ActivityManager.RunningAppProcessInfo(app.processName, 11523 app.pid, app.getPackageList()); 11524 fillInProcMemInfo(app, currApp); 11525 if (app.adjSource instanceof ProcessRecord) { 11526 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11527 currApp.importanceReasonImportance = 11528 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11529 app.adjSourceProcState); 11530 } else if (app.adjSource instanceof ActivityRecord) { 11531 ActivityRecord r = (ActivityRecord)app.adjSource; 11532 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11533 } 11534 if (app.adjTarget instanceof ComponentName) { 11535 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11536 } 11537 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11538 // + " lru=" + currApp.lru); 11539 if (runList == null) { 11540 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11541 } 11542 runList.add(currApp); 11543 } 11544 } 11545 } 11546 return runList; 11547 } 11548 11549 public List<ApplicationInfo> getRunningExternalApplications() { 11550 enforceNotIsolatedCaller("getRunningExternalApplications"); 11551 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11552 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11553 if (runningApps != null && runningApps.size() > 0) { 11554 Set<String> extList = new HashSet<String>(); 11555 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11556 if (app.pkgList != null) { 11557 for (String pkg : app.pkgList) { 11558 extList.add(pkg); 11559 } 11560 } 11561 } 11562 IPackageManager pm = AppGlobals.getPackageManager(); 11563 for (String pkg : extList) { 11564 try { 11565 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11566 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11567 retList.add(info); 11568 } 11569 } catch (RemoteException e) { 11570 } 11571 } 11572 } 11573 return retList; 11574 } 11575 11576 @Override 11577 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11578 enforceNotIsolatedCaller("getMyMemoryState"); 11579 synchronized (this) { 11580 ProcessRecord proc; 11581 synchronized (mPidsSelfLocked) { 11582 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11583 } 11584 fillInProcMemInfo(proc, outInfo); 11585 } 11586 } 11587 11588 @Override 11589 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11590 if (checkCallingPermission(android.Manifest.permission.DUMP) 11591 != PackageManager.PERMISSION_GRANTED) { 11592 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11593 + Binder.getCallingPid() 11594 + ", uid=" + Binder.getCallingUid() 11595 + " without permission " 11596 + android.Manifest.permission.DUMP); 11597 return; 11598 } 11599 11600 boolean dumpAll = false; 11601 boolean dumpClient = false; 11602 String dumpPackage = null; 11603 11604 int opti = 0; 11605 while (opti < args.length) { 11606 String opt = args[opti]; 11607 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11608 break; 11609 } 11610 opti++; 11611 if ("-a".equals(opt)) { 11612 dumpAll = true; 11613 } else if ("-c".equals(opt)) { 11614 dumpClient = true; 11615 } else if ("-h".equals(opt)) { 11616 pw.println("Activity manager dump options:"); 11617 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11618 pw.println(" cmd may be one of:"); 11619 pw.println(" a[ctivities]: activity stack state"); 11620 pw.println(" r[recents]: recent activities state"); 11621 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11622 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11623 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11624 pw.println(" o[om]: out of memory management"); 11625 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11626 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11627 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11628 pw.println(" service [COMP_SPEC]: service client-side state"); 11629 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11630 pw.println(" all: dump all activities"); 11631 pw.println(" top: dump the top activity"); 11632 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11633 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11634 pw.println(" a partial substring in a component name, a"); 11635 pw.println(" hex object identifier."); 11636 pw.println(" -a: include all available server state."); 11637 pw.println(" -c: include client state."); 11638 return; 11639 } else { 11640 pw.println("Unknown argument: " + opt + "; use -h for help"); 11641 } 11642 } 11643 11644 long origId = Binder.clearCallingIdentity(); 11645 boolean more = false; 11646 // Is the caller requesting to dump a particular piece of data? 11647 if (opti < args.length) { 11648 String cmd = args[opti]; 11649 opti++; 11650 if ("activities".equals(cmd) || "a".equals(cmd)) { 11651 synchronized (this) { 11652 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11653 } 11654 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 11655 synchronized (this) { 11656 dumpRecentsLocked(fd, pw, args, opti, true, null); 11657 } 11658 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11659 String[] newArgs; 11660 String name; 11661 if (opti >= args.length) { 11662 name = null; 11663 newArgs = EMPTY_STRING_ARRAY; 11664 } else { 11665 name = args[opti]; 11666 opti++; 11667 newArgs = new String[args.length - opti]; 11668 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11669 args.length - opti); 11670 } 11671 synchronized (this) { 11672 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11673 } 11674 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11675 String[] newArgs; 11676 String name; 11677 if (opti >= args.length) { 11678 name = null; 11679 newArgs = EMPTY_STRING_ARRAY; 11680 } else { 11681 name = args[opti]; 11682 opti++; 11683 newArgs = new String[args.length - opti]; 11684 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11685 args.length - opti); 11686 } 11687 synchronized (this) { 11688 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11689 } 11690 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11691 String[] newArgs; 11692 String name; 11693 if (opti >= args.length) { 11694 name = null; 11695 newArgs = EMPTY_STRING_ARRAY; 11696 } else { 11697 name = args[opti]; 11698 opti++; 11699 newArgs = new String[args.length - opti]; 11700 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11701 args.length - opti); 11702 } 11703 synchronized (this) { 11704 dumpProcessesLocked(fd, pw, args, opti, true, name); 11705 } 11706 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11707 synchronized (this) { 11708 dumpOomLocked(fd, pw, args, opti, true); 11709 } 11710 } else if ("provider".equals(cmd)) { 11711 String[] newArgs; 11712 String name; 11713 if (opti >= args.length) { 11714 name = null; 11715 newArgs = EMPTY_STRING_ARRAY; 11716 } else { 11717 name = args[opti]; 11718 opti++; 11719 newArgs = new String[args.length - opti]; 11720 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11721 } 11722 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11723 pw.println("No providers match: " + name); 11724 pw.println("Use -h for help."); 11725 } 11726 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11727 synchronized (this) { 11728 dumpProvidersLocked(fd, pw, args, opti, true, null); 11729 } 11730 } else if ("service".equals(cmd)) { 11731 String[] newArgs; 11732 String name; 11733 if (opti >= args.length) { 11734 name = null; 11735 newArgs = EMPTY_STRING_ARRAY; 11736 } else { 11737 name = args[opti]; 11738 opti++; 11739 newArgs = new String[args.length - opti]; 11740 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11741 args.length - opti); 11742 } 11743 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11744 pw.println("No services match: " + name); 11745 pw.println("Use -h for help."); 11746 } 11747 } else if ("package".equals(cmd)) { 11748 String[] newArgs; 11749 if (opti >= args.length) { 11750 pw.println("package: no package name specified"); 11751 pw.println("Use -h for help."); 11752 } else { 11753 dumpPackage = args[opti]; 11754 opti++; 11755 newArgs = new String[args.length - opti]; 11756 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11757 args.length - opti); 11758 args = newArgs; 11759 opti = 0; 11760 more = true; 11761 } 11762 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11763 synchronized (this) { 11764 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11765 } 11766 } else { 11767 // Dumping a single activity? 11768 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11769 pw.println("Bad activity command, or no activities match: " + cmd); 11770 pw.println("Use -h for help."); 11771 } 11772 } 11773 if (!more) { 11774 Binder.restoreCallingIdentity(origId); 11775 return; 11776 } 11777 } 11778 11779 // No piece of data specified, dump everything. 11780 synchronized (this) { 11781 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11782 pw.println(); 11783 if (dumpAll) { 11784 pw.println("-------------------------------------------------------------------------------"); 11785 } 11786 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11787 pw.println(); 11788 if (dumpAll) { 11789 pw.println("-------------------------------------------------------------------------------"); 11790 } 11791 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11792 pw.println(); 11793 if (dumpAll) { 11794 pw.println("-------------------------------------------------------------------------------"); 11795 } 11796 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11797 pw.println(); 11798 if (dumpAll) { 11799 pw.println("-------------------------------------------------------------------------------"); 11800 } 11801 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11802 pw.println(); 11803 if (dumpAll) { 11804 pw.println("-------------------------------------------------------------------------------"); 11805 } 11806 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11807 pw.println(); 11808 if (dumpAll) { 11809 pw.println("-------------------------------------------------------------------------------"); 11810 } 11811 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11812 } 11813 Binder.restoreCallingIdentity(origId); 11814 } 11815 11816 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11817 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11818 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11819 11820 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11821 dumpPackage); 11822 boolean needSep = printedAnything; 11823 11824 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11825 dumpPackage, needSep, " mFocusedActivity: "); 11826 if (printed) { 11827 printedAnything = true; 11828 needSep = false; 11829 } 11830 11831 if (dumpPackage == null) { 11832 if (needSep) { 11833 pw.println(); 11834 } 11835 needSep = true; 11836 printedAnything = true; 11837 mStackSupervisor.dump(pw, " "); 11838 } 11839 11840 if (!printedAnything) { 11841 pw.println(" (nothing)"); 11842 } 11843 } 11844 11845 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11846 int opti, boolean dumpAll, String dumpPackage) { 11847 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 11848 11849 boolean printedAnything = false; 11850 11851 if (mRecentTasks.size() > 0) { 11852 boolean printedHeader = false; 11853 11854 final int N = mRecentTasks.size(); 11855 for (int i=0; i<N; i++) { 11856 TaskRecord tr = mRecentTasks.get(i); 11857 if (dumpPackage != null) { 11858 if (tr.realActivity == null || 11859 !dumpPackage.equals(tr.realActivity)) { 11860 continue; 11861 } 11862 } 11863 if (!printedHeader) { 11864 pw.println(" Recent tasks:"); 11865 printedHeader = true; 11866 printedAnything = true; 11867 } 11868 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11869 pw.println(tr); 11870 if (dumpAll) { 11871 mRecentTasks.get(i).dump(pw, " "); 11872 } 11873 } 11874 } 11875 11876 if (!printedAnything) { 11877 pw.println(" (nothing)"); 11878 } 11879 } 11880 11881 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11882 int opti, boolean dumpAll, String dumpPackage) { 11883 boolean needSep = false; 11884 boolean printedAnything = false; 11885 int numPers = 0; 11886 11887 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11888 11889 if (dumpAll) { 11890 final int NP = mProcessNames.getMap().size(); 11891 for (int ip=0; ip<NP; ip++) { 11892 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11893 final int NA = procs.size(); 11894 for (int ia=0; ia<NA; ia++) { 11895 ProcessRecord r = procs.valueAt(ia); 11896 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11897 continue; 11898 } 11899 if (!needSep) { 11900 pw.println(" All known processes:"); 11901 needSep = true; 11902 printedAnything = true; 11903 } 11904 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11905 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11906 pw.print(" "); pw.println(r); 11907 r.dump(pw, " "); 11908 if (r.persistent) { 11909 numPers++; 11910 } 11911 } 11912 } 11913 } 11914 11915 if (mIsolatedProcesses.size() > 0) { 11916 boolean printed = false; 11917 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11918 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11919 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11920 continue; 11921 } 11922 if (!printed) { 11923 if (needSep) { 11924 pw.println(); 11925 } 11926 pw.println(" Isolated process list (sorted by uid):"); 11927 printedAnything = true; 11928 printed = true; 11929 needSep = true; 11930 } 11931 pw.println(String.format("%sIsolated #%2d: %s", 11932 " ", i, r.toString())); 11933 } 11934 } 11935 11936 if (mLruProcesses.size() > 0) { 11937 if (needSep) { 11938 pw.println(); 11939 } 11940 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11941 pw.print(" total, non-act at "); 11942 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11943 pw.print(", non-svc at "); 11944 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11945 pw.println("):"); 11946 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11947 needSep = true; 11948 printedAnything = true; 11949 } 11950 11951 if (dumpAll || dumpPackage != null) { 11952 synchronized (mPidsSelfLocked) { 11953 boolean printed = false; 11954 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11955 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11956 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11957 continue; 11958 } 11959 if (!printed) { 11960 if (needSep) pw.println(); 11961 needSep = true; 11962 pw.println(" PID mappings:"); 11963 printed = true; 11964 printedAnything = true; 11965 } 11966 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11967 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11968 } 11969 } 11970 } 11971 11972 if (mForegroundProcesses.size() > 0) { 11973 synchronized (mPidsSelfLocked) { 11974 boolean printed = false; 11975 for (int i=0; i<mForegroundProcesses.size(); i++) { 11976 ProcessRecord r = mPidsSelfLocked.get( 11977 mForegroundProcesses.valueAt(i).pid); 11978 if (dumpPackage != null && (r == null 11979 || !r.pkgList.containsKey(dumpPackage))) { 11980 continue; 11981 } 11982 if (!printed) { 11983 if (needSep) pw.println(); 11984 needSep = true; 11985 pw.println(" Foreground Processes:"); 11986 printed = true; 11987 printedAnything = true; 11988 } 11989 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11990 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11991 } 11992 } 11993 } 11994 11995 if (mPersistentStartingProcesses.size() > 0) { 11996 if (needSep) pw.println(); 11997 needSep = true; 11998 printedAnything = true; 11999 pw.println(" Persisent processes that are starting:"); 12000 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12001 "Starting Norm", "Restarting PERS", dumpPackage); 12002 } 12003 12004 if (mRemovedProcesses.size() > 0) { 12005 if (needSep) pw.println(); 12006 needSep = true; 12007 printedAnything = true; 12008 pw.println(" Processes that are being removed:"); 12009 dumpProcessList(pw, this, mRemovedProcesses, " ", 12010 "Removed Norm", "Removed PERS", dumpPackage); 12011 } 12012 12013 if (mProcessesOnHold.size() > 0) { 12014 if (needSep) pw.println(); 12015 needSep = true; 12016 printedAnything = true; 12017 pw.println(" Processes that are on old until the system is ready:"); 12018 dumpProcessList(pw, this, mProcessesOnHold, " ", 12019 "OnHold Norm", "OnHold PERS", dumpPackage); 12020 } 12021 12022 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12023 12024 if (mProcessCrashTimes.getMap().size() > 0) { 12025 boolean printed = false; 12026 long now = SystemClock.uptimeMillis(); 12027 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12028 final int NP = pmap.size(); 12029 for (int ip=0; ip<NP; ip++) { 12030 String pname = pmap.keyAt(ip); 12031 SparseArray<Long> uids = pmap.valueAt(ip); 12032 final int N = uids.size(); 12033 for (int i=0; i<N; i++) { 12034 int puid = uids.keyAt(i); 12035 ProcessRecord r = mProcessNames.get(pname, puid); 12036 if (dumpPackage != null && (r == null 12037 || !r.pkgList.containsKey(dumpPackage))) { 12038 continue; 12039 } 12040 if (!printed) { 12041 if (needSep) pw.println(); 12042 needSep = true; 12043 pw.println(" Time since processes crashed:"); 12044 printed = true; 12045 printedAnything = true; 12046 } 12047 pw.print(" Process "); pw.print(pname); 12048 pw.print(" uid "); pw.print(puid); 12049 pw.print(": last crashed "); 12050 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12051 pw.println(" ago"); 12052 } 12053 } 12054 } 12055 12056 if (mBadProcesses.getMap().size() > 0) { 12057 boolean printed = false; 12058 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12059 final int NP = pmap.size(); 12060 for (int ip=0; ip<NP; ip++) { 12061 String pname = pmap.keyAt(ip); 12062 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12063 final int N = uids.size(); 12064 for (int i=0; i<N; i++) { 12065 int puid = uids.keyAt(i); 12066 ProcessRecord r = mProcessNames.get(pname, puid); 12067 if (dumpPackage != null && (r == null 12068 || !r.pkgList.containsKey(dumpPackage))) { 12069 continue; 12070 } 12071 if (!printed) { 12072 if (needSep) pw.println(); 12073 needSep = true; 12074 pw.println(" Bad processes:"); 12075 printedAnything = true; 12076 } 12077 BadProcessInfo info = uids.valueAt(i); 12078 pw.print(" Bad process "); pw.print(pname); 12079 pw.print(" uid "); pw.print(puid); 12080 pw.print(": crashed at time "); pw.println(info.time); 12081 if (info.shortMsg != null) { 12082 pw.print(" Short msg: "); pw.println(info.shortMsg); 12083 } 12084 if (info.longMsg != null) { 12085 pw.print(" Long msg: "); pw.println(info.longMsg); 12086 } 12087 if (info.stack != null) { 12088 pw.println(" Stack:"); 12089 int lastPos = 0; 12090 for (int pos=0; pos<info.stack.length(); pos++) { 12091 if (info.stack.charAt(pos) == '\n') { 12092 pw.print(" "); 12093 pw.write(info.stack, lastPos, pos-lastPos); 12094 pw.println(); 12095 lastPos = pos+1; 12096 } 12097 } 12098 if (lastPos < info.stack.length()) { 12099 pw.print(" "); 12100 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12101 pw.println(); 12102 } 12103 } 12104 } 12105 } 12106 } 12107 12108 if (dumpPackage == null) { 12109 pw.println(); 12110 needSep = false; 12111 pw.println(" mStartedUsers:"); 12112 for (int i=0; i<mStartedUsers.size(); i++) { 12113 UserStartedState uss = mStartedUsers.valueAt(i); 12114 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12115 pw.print(": "); uss.dump("", pw); 12116 } 12117 pw.print(" mStartedUserArray: ["); 12118 for (int i=0; i<mStartedUserArray.length; i++) { 12119 if (i > 0) pw.print(", "); 12120 pw.print(mStartedUserArray[i]); 12121 } 12122 pw.println("]"); 12123 pw.print(" mUserLru: ["); 12124 for (int i=0; i<mUserLru.size(); i++) { 12125 if (i > 0) pw.print(", "); 12126 pw.print(mUserLru.get(i)); 12127 } 12128 pw.println("]"); 12129 if (dumpAll) { 12130 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12131 } 12132 synchronized (mUserProfileGroupIdsSelfLocked) { 12133 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12134 pw.println(" mUserProfileGroupIds:"); 12135 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12136 pw.print(" User #"); 12137 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12138 pw.print(" -> profile #"); 12139 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12140 } 12141 } 12142 } 12143 } 12144 if (mHomeProcess != null && (dumpPackage == null 12145 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12146 if (needSep) { 12147 pw.println(); 12148 needSep = false; 12149 } 12150 pw.println(" mHomeProcess: " + mHomeProcess); 12151 } 12152 if (mPreviousProcess != null && (dumpPackage == null 12153 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12154 if (needSep) { 12155 pw.println(); 12156 needSep = false; 12157 } 12158 pw.println(" mPreviousProcess: " + mPreviousProcess); 12159 } 12160 if (dumpAll) { 12161 StringBuilder sb = new StringBuilder(128); 12162 sb.append(" mPreviousProcessVisibleTime: "); 12163 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12164 pw.println(sb); 12165 } 12166 if (mHeavyWeightProcess != null && (dumpPackage == null 12167 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12168 if (needSep) { 12169 pw.println(); 12170 needSep = false; 12171 } 12172 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12173 } 12174 if (dumpPackage == null) { 12175 pw.println(" mConfiguration: " + mConfiguration); 12176 } 12177 if (dumpAll) { 12178 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12179 if (mCompatModePackages.getPackages().size() > 0) { 12180 boolean printed = false; 12181 for (Map.Entry<String, Integer> entry 12182 : mCompatModePackages.getPackages().entrySet()) { 12183 String pkg = entry.getKey(); 12184 int mode = entry.getValue(); 12185 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12186 continue; 12187 } 12188 if (!printed) { 12189 pw.println(" mScreenCompatPackages:"); 12190 printed = true; 12191 } 12192 pw.print(" "); pw.print(pkg); pw.print(": "); 12193 pw.print(mode); pw.println(); 12194 } 12195 } 12196 } 12197 if (dumpPackage == null) { 12198 if (mSleeping || mWentToSleep || mLockScreenShown) { 12199 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12200 + " mLockScreenShown " + mLockScreenShown); 12201 } 12202 if (mShuttingDown || mRunningVoice) { 12203 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12204 } 12205 } 12206 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12207 || mOrigWaitForDebugger) { 12208 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12209 || dumpPackage.equals(mOrigDebugApp)) { 12210 if (needSep) { 12211 pw.println(); 12212 needSep = false; 12213 } 12214 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12215 + " mDebugTransient=" + mDebugTransient 12216 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12217 } 12218 } 12219 if (mOpenGlTraceApp != null) { 12220 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12221 if (needSep) { 12222 pw.println(); 12223 needSep = false; 12224 } 12225 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12226 } 12227 } 12228 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12229 || mProfileFd != null) { 12230 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12231 if (needSep) { 12232 pw.println(); 12233 needSep = false; 12234 } 12235 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12236 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12237 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 12238 + mAutoStopProfiler); 12239 } 12240 } 12241 if (dumpPackage == null) { 12242 if (mAlwaysFinishActivities || mController != null) { 12243 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12244 + " mController=" + mController); 12245 } 12246 if (dumpAll) { 12247 pw.println(" Total persistent processes: " + numPers); 12248 pw.println(" mProcessesReady=" + mProcessesReady 12249 + " mSystemReady=" + mSystemReady); 12250 pw.println(" mBooting=" + mBooting 12251 + " mBooted=" + mBooted 12252 + " mFactoryTest=" + mFactoryTest); 12253 pw.print(" mLastPowerCheckRealtime="); 12254 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12255 pw.println(""); 12256 pw.print(" mLastPowerCheckUptime="); 12257 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12258 pw.println(""); 12259 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12260 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12261 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12262 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12263 + " (" + mLruProcesses.size() + " total)" 12264 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12265 + " mNumServiceProcs=" + mNumServiceProcs 12266 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12267 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12268 + " mLastMemoryLevel" + mLastMemoryLevel 12269 + " mLastNumProcesses" + mLastNumProcesses); 12270 long now = SystemClock.uptimeMillis(); 12271 pw.print(" mLastIdleTime="); 12272 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12273 pw.print(" mLowRamSinceLastIdle="); 12274 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12275 pw.println(); 12276 } 12277 } 12278 12279 if (!printedAnything) { 12280 pw.println(" (nothing)"); 12281 } 12282 } 12283 12284 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12285 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12286 if (mProcessesToGc.size() > 0) { 12287 boolean printed = false; 12288 long now = SystemClock.uptimeMillis(); 12289 for (int i=0; i<mProcessesToGc.size(); i++) { 12290 ProcessRecord proc = mProcessesToGc.get(i); 12291 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12292 continue; 12293 } 12294 if (!printed) { 12295 if (needSep) pw.println(); 12296 needSep = true; 12297 pw.println(" Processes that are waiting to GC:"); 12298 printed = true; 12299 } 12300 pw.print(" Process "); pw.println(proc); 12301 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12302 pw.print(", last gced="); 12303 pw.print(now-proc.lastRequestedGc); 12304 pw.print(" ms ago, last lowMem="); 12305 pw.print(now-proc.lastLowMemory); 12306 pw.println(" ms ago"); 12307 12308 } 12309 } 12310 return needSep; 12311 } 12312 12313 void printOomLevel(PrintWriter pw, String name, int adj) { 12314 pw.print(" "); 12315 if (adj >= 0) { 12316 pw.print(' '); 12317 if (adj < 10) pw.print(' '); 12318 } else { 12319 if (adj > -10) pw.print(' '); 12320 } 12321 pw.print(adj); 12322 pw.print(": "); 12323 pw.print(name); 12324 pw.print(" ("); 12325 pw.print(mProcessList.getMemLevel(adj)/1024); 12326 pw.println(" kB)"); 12327 } 12328 12329 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12330 int opti, boolean dumpAll) { 12331 boolean needSep = false; 12332 12333 if (mLruProcesses.size() > 0) { 12334 if (needSep) pw.println(); 12335 needSep = true; 12336 pw.println(" OOM levels:"); 12337 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12338 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12339 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12340 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12341 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12342 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12343 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12344 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12345 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12346 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12347 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12348 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12349 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12350 12351 if (needSep) pw.println(); 12352 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12353 pw.print(" total, non-act at "); 12354 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12355 pw.print(", non-svc at "); 12356 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12357 pw.println("):"); 12358 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12359 needSep = true; 12360 } 12361 12362 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12363 12364 pw.println(); 12365 pw.println(" mHomeProcess: " + mHomeProcess); 12366 pw.println(" mPreviousProcess: " + mPreviousProcess); 12367 if (mHeavyWeightProcess != null) { 12368 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12369 } 12370 12371 return true; 12372 } 12373 12374 /** 12375 * There are three ways to call this: 12376 * - no provider specified: dump all the providers 12377 * - a flattened component name that matched an existing provider was specified as the 12378 * first arg: dump that one provider 12379 * - the first arg isn't the flattened component name of an existing provider: 12380 * dump all providers whose component contains the first arg as a substring 12381 */ 12382 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12383 int opti, boolean dumpAll) { 12384 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12385 } 12386 12387 static class ItemMatcher { 12388 ArrayList<ComponentName> components; 12389 ArrayList<String> strings; 12390 ArrayList<Integer> objects; 12391 boolean all; 12392 12393 ItemMatcher() { 12394 all = true; 12395 } 12396 12397 void build(String name) { 12398 ComponentName componentName = ComponentName.unflattenFromString(name); 12399 if (componentName != null) { 12400 if (components == null) { 12401 components = new ArrayList<ComponentName>(); 12402 } 12403 components.add(componentName); 12404 all = false; 12405 } else { 12406 int objectId = 0; 12407 // Not a '/' separated full component name; maybe an object ID? 12408 try { 12409 objectId = Integer.parseInt(name, 16); 12410 if (objects == null) { 12411 objects = new ArrayList<Integer>(); 12412 } 12413 objects.add(objectId); 12414 all = false; 12415 } catch (RuntimeException e) { 12416 // Not an integer; just do string match. 12417 if (strings == null) { 12418 strings = new ArrayList<String>(); 12419 } 12420 strings.add(name); 12421 all = false; 12422 } 12423 } 12424 } 12425 12426 int build(String[] args, int opti) { 12427 for (; opti<args.length; opti++) { 12428 String name = args[opti]; 12429 if ("--".equals(name)) { 12430 return opti+1; 12431 } 12432 build(name); 12433 } 12434 return opti; 12435 } 12436 12437 boolean match(Object object, ComponentName comp) { 12438 if (all) { 12439 return true; 12440 } 12441 if (components != null) { 12442 for (int i=0; i<components.size(); i++) { 12443 if (components.get(i).equals(comp)) { 12444 return true; 12445 } 12446 } 12447 } 12448 if (objects != null) { 12449 for (int i=0; i<objects.size(); i++) { 12450 if (System.identityHashCode(object) == objects.get(i)) { 12451 return true; 12452 } 12453 } 12454 } 12455 if (strings != null) { 12456 String flat = comp.flattenToString(); 12457 for (int i=0; i<strings.size(); i++) { 12458 if (flat.contains(strings.get(i))) { 12459 return true; 12460 } 12461 } 12462 } 12463 return false; 12464 } 12465 } 12466 12467 /** 12468 * There are three things that cmd can be: 12469 * - a flattened component name that matches an existing activity 12470 * - the cmd arg isn't the flattened component name of an existing activity: 12471 * dump all activity whose component contains the cmd as a substring 12472 * - A hex number of the ActivityRecord object instance. 12473 */ 12474 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12475 int opti, boolean dumpAll) { 12476 ArrayList<ActivityRecord> activities; 12477 12478 synchronized (this) { 12479 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12480 } 12481 12482 if (activities.size() <= 0) { 12483 return false; 12484 } 12485 12486 String[] newArgs = new String[args.length - opti]; 12487 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12488 12489 TaskRecord lastTask = null; 12490 boolean needSep = false; 12491 for (int i=activities.size()-1; i>=0; i--) { 12492 ActivityRecord r = activities.get(i); 12493 if (needSep) { 12494 pw.println(); 12495 } 12496 needSep = true; 12497 synchronized (this) { 12498 if (lastTask != r.task) { 12499 lastTask = r.task; 12500 pw.print("TASK "); pw.print(lastTask.affinity); 12501 pw.print(" id="); pw.println(lastTask.taskId); 12502 if (dumpAll) { 12503 lastTask.dump(pw, " "); 12504 } 12505 } 12506 } 12507 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12508 } 12509 return true; 12510 } 12511 12512 /** 12513 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12514 * there is a thread associated with the activity. 12515 */ 12516 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12517 final ActivityRecord r, String[] args, boolean dumpAll) { 12518 String innerPrefix = prefix + " "; 12519 synchronized (this) { 12520 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12521 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12522 pw.print(" pid="); 12523 if (r.app != null) pw.println(r.app.pid); 12524 else pw.println("(not running)"); 12525 if (dumpAll) { 12526 r.dump(pw, innerPrefix); 12527 } 12528 } 12529 if (r.app != null && r.app.thread != null) { 12530 // flush anything that is already in the PrintWriter since the thread is going 12531 // to write to the file descriptor directly 12532 pw.flush(); 12533 try { 12534 TransferPipe tp = new TransferPipe(); 12535 try { 12536 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12537 r.appToken, innerPrefix, args); 12538 tp.go(fd); 12539 } finally { 12540 tp.kill(); 12541 } 12542 } catch (IOException e) { 12543 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12544 } catch (RemoteException e) { 12545 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12546 } 12547 } 12548 } 12549 12550 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12551 int opti, boolean dumpAll, String dumpPackage) { 12552 boolean needSep = false; 12553 boolean onlyHistory = false; 12554 boolean printedAnything = false; 12555 12556 if ("history".equals(dumpPackage)) { 12557 if (opti < args.length && "-s".equals(args[opti])) { 12558 dumpAll = false; 12559 } 12560 onlyHistory = true; 12561 dumpPackage = null; 12562 } 12563 12564 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12565 if (!onlyHistory && dumpAll) { 12566 if (mRegisteredReceivers.size() > 0) { 12567 boolean printed = false; 12568 Iterator it = mRegisteredReceivers.values().iterator(); 12569 while (it.hasNext()) { 12570 ReceiverList r = (ReceiverList)it.next(); 12571 if (dumpPackage != null && (r.app == null || 12572 !dumpPackage.equals(r.app.info.packageName))) { 12573 continue; 12574 } 12575 if (!printed) { 12576 pw.println(" Registered Receivers:"); 12577 needSep = true; 12578 printed = true; 12579 printedAnything = true; 12580 } 12581 pw.print(" * "); pw.println(r); 12582 r.dump(pw, " "); 12583 } 12584 } 12585 12586 if (mReceiverResolver.dump(pw, needSep ? 12587 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12588 " ", dumpPackage, false)) { 12589 needSep = true; 12590 printedAnything = true; 12591 } 12592 } 12593 12594 for (BroadcastQueue q : mBroadcastQueues) { 12595 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12596 printedAnything |= needSep; 12597 } 12598 12599 needSep = true; 12600 12601 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12602 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12603 if (needSep) { 12604 pw.println(); 12605 } 12606 needSep = true; 12607 printedAnything = true; 12608 pw.print(" Sticky broadcasts for user "); 12609 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12610 StringBuilder sb = new StringBuilder(128); 12611 for (Map.Entry<String, ArrayList<Intent>> ent 12612 : mStickyBroadcasts.valueAt(user).entrySet()) { 12613 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12614 if (dumpAll) { 12615 pw.println(":"); 12616 ArrayList<Intent> intents = ent.getValue(); 12617 final int N = intents.size(); 12618 for (int i=0; i<N; i++) { 12619 sb.setLength(0); 12620 sb.append(" Intent: "); 12621 intents.get(i).toShortString(sb, false, true, false, false); 12622 pw.println(sb.toString()); 12623 Bundle bundle = intents.get(i).getExtras(); 12624 if (bundle != null) { 12625 pw.print(" "); 12626 pw.println(bundle.toString()); 12627 } 12628 } 12629 } else { 12630 pw.println(""); 12631 } 12632 } 12633 } 12634 } 12635 12636 if (!onlyHistory && dumpAll) { 12637 pw.println(); 12638 for (BroadcastQueue queue : mBroadcastQueues) { 12639 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12640 + queue.mBroadcastsScheduled); 12641 } 12642 pw.println(" mHandler:"); 12643 mHandler.dump(new PrintWriterPrinter(pw), " "); 12644 needSep = true; 12645 printedAnything = true; 12646 } 12647 12648 if (!printedAnything) { 12649 pw.println(" (nothing)"); 12650 } 12651 } 12652 12653 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12654 int opti, boolean dumpAll, String dumpPackage) { 12655 boolean needSep; 12656 boolean printedAnything = false; 12657 12658 ItemMatcher matcher = new ItemMatcher(); 12659 matcher.build(args, opti); 12660 12661 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12662 12663 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12664 printedAnything |= needSep; 12665 12666 if (mLaunchingProviders.size() > 0) { 12667 boolean printed = false; 12668 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12669 ContentProviderRecord r = mLaunchingProviders.get(i); 12670 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12671 continue; 12672 } 12673 if (!printed) { 12674 if (needSep) pw.println(); 12675 needSep = true; 12676 pw.println(" Launching content providers:"); 12677 printed = true; 12678 printedAnything = true; 12679 } 12680 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12681 pw.println(r); 12682 } 12683 } 12684 12685 if (mGrantedUriPermissions.size() > 0) { 12686 boolean printed = false; 12687 int dumpUid = -2; 12688 if (dumpPackage != null) { 12689 try { 12690 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12691 } catch (NameNotFoundException e) { 12692 dumpUid = -1; 12693 } 12694 } 12695 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12696 int uid = mGrantedUriPermissions.keyAt(i); 12697 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12698 continue; 12699 } 12700 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12701 if (!printed) { 12702 if (needSep) pw.println(); 12703 needSep = true; 12704 pw.println(" Granted Uri Permissions:"); 12705 printed = true; 12706 printedAnything = true; 12707 } 12708 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12709 for (UriPermission perm : perms.values()) { 12710 pw.print(" "); pw.println(perm); 12711 if (dumpAll) { 12712 perm.dump(pw, " "); 12713 } 12714 } 12715 } 12716 } 12717 12718 if (!printedAnything) { 12719 pw.println(" (nothing)"); 12720 } 12721 } 12722 12723 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12724 int opti, boolean dumpAll, String dumpPackage) { 12725 boolean printed = false; 12726 12727 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12728 12729 if (mIntentSenderRecords.size() > 0) { 12730 Iterator<WeakReference<PendingIntentRecord>> it 12731 = mIntentSenderRecords.values().iterator(); 12732 while (it.hasNext()) { 12733 WeakReference<PendingIntentRecord> ref = it.next(); 12734 PendingIntentRecord rec = ref != null ? ref.get(): null; 12735 if (dumpPackage != null && (rec == null 12736 || !dumpPackage.equals(rec.key.packageName))) { 12737 continue; 12738 } 12739 printed = true; 12740 if (rec != null) { 12741 pw.print(" * "); pw.println(rec); 12742 if (dumpAll) { 12743 rec.dump(pw, " "); 12744 } 12745 } else { 12746 pw.print(" * "); pw.println(ref); 12747 } 12748 } 12749 } 12750 12751 if (!printed) { 12752 pw.println(" (nothing)"); 12753 } 12754 } 12755 12756 private static final int dumpProcessList(PrintWriter pw, 12757 ActivityManagerService service, List list, 12758 String prefix, String normalLabel, String persistentLabel, 12759 String dumpPackage) { 12760 int numPers = 0; 12761 final int N = list.size()-1; 12762 for (int i=N; i>=0; i--) { 12763 ProcessRecord r = (ProcessRecord)list.get(i); 12764 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12765 continue; 12766 } 12767 pw.println(String.format("%s%s #%2d: %s", 12768 prefix, (r.persistent ? persistentLabel : normalLabel), 12769 i, r.toString())); 12770 if (r.persistent) { 12771 numPers++; 12772 } 12773 } 12774 return numPers; 12775 } 12776 12777 private static final boolean dumpProcessOomList(PrintWriter pw, 12778 ActivityManagerService service, List<ProcessRecord> origList, 12779 String prefix, String normalLabel, String persistentLabel, 12780 boolean inclDetails, String dumpPackage) { 12781 12782 ArrayList<Pair<ProcessRecord, Integer>> list 12783 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12784 for (int i=0; i<origList.size(); i++) { 12785 ProcessRecord r = origList.get(i); 12786 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12787 continue; 12788 } 12789 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12790 } 12791 12792 if (list.size() <= 0) { 12793 return false; 12794 } 12795 12796 Comparator<Pair<ProcessRecord, Integer>> comparator 12797 = new Comparator<Pair<ProcessRecord, Integer>>() { 12798 @Override 12799 public int compare(Pair<ProcessRecord, Integer> object1, 12800 Pair<ProcessRecord, Integer> object2) { 12801 if (object1.first.setAdj != object2.first.setAdj) { 12802 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12803 } 12804 if (object1.second.intValue() != object2.second.intValue()) { 12805 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12806 } 12807 return 0; 12808 } 12809 }; 12810 12811 Collections.sort(list, comparator); 12812 12813 final long curRealtime = SystemClock.elapsedRealtime(); 12814 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12815 final long curUptime = SystemClock.uptimeMillis(); 12816 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12817 12818 for (int i=list.size()-1; i>=0; i--) { 12819 ProcessRecord r = list.get(i).first; 12820 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12821 char schedGroup; 12822 switch (r.setSchedGroup) { 12823 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12824 schedGroup = 'B'; 12825 break; 12826 case Process.THREAD_GROUP_DEFAULT: 12827 schedGroup = 'F'; 12828 break; 12829 default: 12830 schedGroup = '?'; 12831 break; 12832 } 12833 char foreground; 12834 if (r.foregroundActivities) { 12835 foreground = 'A'; 12836 } else if (r.foregroundServices) { 12837 foreground = 'S'; 12838 } else { 12839 foreground = ' '; 12840 } 12841 String procState = ProcessList.makeProcStateString(r.curProcState); 12842 pw.print(prefix); 12843 pw.print(r.persistent ? persistentLabel : normalLabel); 12844 pw.print(" #"); 12845 int num = (origList.size()-1)-list.get(i).second; 12846 if (num < 10) pw.print(' '); 12847 pw.print(num); 12848 pw.print(": "); 12849 pw.print(oomAdj); 12850 pw.print(' '); 12851 pw.print(schedGroup); 12852 pw.print('/'); 12853 pw.print(foreground); 12854 pw.print('/'); 12855 pw.print(procState); 12856 pw.print(" trm:"); 12857 if (r.trimMemoryLevel < 10) pw.print(' '); 12858 pw.print(r.trimMemoryLevel); 12859 pw.print(' '); 12860 pw.print(r.toShortString()); 12861 pw.print(" ("); 12862 pw.print(r.adjType); 12863 pw.println(')'); 12864 if (r.adjSource != null || r.adjTarget != null) { 12865 pw.print(prefix); 12866 pw.print(" "); 12867 if (r.adjTarget instanceof ComponentName) { 12868 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12869 } else if (r.adjTarget != null) { 12870 pw.print(r.adjTarget.toString()); 12871 } else { 12872 pw.print("{null}"); 12873 } 12874 pw.print("<="); 12875 if (r.adjSource instanceof ProcessRecord) { 12876 pw.print("Proc{"); 12877 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12878 pw.println("}"); 12879 } else if (r.adjSource != null) { 12880 pw.println(r.adjSource.toString()); 12881 } else { 12882 pw.println("{null}"); 12883 } 12884 } 12885 if (inclDetails) { 12886 pw.print(prefix); 12887 pw.print(" "); 12888 pw.print("oom: max="); pw.print(r.maxAdj); 12889 pw.print(" curRaw="); pw.print(r.curRawAdj); 12890 pw.print(" setRaw="); pw.print(r.setRawAdj); 12891 pw.print(" cur="); pw.print(r.curAdj); 12892 pw.print(" set="); pw.println(r.setAdj); 12893 pw.print(prefix); 12894 pw.print(" "); 12895 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12896 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12897 pw.print(" lastPss="); pw.print(r.lastPss); 12898 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12899 pw.print(prefix); 12900 pw.print(" "); 12901 pw.print("cached="); pw.print(r.cached); 12902 pw.print(" empty="); pw.print(r.empty); 12903 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12904 12905 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12906 if (r.lastWakeTime != 0) { 12907 long wtime; 12908 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12909 synchronized (stats) { 12910 wtime = stats.getProcessWakeTime(r.info.uid, 12911 r.pid, curRealtime); 12912 } 12913 long timeUsed = wtime - r.lastWakeTime; 12914 pw.print(prefix); 12915 pw.print(" "); 12916 pw.print("keep awake over "); 12917 TimeUtils.formatDuration(realtimeSince, pw); 12918 pw.print(" used "); 12919 TimeUtils.formatDuration(timeUsed, pw); 12920 pw.print(" ("); 12921 pw.print((timeUsed*100)/realtimeSince); 12922 pw.println("%)"); 12923 } 12924 if (r.lastCpuTime != 0) { 12925 long timeUsed = r.curCpuTime - r.lastCpuTime; 12926 pw.print(prefix); 12927 pw.print(" "); 12928 pw.print("run cpu over "); 12929 TimeUtils.formatDuration(uptimeSince, pw); 12930 pw.print(" used "); 12931 TimeUtils.formatDuration(timeUsed, pw); 12932 pw.print(" ("); 12933 pw.print((timeUsed*100)/uptimeSince); 12934 pw.println("%)"); 12935 } 12936 } 12937 } 12938 } 12939 return true; 12940 } 12941 12942 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12943 ArrayList<ProcessRecord> procs; 12944 synchronized (this) { 12945 if (args != null && args.length > start 12946 && args[start].charAt(0) != '-') { 12947 procs = new ArrayList<ProcessRecord>(); 12948 int pid = -1; 12949 try { 12950 pid = Integer.parseInt(args[start]); 12951 } catch (NumberFormatException e) { 12952 } 12953 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12954 ProcessRecord proc = mLruProcesses.get(i); 12955 if (proc.pid == pid) { 12956 procs.add(proc); 12957 } else if (proc.processName.equals(args[start])) { 12958 procs.add(proc); 12959 } 12960 } 12961 if (procs.size() <= 0) { 12962 return null; 12963 } 12964 } else { 12965 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12966 } 12967 } 12968 return procs; 12969 } 12970 12971 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12972 PrintWriter pw, String[] args) { 12973 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12974 if (procs == null) { 12975 pw.println("No process found for: " + args[0]); 12976 return; 12977 } 12978 12979 long uptime = SystemClock.uptimeMillis(); 12980 long realtime = SystemClock.elapsedRealtime(); 12981 pw.println("Applications Graphics Acceleration Info:"); 12982 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12983 12984 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12985 ProcessRecord r = procs.get(i); 12986 if (r.thread != null) { 12987 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12988 pw.flush(); 12989 try { 12990 TransferPipe tp = new TransferPipe(); 12991 try { 12992 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12993 tp.go(fd); 12994 } finally { 12995 tp.kill(); 12996 } 12997 } catch (IOException e) { 12998 pw.println("Failure while dumping the app: " + r); 12999 pw.flush(); 13000 } catch (RemoteException e) { 13001 pw.println("Got a RemoteException while dumping the app " + r); 13002 pw.flush(); 13003 } 13004 } 13005 } 13006 } 13007 13008 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13009 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13010 if (procs == null) { 13011 pw.println("No process found for: " + args[0]); 13012 return; 13013 } 13014 13015 pw.println("Applications Database Info:"); 13016 13017 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13018 ProcessRecord r = procs.get(i); 13019 if (r.thread != null) { 13020 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13021 pw.flush(); 13022 try { 13023 TransferPipe tp = new TransferPipe(); 13024 try { 13025 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13026 tp.go(fd); 13027 } finally { 13028 tp.kill(); 13029 } 13030 } catch (IOException e) { 13031 pw.println("Failure while dumping the app: " + r); 13032 pw.flush(); 13033 } catch (RemoteException e) { 13034 pw.println("Got a RemoteException while dumping the app " + r); 13035 pw.flush(); 13036 } 13037 } 13038 } 13039 } 13040 13041 final static class MemItem { 13042 final boolean isProc; 13043 final String label; 13044 final String shortLabel; 13045 final long pss; 13046 final int id; 13047 final boolean hasActivities; 13048 ArrayList<MemItem> subitems; 13049 13050 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13051 boolean _hasActivities) { 13052 isProc = true; 13053 label = _label; 13054 shortLabel = _shortLabel; 13055 pss = _pss; 13056 id = _id; 13057 hasActivities = _hasActivities; 13058 } 13059 13060 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13061 isProc = false; 13062 label = _label; 13063 shortLabel = _shortLabel; 13064 pss = _pss; 13065 id = _id; 13066 hasActivities = false; 13067 } 13068 } 13069 13070 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13071 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13072 if (sort && !isCompact) { 13073 Collections.sort(items, new Comparator<MemItem>() { 13074 @Override 13075 public int compare(MemItem lhs, MemItem rhs) { 13076 if (lhs.pss < rhs.pss) { 13077 return 1; 13078 } else if (lhs.pss > rhs.pss) { 13079 return -1; 13080 } 13081 return 0; 13082 } 13083 }); 13084 } 13085 13086 for (int i=0; i<items.size(); i++) { 13087 MemItem mi = items.get(i); 13088 if (!isCompact) { 13089 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13090 } else if (mi.isProc) { 13091 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13092 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13093 pw.println(mi.hasActivities ? ",a" : ",e"); 13094 } else { 13095 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13096 pw.println(mi.pss); 13097 } 13098 if (mi.subitems != null) { 13099 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13100 true, isCompact); 13101 } 13102 } 13103 } 13104 13105 // These are in KB. 13106 static final long[] DUMP_MEM_BUCKETS = new long[] { 13107 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13108 120*1024, 160*1024, 200*1024, 13109 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13110 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13111 }; 13112 13113 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13114 boolean stackLike) { 13115 int start = label.lastIndexOf('.'); 13116 if (start >= 0) start++; 13117 else start = 0; 13118 int end = label.length(); 13119 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13120 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13121 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13122 out.append(bucket); 13123 out.append(stackLike ? "MB." : "MB "); 13124 out.append(label, start, end); 13125 return; 13126 } 13127 } 13128 out.append(memKB/1024); 13129 out.append(stackLike ? "MB." : "MB "); 13130 out.append(label, start, end); 13131 } 13132 13133 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13134 ProcessList.NATIVE_ADJ, 13135 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13136 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13137 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13138 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13139 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13140 }; 13141 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13142 "Native", 13143 "System", "Persistent", "Foreground", 13144 "Visible", "Perceptible", 13145 "Heavy Weight", "Backup", 13146 "A Services", "Home", 13147 "Previous", "B Services", "Cached" 13148 }; 13149 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13150 "native", 13151 "sys", "pers", "fore", 13152 "vis", "percept", 13153 "heavy", "backup", 13154 "servicea", "home", 13155 "prev", "serviceb", "cached" 13156 }; 13157 13158 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13159 long realtime, boolean isCheckinRequest, boolean isCompact) { 13160 if (isCheckinRequest || isCompact) { 13161 // short checkin version 13162 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13163 } else { 13164 pw.println("Applications Memory Usage (kB):"); 13165 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13166 } 13167 } 13168 13169 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13170 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13171 boolean dumpDetails = false; 13172 boolean dumpFullDetails = false; 13173 boolean dumpDalvik = false; 13174 boolean oomOnly = false; 13175 boolean isCompact = false; 13176 boolean localOnly = false; 13177 13178 int opti = 0; 13179 while (opti < args.length) { 13180 String opt = args[opti]; 13181 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13182 break; 13183 } 13184 opti++; 13185 if ("-a".equals(opt)) { 13186 dumpDetails = true; 13187 dumpFullDetails = true; 13188 dumpDalvik = true; 13189 } else if ("-d".equals(opt)) { 13190 dumpDalvik = true; 13191 } else if ("-c".equals(opt)) { 13192 isCompact = true; 13193 } else if ("--oom".equals(opt)) { 13194 oomOnly = true; 13195 } else if ("--local".equals(opt)) { 13196 localOnly = true; 13197 } else if ("-h".equals(opt)) { 13198 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13199 pw.println(" -a: include all available information for each process."); 13200 pw.println(" -d: include dalvik details when dumping process details."); 13201 pw.println(" -c: dump in a compact machine-parseable representation."); 13202 pw.println(" --oom: only show processes organized by oom adj."); 13203 pw.println(" --local: only collect details locally, don't call process."); 13204 pw.println("If [process] is specified it can be the name or "); 13205 pw.println("pid of a specific process to dump."); 13206 return; 13207 } else { 13208 pw.println("Unknown argument: " + opt + "; use -h for help"); 13209 } 13210 } 13211 13212 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13213 long uptime = SystemClock.uptimeMillis(); 13214 long realtime = SystemClock.elapsedRealtime(); 13215 final long[] tmpLong = new long[1]; 13216 13217 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13218 if (procs == null) { 13219 // No Java processes. Maybe they want to print a native process. 13220 if (args != null && args.length > opti 13221 && args[opti].charAt(0) != '-') { 13222 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13223 = new ArrayList<ProcessCpuTracker.Stats>(); 13224 updateCpuStatsNow(); 13225 int findPid = -1; 13226 try { 13227 findPid = Integer.parseInt(args[opti]); 13228 } catch (NumberFormatException e) { 13229 } 13230 synchronized (mProcessCpuThread) { 13231 final int N = mProcessCpuTracker.countStats(); 13232 for (int i=0; i<N; i++) { 13233 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13234 if (st.pid == findPid || (st.baseName != null 13235 && st.baseName.equals(args[opti]))) { 13236 nativeProcs.add(st); 13237 } 13238 } 13239 } 13240 if (nativeProcs.size() > 0) { 13241 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13242 isCompact); 13243 Debug.MemoryInfo mi = null; 13244 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13245 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13246 final int pid = r.pid; 13247 if (!isCheckinRequest && dumpDetails) { 13248 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13249 } 13250 if (mi == null) { 13251 mi = new Debug.MemoryInfo(); 13252 } 13253 if (dumpDetails || (!brief && !oomOnly)) { 13254 Debug.getMemoryInfo(pid, mi); 13255 } else { 13256 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13257 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13258 } 13259 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13260 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13261 if (isCheckinRequest) { 13262 pw.println(); 13263 } 13264 } 13265 return; 13266 } 13267 } 13268 pw.println("No process found for: " + args[opti]); 13269 return; 13270 } 13271 13272 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13273 dumpDetails = true; 13274 } 13275 13276 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13277 13278 String[] innerArgs = new String[args.length-opti]; 13279 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13280 13281 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13282 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13283 long nativePss=0, dalvikPss=0, otherPss=0; 13284 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13285 13286 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13287 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13288 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13289 13290 long totalPss = 0; 13291 long cachedPss = 0; 13292 13293 Debug.MemoryInfo mi = null; 13294 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13295 final ProcessRecord r = procs.get(i); 13296 final IApplicationThread thread; 13297 final int pid; 13298 final int oomAdj; 13299 final boolean hasActivities; 13300 synchronized (this) { 13301 thread = r.thread; 13302 pid = r.pid; 13303 oomAdj = r.getSetAdjWithServices(); 13304 hasActivities = r.activities.size() > 0; 13305 } 13306 if (thread != null) { 13307 if (!isCheckinRequest && dumpDetails) { 13308 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13309 } 13310 if (mi == null) { 13311 mi = new Debug.MemoryInfo(); 13312 } 13313 if (dumpDetails || (!brief && !oomOnly)) { 13314 Debug.getMemoryInfo(pid, mi); 13315 } else { 13316 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13317 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13318 } 13319 if (dumpDetails) { 13320 if (localOnly) { 13321 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13322 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13323 if (isCheckinRequest) { 13324 pw.println(); 13325 } 13326 } else { 13327 try { 13328 pw.flush(); 13329 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13330 dumpDalvik, innerArgs); 13331 } catch (RemoteException e) { 13332 if (!isCheckinRequest) { 13333 pw.println("Got RemoteException!"); 13334 pw.flush(); 13335 } 13336 } 13337 } 13338 } 13339 13340 final long myTotalPss = mi.getTotalPss(); 13341 final long myTotalUss = mi.getTotalUss(); 13342 13343 synchronized (this) { 13344 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13345 // Record this for posterity if the process has been stable. 13346 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13347 } 13348 } 13349 13350 if (!isCheckinRequest && mi != null) { 13351 totalPss += myTotalPss; 13352 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13353 (hasActivities ? " / activities)" : ")"), 13354 r.processName, myTotalPss, pid, hasActivities); 13355 procMems.add(pssItem); 13356 procMemsMap.put(pid, pssItem); 13357 13358 nativePss += mi.nativePss; 13359 dalvikPss += mi.dalvikPss; 13360 otherPss += mi.otherPss; 13361 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13362 long mem = mi.getOtherPss(j); 13363 miscPss[j] += mem; 13364 otherPss -= mem; 13365 } 13366 13367 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13368 cachedPss += myTotalPss; 13369 } 13370 13371 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13372 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13373 || oomIndex == (oomPss.length-1)) { 13374 oomPss[oomIndex] += myTotalPss; 13375 if (oomProcs[oomIndex] == null) { 13376 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13377 } 13378 oomProcs[oomIndex].add(pssItem); 13379 break; 13380 } 13381 } 13382 } 13383 } 13384 } 13385 13386 long nativeProcTotalPss = 0; 13387 13388 if (!isCheckinRequest && procs.size() > 1) { 13389 // If we are showing aggregations, also look for native processes to 13390 // include so that our aggregations are more accurate. 13391 updateCpuStatsNow(); 13392 synchronized (mProcessCpuThread) { 13393 final int N = mProcessCpuTracker.countStats(); 13394 for (int i=0; i<N; i++) { 13395 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13396 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13397 if (mi == null) { 13398 mi = new Debug.MemoryInfo(); 13399 } 13400 if (!brief && !oomOnly) { 13401 Debug.getMemoryInfo(st.pid, mi); 13402 } else { 13403 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13404 mi.nativePrivateDirty = (int)tmpLong[0]; 13405 } 13406 13407 final long myTotalPss = mi.getTotalPss(); 13408 totalPss += myTotalPss; 13409 nativeProcTotalPss += myTotalPss; 13410 13411 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13412 st.name, myTotalPss, st.pid, false); 13413 procMems.add(pssItem); 13414 13415 nativePss += mi.nativePss; 13416 dalvikPss += mi.dalvikPss; 13417 otherPss += mi.otherPss; 13418 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13419 long mem = mi.getOtherPss(j); 13420 miscPss[j] += mem; 13421 otherPss -= mem; 13422 } 13423 oomPss[0] += myTotalPss; 13424 if (oomProcs[0] == null) { 13425 oomProcs[0] = new ArrayList<MemItem>(); 13426 } 13427 oomProcs[0].add(pssItem); 13428 } 13429 } 13430 } 13431 13432 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13433 13434 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13435 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13436 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13437 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13438 String label = Debug.MemoryInfo.getOtherLabel(j); 13439 catMems.add(new MemItem(label, label, miscPss[j], j)); 13440 } 13441 13442 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13443 for (int j=0; j<oomPss.length; j++) { 13444 if (oomPss[j] != 0) { 13445 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13446 : DUMP_MEM_OOM_LABEL[j]; 13447 MemItem item = new MemItem(label, label, oomPss[j], 13448 DUMP_MEM_OOM_ADJ[j]); 13449 item.subitems = oomProcs[j]; 13450 oomMems.add(item); 13451 } 13452 } 13453 13454 if (!brief && !oomOnly && !isCompact) { 13455 pw.println(); 13456 pw.println("Total PSS by process:"); 13457 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13458 pw.println(); 13459 } 13460 if (!isCompact) { 13461 pw.println("Total PSS by OOM adjustment:"); 13462 } 13463 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13464 if (!brief && !oomOnly) { 13465 PrintWriter out = categoryPw != null ? categoryPw : pw; 13466 if (!isCompact) { 13467 out.println(); 13468 out.println("Total PSS by category:"); 13469 } 13470 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13471 } 13472 if (!isCompact) { 13473 pw.println(); 13474 } 13475 MemInfoReader memInfo = new MemInfoReader(); 13476 memInfo.readMemInfo(); 13477 if (nativeProcTotalPss > 0) { 13478 synchronized (this) { 13479 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13480 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13481 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13482 nativeProcTotalPss); 13483 } 13484 } 13485 if (!brief) { 13486 if (!isCompact) { 13487 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13488 pw.print(" kB (status "); 13489 switch (mLastMemoryLevel) { 13490 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13491 pw.println("normal)"); 13492 break; 13493 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13494 pw.println("moderate)"); 13495 break; 13496 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13497 pw.println("low)"); 13498 break; 13499 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13500 pw.println("critical)"); 13501 break; 13502 default: 13503 pw.print(mLastMemoryLevel); 13504 pw.println(")"); 13505 break; 13506 } 13507 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13508 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13509 pw.print(cachedPss); pw.print(" cached pss + "); 13510 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13511 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13512 } else { 13513 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13514 pw.print(cachedPss + memInfo.getCachedSizeKb() 13515 + memInfo.getFreeSizeKb()); pw.print(","); 13516 pw.println(totalPss - cachedPss); 13517 } 13518 } 13519 if (!isCompact) { 13520 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13521 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13522 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13523 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13524 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13525 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13526 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13527 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13528 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13529 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13530 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13531 } 13532 if (!brief) { 13533 if (memInfo.getZramTotalSizeKb() != 0) { 13534 if (!isCompact) { 13535 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13536 pw.print(" kB physical used for "); 13537 pw.print(memInfo.getSwapTotalSizeKb() 13538 - memInfo.getSwapFreeSizeKb()); 13539 pw.print(" kB in swap ("); 13540 pw.print(memInfo.getSwapTotalSizeKb()); 13541 pw.println(" kB total swap)"); 13542 } else { 13543 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13544 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13545 pw.println(memInfo.getSwapFreeSizeKb()); 13546 } 13547 } 13548 final int[] SINGLE_LONG_FORMAT = new int[] { 13549 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13550 }; 13551 long[] longOut = new long[1]; 13552 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13553 SINGLE_LONG_FORMAT, null, longOut, null); 13554 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13555 longOut[0] = 0; 13556 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13557 SINGLE_LONG_FORMAT, null, longOut, null); 13558 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13559 longOut[0] = 0; 13560 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13561 SINGLE_LONG_FORMAT, null, longOut, null); 13562 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13563 longOut[0] = 0; 13564 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13565 SINGLE_LONG_FORMAT, null, longOut, null); 13566 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13567 if (!isCompact) { 13568 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13569 pw.print(" KSM: "); pw.print(sharing); 13570 pw.print(" kB saved from shared "); 13571 pw.print(shared); pw.println(" kB"); 13572 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13573 pw.print(voltile); pw.println(" kB volatile"); 13574 } 13575 pw.print(" Tuning: "); 13576 pw.print(ActivityManager.staticGetMemoryClass()); 13577 pw.print(" (large "); 13578 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13579 pw.print("), oom "); 13580 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13581 pw.print(" kB"); 13582 pw.print(", restore limit "); 13583 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13584 pw.print(" kB"); 13585 if (ActivityManager.isLowRamDeviceStatic()) { 13586 pw.print(" (low-ram)"); 13587 } 13588 if (ActivityManager.isHighEndGfx()) { 13589 pw.print(" (high-end-gfx)"); 13590 } 13591 pw.println(); 13592 } else { 13593 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13594 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13595 pw.println(voltile); 13596 pw.print("tuning,"); 13597 pw.print(ActivityManager.staticGetMemoryClass()); 13598 pw.print(','); 13599 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13600 pw.print(','); 13601 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13602 if (ActivityManager.isLowRamDeviceStatic()) { 13603 pw.print(",low-ram"); 13604 } 13605 if (ActivityManager.isHighEndGfx()) { 13606 pw.print(",high-end-gfx"); 13607 } 13608 pw.println(); 13609 } 13610 } 13611 } 13612 } 13613 13614 /** 13615 * Searches array of arguments for the specified string 13616 * @param args array of argument strings 13617 * @param value value to search for 13618 * @return true if the value is contained in the array 13619 */ 13620 private static boolean scanArgs(String[] args, String value) { 13621 if (args != null) { 13622 for (String arg : args) { 13623 if (value.equals(arg)) { 13624 return true; 13625 } 13626 } 13627 } 13628 return false; 13629 } 13630 13631 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13632 ContentProviderRecord cpr, boolean always) { 13633 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13634 13635 if (!inLaunching || always) { 13636 synchronized (cpr) { 13637 cpr.launchingApp = null; 13638 cpr.notifyAll(); 13639 } 13640 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13641 String names[] = cpr.info.authority.split(";"); 13642 for (int j = 0; j < names.length; j++) { 13643 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13644 } 13645 } 13646 13647 for (int i=0; i<cpr.connections.size(); i++) { 13648 ContentProviderConnection conn = cpr.connections.get(i); 13649 if (conn.waiting) { 13650 // If this connection is waiting for the provider, then we don't 13651 // need to mess with its process unless we are always removing 13652 // or for some reason the provider is not currently launching. 13653 if (inLaunching && !always) { 13654 continue; 13655 } 13656 } 13657 ProcessRecord capp = conn.client; 13658 conn.dead = true; 13659 if (conn.stableCount > 0) { 13660 if (!capp.persistent && capp.thread != null 13661 && capp.pid != 0 13662 && capp.pid != MY_PID) { 13663 killUnneededProcessLocked(capp, "depends on provider " 13664 + cpr.name.flattenToShortString() 13665 + " in dying proc " + (proc != null ? proc.processName : "??")); 13666 } 13667 } else if (capp.thread != null && conn.provider.provider != null) { 13668 try { 13669 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13670 } catch (RemoteException e) { 13671 } 13672 // In the protocol here, we don't expect the client to correctly 13673 // clean up this connection, we'll just remove it. 13674 cpr.connections.remove(i); 13675 conn.client.conProviders.remove(conn); 13676 } 13677 } 13678 13679 if (inLaunching && always) { 13680 mLaunchingProviders.remove(cpr); 13681 } 13682 return inLaunching; 13683 } 13684 13685 /** 13686 * Main code for cleaning up a process when it has gone away. This is 13687 * called both as a result of the process dying, or directly when stopping 13688 * a process when running in single process mode. 13689 */ 13690 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13691 boolean restarting, boolean allowRestart, int index) { 13692 if (index >= 0) { 13693 removeLruProcessLocked(app); 13694 ProcessList.remove(app.pid); 13695 } 13696 13697 mProcessesToGc.remove(app); 13698 mPendingPssProcesses.remove(app); 13699 13700 // Dismiss any open dialogs. 13701 if (app.crashDialog != null && !app.forceCrashReport) { 13702 app.crashDialog.dismiss(); 13703 app.crashDialog = null; 13704 } 13705 if (app.anrDialog != null) { 13706 app.anrDialog.dismiss(); 13707 app.anrDialog = null; 13708 } 13709 if (app.waitDialog != null) { 13710 app.waitDialog.dismiss(); 13711 app.waitDialog = null; 13712 } 13713 13714 app.crashing = false; 13715 app.notResponding = false; 13716 13717 app.resetPackageList(mProcessStats); 13718 app.unlinkDeathRecipient(); 13719 app.makeInactive(mProcessStats); 13720 app.waitingToKill = null; 13721 app.forcingToForeground = null; 13722 updateProcessForegroundLocked(app, false, false); 13723 app.foregroundActivities = false; 13724 app.hasShownUi = false; 13725 app.treatLikeActivity = false; 13726 app.hasAboveClient = false; 13727 app.hasClientActivities = false; 13728 13729 mServices.killServicesLocked(app, allowRestart); 13730 13731 boolean restart = false; 13732 13733 // Remove published content providers. 13734 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13735 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13736 final boolean always = app.bad || !allowRestart; 13737 if (removeDyingProviderLocked(app, cpr, always) || always) { 13738 // We left the provider in the launching list, need to 13739 // restart it. 13740 restart = true; 13741 } 13742 13743 cpr.provider = null; 13744 cpr.proc = null; 13745 } 13746 app.pubProviders.clear(); 13747 13748 // Take care of any launching providers waiting for this process. 13749 if (checkAppInLaunchingProvidersLocked(app, false)) { 13750 restart = true; 13751 } 13752 13753 // Unregister from connected content providers. 13754 if (!app.conProviders.isEmpty()) { 13755 for (int i=0; i<app.conProviders.size(); i++) { 13756 ContentProviderConnection conn = app.conProviders.get(i); 13757 conn.provider.connections.remove(conn); 13758 } 13759 app.conProviders.clear(); 13760 } 13761 13762 // At this point there may be remaining entries in mLaunchingProviders 13763 // where we were the only one waiting, so they are no longer of use. 13764 // Look for these and clean up if found. 13765 // XXX Commented out for now. Trying to figure out a way to reproduce 13766 // the actual situation to identify what is actually going on. 13767 if (false) { 13768 for (int i=0; i<mLaunchingProviders.size(); i++) { 13769 ContentProviderRecord cpr = (ContentProviderRecord) 13770 mLaunchingProviders.get(i); 13771 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13772 synchronized (cpr) { 13773 cpr.launchingApp = null; 13774 cpr.notifyAll(); 13775 } 13776 } 13777 } 13778 } 13779 13780 skipCurrentReceiverLocked(app); 13781 13782 // Unregister any receivers. 13783 for (int i=app.receivers.size()-1; i>=0; i--) { 13784 removeReceiverLocked(app.receivers.valueAt(i)); 13785 } 13786 app.receivers.clear(); 13787 13788 // If the app is undergoing backup, tell the backup manager about it 13789 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13790 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13791 + mBackupTarget.appInfo + " died during backup"); 13792 try { 13793 IBackupManager bm = IBackupManager.Stub.asInterface( 13794 ServiceManager.getService(Context.BACKUP_SERVICE)); 13795 bm.agentDisconnected(app.info.packageName); 13796 } catch (RemoteException e) { 13797 // can't happen; backup manager is local 13798 } 13799 } 13800 13801 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13802 ProcessChangeItem item = mPendingProcessChanges.get(i); 13803 if (item.pid == app.pid) { 13804 mPendingProcessChanges.remove(i); 13805 mAvailProcessChanges.add(item); 13806 } 13807 } 13808 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13809 13810 // If the caller is restarting this app, then leave it in its 13811 // current lists and let the caller take care of it. 13812 if (restarting) { 13813 return; 13814 } 13815 13816 if (!app.persistent || app.isolated) { 13817 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13818 "Removing non-persistent process during cleanup: " + app); 13819 mProcessNames.remove(app.processName, app.uid); 13820 mIsolatedProcesses.remove(app.uid); 13821 if (mHeavyWeightProcess == app) { 13822 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13823 mHeavyWeightProcess.userId, 0)); 13824 mHeavyWeightProcess = null; 13825 } 13826 } else if (!app.removed) { 13827 // This app is persistent, so we need to keep its record around. 13828 // If it is not already on the pending app list, add it there 13829 // and start a new process for it. 13830 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13831 mPersistentStartingProcesses.add(app); 13832 restart = true; 13833 } 13834 } 13835 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13836 "Clean-up removing on hold: " + app); 13837 mProcessesOnHold.remove(app); 13838 13839 if (app == mHomeProcess) { 13840 mHomeProcess = null; 13841 } 13842 if (app == mPreviousProcess) { 13843 mPreviousProcess = null; 13844 } 13845 13846 if (restart && !app.isolated) { 13847 // We have components that still need to be running in the 13848 // process, so re-launch it. 13849 mProcessNames.put(app.processName, app.uid, app); 13850 startProcessLocked(app, "restart", app.processName); 13851 } else if (app.pid > 0 && app.pid != MY_PID) { 13852 // Goodbye! 13853 boolean removed; 13854 synchronized (mPidsSelfLocked) { 13855 mPidsSelfLocked.remove(app.pid); 13856 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13857 } 13858 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13859 if (app.isolated) { 13860 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13861 } 13862 app.setPid(0); 13863 } 13864 } 13865 13866 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13867 // Look through the content providers we are waiting to have launched, 13868 // and if any run in this process then either schedule a restart of 13869 // the process or kill the client waiting for it if this process has 13870 // gone bad. 13871 int NL = mLaunchingProviders.size(); 13872 boolean restart = false; 13873 for (int i=0; i<NL; i++) { 13874 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13875 if (cpr.launchingApp == app) { 13876 if (!alwaysBad && !app.bad) { 13877 restart = true; 13878 } else { 13879 removeDyingProviderLocked(app, cpr, true); 13880 // cpr should have been removed from mLaunchingProviders 13881 NL = mLaunchingProviders.size(); 13882 i--; 13883 } 13884 } 13885 } 13886 return restart; 13887 } 13888 13889 // ========================================================= 13890 // SERVICES 13891 // ========================================================= 13892 13893 @Override 13894 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13895 int flags) { 13896 enforceNotIsolatedCaller("getServices"); 13897 synchronized (this) { 13898 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13899 } 13900 } 13901 13902 @Override 13903 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13904 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13905 synchronized (this) { 13906 return mServices.getRunningServiceControlPanelLocked(name); 13907 } 13908 } 13909 13910 @Override 13911 public ComponentName startService(IApplicationThread caller, Intent service, 13912 String resolvedType, int userId) { 13913 enforceNotIsolatedCaller("startService"); 13914 // Refuse possible leaked file descriptors 13915 if (service != null && service.hasFileDescriptors() == true) { 13916 throw new IllegalArgumentException("File descriptors passed in Intent"); 13917 } 13918 13919 if (DEBUG_SERVICE) 13920 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13921 synchronized(this) { 13922 final int callingPid = Binder.getCallingPid(); 13923 final int callingUid = Binder.getCallingUid(); 13924 final long origId = Binder.clearCallingIdentity(); 13925 ComponentName res = mServices.startServiceLocked(caller, service, 13926 resolvedType, callingPid, callingUid, userId); 13927 Binder.restoreCallingIdentity(origId); 13928 return res; 13929 } 13930 } 13931 13932 ComponentName startServiceInPackage(int uid, 13933 Intent service, String resolvedType, int userId) { 13934 synchronized(this) { 13935 if (DEBUG_SERVICE) 13936 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13937 final long origId = Binder.clearCallingIdentity(); 13938 ComponentName res = mServices.startServiceLocked(null, service, 13939 resolvedType, -1, uid, userId); 13940 Binder.restoreCallingIdentity(origId); 13941 return res; 13942 } 13943 } 13944 13945 @Override 13946 public int stopService(IApplicationThread caller, Intent service, 13947 String resolvedType, int userId) { 13948 enforceNotIsolatedCaller("stopService"); 13949 // Refuse possible leaked file descriptors 13950 if (service != null && service.hasFileDescriptors() == true) { 13951 throw new IllegalArgumentException("File descriptors passed in Intent"); 13952 } 13953 13954 synchronized(this) { 13955 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13956 } 13957 } 13958 13959 @Override 13960 public IBinder peekService(Intent service, String resolvedType) { 13961 enforceNotIsolatedCaller("peekService"); 13962 // Refuse possible leaked file descriptors 13963 if (service != null && service.hasFileDescriptors() == true) { 13964 throw new IllegalArgumentException("File descriptors passed in Intent"); 13965 } 13966 synchronized(this) { 13967 return mServices.peekServiceLocked(service, resolvedType); 13968 } 13969 } 13970 13971 @Override 13972 public boolean stopServiceToken(ComponentName className, IBinder token, 13973 int startId) { 13974 synchronized(this) { 13975 return mServices.stopServiceTokenLocked(className, token, startId); 13976 } 13977 } 13978 13979 @Override 13980 public void setServiceForeground(ComponentName className, IBinder token, 13981 int id, Notification notification, boolean removeNotification) { 13982 synchronized(this) { 13983 mServices.setServiceForegroundLocked(className, token, id, notification, 13984 removeNotification); 13985 } 13986 } 13987 13988 @Override 13989 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13990 boolean requireFull, String name, String callerPackage) { 13991 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13992 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13993 } 13994 13995 int unsafeConvertIncomingUser(int userId) { 13996 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13997 ? mCurrentUserId : userId; 13998 } 13999 14000 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14001 int allowMode, String name, String callerPackage) { 14002 final int callingUserId = UserHandle.getUserId(callingUid); 14003 if (callingUserId == userId) { 14004 return userId; 14005 } 14006 14007 // Note that we may be accessing mCurrentUserId outside of a lock... 14008 // shouldn't be a big deal, if this is being called outside 14009 // of a locked context there is intrinsically a race with 14010 // the value the caller will receive and someone else changing it. 14011 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14012 // we will switch to the calling user if access to the current user fails. 14013 int targetUserId = unsafeConvertIncomingUser(userId); 14014 14015 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14016 final boolean allow; 14017 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14018 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14019 // If the caller has this permission, they always pass go. And collect $200. 14020 allow = true; 14021 } else if (allowMode == ALLOW_FULL_ONLY) { 14022 // We require full access, sucks to be you. 14023 allow = false; 14024 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14025 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14026 // If the caller does not have either permission, they are always doomed. 14027 allow = false; 14028 } else if (allowMode == ALLOW_NON_FULL) { 14029 // We are blanket allowing non-full access, you lucky caller! 14030 allow = true; 14031 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14032 // We may or may not allow this depending on whether the two users are 14033 // in the same profile. 14034 synchronized (mUserProfileGroupIdsSelfLocked) { 14035 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14036 UserInfo.NO_PROFILE_GROUP_ID); 14037 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14038 UserInfo.NO_PROFILE_GROUP_ID); 14039 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14040 && callingProfile == targetProfile; 14041 } 14042 } else { 14043 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14044 } 14045 if (!allow) { 14046 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14047 // In this case, they would like to just execute as their 14048 // owner user instead of failing. 14049 targetUserId = callingUserId; 14050 } else { 14051 StringBuilder builder = new StringBuilder(128); 14052 builder.append("Permission Denial: "); 14053 builder.append(name); 14054 if (callerPackage != null) { 14055 builder.append(" from "); 14056 builder.append(callerPackage); 14057 } 14058 builder.append(" asks to run as user "); 14059 builder.append(userId); 14060 builder.append(" but is calling from user "); 14061 builder.append(UserHandle.getUserId(callingUid)); 14062 builder.append("; this requires "); 14063 builder.append(INTERACT_ACROSS_USERS_FULL); 14064 if (allowMode != ALLOW_FULL_ONLY) { 14065 builder.append(" or "); 14066 builder.append(INTERACT_ACROSS_USERS); 14067 } 14068 String msg = builder.toString(); 14069 Slog.w(TAG, msg); 14070 throw new SecurityException(msg); 14071 } 14072 } 14073 } 14074 if (!allowAll && targetUserId < 0) { 14075 throw new IllegalArgumentException( 14076 "Call does not support special user #" + targetUserId); 14077 } 14078 return targetUserId; 14079 } 14080 14081 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14082 String className, int flags) { 14083 boolean result = false; 14084 // For apps that don't have pre-defined UIDs, check for permission 14085 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14086 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14087 if (ActivityManager.checkUidPermission( 14088 INTERACT_ACROSS_USERS, 14089 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14090 ComponentName comp = new ComponentName(aInfo.packageName, className); 14091 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14092 + " requests FLAG_SINGLE_USER, but app does not hold " 14093 + INTERACT_ACROSS_USERS; 14094 Slog.w(TAG, msg); 14095 throw new SecurityException(msg); 14096 } 14097 // Permission passed 14098 result = true; 14099 } 14100 } else if ("system".equals(componentProcessName)) { 14101 result = true; 14102 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14103 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14104 // Phone app is allowed to export singleuser providers. 14105 result = true; 14106 } else { 14107 // App with pre-defined UID, check if it's a persistent app 14108 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14109 } 14110 if (DEBUG_MU) { 14111 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14112 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14113 } 14114 return result; 14115 } 14116 14117 /** 14118 * Checks to see if the caller is in the same app as the singleton 14119 * component, or the component is in a special app. It allows special apps 14120 * to export singleton components but prevents exporting singleton 14121 * components for regular apps. 14122 */ 14123 boolean isValidSingletonCall(int callingUid, int componentUid) { 14124 int componentAppId = UserHandle.getAppId(componentUid); 14125 return UserHandle.isSameApp(callingUid, componentUid) 14126 || componentAppId == Process.SYSTEM_UID 14127 || componentAppId == Process.PHONE_UID 14128 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14129 == PackageManager.PERMISSION_GRANTED; 14130 } 14131 14132 public int bindService(IApplicationThread caller, IBinder token, 14133 Intent service, String resolvedType, 14134 IServiceConnection connection, int flags, int userId) { 14135 enforceNotIsolatedCaller("bindService"); 14136 // Refuse possible leaked file descriptors 14137 if (service != null && service.hasFileDescriptors() == true) { 14138 throw new IllegalArgumentException("File descriptors passed in Intent"); 14139 } 14140 14141 synchronized(this) { 14142 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14143 connection, flags, userId); 14144 } 14145 } 14146 14147 public boolean unbindService(IServiceConnection connection) { 14148 synchronized (this) { 14149 return mServices.unbindServiceLocked(connection); 14150 } 14151 } 14152 14153 public void publishService(IBinder token, Intent intent, IBinder service) { 14154 // Refuse possible leaked file descriptors 14155 if (intent != null && intent.hasFileDescriptors() == true) { 14156 throw new IllegalArgumentException("File descriptors passed in Intent"); 14157 } 14158 14159 synchronized(this) { 14160 if (!(token instanceof ServiceRecord)) { 14161 throw new IllegalArgumentException("Invalid service token"); 14162 } 14163 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14164 } 14165 } 14166 14167 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14168 // Refuse possible leaked file descriptors 14169 if (intent != null && intent.hasFileDescriptors() == true) { 14170 throw new IllegalArgumentException("File descriptors passed in Intent"); 14171 } 14172 14173 synchronized(this) { 14174 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14175 } 14176 } 14177 14178 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14179 synchronized(this) { 14180 if (!(token instanceof ServiceRecord)) { 14181 throw new IllegalArgumentException("Invalid service token"); 14182 } 14183 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14184 } 14185 } 14186 14187 // ========================================================= 14188 // BACKUP AND RESTORE 14189 // ========================================================= 14190 14191 // Cause the target app to be launched if necessary and its backup agent 14192 // instantiated. The backup agent will invoke backupAgentCreated() on the 14193 // activity manager to announce its creation. 14194 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14195 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14196 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14197 14198 synchronized(this) { 14199 // !!! TODO: currently no check here that we're already bound 14200 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14201 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14202 synchronized (stats) { 14203 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14204 } 14205 14206 // Backup agent is now in use, its package can't be stopped. 14207 try { 14208 AppGlobals.getPackageManager().setPackageStoppedState( 14209 app.packageName, false, UserHandle.getUserId(app.uid)); 14210 } catch (RemoteException e) { 14211 } catch (IllegalArgumentException e) { 14212 Slog.w(TAG, "Failed trying to unstop package " 14213 + app.packageName + ": " + e); 14214 } 14215 14216 BackupRecord r = new BackupRecord(ss, app, backupMode); 14217 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14218 ? new ComponentName(app.packageName, app.backupAgentName) 14219 : new ComponentName("android", "FullBackupAgent"); 14220 // startProcessLocked() returns existing proc's record if it's already running 14221 ProcessRecord proc = startProcessLocked(app.processName, app, 14222 false, 0, "backup", hostingName, false, false, false); 14223 if (proc == null) { 14224 Slog.e(TAG, "Unable to start backup agent process " + r); 14225 return false; 14226 } 14227 14228 r.app = proc; 14229 mBackupTarget = r; 14230 mBackupAppName = app.packageName; 14231 14232 // Try not to kill the process during backup 14233 updateOomAdjLocked(proc); 14234 14235 // If the process is already attached, schedule the creation of the backup agent now. 14236 // If it is not yet live, this will be done when it attaches to the framework. 14237 if (proc.thread != null) { 14238 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14239 try { 14240 proc.thread.scheduleCreateBackupAgent(app, 14241 compatibilityInfoForPackageLocked(app), backupMode); 14242 } catch (RemoteException e) { 14243 // Will time out on the backup manager side 14244 } 14245 } else { 14246 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14247 } 14248 // Invariants: at this point, the target app process exists and the application 14249 // is either already running or in the process of coming up. mBackupTarget and 14250 // mBackupAppName describe the app, so that when it binds back to the AM we 14251 // know that it's scheduled for a backup-agent operation. 14252 } 14253 14254 return true; 14255 } 14256 14257 @Override 14258 public void clearPendingBackup() { 14259 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14260 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14261 14262 synchronized (this) { 14263 mBackupTarget = null; 14264 mBackupAppName = null; 14265 } 14266 } 14267 14268 // A backup agent has just come up 14269 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14270 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14271 + " = " + agent); 14272 14273 synchronized(this) { 14274 if (!agentPackageName.equals(mBackupAppName)) { 14275 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14276 return; 14277 } 14278 } 14279 14280 long oldIdent = Binder.clearCallingIdentity(); 14281 try { 14282 IBackupManager bm = IBackupManager.Stub.asInterface( 14283 ServiceManager.getService(Context.BACKUP_SERVICE)); 14284 bm.agentConnected(agentPackageName, agent); 14285 } catch (RemoteException e) { 14286 // can't happen; the backup manager service is local 14287 } catch (Exception e) { 14288 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14289 e.printStackTrace(); 14290 } finally { 14291 Binder.restoreCallingIdentity(oldIdent); 14292 } 14293 } 14294 14295 // done with this agent 14296 public void unbindBackupAgent(ApplicationInfo appInfo) { 14297 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14298 if (appInfo == null) { 14299 Slog.w(TAG, "unbind backup agent for null app"); 14300 return; 14301 } 14302 14303 synchronized(this) { 14304 try { 14305 if (mBackupAppName == null) { 14306 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14307 return; 14308 } 14309 14310 if (!mBackupAppName.equals(appInfo.packageName)) { 14311 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14312 return; 14313 } 14314 14315 // Not backing this app up any more; reset its OOM adjustment 14316 final ProcessRecord proc = mBackupTarget.app; 14317 updateOomAdjLocked(proc); 14318 14319 // If the app crashed during backup, 'thread' will be null here 14320 if (proc.thread != null) { 14321 try { 14322 proc.thread.scheduleDestroyBackupAgent(appInfo, 14323 compatibilityInfoForPackageLocked(appInfo)); 14324 } catch (Exception e) { 14325 Slog.e(TAG, "Exception when unbinding backup agent:"); 14326 e.printStackTrace(); 14327 } 14328 } 14329 } finally { 14330 mBackupTarget = null; 14331 mBackupAppName = null; 14332 } 14333 } 14334 } 14335 // ========================================================= 14336 // BROADCASTS 14337 // ========================================================= 14338 14339 private final List getStickiesLocked(String action, IntentFilter filter, 14340 List cur, int userId) { 14341 final ContentResolver resolver = mContext.getContentResolver(); 14342 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14343 if (stickies == null) { 14344 return cur; 14345 } 14346 final ArrayList<Intent> list = stickies.get(action); 14347 if (list == null) { 14348 return cur; 14349 } 14350 int N = list.size(); 14351 for (int i=0; i<N; i++) { 14352 Intent intent = list.get(i); 14353 if (filter.match(resolver, intent, true, TAG) >= 0) { 14354 if (cur == null) { 14355 cur = new ArrayList<Intent>(); 14356 } 14357 cur.add(intent); 14358 } 14359 } 14360 return cur; 14361 } 14362 14363 boolean isPendingBroadcastProcessLocked(int pid) { 14364 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14365 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14366 } 14367 14368 void skipPendingBroadcastLocked(int pid) { 14369 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14370 for (BroadcastQueue queue : mBroadcastQueues) { 14371 queue.skipPendingBroadcastLocked(pid); 14372 } 14373 } 14374 14375 // The app just attached; send any pending broadcasts that it should receive 14376 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14377 boolean didSomething = false; 14378 for (BroadcastQueue queue : mBroadcastQueues) { 14379 didSomething |= queue.sendPendingBroadcastsLocked(app); 14380 } 14381 return didSomething; 14382 } 14383 14384 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14385 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14386 enforceNotIsolatedCaller("registerReceiver"); 14387 int callingUid; 14388 int callingPid; 14389 synchronized(this) { 14390 ProcessRecord callerApp = null; 14391 if (caller != null) { 14392 callerApp = getRecordForAppLocked(caller); 14393 if (callerApp == null) { 14394 throw new SecurityException( 14395 "Unable to find app for caller " + caller 14396 + " (pid=" + Binder.getCallingPid() 14397 + ") when registering receiver " + receiver); 14398 } 14399 if (callerApp.info.uid != Process.SYSTEM_UID && 14400 !callerApp.pkgList.containsKey(callerPackage) && 14401 !"android".equals(callerPackage)) { 14402 throw new SecurityException("Given caller package " + callerPackage 14403 + " is not running in process " + callerApp); 14404 } 14405 callingUid = callerApp.info.uid; 14406 callingPid = callerApp.pid; 14407 } else { 14408 callerPackage = null; 14409 callingUid = Binder.getCallingUid(); 14410 callingPid = Binder.getCallingPid(); 14411 } 14412 14413 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14414 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14415 14416 List allSticky = null; 14417 14418 // Look for any matching sticky broadcasts... 14419 Iterator actions = filter.actionsIterator(); 14420 if (actions != null) { 14421 while (actions.hasNext()) { 14422 String action = (String)actions.next(); 14423 allSticky = getStickiesLocked(action, filter, allSticky, 14424 UserHandle.USER_ALL); 14425 allSticky = getStickiesLocked(action, filter, allSticky, 14426 UserHandle.getUserId(callingUid)); 14427 } 14428 } else { 14429 allSticky = getStickiesLocked(null, filter, allSticky, 14430 UserHandle.USER_ALL); 14431 allSticky = getStickiesLocked(null, filter, allSticky, 14432 UserHandle.getUserId(callingUid)); 14433 } 14434 14435 // The first sticky in the list is returned directly back to 14436 // the client. 14437 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14438 14439 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14440 + ": " + sticky); 14441 14442 if (receiver == null) { 14443 return sticky; 14444 } 14445 14446 ReceiverList rl 14447 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14448 if (rl == null) { 14449 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14450 userId, receiver); 14451 if (rl.app != null) { 14452 rl.app.receivers.add(rl); 14453 } else { 14454 try { 14455 receiver.asBinder().linkToDeath(rl, 0); 14456 } catch (RemoteException e) { 14457 return sticky; 14458 } 14459 rl.linkedToDeath = true; 14460 } 14461 mRegisteredReceivers.put(receiver.asBinder(), rl); 14462 } else if (rl.uid != callingUid) { 14463 throw new IllegalArgumentException( 14464 "Receiver requested to register for uid " + callingUid 14465 + " was previously registered for uid " + rl.uid); 14466 } else if (rl.pid != callingPid) { 14467 throw new IllegalArgumentException( 14468 "Receiver requested to register for pid " + callingPid 14469 + " was previously registered for pid " + rl.pid); 14470 } else if (rl.userId != userId) { 14471 throw new IllegalArgumentException( 14472 "Receiver requested to register for user " + userId 14473 + " was previously registered for user " + rl.userId); 14474 } 14475 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14476 permission, callingUid, userId); 14477 rl.add(bf); 14478 if (!bf.debugCheck()) { 14479 Slog.w(TAG, "==> For Dynamic broadast"); 14480 } 14481 mReceiverResolver.addFilter(bf); 14482 14483 // Enqueue broadcasts for all existing stickies that match 14484 // this filter. 14485 if (allSticky != null) { 14486 ArrayList receivers = new ArrayList(); 14487 receivers.add(bf); 14488 14489 int N = allSticky.size(); 14490 for (int i=0; i<N; i++) { 14491 Intent intent = (Intent)allSticky.get(i); 14492 BroadcastQueue queue = broadcastQueueForIntent(intent); 14493 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14494 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14495 null, null, false, true, true, -1); 14496 queue.enqueueParallelBroadcastLocked(r); 14497 queue.scheduleBroadcastsLocked(); 14498 } 14499 } 14500 14501 return sticky; 14502 } 14503 } 14504 14505 public void unregisterReceiver(IIntentReceiver receiver) { 14506 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14507 14508 final long origId = Binder.clearCallingIdentity(); 14509 try { 14510 boolean doTrim = false; 14511 14512 synchronized(this) { 14513 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14514 if (rl != null) { 14515 if (rl.curBroadcast != null) { 14516 BroadcastRecord r = rl.curBroadcast; 14517 final boolean doNext = finishReceiverLocked( 14518 receiver.asBinder(), r.resultCode, r.resultData, 14519 r.resultExtras, r.resultAbort); 14520 if (doNext) { 14521 doTrim = true; 14522 r.queue.processNextBroadcast(false); 14523 } 14524 } 14525 14526 if (rl.app != null) { 14527 rl.app.receivers.remove(rl); 14528 } 14529 removeReceiverLocked(rl); 14530 if (rl.linkedToDeath) { 14531 rl.linkedToDeath = false; 14532 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14533 } 14534 } 14535 } 14536 14537 // If we actually concluded any broadcasts, we might now be able 14538 // to trim the recipients' apps from our working set 14539 if (doTrim) { 14540 trimApplications(); 14541 return; 14542 } 14543 14544 } finally { 14545 Binder.restoreCallingIdentity(origId); 14546 } 14547 } 14548 14549 void removeReceiverLocked(ReceiverList rl) { 14550 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14551 int N = rl.size(); 14552 for (int i=0; i<N; i++) { 14553 mReceiverResolver.removeFilter(rl.get(i)); 14554 } 14555 } 14556 14557 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14558 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14559 ProcessRecord r = mLruProcesses.get(i); 14560 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14561 try { 14562 r.thread.dispatchPackageBroadcast(cmd, packages); 14563 } catch (RemoteException ex) { 14564 } 14565 } 14566 } 14567 } 14568 14569 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14570 int[] users) { 14571 List<ResolveInfo> receivers = null; 14572 try { 14573 HashSet<ComponentName> singleUserReceivers = null; 14574 boolean scannedFirstReceivers = false; 14575 for (int user : users) { 14576 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14577 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14578 if (user != 0 && newReceivers != null) { 14579 // If this is not the primary user, we need to check for 14580 // any receivers that should be filtered out. 14581 for (int i=0; i<newReceivers.size(); i++) { 14582 ResolveInfo ri = newReceivers.get(i); 14583 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14584 newReceivers.remove(i); 14585 i--; 14586 } 14587 } 14588 } 14589 if (newReceivers != null && newReceivers.size() == 0) { 14590 newReceivers = null; 14591 } 14592 if (receivers == null) { 14593 receivers = newReceivers; 14594 } else if (newReceivers != null) { 14595 // We need to concatenate the additional receivers 14596 // found with what we have do far. This would be easy, 14597 // but we also need to de-dup any receivers that are 14598 // singleUser. 14599 if (!scannedFirstReceivers) { 14600 // Collect any single user receivers we had already retrieved. 14601 scannedFirstReceivers = true; 14602 for (int i=0; i<receivers.size(); i++) { 14603 ResolveInfo ri = receivers.get(i); 14604 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14605 ComponentName cn = new ComponentName( 14606 ri.activityInfo.packageName, ri.activityInfo.name); 14607 if (singleUserReceivers == null) { 14608 singleUserReceivers = new HashSet<ComponentName>(); 14609 } 14610 singleUserReceivers.add(cn); 14611 } 14612 } 14613 } 14614 // Add the new results to the existing results, tracking 14615 // and de-dupping single user receivers. 14616 for (int i=0; i<newReceivers.size(); i++) { 14617 ResolveInfo ri = newReceivers.get(i); 14618 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14619 ComponentName cn = new ComponentName( 14620 ri.activityInfo.packageName, ri.activityInfo.name); 14621 if (singleUserReceivers == null) { 14622 singleUserReceivers = new HashSet<ComponentName>(); 14623 } 14624 if (!singleUserReceivers.contains(cn)) { 14625 singleUserReceivers.add(cn); 14626 receivers.add(ri); 14627 } 14628 } else { 14629 receivers.add(ri); 14630 } 14631 } 14632 } 14633 } 14634 } catch (RemoteException ex) { 14635 // pm is in same process, this will never happen. 14636 } 14637 return receivers; 14638 } 14639 14640 private final int broadcastIntentLocked(ProcessRecord callerApp, 14641 String callerPackage, Intent intent, String resolvedType, 14642 IIntentReceiver resultTo, int resultCode, String resultData, 14643 Bundle map, String requiredPermission, int appOp, 14644 boolean ordered, boolean sticky, int callingPid, int callingUid, 14645 int userId) { 14646 intent = new Intent(intent); 14647 14648 // By default broadcasts do not go to stopped apps. 14649 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14650 14651 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14652 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14653 + " ordered=" + ordered + " userid=" + userId); 14654 if ((resultTo != null) && !ordered) { 14655 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14656 } 14657 14658 userId = handleIncomingUser(callingPid, callingUid, userId, 14659 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14660 14661 // Make sure that the user who is receiving this broadcast is started. 14662 // If not, we will just skip it. 14663 14664 14665 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14666 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14667 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14668 Slog.w(TAG, "Skipping broadcast of " + intent 14669 + ": user " + userId + " is stopped"); 14670 return ActivityManager.BROADCAST_SUCCESS; 14671 } 14672 } 14673 14674 /* 14675 * Prevent non-system code (defined here to be non-persistent 14676 * processes) from sending protected broadcasts. 14677 */ 14678 int callingAppId = UserHandle.getAppId(callingUid); 14679 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14680 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14681 || callingAppId == Process.NFC_UID || callingUid == 0) { 14682 // Always okay. 14683 } else if (callerApp == null || !callerApp.persistent) { 14684 try { 14685 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14686 intent.getAction())) { 14687 String msg = "Permission Denial: not allowed to send broadcast " 14688 + intent.getAction() + " from pid=" 14689 + callingPid + ", uid=" + callingUid; 14690 Slog.w(TAG, msg); 14691 throw new SecurityException(msg); 14692 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14693 // Special case for compatibility: we don't want apps to send this, 14694 // but historically it has not been protected and apps may be using it 14695 // to poke their own app widget. So, instead of making it protected, 14696 // just limit it to the caller. 14697 if (callerApp == null) { 14698 String msg = "Permission Denial: not allowed to send broadcast " 14699 + intent.getAction() + " from unknown caller."; 14700 Slog.w(TAG, msg); 14701 throw new SecurityException(msg); 14702 } else if (intent.getComponent() != null) { 14703 // They are good enough to send to an explicit component... verify 14704 // it is being sent to the calling app. 14705 if (!intent.getComponent().getPackageName().equals( 14706 callerApp.info.packageName)) { 14707 String msg = "Permission Denial: not allowed to send broadcast " 14708 + intent.getAction() + " to " 14709 + intent.getComponent().getPackageName() + " from " 14710 + callerApp.info.packageName; 14711 Slog.w(TAG, msg); 14712 throw new SecurityException(msg); 14713 } 14714 } else { 14715 // Limit broadcast to their own package. 14716 intent.setPackage(callerApp.info.packageName); 14717 } 14718 } 14719 } catch (RemoteException e) { 14720 Slog.w(TAG, "Remote exception", e); 14721 return ActivityManager.BROADCAST_SUCCESS; 14722 } 14723 } 14724 14725 // Handle special intents: if this broadcast is from the package 14726 // manager about a package being removed, we need to remove all of 14727 // its activities from the history stack. 14728 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14729 intent.getAction()); 14730 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14731 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14732 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14733 || uidRemoved) { 14734 if (checkComponentPermission( 14735 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14736 callingPid, callingUid, -1, true) 14737 == PackageManager.PERMISSION_GRANTED) { 14738 if (uidRemoved) { 14739 final Bundle intentExtras = intent.getExtras(); 14740 final int uid = intentExtras != null 14741 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14742 if (uid >= 0) { 14743 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14744 synchronized (bs) { 14745 bs.removeUidStatsLocked(uid); 14746 } 14747 mAppOpsService.uidRemoved(uid); 14748 } 14749 } else { 14750 // If resources are unavailable just force stop all 14751 // those packages and flush the attribute cache as well. 14752 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14753 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14754 if (list != null && (list.length > 0)) { 14755 for (String pkg : list) { 14756 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14757 "storage unmount"); 14758 } 14759 sendPackageBroadcastLocked( 14760 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14761 } 14762 } else { 14763 Uri data = intent.getData(); 14764 String ssp; 14765 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14766 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14767 intent.getAction()); 14768 boolean fullUninstall = removed && 14769 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14770 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14771 forceStopPackageLocked(ssp, UserHandle.getAppId( 14772 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14773 false, fullUninstall, userId, 14774 removed ? "pkg removed" : "pkg changed"); 14775 } 14776 if (removed) { 14777 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14778 new String[] {ssp}, userId); 14779 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14780 mAppOpsService.packageRemoved( 14781 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14782 14783 // Remove all permissions granted from/to this package 14784 removeUriPermissionsForPackageLocked(ssp, userId, true); 14785 } 14786 } 14787 } 14788 } 14789 } 14790 } else { 14791 String msg = "Permission Denial: " + intent.getAction() 14792 + " broadcast from " + callerPackage + " (pid=" + callingPid 14793 + ", uid=" + callingUid + ")" 14794 + " requires " 14795 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14796 Slog.w(TAG, msg); 14797 throw new SecurityException(msg); 14798 } 14799 14800 // Special case for adding a package: by default turn on compatibility 14801 // mode. 14802 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14803 Uri data = intent.getData(); 14804 String ssp; 14805 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14806 mCompatModePackages.handlePackageAddedLocked(ssp, 14807 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14808 } 14809 } 14810 14811 /* 14812 * If this is the time zone changed action, queue up a message that will reset the timezone 14813 * of all currently running processes. This message will get queued up before the broadcast 14814 * happens. 14815 */ 14816 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14817 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14818 } 14819 14820 /* 14821 * If the user set the time, let all running processes know. 14822 */ 14823 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14824 final int is24Hour = intent.getBooleanExtra( 14825 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14826 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14827 } 14828 14829 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14830 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14831 } 14832 14833 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14834 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14835 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14836 } 14837 14838 // Add to the sticky list if requested. 14839 if (sticky) { 14840 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14841 callingPid, callingUid) 14842 != PackageManager.PERMISSION_GRANTED) { 14843 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14844 + callingPid + ", uid=" + callingUid 14845 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14846 Slog.w(TAG, msg); 14847 throw new SecurityException(msg); 14848 } 14849 if (requiredPermission != null) { 14850 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14851 + " and enforce permission " + requiredPermission); 14852 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14853 } 14854 if (intent.getComponent() != null) { 14855 throw new SecurityException( 14856 "Sticky broadcasts can't target a specific component"); 14857 } 14858 // We use userId directly here, since the "all" target is maintained 14859 // as a separate set of sticky broadcasts. 14860 if (userId != UserHandle.USER_ALL) { 14861 // But first, if this is not a broadcast to all users, then 14862 // make sure it doesn't conflict with an existing broadcast to 14863 // all users. 14864 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14865 UserHandle.USER_ALL); 14866 if (stickies != null) { 14867 ArrayList<Intent> list = stickies.get(intent.getAction()); 14868 if (list != null) { 14869 int N = list.size(); 14870 int i; 14871 for (i=0; i<N; i++) { 14872 if (intent.filterEquals(list.get(i))) { 14873 throw new IllegalArgumentException( 14874 "Sticky broadcast " + intent + " for user " 14875 + userId + " conflicts with existing global broadcast"); 14876 } 14877 } 14878 } 14879 } 14880 } 14881 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14882 if (stickies == null) { 14883 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14884 mStickyBroadcasts.put(userId, stickies); 14885 } 14886 ArrayList<Intent> list = stickies.get(intent.getAction()); 14887 if (list == null) { 14888 list = new ArrayList<Intent>(); 14889 stickies.put(intent.getAction(), list); 14890 } 14891 int N = list.size(); 14892 int i; 14893 for (i=0; i<N; i++) { 14894 if (intent.filterEquals(list.get(i))) { 14895 // This sticky already exists, replace it. 14896 list.set(i, new Intent(intent)); 14897 break; 14898 } 14899 } 14900 if (i >= N) { 14901 list.add(new Intent(intent)); 14902 } 14903 } 14904 14905 int[] users; 14906 if (userId == UserHandle.USER_ALL) { 14907 // Caller wants broadcast to go to all started users. 14908 users = mStartedUserArray; 14909 } else { 14910 // Caller wants broadcast to go to one specific user. 14911 users = new int[] {userId}; 14912 } 14913 14914 // Figure out who all will receive this broadcast. 14915 List receivers = null; 14916 List<BroadcastFilter> registeredReceivers = null; 14917 // Need to resolve the intent to interested receivers... 14918 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14919 == 0) { 14920 receivers = collectReceiverComponents(intent, resolvedType, users); 14921 } 14922 if (intent.getComponent() == null) { 14923 registeredReceivers = mReceiverResolver.queryIntent(intent, 14924 resolvedType, false, userId); 14925 } 14926 14927 final boolean replacePending = 14928 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14929 14930 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14931 + " replacePending=" + replacePending); 14932 14933 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14934 if (!ordered && NR > 0) { 14935 // If we are not serializing this broadcast, then send the 14936 // registered receivers separately so they don't wait for the 14937 // components to be launched. 14938 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14939 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14940 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14941 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14942 ordered, sticky, false, userId); 14943 if (DEBUG_BROADCAST) Slog.v( 14944 TAG, "Enqueueing parallel broadcast " + r); 14945 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14946 if (!replaced) { 14947 queue.enqueueParallelBroadcastLocked(r); 14948 queue.scheduleBroadcastsLocked(); 14949 } 14950 registeredReceivers = null; 14951 NR = 0; 14952 } 14953 14954 // Merge into one list. 14955 int ir = 0; 14956 if (receivers != null) { 14957 // A special case for PACKAGE_ADDED: do not allow the package 14958 // being added to see this broadcast. This prevents them from 14959 // using this as a back door to get run as soon as they are 14960 // installed. Maybe in the future we want to have a special install 14961 // broadcast or such for apps, but we'd like to deliberately make 14962 // this decision. 14963 String skipPackages[] = null; 14964 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14965 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14966 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14967 Uri data = intent.getData(); 14968 if (data != null) { 14969 String pkgName = data.getSchemeSpecificPart(); 14970 if (pkgName != null) { 14971 skipPackages = new String[] { pkgName }; 14972 } 14973 } 14974 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14975 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14976 } 14977 if (skipPackages != null && (skipPackages.length > 0)) { 14978 for (String skipPackage : skipPackages) { 14979 if (skipPackage != null) { 14980 int NT = receivers.size(); 14981 for (int it=0; it<NT; it++) { 14982 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14983 if (curt.activityInfo.packageName.equals(skipPackage)) { 14984 receivers.remove(it); 14985 it--; 14986 NT--; 14987 } 14988 } 14989 } 14990 } 14991 } 14992 14993 int NT = receivers != null ? receivers.size() : 0; 14994 int it = 0; 14995 ResolveInfo curt = null; 14996 BroadcastFilter curr = null; 14997 while (it < NT && ir < NR) { 14998 if (curt == null) { 14999 curt = (ResolveInfo)receivers.get(it); 15000 } 15001 if (curr == null) { 15002 curr = registeredReceivers.get(ir); 15003 } 15004 if (curr.getPriority() >= curt.priority) { 15005 // Insert this broadcast record into the final list. 15006 receivers.add(it, curr); 15007 ir++; 15008 curr = null; 15009 it++; 15010 NT++; 15011 } else { 15012 // Skip to the next ResolveInfo in the final list. 15013 it++; 15014 curt = null; 15015 } 15016 } 15017 } 15018 while (ir < NR) { 15019 if (receivers == null) { 15020 receivers = new ArrayList(); 15021 } 15022 receivers.add(registeredReceivers.get(ir)); 15023 ir++; 15024 } 15025 15026 if ((receivers != null && receivers.size() > 0) 15027 || resultTo != null) { 15028 BroadcastQueue queue = broadcastQueueForIntent(intent); 15029 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15030 callerPackage, callingPid, callingUid, resolvedType, 15031 requiredPermission, appOp, receivers, resultTo, resultCode, 15032 resultData, map, ordered, sticky, false, userId); 15033 if (DEBUG_BROADCAST) Slog.v( 15034 TAG, "Enqueueing ordered broadcast " + r 15035 + ": prev had " + queue.mOrderedBroadcasts.size()); 15036 if (DEBUG_BROADCAST) { 15037 int seq = r.intent.getIntExtra("seq", -1); 15038 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15039 } 15040 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15041 if (!replaced) { 15042 queue.enqueueOrderedBroadcastLocked(r); 15043 queue.scheduleBroadcastsLocked(); 15044 } 15045 } 15046 15047 return ActivityManager.BROADCAST_SUCCESS; 15048 } 15049 15050 final Intent verifyBroadcastLocked(Intent intent) { 15051 // Refuse possible leaked file descriptors 15052 if (intent != null && intent.hasFileDescriptors() == true) { 15053 throw new IllegalArgumentException("File descriptors passed in Intent"); 15054 } 15055 15056 int flags = intent.getFlags(); 15057 15058 if (!mProcessesReady) { 15059 // if the caller really truly claims to know what they're doing, go 15060 // ahead and allow the broadcast without launching any receivers 15061 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15062 intent = new Intent(intent); 15063 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15064 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15065 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15066 + " before boot completion"); 15067 throw new IllegalStateException("Cannot broadcast before boot completed"); 15068 } 15069 } 15070 15071 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15072 throw new IllegalArgumentException( 15073 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15074 } 15075 15076 return intent; 15077 } 15078 15079 public final int broadcastIntent(IApplicationThread caller, 15080 Intent intent, String resolvedType, IIntentReceiver resultTo, 15081 int resultCode, String resultData, Bundle map, 15082 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15083 enforceNotIsolatedCaller("broadcastIntent"); 15084 synchronized(this) { 15085 intent = verifyBroadcastLocked(intent); 15086 15087 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15088 final int callingPid = Binder.getCallingPid(); 15089 final int callingUid = Binder.getCallingUid(); 15090 final long origId = Binder.clearCallingIdentity(); 15091 int res = broadcastIntentLocked(callerApp, 15092 callerApp != null ? callerApp.info.packageName : null, 15093 intent, resolvedType, resultTo, 15094 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15095 callingPid, callingUid, userId); 15096 Binder.restoreCallingIdentity(origId); 15097 return res; 15098 } 15099 } 15100 15101 int broadcastIntentInPackage(String packageName, int uid, 15102 Intent intent, String resolvedType, IIntentReceiver resultTo, 15103 int resultCode, String resultData, Bundle map, 15104 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15105 synchronized(this) { 15106 intent = verifyBroadcastLocked(intent); 15107 15108 final long origId = Binder.clearCallingIdentity(); 15109 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15110 resultTo, resultCode, resultData, map, requiredPermission, 15111 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15112 Binder.restoreCallingIdentity(origId); 15113 return res; 15114 } 15115 } 15116 15117 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15118 // Refuse possible leaked file descriptors 15119 if (intent != null && intent.hasFileDescriptors() == true) { 15120 throw new IllegalArgumentException("File descriptors passed in Intent"); 15121 } 15122 15123 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15124 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15125 15126 synchronized(this) { 15127 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15128 != PackageManager.PERMISSION_GRANTED) { 15129 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15130 + Binder.getCallingPid() 15131 + ", uid=" + Binder.getCallingUid() 15132 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15133 Slog.w(TAG, msg); 15134 throw new SecurityException(msg); 15135 } 15136 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15137 if (stickies != null) { 15138 ArrayList<Intent> list = stickies.get(intent.getAction()); 15139 if (list != null) { 15140 int N = list.size(); 15141 int i; 15142 for (i=0; i<N; i++) { 15143 if (intent.filterEquals(list.get(i))) { 15144 list.remove(i); 15145 break; 15146 } 15147 } 15148 if (list.size() <= 0) { 15149 stickies.remove(intent.getAction()); 15150 } 15151 } 15152 if (stickies.size() <= 0) { 15153 mStickyBroadcasts.remove(userId); 15154 } 15155 } 15156 } 15157 } 15158 15159 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15160 String resultData, Bundle resultExtras, boolean resultAbort) { 15161 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15162 if (r == null) { 15163 Slog.w(TAG, "finishReceiver called but not found on queue"); 15164 return false; 15165 } 15166 15167 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15168 } 15169 15170 void backgroundServicesFinishedLocked(int userId) { 15171 for (BroadcastQueue queue : mBroadcastQueues) { 15172 queue.backgroundServicesFinishedLocked(userId); 15173 } 15174 } 15175 15176 public void finishReceiver(IBinder who, int resultCode, String resultData, 15177 Bundle resultExtras, boolean resultAbort) { 15178 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15179 15180 // Refuse possible leaked file descriptors 15181 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15182 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15183 } 15184 15185 final long origId = Binder.clearCallingIdentity(); 15186 try { 15187 boolean doNext = false; 15188 BroadcastRecord r; 15189 15190 synchronized(this) { 15191 r = broadcastRecordForReceiverLocked(who); 15192 if (r != null) { 15193 doNext = r.queue.finishReceiverLocked(r, resultCode, 15194 resultData, resultExtras, resultAbort, true); 15195 } 15196 } 15197 15198 if (doNext) { 15199 r.queue.processNextBroadcast(false); 15200 } 15201 trimApplications(); 15202 } finally { 15203 Binder.restoreCallingIdentity(origId); 15204 } 15205 } 15206 15207 // ========================================================= 15208 // INSTRUMENTATION 15209 // ========================================================= 15210 15211 public boolean startInstrumentation(ComponentName className, 15212 String profileFile, int flags, Bundle arguments, 15213 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15214 int userId, String abiOverride) { 15215 enforceNotIsolatedCaller("startInstrumentation"); 15216 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15217 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15218 // Refuse possible leaked file descriptors 15219 if (arguments != null && arguments.hasFileDescriptors()) { 15220 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15221 } 15222 15223 synchronized(this) { 15224 InstrumentationInfo ii = null; 15225 ApplicationInfo ai = null; 15226 try { 15227 ii = mContext.getPackageManager().getInstrumentationInfo( 15228 className, STOCK_PM_FLAGS); 15229 ai = AppGlobals.getPackageManager().getApplicationInfo( 15230 ii.targetPackage, STOCK_PM_FLAGS, userId); 15231 } catch (PackageManager.NameNotFoundException e) { 15232 } catch (RemoteException e) { 15233 } 15234 if (ii == null) { 15235 reportStartInstrumentationFailure(watcher, className, 15236 "Unable to find instrumentation info for: " + className); 15237 return false; 15238 } 15239 if (ai == null) { 15240 reportStartInstrumentationFailure(watcher, className, 15241 "Unable to find instrumentation target package: " + ii.targetPackage); 15242 return false; 15243 } 15244 15245 int match = mContext.getPackageManager().checkSignatures( 15246 ii.targetPackage, ii.packageName); 15247 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15248 String msg = "Permission Denial: starting instrumentation " 15249 + className + " from pid=" 15250 + Binder.getCallingPid() 15251 + ", uid=" + Binder.getCallingPid() 15252 + " not allowed because package " + ii.packageName 15253 + " does not have a signature matching the target " 15254 + ii.targetPackage; 15255 reportStartInstrumentationFailure(watcher, className, msg); 15256 throw new SecurityException(msg); 15257 } 15258 15259 final long origId = Binder.clearCallingIdentity(); 15260 // Instrumentation can kill and relaunch even persistent processes 15261 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15262 "start instr"); 15263 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15264 app.instrumentationClass = className; 15265 app.instrumentationInfo = ai; 15266 app.instrumentationProfileFile = profileFile; 15267 app.instrumentationArguments = arguments; 15268 app.instrumentationWatcher = watcher; 15269 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15270 app.instrumentationResultClass = className; 15271 Binder.restoreCallingIdentity(origId); 15272 } 15273 15274 return true; 15275 } 15276 15277 /** 15278 * Report errors that occur while attempting to start Instrumentation. Always writes the 15279 * error to the logs, but if somebody is watching, send the report there too. This enables 15280 * the "am" command to report errors with more information. 15281 * 15282 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15283 * @param cn The component name of the instrumentation. 15284 * @param report The error report. 15285 */ 15286 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15287 ComponentName cn, String report) { 15288 Slog.w(TAG, report); 15289 try { 15290 if (watcher != null) { 15291 Bundle results = new Bundle(); 15292 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15293 results.putString("Error", report); 15294 watcher.instrumentationStatus(cn, -1, results); 15295 } 15296 } catch (RemoteException e) { 15297 Slog.w(TAG, e); 15298 } 15299 } 15300 15301 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15302 if (app.instrumentationWatcher != null) { 15303 try { 15304 // NOTE: IInstrumentationWatcher *must* be oneway here 15305 app.instrumentationWatcher.instrumentationFinished( 15306 app.instrumentationClass, 15307 resultCode, 15308 results); 15309 } catch (RemoteException e) { 15310 } 15311 } 15312 if (app.instrumentationUiAutomationConnection != null) { 15313 try { 15314 app.instrumentationUiAutomationConnection.shutdown(); 15315 } catch (RemoteException re) { 15316 /* ignore */ 15317 } 15318 // Only a UiAutomation can set this flag and now that 15319 // it is finished we make sure it is reset to its default. 15320 mUserIsMonkey = false; 15321 } 15322 app.instrumentationWatcher = null; 15323 app.instrumentationUiAutomationConnection = null; 15324 app.instrumentationClass = null; 15325 app.instrumentationInfo = null; 15326 app.instrumentationProfileFile = null; 15327 app.instrumentationArguments = null; 15328 15329 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15330 "finished inst"); 15331 } 15332 15333 public void finishInstrumentation(IApplicationThread target, 15334 int resultCode, Bundle results) { 15335 int userId = UserHandle.getCallingUserId(); 15336 // Refuse possible leaked file descriptors 15337 if (results != null && results.hasFileDescriptors()) { 15338 throw new IllegalArgumentException("File descriptors passed in Intent"); 15339 } 15340 15341 synchronized(this) { 15342 ProcessRecord app = getRecordForAppLocked(target); 15343 if (app == null) { 15344 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15345 return; 15346 } 15347 final long origId = Binder.clearCallingIdentity(); 15348 finishInstrumentationLocked(app, resultCode, results); 15349 Binder.restoreCallingIdentity(origId); 15350 } 15351 } 15352 15353 // ========================================================= 15354 // CONFIGURATION 15355 // ========================================================= 15356 15357 public ConfigurationInfo getDeviceConfigurationInfo() { 15358 ConfigurationInfo config = new ConfigurationInfo(); 15359 synchronized (this) { 15360 config.reqTouchScreen = mConfiguration.touchscreen; 15361 config.reqKeyboardType = mConfiguration.keyboard; 15362 config.reqNavigation = mConfiguration.navigation; 15363 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15364 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15365 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15366 } 15367 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15368 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15369 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15370 } 15371 config.reqGlEsVersion = GL_ES_VERSION; 15372 } 15373 return config; 15374 } 15375 15376 ActivityStack getFocusedStack() { 15377 return mStackSupervisor.getFocusedStack(); 15378 } 15379 15380 public Configuration getConfiguration() { 15381 Configuration ci; 15382 synchronized(this) { 15383 ci = new Configuration(mConfiguration); 15384 } 15385 return ci; 15386 } 15387 15388 public void updatePersistentConfiguration(Configuration values) { 15389 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15390 "updateConfiguration()"); 15391 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15392 "updateConfiguration()"); 15393 if (values == null) { 15394 throw new NullPointerException("Configuration must not be null"); 15395 } 15396 15397 synchronized(this) { 15398 final long origId = Binder.clearCallingIdentity(); 15399 updateConfigurationLocked(values, null, true, false); 15400 Binder.restoreCallingIdentity(origId); 15401 } 15402 } 15403 15404 public void updateConfiguration(Configuration values) { 15405 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15406 "updateConfiguration()"); 15407 15408 synchronized(this) { 15409 if (values == null && mWindowManager != null) { 15410 // sentinel: fetch the current configuration from the window manager 15411 values = mWindowManager.computeNewConfiguration(); 15412 } 15413 15414 if (mWindowManager != null) { 15415 mProcessList.applyDisplaySize(mWindowManager); 15416 } 15417 15418 final long origId = Binder.clearCallingIdentity(); 15419 if (values != null) { 15420 Settings.System.clearConfiguration(values); 15421 } 15422 updateConfigurationLocked(values, null, false, false); 15423 Binder.restoreCallingIdentity(origId); 15424 } 15425 } 15426 15427 /** 15428 * Do either or both things: (1) change the current configuration, and (2) 15429 * make sure the given activity is running with the (now) current 15430 * configuration. Returns true if the activity has been left running, or 15431 * false if <var>starting</var> is being destroyed to match the new 15432 * configuration. 15433 * @param persistent TODO 15434 */ 15435 boolean updateConfigurationLocked(Configuration values, 15436 ActivityRecord starting, boolean persistent, boolean initLocale) { 15437 int changes = 0; 15438 15439 if (values != null) { 15440 Configuration newConfig = new Configuration(mConfiguration); 15441 changes = newConfig.updateFrom(values); 15442 if (changes != 0) { 15443 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15444 Slog.i(TAG, "Updating configuration to: " + values); 15445 } 15446 15447 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15448 15449 if (values.locale != null && !initLocale) { 15450 saveLocaleLocked(values.locale, 15451 !values.locale.equals(mConfiguration.locale), 15452 values.userSetLocale); 15453 } 15454 15455 mConfigurationSeq++; 15456 if (mConfigurationSeq <= 0) { 15457 mConfigurationSeq = 1; 15458 } 15459 newConfig.seq = mConfigurationSeq; 15460 mConfiguration = newConfig; 15461 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15462 //mUsageStatsService.noteStartConfig(newConfig); 15463 15464 final Configuration configCopy = new Configuration(mConfiguration); 15465 15466 // TODO: If our config changes, should we auto dismiss any currently 15467 // showing dialogs? 15468 mShowDialogs = shouldShowDialogs(newConfig); 15469 15470 AttributeCache ac = AttributeCache.instance(); 15471 if (ac != null) { 15472 ac.updateConfiguration(configCopy); 15473 } 15474 15475 // Make sure all resources in our process are updated 15476 // right now, so that anyone who is going to retrieve 15477 // resource values after we return will be sure to get 15478 // the new ones. This is especially important during 15479 // boot, where the first config change needs to guarantee 15480 // all resources have that config before following boot 15481 // code is executed. 15482 mSystemThread.applyConfigurationToResources(configCopy); 15483 15484 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15485 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15486 msg.obj = new Configuration(configCopy); 15487 mHandler.sendMessage(msg); 15488 } 15489 15490 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15491 ProcessRecord app = mLruProcesses.get(i); 15492 try { 15493 if (app.thread != null) { 15494 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15495 + app.processName + " new config " + mConfiguration); 15496 app.thread.scheduleConfigurationChanged(configCopy); 15497 } 15498 } catch (Exception e) { 15499 } 15500 } 15501 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15502 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15503 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15504 | Intent.FLAG_RECEIVER_FOREGROUND); 15505 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15506 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15507 Process.SYSTEM_UID, UserHandle.USER_ALL); 15508 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15509 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15510 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15511 broadcastIntentLocked(null, null, intent, 15512 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15513 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15514 } 15515 } 15516 } 15517 15518 boolean kept = true; 15519 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15520 // mainStack is null during startup. 15521 if (mainStack != null) { 15522 if (changes != 0 && starting == null) { 15523 // If the configuration changed, and the caller is not already 15524 // in the process of starting an activity, then find the top 15525 // activity to check if its configuration needs to change. 15526 starting = mainStack.topRunningActivityLocked(null); 15527 } 15528 15529 if (starting != null) { 15530 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15531 // And we need to make sure at this point that all other activities 15532 // are made visible with the correct configuration. 15533 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15534 } 15535 } 15536 15537 if (values != null && mWindowManager != null) { 15538 mWindowManager.setNewConfiguration(mConfiguration); 15539 } 15540 15541 return kept; 15542 } 15543 15544 /** 15545 * Decide based on the configuration whether we should shouw the ANR, 15546 * crash, etc dialogs. The idea is that if there is no affordnace to 15547 * press the on-screen buttons, we shouldn't show the dialog. 15548 * 15549 * A thought: SystemUI might also want to get told about this, the Power 15550 * dialog / global actions also might want different behaviors. 15551 */ 15552 private static final boolean shouldShowDialogs(Configuration config) { 15553 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15554 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15555 } 15556 15557 /** 15558 * Save the locale. You must be inside a synchronized (this) block. 15559 */ 15560 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15561 if(isDiff) { 15562 SystemProperties.set("user.language", l.getLanguage()); 15563 SystemProperties.set("user.region", l.getCountry()); 15564 } 15565 15566 if(isPersist) { 15567 SystemProperties.set("persist.sys.language", l.getLanguage()); 15568 SystemProperties.set("persist.sys.country", l.getCountry()); 15569 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15570 } 15571 } 15572 15573 @Override 15574 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15575 ActivityRecord srec = ActivityRecord.forToken(token); 15576 return srec != null && srec.task.affinity != null && 15577 srec.task.affinity.equals(destAffinity); 15578 } 15579 15580 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15581 Intent resultData) { 15582 15583 synchronized (this) { 15584 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15585 if (stack != null) { 15586 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15587 } 15588 return false; 15589 } 15590 } 15591 15592 public int getLaunchedFromUid(IBinder activityToken) { 15593 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15594 if (srec == null) { 15595 return -1; 15596 } 15597 return srec.launchedFromUid; 15598 } 15599 15600 public String getLaunchedFromPackage(IBinder activityToken) { 15601 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15602 if (srec == null) { 15603 return null; 15604 } 15605 return srec.launchedFromPackage; 15606 } 15607 15608 // ========================================================= 15609 // LIFETIME MANAGEMENT 15610 // ========================================================= 15611 15612 // Returns which broadcast queue the app is the current [or imminent] receiver 15613 // on, or 'null' if the app is not an active broadcast recipient. 15614 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15615 BroadcastRecord r = app.curReceiver; 15616 if (r != null) { 15617 return r.queue; 15618 } 15619 15620 // It's not the current receiver, but it might be starting up to become one 15621 synchronized (this) { 15622 for (BroadcastQueue queue : mBroadcastQueues) { 15623 r = queue.mPendingBroadcast; 15624 if (r != null && r.curApp == app) { 15625 // found it; report which queue it's in 15626 return queue; 15627 } 15628 } 15629 } 15630 15631 return null; 15632 } 15633 15634 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15635 boolean doingAll, long now) { 15636 if (mAdjSeq == app.adjSeq) { 15637 // This adjustment has already been computed. 15638 return app.curRawAdj; 15639 } 15640 15641 if (app.thread == null) { 15642 app.adjSeq = mAdjSeq; 15643 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15644 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15645 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15646 } 15647 15648 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15649 app.adjSource = null; 15650 app.adjTarget = null; 15651 app.empty = false; 15652 app.cached = false; 15653 15654 final int activitiesSize = app.activities.size(); 15655 15656 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15657 // The max adjustment doesn't allow this app to be anything 15658 // below foreground, so it is not worth doing work for it. 15659 app.adjType = "fixed"; 15660 app.adjSeq = mAdjSeq; 15661 app.curRawAdj = app.maxAdj; 15662 app.foregroundActivities = false; 15663 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15664 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15665 // System processes can do UI, and when they do we want to have 15666 // them trim their memory after the user leaves the UI. To 15667 // facilitate this, here we need to determine whether or not it 15668 // is currently showing UI. 15669 app.systemNoUi = true; 15670 if (app == TOP_APP) { 15671 app.systemNoUi = false; 15672 } else if (activitiesSize > 0) { 15673 for (int j = 0; j < activitiesSize; j++) { 15674 final ActivityRecord r = app.activities.get(j); 15675 if (r.visible) { 15676 app.systemNoUi = false; 15677 } 15678 } 15679 } 15680 if (!app.systemNoUi) { 15681 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15682 } 15683 return (app.curAdj=app.maxAdj); 15684 } 15685 15686 app.systemNoUi = false; 15687 15688 // Determine the importance of the process, starting with most 15689 // important to least, and assign an appropriate OOM adjustment. 15690 int adj; 15691 int schedGroup; 15692 int procState; 15693 boolean foregroundActivities = false; 15694 BroadcastQueue queue; 15695 if (app == TOP_APP) { 15696 // The last app on the list is the foreground app. 15697 adj = ProcessList.FOREGROUND_APP_ADJ; 15698 schedGroup = Process.THREAD_GROUP_DEFAULT; 15699 app.adjType = "top-activity"; 15700 foregroundActivities = true; 15701 procState = ActivityManager.PROCESS_STATE_TOP; 15702 } else if (app.instrumentationClass != null) { 15703 // Don't want to kill running instrumentation. 15704 adj = ProcessList.FOREGROUND_APP_ADJ; 15705 schedGroup = Process.THREAD_GROUP_DEFAULT; 15706 app.adjType = "instrumentation"; 15707 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15708 } else if ((queue = isReceivingBroadcast(app)) != null) { 15709 // An app that is currently receiving a broadcast also 15710 // counts as being in the foreground for OOM killer purposes. 15711 // It's placed in a sched group based on the nature of the 15712 // broadcast as reflected by which queue it's active in. 15713 adj = ProcessList.FOREGROUND_APP_ADJ; 15714 schedGroup = (queue == mFgBroadcastQueue) 15715 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15716 app.adjType = "broadcast"; 15717 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15718 } else if (app.executingServices.size() > 0) { 15719 // An app that is currently executing a service callback also 15720 // counts as being in the foreground. 15721 adj = ProcessList.FOREGROUND_APP_ADJ; 15722 schedGroup = app.execServicesFg ? 15723 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15724 app.adjType = "exec-service"; 15725 procState = ActivityManager.PROCESS_STATE_SERVICE; 15726 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15727 } else { 15728 // As far as we know the process is empty. We may change our mind later. 15729 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15730 // At this point we don't actually know the adjustment. Use the cached adj 15731 // value that the caller wants us to. 15732 adj = cachedAdj; 15733 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15734 app.cached = true; 15735 app.empty = true; 15736 app.adjType = "cch-empty"; 15737 } 15738 15739 // Examine all activities if not already foreground. 15740 if (!foregroundActivities && activitiesSize > 0) { 15741 for (int j = 0; j < activitiesSize; j++) { 15742 final ActivityRecord r = app.activities.get(j); 15743 if (r.app != app) { 15744 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15745 + app + "?!?"); 15746 continue; 15747 } 15748 if (r.visible) { 15749 // App has a visible activity; only upgrade adjustment. 15750 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15751 adj = ProcessList.VISIBLE_APP_ADJ; 15752 app.adjType = "visible"; 15753 } 15754 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15755 procState = ActivityManager.PROCESS_STATE_TOP; 15756 } 15757 schedGroup = Process.THREAD_GROUP_DEFAULT; 15758 app.cached = false; 15759 app.empty = false; 15760 foregroundActivities = true; 15761 break; 15762 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15763 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15764 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15765 app.adjType = "pausing"; 15766 } 15767 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15768 procState = ActivityManager.PROCESS_STATE_TOP; 15769 } 15770 schedGroup = Process.THREAD_GROUP_DEFAULT; 15771 app.cached = false; 15772 app.empty = false; 15773 foregroundActivities = true; 15774 } else if (r.state == ActivityState.STOPPING) { 15775 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15776 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15777 app.adjType = "stopping"; 15778 } 15779 // For the process state, we will at this point consider the 15780 // process to be cached. It will be cached either as an activity 15781 // or empty depending on whether the activity is finishing. We do 15782 // this so that we can treat the process as cached for purposes of 15783 // memory trimming (determing current memory level, trim command to 15784 // send to process) since there can be an arbitrary number of stopping 15785 // processes and they should soon all go into the cached state. 15786 if (!r.finishing) { 15787 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15788 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15789 } 15790 } 15791 app.cached = false; 15792 app.empty = false; 15793 foregroundActivities = true; 15794 } else { 15795 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15796 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15797 app.adjType = "cch-act"; 15798 } 15799 } 15800 } 15801 } 15802 15803 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15804 if (app.foregroundServices) { 15805 // The user is aware of this app, so make it visible. 15806 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15807 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15808 app.cached = false; 15809 app.adjType = "fg-service"; 15810 schedGroup = Process.THREAD_GROUP_DEFAULT; 15811 } else if (app.forcingToForeground != null) { 15812 // The user is aware of this app, so make it visible. 15813 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15814 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15815 app.cached = false; 15816 app.adjType = "force-fg"; 15817 app.adjSource = app.forcingToForeground; 15818 schedGroup = Process.THREAD_GROUP_DEFAULT; 15819 } 15820 } 15821 15822 if (app == mHeavyWeightProcess) { 15823 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15824 // We don't want to kill the current heavy-weight process. 15825 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15826 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15827 app.cached = false; 15828 app.adjType = "heavy"; 15829 } 15830 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15831 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15832 } 15833 } 15834 15835 if (app == mHomeProcess) { 15836 if (adj > ProcessList.HOME_APP_ADJ) { 15837 // This process is hosting what we currently consider to be the 15838 // home app, so we don't want to let it go into the background. 15839 adj = ProcessList.HOME_APP_ADJ; 15840 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15841 app.cached = false; 15842 app.adjType = "home"; 15843 } 15844 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15845 procState = ActivityManager.PROCESS_STATE_HOME; 15846 } 15847 } 15848 15849 if (app == mPreviousProcess && app.activities.size() > 0) { 15850 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15851 // This was the previous process that showed UI to the user. 15852 // We want to try to keep it around more aggressively, to give 15853 // a good experience around switching between two apps. 15854 adj = ProcessList.PREVIOUS_APP_ADJ; 15855 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15856 app.cached = false; 15857 app.adjType = "previous"; 15858 } 15859 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15860 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15861 } 15862 } 15863 15864 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15865 + " reason=" + app.adjType); 15866 15867 // By default, we use the computed adjustment. It may be changed if 15868 // there are applications dependent on our services or providers, but 15869 // this gives us a baseline and makes sure we don't get into an 15870 // infinite recursion. 15871 app.adjSeq = mAdjSeq; 15872 app.curRawAdj = adj; 15873 app.hasStartedServices = false; 15874 15875 if (mBackupTarget != null && app == mBackupTarget.app) { 15876 // If possible we want to avoid killing apps while they're being backed up 15877 if (adj > ProcessList.BACKUP_APP_ADJ) { 15878 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15879 adj = ProcessList.BACKUP_APP_ADJ; 15880 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15881 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15882 } 15883 app.adjType = "backup"; 15884 app.cached = false; 15885 } 15886 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15887 procState = ActivityManager.PROCESS_STATE_BACKUP; 15888 } 15889 } 15890 15891 boolean mayBeTop = false; 15892 15893 for (int is = app.services.size()-1; 15894 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15895 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15896 || procState > ActivityManager.PROCESS_STATE_TOP); 15897 is--) { 15898 ServiceRecord s = app.services.valueAt(is); 15899 if (s.startRequested) { 15900 app.hasStartedServices = true; 15901 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15902 procState = ActivityManager.PROCESS_STATE_SERVICE; 15903 } 15904 if (app.hasShownUi && app != mHomeProcess) { 15905 // If this process has shown some UI, let it immediately 15906 // go to the LRU list because it may be pretty heavy with 15907 // UI stuff. We'll tag it with a label just to help 15908 // debug and understand what is going on. 15909 if (adj > ProcessList.SERVICE_ADJ) { 15910 app.adjType = "cch-started-ui-services"; 15911 } 15912 } else { 15913 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15914 // This service has seen some activity within 15915 // recent memory, so we will keep its process ahead 15916 // of the background processes. 15917 if (adj > ProcessList.SERVICE_ADJ) { 15918 adj = ProcessList.SERVICE_ADJ; 15919 app.adjType = "started-services"; 15920 app.cached = false; 15921 } 15922 } 15923 // If we have let the service slide into the background 15924 // state, still have some text describing what it is doing 15925 // even though the service no longer has an impact. 15926 if (adj > ProcessList.SERVICE_ADJ) { 15927 app.adjType = "cch-started-services"; 15928 } 15929 } 15930 } 15931 for (int conni = s.connections.size()-1; 15932 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15933 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15934 || procState > ActivityManager.PROCESS_STATE_TOP); 15935 conni--) { 15936 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15937 for (int i = 0; 15938 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15940 || procState > ActivityManager.PROCESS_STATE_TOP); 15941 i++) { 15942 // XXX should compute this based on the max of 15943 // all connected clients. 15944 ConnectionRecord cr = clist.get(i); 15945 if (cr.binding.client == app) { 15946 // Binding to ourself is not interesting. 15947 continue; 15948 } 15949 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15950 ProcessRecord client = cr.binding.client; 15951 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15952 TOP_APP, doingAll, now); 15953 int clientProcState = client.curProcState; 15954 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15955 // If the other app is cached for any reason, for purposes here 15956 // we are going to consider it empty. The specific cached state 15957 // doesn't propagate except under certain conditions. 15958 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15959 } 15960 String adjType = null; 15961 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15962 // Not doing bind OOM management, so treat 15963 // this guy more like a started service. 15964 if (app.hasShownUi && app != mHomeProcess) { 15965 // If this process has shown some UI, let it immediately 15966 // go to the LRU list because it may be pretty heavy with 15967 // UI stuff. We'll tag it with a label just to help 15968 // debug and understand what is going on. 15969 if (adj > clientAdj) { 15970 adjType = "cch-bound-ui-services"; 15971 } 15972 app.cached = false; 15973 clientAdj = adj; 15974 clientProcState = procState; 15975 } else { 15976 if (now >= (s.lastActivity 15977 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15978 // This service has not seen activity within 15979 // recent memory, so allow it to drop to the 15980 // LRU list if there is no other reason to keep 15981 // it around. We'll also tag it with a label just 15982 // to help debug and undertand what is going on. 15983 if (adj > clientAdj) { 15984 adjType = "cch-bound-services"; 15985 } 15986 clientAdj = adj; 15987 } 15988 } 15989 } 15990 if (adj > clientAdj) { 15991 // If this process has recently shown UI, and 15992 // the process that is binding to it is less 15993 // important than being visible, then we don't 15994 // care about the binding as much as we care 15995 // about letting this process get into the LRU 15996 // list to be killed and restarted if needed for 15997 // memory. 15998 if (app.hasShownUi && app != mHomeProcess 15999 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16000 adjType = "cch-bound-ui-services"; 16001 } else { 16002 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16003 |Context.BIND_IMPORTANT)) != 0) { 16004 adj = clientAdj; 16005 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16006 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16007 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16008 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16009 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16010 adj = clientAdj; 16011 } else { 16012 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16013 adj = ProcessList.VISIBLE_APP_ADJ; 16014 } 16015 } 16016 if (!client.cached) { 16017 app.cached = false; 16018 } 16019 adjType = "service"; 16020 } 16021 } 16022 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16023 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16024 schedGroup = Process.THREAD_GROUP_DEFAULT; 16025 } 16026 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16027 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16028 // Special handling of clients who are in the top state. 16029 // We *may* want to consider this process to be in the 16030 // top state as well, but only if there is not another 16031 // reason for it to be running. Being on the top is a 16032 // special state, meaning you are specifically running 16033 // for the current top app. If the process is already 16034 // running in the background for some other reason, it 16035 // is more important to continue considering it to be 16036 // in the background state. 16037 mayBeTop = true; 16038 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16039 } else { 16040 // Special handling for above-top states (persistent 16041 // processes). These should not bring the current process 16042 // into the top state, since they are not on top. Instead 16043 // give them the best state after that. 16044 clientProcState = 16045 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16046 } 16047 } 16048 } else { 16049 if (clientProcState < 16050 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16051 clientProcState = 16052 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16053 } 16054 } 16055 if (procState > clientProcState) { 16056 procState = clientProcState; 16057 } 16058 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16059 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16060 app.pendingUiClean = true; 16061 } 16062 if (adjType != null) { 16063 app.adjType = adjType; 16064 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16065 .REASON_SERVICE_IN_USE; 16066 app.adjSource = cr.binding.client; 16067 app.adjSourceProcState = clientProcState; 16068 app.adjTarget = s.name; 16069 } 16070 } 16071 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16072 app.treatLikeActivity = true; 16073 } 16074 final ActivityRecord a = cr.activity; 16075 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16076 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16077 (a.visible || a.state == ActivityState.RESUMED 16078 || a.state == ActivityState.PAUSING)) { 16079 adj = ProcessList.FOREGROUND_APP_ADJ; 16080 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16081 schedGroup = Process.THREAD_GROUP_DEFAULT; 16082 } 16083 app.cached = false; 16084 app.adjType = "service"; 16085 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16086 .REASON_SERVICE_IN_USE; 16087 app.adjSource = a; 16088 app.adjSourceProcState = procState; 16089 app.adjTarget = s.name; 16090 } 16091 } 16092 } 16093 } 16094 } 16095 16096 for (int provi = app.pubProviders.size()-1; 16097 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16098 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16099 || procState > ActivityManager.PROCESS_STATE_TOP); 16100 provi--) { 16101 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16102 for (int i = cpr.connections.size()-1; 16103 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16104 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16105 || procState > ActivityManager.PROCESS_STATE_TOP); 16106 i--) { 16107 ContentProviderConnection conn = cpr.connections.get(i); 16108 ProcessRecord client = conn.client; 16109 if (client == app) { 16110 // Being our own client is not interesting. 16111 continue; 16112 } 16113 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16114 int clientProcState = client.curProcState; 16115 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16116 // If the other app is cached for any reason, for purposes here 16117 // we are going to consider it empty. 16118 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16119 } 16120 if (adj > clientAdj) { 16121 if (app.hasShownUi && app != mHomeProcess 16122 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16123 app.adjType = "cch-ui-provider"; 16124 } else { 16125 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16126 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16127 app.adjType = "provider"; 16128 } 16129 app.cached &= client.cached; 16130 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16131 .REASON_PROVIDER_IN_USE; 16132 app.adjSource = client; 16133 app.adjSourceProcState = clientProcState; 16134 app.adjTarget = cpr.name; 16135 } 16136 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16137 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16138 // Special handling of clients who are in the top state. 16139 // We *may* want to consider this process to be in the 16140 // top state as well, but only if there is not another 16141 // reason for it to be running. Being on the top is a 16142 // special state, meaning you are specifically running 16143 // for the current top app. If the process is already 16144 // running in the background for some other reason, it 16145 // is more important to continue considering it to be 16146 // in the background state. 16147 mayBeTop = true; 16148 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16149 } else { 16150 // Special handling for above-top states (persistent 16151 // processes). These should not bring the current process 16152 // into the top state, since they are not on top. Instead 16153 // give them the best state after that. 16154 clientProcState = 16155 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16156 } 16157 } 16158 if (procState > clientProcState) { 16159 procState = clientProcState; 16160 } 16161 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16162 schedGroup = Process.THREAD_GROUP_DEFAULT; 16163 } 16164 } 16165 // If the provider has external (non-framework) process 16166 // dependencies, ensure that its adjustment is at least 16167 // FOREGROUND_APP_ADJ. 16168 if (cpr.hasExternalProcessHandles()) { 16169 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16170 adj = ProcessList.FOREGROUND_APP_ADJ; 16171 schedGroup = Process.THREAD_GROUP_DEFAULT; 16172 app.cached = false; 16173 app.adjType = "provider"; 16174 app.adjTarget = cpr.name; 16175 } 16176 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16177 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16178 } 16179 } 16180 } 16181 16182 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16183 // A client of one of our services or providers is in the top state. We 16184 // *may* want to be in the top state, but not if we are already running in 16185 // the background for some other reason. For the decision here, we are going 16186 // to pick out a few specific states that we want to remain in when a client 16187 // is top (states that tend to be longer-term) and otherwise allow it to go 16188 // to the top state. 16189 switch (procState) { 16190 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16191 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16192 case ActivityManager.PROCESS_STATE_SERVICE: 16193 // These all are longer-term states, so pull them up to the top 16194 // of the background states, but not all the way to the top state. 16195 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16196 break; 16197 default: 16198 // Otherwise, top is a better choice, so take it. 16199 procState = ActivityManager.PROCESS_STATE_TOP; 16200 break; 16201 } 16202 } 16203 16204 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16205 if (app.hasClientActivities) { 16206 // This is a cached process, but with client activities. Mark it so. 16207 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16208 app.adjType = "cch-client-act"; 16209 } else if (app.treatLikeActivity) { 16210 // This is a cached process, but somebody wants us to treat it like it has 16211 // an activity, okay! 16212 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16213 app.adjType = "cch-as-act"; 16214 } 16215 } 16216 16217 if (adj == ProcessList.SERVICE_ADJ) { 16218 if (doingAll) { 16219 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16220 mNewNumServiceProcs++; 16221 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16222 if (!app.serviceb) { 16223 // This service isn't far enough down on the LRU list to 16224 // normally be a B service, but if we are low on RAM and it 16225 // is large we want to force it down since we would prefer to 16226 // keep launcher over it. 16227 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16228 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16229 app.serviceHighRam = true; 16230 app.serviceb = true; 16231 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16232 } else { 16233 mNewNumAServiceProcs++; 16234 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16235 } 16236 } else { 16237 app.serviceHighRam = false; 16238 } 16239 } 16240 if (app.serviceb) { 16241 adj = ProcessList.SERVICE_B_ADJ; 16242 } 16243 } 16244 16245 app.curRawAdj = adj; 16246 16247 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16248 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16249 if (adj > app.maxAdj) { 16250 adj = app.maxAdj; 16251 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16252 schedGroup = Process.THREAD_GROUP_DEFAULT; 16253 } 16254 } 16255 16256 // Do final modification to adj. Everything we do between here and applying 16257 // the final setAdj must be done in this function, because we will also use 16258 // it when computing the final cached adj later. Note that we don't need to 16259 // worry about this for max adj above, since max adj will always be used to 16260 // keep it out of the cached vaues. 16261 app.curAdj = app.modifyRawOomAdj(adj); 16262 app.curSchedGroup = schedGroup; 16263 app.curProcState = procState; 16264 app.foregroundActivities = foregroundActivities; 16265 16266 return app.curRawAdj; 16267 } 16268 16269 /** 16270 * Schedule PSS collection of a process. 16271 */ 16272 void requestPssLocked(ProcessRecord proc, int procState) { 16273 if (mPendingPssProcesses.contains(proc)) { 16274 return; 16275 } 16276 if (mPendingPssProcesses.size() == 0) { 16277 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16278 } 16279 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16280 proc.pssProcState = procState; 16281 mPendingPssProcesses.add(proc); 16282 } 16283 16284 /** 16285 * Schedule PSS collection of all processes. 16286 */ 16287 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16288 if (!always) { 16289 if (now < (mLastFullPssTime + 16290 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16291 return; 16292 } 16293 } 16294 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16295 mLastFullPssTime = now; 16296 mFullPssPending = true; 16297 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16298 mPendingPssProcesses.clear(); 16299 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16300 ProcessRecord app = mLruProcesses.get(i); 16301 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16302 app.pssProcState = app.setProcState; 16303 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16304 isSleeping(), now); 16305 mPendingPssProcesses.add(app); 16306 } 16307 } 16308 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16309 } 16310 16311 /** 16312 * Ask a given process to GC right now. 16313 */ 16314 final void performAppGcLocked(ProcessRecord app) { 16315 try { 16316 app.lastRequestedGc = SystemClock.uptimeMillis(); 16317 if (app.thread != null) { 16318 if (app.reportLowMemory) { 16319 app.reportLowMemory = false; 16320 app.thread.scheduleLowMemory(); 16321 } else { 16322 app.thread.processInBackground(); 16323 } 16324 } 16325 } catch (Exception e) { 16326 // whatever. 16327 } 16328 } 16329 16330 /** 16331 * Returns true if things are idle enough to perform GCs. 16332 */ 16333 private final boolean canGcNowLocked() { 16334 boolean processingBroadcasts = false; 16335 for (BroadcastQueue q : mBroadcastQueues) { 16336 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16337 processingBroadcasts = true; 16338 } 16339 } 16340 return !processingBroadcasts 16341 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16342 } 16343 16344 /** 16345 * Perform GCs on all processes that are waiting for it, but only 16346 * if things are idle. 16347 */ 16348 final void performAppGcsLocked() { 16349 final int N = mProcessesToGc.size(); 16350 if (N <= 0) { 16351 return; 16352 } 16353 if (canGcNowLocked()) { 16354 while (mProcessesToGc.size() > 0) { 16355 ProcessRecord proc = mProcessesToGc.remove(0); 16356 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16357 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16358 <= SystemClock.uptimeMillis()) { 16359 // To avoid spamming the system, we will GC processes one 16360 // at a time, waiting a few seconds between each. 16361 performAppGcLocked(proc); 16362 scheduleAppGcsLocked(); 16363 return; 16364 } else { 16365 // It hasn't been long enough since we last GCed this 16366 // process... put it in the list to wait for its time. 16367 addProcessToGcListLocked(proc); 16368 break; 16369 } 16370 } 16371 } 16372 16373 scheduleAppGcsLocked(); 16374 } 16375 } 16376 16377 /** 16378 * If all looks good, perform GCs on all processes waiting for them. 16379 */ 16380 final void performAppGcsIfAppropriateLocked() { 16381 if (canGcNowLocked()) { 16382 performAppGcsLocked(); 16383 return; 16384 } 16385 // Still not idle, wait some more. 16386 scheduleAppGcsLocked(); 16387 } 16388 16389 /** 16390 * Schedule the execution of all pending app GCs. 16391 */ 16392 final void scheduleAppGcsLocked() { 16393 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16394 16395 if (mProcessesToGc.size() > 0) { 16396 // Schedule a GC for the time to the next process. 16397 ProcessRecord proc = mProcessesToGc.get(0); 16398 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16399 16400 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16401 long now = SystemClock.uptimeMillis(); 16402 if (when < (now+GC_TIMEOUT)) { 16403 when = now + GC_TIMEOUT; 16404 } 16405 mHandler.sendMessageAtTime(msg, when); 16406 } 16407 } 16408 16409 /** 16410 * Add a process to the array of processes waiting to be GCed. Keeps the 16411 * list in sorted order by the last GC time. The process can't already be 16412 * on the list. 16413 */ 16414 final void addProcessToGcListLocked(ProcessRecord proc) { 16415 boolean added = false; 16416 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16417 if (mProcessesToGc.get(i).lastRequestedGc < 16418 proc.lastRequestedGc) { 16419 added = true; 16420 mProcessesToGc.add(i+1, proc); 16421 break; 16422 } 16423 } 16424 if (!added) { 16425 mProcessesToGc.add(0, proc); 16426 } 16427 } 16428 16429 /** 16430 * Set up to ask a process to GC itself. This will either do it 16431 * immediately, or put it on the list of processes to gc the next 16432 * time things are idle. 16433 */ 16434 final void scheduleAppGcLocked(ProcessRecord app) { 16435 long now = SystemClock.uptimeMillis(); 16436 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16437 return; 16438 } 16439 if (!mProcessesToGc.contains(app)) { 16440 addProcessToGcListLocked(app); 16441 scheduleAppGcsLocked(); 16442 } 16443 } 16444 16445 final void checkExcessivePowerUsageLocked(boolean doKills) { 16446 updateCpuStatsNow(); 16447 16448 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16449 boolean doWakeKills = doKills; 16450 boolean doCpuKills = doKills; 16451 if (mLastPowerCheckRealtime == 0) { 16452 doWakeKills = false; 16453 } 16454 if (mLastPowerCheckUptime == 0) { 16455 doCpuKills = false; 16456 } 16457 if (stats.isScreenOn()) { 16458 doWakeKills = false; 16459 } 16460 final long curRealtime = SystemClock.elapsedRealtime(); 16461 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16462 final long curUptime = SystemClock.uptimeMillis(); 16463 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16464 mLastPowerCheckRealtime = curRealtime; 16465 mLastPowerCheckUptime = curUptime; 16466 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16467 doWakeKills = false; 16468 } 16469 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16470 doCpuKills = false; 16471 } 16472 int i = mLruProcesses.size(); 16473 while (i > 0) { 16474 i--; 16475 ProcessRecord app = mLruProcesses.get(i); 16476 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16477 long wtime; 16478 synchronized (stats) { 16479 wtime = stats.getProcessWakeTime(app.info.uid, 16480 app.pid, curRealtime); 16481 } 16482 long wtimeUsed = wtime - app.lastWakeTime; 16483 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16484 if (DEBUG_POWER) { 16485 StringBuilder sb = new StringBuilder(128); 16486 sb.append("Wake for "); 16487 app.toShortString(sb); 16488 sb.append(": over "); 16489 TimeUtils.formatDuration(realtimeSince, sb); 16490 sb.append(" used "); 16491 TimeUtils.formatDuration(wtimeUsed, sb); 16492 sb.append(" ("); 16493 sb.append((wtimeUsed*100)/realtimeSince); 16494 sb.append("%)"); 16495 Slog.i(TAG, sb.toString()); 16496 sb.setLength(0); 16497 sb.append("CPU for "); 16498 app.toShortString(sb); 16499 sb.append(": over "); 16500 TimeUtils.formatDuration(uptimeSince, sb); 16501 sb.append(" used "); 16502 TimeUtils.formatDuration(cputimeUsed, sb); 16503 sb.append(" ("); 16504 sb.append((cputimeUsed*100)/uptimeSince); 16505 sb.append("%)"); 16506 Slog.i(TAG, sb.toString()); 16507 } 16508 // If a process has held a wake lock for more 16509 // than 50% of the time during this period, 16510 // that sounds bad. Kill! 16511 if (doWakeKills && realtimeSince > 0 16512 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16513 synchronized (stats) { 16514 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16515 realtimeSince, wtimeUsed); 16516 } 16517 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16518 + " during " + realtimeSince); 16519 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16520 } else if (doCpuKills && uptimeSince > 0 16521 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16522 synchronized (stats) { 16523 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16524 uptimeSince, cputimeUsed); 16525 } 16526 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16527 + " during " + uptimeSince); 16528 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16529 } else { 16530 app.lastWakeTime = wtime; 16531 app.lastCpuTime = app.curCpuTime; 16532 } 16533 } 16534 } 16535 } 16536 16537 private final boolean applyOomAdjLocked(ProcessRecord app, 16538 ProcessRecord TOP_APP, boolean doingAll, long now) { 16539 boolean success = true; 16540 16541 if (app.curRawAdj != app.setRawAdj) { 16542 app.setRawAdj = app.curRawAdj; 16543 } 16544 16545 int changes = 0; 16546 16547 if (app.curAdj != app.setAdj) { 16548 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16549 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16550 TAG, "Set " + app.pid + " " + app.processName + 16551 " adj " + app.curAdj + ": " + app.adjType); 16552 app.setAdj = app.curAdj; 16553 } 16554 16555 if (app.setSchedGroup != app.curSchedGroup) { 16556 app.setSchedGroup = app.curSchedGroup; 16557 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16558 "Setting process group of " + app.processName 16559 + " to " + app.curSchedGroup); 16560 if (app.waitingToKill != null && 16561 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16562 killUnneededProcessLocked(app, app.waitingToKill); 16563 success = false; 16564 } else { 16565 if (true) { 16566 long oldId = Binder.clearCallingIdentity(); 16567 try { 16568 Process.setProcessGroup(app.pid, app.curSchedGroup); 16569 } catch (Exception e) { 16570 Slog.w(TAG, "Failed setting process group of " + app.pid 16571 + " to " + app.curSchedGroup); 16572 e.printStackTrace(); 16573 } finally { 16574 Binder.restoreCallingIdentity(oldId); 16575 } 16576 } else { 16577 if (app.thread != null) { 16578 try { 16579 app.thread.setSchedulingGroup(app.curSchedGroup); 16580 } catch (RemoteException e) { 16581 } 16582 } 16583 } 16584 Process.setSwappiness(app.pid, 16585 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16586 } 16587 } 16588 if (app.repForegroundActivities != app.foregroundActivities) { 16589 app.repForegroundActivities = app.foregroundActivities; 16590 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16591 } 16592 if (app.repProcState != app.curProcState) { 16593 app.repProcState = app.curProcState; 16594 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16595 if (app.thread != null) { 16596 try { 16597 if (false) { 16598 //RuntimeException h = new RuntimeException("here"); 16599 Slog.i(TAG, "Sending new process state " + app.repProcState 16600 + " to " + app /*, h*/); 16601 } 16602 app.thread.setProcessState(app.repProcState); 16603 } catch (RemoteException e) { 16604 } 16605 } 16606 } 16607 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16608 app.setProcState)) { 16609 app.lastStateTime = now; 16610 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16611 isSleeping(), now); 16612 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16613 + ProcessList.makeProcStateString(app.setProcState) + " to " 16614 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16615 + (app.nextPssTime-now) + ": " + app); 16616 } else { 16617 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16618 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16619 requestPssLocked(app, app.setProcState); 16620 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16621 isSleeping(), now); 16622 } else if (false && DEBUG_PSS) { 16623 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16624 } 16625 } 16626 if (app.setProcState != app.curProcState) { 16627 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16628 "Proc state change of " + app.processName 16629 + " to " + app.curProcState); 16630 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16631 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16632 if (setImportant && !curImportant) { 16633 // This app is no longer something we consider important enough to allow to 16634 // use arbitrary amounts of battery power. Note 16635 // its current wake lock time to later know to kill it if 16636 // it is not behaving well. 16637 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16638 synchronized (stats) { 16639 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16640 app.pid, SystemClock.elapsedRealtime()); 16641 } 16642 app.lastCpuTime = app.curCpuTime; 16643 16644 } 16645 app.setProcState = app.curProcState; 16646 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16647 app.notCachedSinceIdle = false; 16648 } 16649 if (!doingAll) { 16650 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16651 } else { 16652 app.procStateChanged = true; 16653 } 16654 } 16655 16656 if (changes != 0) { 16657 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16658 int i = mPendingProcessChanges.size()-1; 16659 ProcessChangeItem item = null; 16660 while (i >= 0) { 16661 item = mPendingProcessChanges.get(i); 16662 if (item.pid == app.pid) { 16663 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16664 break; 16665 } 16666 i--; 16667 } 16668 if (i < 0) { 16669 // No existing item in pending changes; need a new one. 16670 final int NA = mAvailProcessChanges.size(); 16671 if (NA > 0) { 16672 item = mAvailProcessChanges.remove(NA-1); 16673 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16674 } else { 16675 item = new ProcessChangeItem(); 16676 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16677 } 16678 item.changes = 0; 16679 item.pid = app.pid; 16680 item.uid = app.info.uid; 16681 if (mPendingProcessChanges.size() == 0) { 16682 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16683 "*** Enqueueing dispatch processes changed!"); 16684 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16685 } 16686 mPendingProcessChanges.add(item); 16687 } 16688 item.changes |= changes; 16689 item.processState = app.repProcState; 16690 item.foregroundActivities = app.repForegroundActivities; 16691 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16692 + Integer.toHexString(System.identityHashCode(item)) 16693 + " " + app.toShortString() + ": changes=" + item.changes 16694 + " procState=" + item.processState 16695 + " foreground=" + item.foregroundActivities 16696 + " type=" + app.adjType + " source=" + app.adjSource 16697 + " target=" + app.adjTarget); 16698 } 16699 16700 return success; 16701 } 16702 16703 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16704 if (proc.thread != null) { 16705 if (proc.baseProcessTracker != null) { 16706 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16707 } 16708 if (proc.repProcState >= 0) { 16709 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16710 proc.repProcState); 16711 } 16712 } 16713 } 16714 16715 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16716 ProcessRecord TOP_APP, boolean doingAll, long now) { 16717 if (app.thread == null) { 16718 return false; 16719 } 16720 16721 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16722 16723 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16724 } 16725 16726 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16727 boolean oomAdj) { 16728 if (isForeground != proc.foregroundServices) { 16729 proc.foregroundServices = isForeground; 16730 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16731 proc.info.uid); 16732 if (isForeground) { 16733 if (curProcs == null) { 16734 curProcs = new ArrayList<ProcessRecord>(); 16735 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16736 } 16737 if (!curProcs.contains(proc)) { 16738 curProcs.add(proc); 16739 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16740 proc.info.packageName, proc.info.uid); 16741 } 16742 } else { 16743 if (curProcs != null) { 16744 if (curProcs.remove(proc)) { 16745 mBatteryStatsService.noteEvent( 16746 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16747 proc.info.packageName, proc.info.uid); 16748 if (curProcs.size() <= 0) { 16749 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16750 } 16751 } 16752 } 16753 } 16754 if (oomAdj) { 16755 updateOomAdjLocked(); 16756 } 16757 } 16758 } 16759 16760 private final ActivityRecord resumedAppLocked() { 16761 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16762 String pkg; 16763 int uid; 16764 if (act != null) { 16765 pkg = act.packageName; 16766 uid = act.info.applicationInfo.uid; 16767 } else { 16768 pkg = null; 16769 uid = -1; 16770 } 16771 // Has the UID or resumed package name changed? 16772 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16773 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16774 if (mCurResumedPackage != null) { 16775 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16776 mCurResumedPackage, mCurResumedUid); 16777 } 16778 mCurResumedPackage = pkg; 16779 mCurResumedUid = uid; 16780 if (mCurResumedPackage != null) { 16781 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16782 mCurResumedPackage, mCurResumedUid); 16783 } 16784 } 16785 return act; 16786 } 16787 16788 final boolean updateOomAdjLocked(ProcessRecord app) { 16789 final ActivityRecord TOP_ACT = resumedAppLocked(); 16790 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16791 final boolean wasCached = app.cached; 16792 16793 mAdjSeq++; 16794 16795 // This is the desired cached adjusment we want to tell it to use. 16796 // If our app is currently cached, we know it, and that is it. Otherwise, 16797 // we don't know it yet, and it needs to now be cached we will then 16798 // need to do a complete oom adj. 16799 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16800 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16801 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16802 SystemClock.uptimeMillis()); 16803 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16804 // Changed to/from cached state, so apps after it in the LRU 16805 // list may also be changed. 16806 updateOomAdjLocked(); 16807 } 16808 return success; 16809 } 16810 16811 final void updateOomAdjLocked() { 16812 final ActivityRecord TOP_ACT = resumedAppLocked(); 16813 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16814 final long now = SystemClock.uptimeMillis(); 16815 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16816 final int N = mLruProcesses.size(); 16817 16818 if (false) { 16819 RuntimeException e = new RuntimeException(); 16820 e.fillInStackTrace(); 16821 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16822 } 16823 16824 mAdjSeq++; 16825 mNewNumServiceProcs = 0; 16826 mNewNumAServiceProcs = 0; 16827 16828 final int emptyProcessLimit; 16829 final int cachedProcessLimit; 16830 if (mProcessLimit <= 0) { 16831 emptyProcessLimit = cachedProcessLimit = 0; 16832 } else if (mProcessLimit == 1) { 16833 emptyProcessLimit = 1; 16834 cachedProcessLimit = 0; 16835 } else { 16836 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16837 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16838 } 16839 16840 // Let's determine how many processes we have running vs. 16841 // how many slots we have for background processes; we may want 16842 // to put multiple processes in a slot of there are enough of 16843 // them. 16844 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16845 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16846 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16847 if (numEmptyProcs > cachedProcessLimit) { 16848 // If there are more empty processes than our limit on cached 16849 // processes, then use the cached process limit for the factor. 16850 // This ensures that the really old empty processes get pushed 16851 // down to the bottom, so if we are running low on memory we will 16852 // have a better chance at keeping around more cached processes 16853 // instead of a gazillion empty processes. 16854 numEmptyProcs = cachedProcessLimit; 16855 } 16856 int emptyFactor = numEmptyProcs/numSlots; 16857 if (emptyFactor < 1) emptyFactor = 1; 16858 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16859 if (cachedFactor < 1) cachedFactor = 1; 16860 int stepCached = 0; 16861 int stepEmpty = 0; 16862 int numCached = 0; 16863 int numEmpty = 0; 16864 int numTrimming = 0; 16865 16866 mNumNonCachedProcs = 0; 16867 mNumCachedHiddenProcs = 0; 16868 16869 // First update the OOM adjustment for each of the 16870 // application processes based on their current state. 16871 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16872 int nextCachedAdj = curCachedAdj+1; 16873 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16874 int nextEmptyAdj = curEmptyAdj+2; 16875 for (int i=N-1; i>=0; i--) { 16876 ProcessRecord app = mLruProcesses.get(i); 16877 if (!app.killedByAm && app.thread != null) { 16878 app.procStateChanged = false; 16879 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16880 16881 // If we haven't yet assigned the final cached adj 16882 // to the process, do that now. 16883 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16884 switch (app.curProcState) { 16885 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16886 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16887 // This process is a cached process holding activities... 16888 // assign it the next cached value for that type, and then 16889 // step that cached level. 16890 app.curRawAdj = curCachedAdj; 16891 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16892 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16893 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16894 + ")"); 16895 if (curCachedAdj != nextCachedAdj) { 16896 stepCached++; 16897 if (stepCached >= cachedFactor) { 16898 stepCached = 0; 16899 curCachedAdj = nextCachedAdj; 16900 nextCachedAdj += 2; 16901 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16902 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16903 } 16904 } 16905 } 16906 break; 16907 default: 16908 // For everything else, assign next empty cached process 16909 // level and bump that up. Note that this means that 16910 // long-running services that have dropped down to the 16911 // cached level will be treated as empty (since their process 16912 // state is still as a service), which is what we want. 16913 app.curRawAdj = curEmptyAdj; 16914 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16915 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16916 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16917 + ")"); 16918 if (curEmptyAdj != nextEmptyAdj) { 16919 stepEmpty++; 16920 if (stepEmpty >= emptyFactor) { 16921 stepEmpty = 0; 16922 curEmptyAdj = nextEmptyAdj; 16923 nextEmptyAdj += 2; 16924 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16925 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16926 } 16927 } 16928 } 16929 break; 16930 } 16931 } 16932 16933 applyOomAdjLocked(app, TOP_APP, true, now); 16934 16935 // Count the number of process types. 16936 switch (app.curProcState) { 16937 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16938 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16939 mNumCachedHiddenProcs++; 16940 numCached++; 16941 if (numCached > cachedProcessLimit) { 16942 killUnneededProcessLocked(app, "cached #" + numCached); 16943 } 16944 break; 16945 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16946 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16947 && app.lastActivityTime < oldTime) { 16948 killUnneededProcessLocked(app, "empty for " 16949 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16950 / 1000) + "s"); 16951 } else { 16952 numEmpty++; 16953 if (numEmpty > emptyProcessLimit) { 16954 killUnneededProcessLocked(app, "empty #" + numEmpty); 16955 } 16956 } 16957 break; 16958 default: 16959 mNumNonCachedProcs++; 16960 break; 16961 } 16962 16963 if (app.isolated && app.services.size() <= 0) { 16964 // If this is an isolated process, and there are no 16965 // services running in it, then the process is no longer 16966 // needed. We agressively kill these because we can by 16967 // definition not re-use the same process again, and it is 16968 // good to avoid having whatever code was running in them 16969 // left sitting around after no longer needed. 16970 killUnneededProcessLocked(app, "isolated not needed"); 16971 } 16972 16973 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16974 && !app.killedByAm) { 16975 numTrimming++; 16976 } 16977 } 16978 } 16979 16980 mNumServiceProcs = mNewNumServiceProcs; 16981 16982 // Now determine the memory trimming level of background processes. 16983 // Unfortunately we need to start at the back of the list to do this 16984 // properly. We only do this if the number of background apps we 16985 // are managing to keep around is less than half the maximum we desire; 16986 // if we are keeping a good number around, we'll let them use whatever 16987 // memory they want. 16988 final int numCachedAndEmpty = numCached + numEmpty; 16989 int memFactor; 16990 if (numCached <= ProcessList.TRIM_CACHED_APPS 16991 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16992 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16993 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16994 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16995 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16996 } else { 16997 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16998 } 16999 } else { 17000 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17001 } 17002 // We always allow the memory level to go up (better). We only allow it to go 17003 // down if we are in a state where that is allowed, *and* the total number of processes 17004 // has gone down since last time. 17005 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17006 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17007 + " last=" + mLastNumProcesses); 17008 if (memFactor > mLastMemoryLevel) { 17009 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17010 memFactor = mLastMemoryLevel; 17011 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17012 } 17013 } 17014 mLastMemoryLevel = memFactor; 17015 mLastNumProcesses = mLruProcesses.size(); 17016 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17017 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17018 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17019 if (mLowRamStartTime == 0) { 17020 mLowRamStartTime = now; 17021 } 17022 int step = 0; 17023 int fgTrimLevel; 17024 switch (memFactor) { 17025 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17026 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17027 break; 17028 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17029 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17030 break; 17031 default: 17032 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17033 break; 17034 } 17035 int factor = numTrimming/3; 17036 int minFactor = 2; 17037 if (mHomeProcess != null) minFactor++; 17038 if (mPreviousProcess != null) minFactor++; 17039 if (factor < minFactor) factor = minFactor; 17040 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17041 for (int i=N-1; i>=0; i--) { 17042 ProcessRecord app = mLruProcesses.get(i); 17043 if (allChanged || app.procStateChanged) { 17044 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17045 app.procStateChanged = false; 17046 } 17047 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17048 && !app.killedByAm) { 17049 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17050 try { 17051 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17052 "Trimming memory of " + app.processName 17053 + " to " + curLevel); 17054 app.thread.scheduleTrimMemory(curLevel); 17055 } catch (RemoteException e) { 17056 } 17057 if (false) { 17058 // For now we won't do this; our memory trimming seems 17059 // to be good enough at this point that destroying 17060 // activities causes more harm than good. 17061 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17062 && app != mHomeProcess && app != mPreviousProcess) { 17063 // Need to do this on its own message because the stack may not 17064 // be in a consistent state at this point. 17065 // For these apps we will also finish their activities 17066 // to help them free memory. 17067 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17068 } 17069 } 17070 } 17071 app.trimMemoryLevel = curLevel; 17072 step++; 17073 if (step >= factor) { 17074 step = 0; 17075 switch (curLevel) { 17076 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17077 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17078 break; 17079 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17080 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17081 break; 17082 } 17083 } 17084 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17085 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17086 && app.thread != null) { 17087 try { 17088 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17089 "Trimming memory of heavy-weight " + app.processName 17090 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17091 app.thread.scheduleTrimMemory( 17092 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17093 } catch (RemoteException e) { 17094 } 17095 } 17096 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17097 } else { 17098 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17099 || app.systemNoUi) && app.pendingUiClean) { 17100 // If this application is now in the background and it 17101 // had done UI, then give it the special trim level to 17102 // have it free UI resources. 17103 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17104 if (app.trimMemoryLevel < level && app.thread != null) { 17105 try { 17106 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17107 "Trimming memory of bg-ui " + app.processName 17108 + " to " + level); 17109 app.thread.scheduleTrimMemory(level); 17110 } catch (RemoteException e) { 17111 } 17112 } 17113 app.pendingUiClean = false; 17114 } 17115 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17116 try { 17117 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17118 "Trimming memory of fg " + app.processName 17119 + " to " + fgTrimLevel); 17120 app.thread.scheduleTrimMemory(fgTrimLevel); 17121 } catch (RemoteException e) { 17122 } 17123 } 17124 app.trimMemoryLevel = fgTrimLevel; 17125 } 17126 } 17127 } else { 17128 if (mLowRamStartTime != 0) { 17129 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17130 mLowRamStartTime = 0; 17131 } 17132 for (int i=N-1; i>=0; i--) { 17133 ProcessRecord app = mLruProcesses.get(i); 17134 if (allChanged || app.procStateChanged) { 17135 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17136 app.procStateChanged = false; 17137 } 17138 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17139 || app.systemNoUi) && app.pendingUiClean) { 17140 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17141 && app.thread != null) { 17142 try { 17143 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17144 "Trimming memory of ui hidden " + app.processName 17145 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17146 app.thread.scheduleTrimMemory( 17147 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17148 } catch (RemoteException e) { 17149 } 17150 } 17151 app.pendingUiClean = false; 17152 } 17153 app.trimMemoryLevel = 0; 17154 } 17155 } 17156 17157 if (mAlwaysFinishActivities) { 17158 // Need to do this on its own message because the stack may not 17159 // be in a consistent state at this point. 17160 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17161 } 17162 17163 if (allChanged) { 17164 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17165 } 17166 17167 if (mProcessStats.shouldWriteNowLocked(now)) { 17168 mHandler.post(new Runnable() { 17169 @Override public void run() { 17170 synchronized (ActivityManagerService.this) { 17171 mProcessStats.writeStateAsyncLocked(); 17172 } 17173 } 17174 }); 17175 } 17176 17177 if (DEBUG_OOM_ADJ) { 17178 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17179 } 17180 } 17181 17182 final void trimApplications() { 17183 synchronized (this) { 17184 int i; 17185 17186 // First remove any unused application processes whose package 17187 // has been removed. 17188 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17189 final ProcessRecord app = mRemovedProcesses.get(i); 17190 if (app.activities.size() == 0 17191 && app.curReceiver == null && app.services.size() == 0) { 17192 Slog.i( 17193 TAG, "Exiting empty application process " 17194 + app.processName + " (" 17195 + (app.thread != null ? app.thread.asBinder() : null) 17196 + ")\n"); 17197 if (app.pid > 0 && app.pid != MY_PID) { 17198 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 17199 app.processName, app.setAdj, "empty"); 17200 app.killedByAm = true; 17201 Process.killProcessQuiet(app.pid); 17202 Process.killProcessGroup(app.info.uid, app.pid); 17203 } else { 17204 try { 17205 app.thread.scheduleExit(); 17206 } catch (Exception e) { 17207 // Ignore exceptions. 17208 } 17209 } 17210 cleanUpApplicationRecordLocked(app, false, true, -1); 17211 mRemovedProcesses.remove(i); 17212 17213 if (app.persistent) { 17214 addAppLocked(app.info, false, null /* ABI override */); 17215 } 17216 } 17217 } 17218 17219 // Now update the oom adj for all processes. 17220 updateOomAdjLocked(); 17221 } 17222 } 17223 17224 /** This method sends the specified signal to each of the persistent apps */ 17225 public void signalPersistentProcesses(int sig) throws RemoteException { 17226 if (sig != Process.SIGNAL_USR1) { 17227 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17228 } 17229 17230 synchronized (this) { 17231 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17232 != PackageManager.PERMISSION_GRANTED) { 17233 throw new SecurityException("Requires permission " 17234 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17235 } 17236 17237 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17238 ProcessRecord r = mLruProcesses.get(i); 17239 if (r.thread != null && r.persistent) { 17240 Process.sendSignal(r.pid, sig); 17241 } 17242 } 17243 } 17244 } 17245 17246 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 17247 if (proc == null || proc == mProfileProc) { 17248 proc = mProfileProc; 17249 path = mProfileFile; 17250 profileType = mProfileType; 17251 clearProfilerLocked(); 17252 } 17253 if (proc == null) { 17254 return; 17255 } 17256 try { 17257 proc.thread.profilerControl(false, path, null, profileType); 17258 } catch (RemoteException e) { 17259 throw new IllegalStateException("Process disappeared"); 17260 } 17261 } 17262 17263 private void clearProfilerLocked() { 17264 if (mProfileFd != null) { 17265 try { 17266 mProfileFd.close(); 17267 } catch (IOException e) { 17268 } 17269 } 17270 mProfileApp = null; 17271 mProfileProc = null; 17272 mProfileFile = null; 17273 mProfileType = 0; 17274 mAutoStopProfiler = false; 17275 } 17276 17277 public boolean profileControl(String process, int userId, boolean start, 17278 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 17279 17280 try { 17281 synchronized (this) { 17282 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17283 // its own permission. 17284 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17285 != PackageManager.PERMISSION_GRANTED) { 17286 throw new SecurityException("Requires permission " 17287 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17288 } 17289 17290 if (start && fd == null) { 17291 throw new IllegalArgumentException("null fd"); 17292 } 17293 17294 ProcessRecord proc = null; 17295 if (process != null) { 17296 proc = findProcessLocked(process, userId, "profileControl"); 17297 } 17298 17299 if (start && (proc == null || proc.thread == null)) { 17300 throw new IllegalArgumentException("Unknown process: " + process); 17301 } 17302 17303 if (start) { 17304 stopProfilerLocked(null, null, 0); 17305 setProfileApp(proc.info, proc.processName, path, fd, false); 17306 mProfileProc = proc; 17307 mProfileType = profileType; 17308 try { 17309 fd = fd.dup(); 17310 } catch (IOException e) { 17311 fd = null; 17312 } 17313 proc.thread.profilerControl(start, path, fd, profileType); 17314 fd = null; 17315 mProfileFd = null; 17316 } else { 17317 stopProfilerLocked(proc, path, profileType); 17318 if (fd != null) { 17319 try { 17320 fd.close(); 17321 } catch (IOException e) { 17322 } 17323 } 17324 } 17325 17326 return true; 17327 } 17328 } catch (RemoteException e) { 17329 throw new IllegalStateException("Process disappeared"); 17330 } finally { 17331 if (fd != null) { 17332 try { 17333 fd.close(); 17334 } catch (IOException e) { 17335 } 17336 } 17337 } 17338 } 17339 17340 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17341 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17342 userId, true, ALLOW_FULL_ONLY, callName, null); 17343 ProcessRecord proc = null; 17344 try { 17345 int pid = Integer.parseInt(process); 17346 synchronized (mPidsSelfLocked) { 17347 proc = mPidsSelfLocked.get(pid); 17348 } 17349 } catch (NumberFormatException e) { 17350 } 17351 17352 if (proc == null) { 17353 ArrayMap<String, SparseArray<ProcessRecord>> all 17354 = mProcessNames.getMap(); 17355 SparseArray<ProcessRecord> procs = all.get(process); 17356 if (procs != null && procs.size() > 0) { 17357 proc = procs.valueAt(0); 17358 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17359 for (int i=1; i<procs.size(); i++) { 17360 ProcessRecord thisProc = procs.valueAt(i); 17361 if (thisProc.userId == userId) { 17362 proc = thisProc; 17363 break; 17364 } 17365 } 17366 } 17367 } 17368 } 17369 17370 return proc; 17371 } 17372 17373 public boolean dumpHeap(String process, int userId, boolean managed, 17374 String path, ParcelFileDescriptor fd) throws RemoteException { 17375 17376 try { 17377 synchronized (this) { 17378 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17379 // its own permission (same as profileControl). 17380 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17381 != PackageManager.PERMISSION_GRANTED) { 17382 throw new SecurityException("Requires permission " 17383 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17384 } 17385 17386 if (fd == null) { 17387 throw new IllegalArgumentException("null fd"); 17388 } 17389 17390 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17391 if (proc == null || proc.thread == null) { 17392 throw new IllegalArgumentException("Unknown process: " + process); 17393 } 17394 17395 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17396 if (!isDebuggable) { 17397 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17398 throw new SecurityException("Process not debuggable: " + proc); 17399 } 17400 } 17401 17402 proc.thread.dumpHeap(managed, path, fd); 17403 fd = null; 17404 return true; 17405 } 17406 } catch (RemoteException e) { 17407 throw new IllegalStateException("Process disappeared"); 17408 } finally { 17409 if (fd != null) { 17410 try { 17411 fd.close(); 17412 } catch (IOException e) { 17413 } 17414 } 17415 } 17416 } 17417 17418 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17419 public void monitor() { 17420 synchronized (this) { } 17421 } 17422 17423 void onCoreSettingsChange(Bundle settings) { 17424 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17425 ProcessRecord processRecord = mLruProcesses.get(i); 17426 try { 17427 if (processRecord.thread != null) { 17428 processRecord.thread.setCoreSettings(settings); 17429 } 17430 } catch (RemoteException re) { 17431 /* ignore */ 17432 } 17433 } 17434 } 17435 17436 // Multi-user methods 17437 17438 /** 17439 * Start user, if its not already running, but don't bring it to foreground. 17440 */ 17441 @Override 17442 public boolean startUserInBackground(final int userId) { 17443 return startUser(userId, /* foreground */ false); 17444 } 17445 17446 /** 17447 * Start user, if its not already running, and bring it to foreground. 17448 */ 17449 boolean startUserInForeground(final int userId, Dialog dlg) { 17450 boolean result = startUser(userId, /* foreground */ true); 17451 dlg.dismiss(); 17452 return result; 17453 } 17454 17455 /** 17456 * Refreshes the list of users related to the current user when either a 17457 * user switch happens or when a new related user is started in the 17458 * background. 17459 */ 17460 private void updateCurrentProfileIdsLocked() { 17461 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17462 mCurrentUserId, false /* enabledOnly */); 17463 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17464 for (int i = 0; i < currentProfileIds.length; i++) { 17465 currentProfileIds[i] = profiles.get(i).id; 17466 } 17467 mCurrentProfileIds = currentProfileIds; 17468 17469 synchronized (mUserProfileGroupIdsSelfLocked) { 17470 mUserProfileGroupIdsSelfLocked.clear(); 17471 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17472 for (int i = 0; i < users.size(); i++) { 17473 UserInfo user = users.get(i); 17474 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17475 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17476 } 17477 } 17478 } 17479 } 17480 17481 private Set getProfileIdsLocked(int userId) { 17482 Set userIds = new HashSet<Integer>(); 17483 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17484 userId, false /* enabledOnly */); 17485 for (UserInfo user : profiles) { 17486 userIds.add(Integer.valueOf(user.id)); 17487 } 17488 return userIds; 17489 } 17490 17491 @Override 17492 public boolean switchUser(final int userId) { 17493 String userName; 17494 synchronized (this) { 17495 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17496 if (userInfo == null) { 17497 Slog.w(TAG, "No user info for user #" + userId); 17498 return false; 17499 } 17500 if (userInfo.isManagedProfile()) { 17501 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17502 return false; 17503 } 17504 userName = userInfo.name; 17505 } 17506 mHandler.removeMessages(START_USER_SWITCH_MSG); 17507 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17508 return true; 17509 } 17510 17511 private void showUserSwitchDialog(int userId, String userName) { 17512 // The dialog will show and then initiate the user switch by calling startUserInForeground 17513 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17514 true /* above system */); 17515 d.show(); 17516 } 17517 17518 private boolean startUser(final int userId, boolean foreground) { 17519 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17520 != PackageManager.PERMISSION_GRANTED) { 17521 String msg = "Permission Denial: switchUser() from pid=" 17522 + Binder.getCallingPid() 17523 + ", uid=" + Binder.getCallingUid() 17524 + " requires " + INTERACT_ACROSS_USERS_FULL; 17525 Slog.w(TAG, msg); 17526 throw new SecurityException(msg); 17527 } 17528 17529 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17530 17531 final long ident = Binder.clearCallingIdentity(); 17532 try { 17533 synchronized (this) { 17534 final int oldUserId = mCurrentUserId; 17535 if (oldUserId == userId) { 17536 return true; 17537 } 17538 17539 mStackSupervisor.setLockTaskModeLocked(null, false); 17540 17541 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17542 if (userInfo == null) { 17543 Slog.w(TAG, "No user info for user #" + userId); 17544 return false; 17545 } 17546 if (foreground && userInfo.isManagedProfile()) { 17547 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17548 return false; 17549 } 17550 17551 if (foreground) { 17552 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17553 R.anim.screen_user_enter); 17554 } 17555 17556 boolean needStart = false; 17557 17558 // If the user we are switching to is not currently started, then 17559 // we need to start it now. 17560 if (mStartedUsers.get(userId) == null) { 17561 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17562 updateStartedUserArrayLocked(); 17563 needStart = true; 17564 } 17565 17566 final Integer userIdInt = Integer.valueOf(userId); 17567 mUserLru.remove(userIdInt); 17568 mUserLru.add(userIdInt); 17569 17570 if (foreground) { 17571 mCurrentUserId = userId; 17572 updateCurrentProfileIdsLocked(); 17573 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17574 // Once the internal notion of the active user has switched, we lock the device 17575 // with the option to show the user switcher on the keyguard. 17576 mWindowManager.lockNow(null); 17577 } else { 17578 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17579 updateCurrentProfileIdsLocked(); 17580 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17581 mUserLru.remove(currentUserIdInt); 17582 mUserLru.add(currentUserIdInt); 17583 } 17584 17585 final UserStartedState uss = mStartedUsers.get(userId); 17586 17587 // Make sure user is in the started state. If it is currently 17588 // stopping, we need to knock that off. 17589 if (uss.mState == UserStartedState.STATE_STOPPING) { 17590 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17591 // so we can just fairly silently bring the user back from 17592 // the almost-dead. 17593 uss.mState = UserStartedState.STATE_RUNNING; 17594 updateStartedUserArrayLocked(); 17595 needStart = true; 17596 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17597 // This means ACTION_SHUTDOWN has been sent, so we will 17598 // need to treat this as a new boot of the user. 17599 uss.mState = UserStartedState.STATE_BOOTING; 17600 updateStartedUserArrayLocked(); 17601 needStart = true; 17602 } 17603 17604 if (uss.mState == UserStartedState.STATE_BOOTING) { 17605 // Booting up a new user, need to tell system services about it. 17606 // Note that this is on the same handler as scheduling of broadcasts, 17607 // which is important because it needs to go first. 17608 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 17609 } 17610 17611 if (foreground) { 17612 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17613 oldUserId)); 17614 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17615 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17616 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17617 oldUserId, userId, uss)); 17618 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17619 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17620 } 17621 17622 if (needStart) { 17623 // Send USER_STARTED broadcast 17624 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17625 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17626 | Intent.FLAG_RECEIVER_FOREGROUND); 17627 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17628 broadcastIntentLocked(null, null, intent, 17629 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17630 false, false, MY_PID, Process.SYSTEM_UID, userId); 17631 } 17632 17633 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17634 if (userId != UserHandle.USER_OWNER) { 17635 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17636 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17637 broadcastIntentLocked(null, null, intent, null, 17638 new IIntentReceiver.Stub() { 17639 public void performReceive(Intent intent, int resultCode, 17640 String data, Bundle extras, boolean ordered, 17641 boolean sticky, int sendingUser) { 17642 userInitialized(uss, userId); 17643 } 17644 }, 0, null, null, null, AppOpsManager.OP_NONE, 17645 true, false, MY_PID, Process.SYSTEM_UID, 17646 userId); 17647 uss.initializing = true; 17648 } else { 17649 getUserManagerLocked().makeInitialized(userInfo.id); 17650 } 17651 } 17652 17653 if (foreground) { 17654 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17655 if (homeInFront) { 17656 startHomeActivityLocked(userId); 17657 } else { 17658 mStackSupervisor.resumeTopActivitiesLocked(); 17659 } 17660 EventLogTags.writeAmSwitchUser(userId); 17661 getUserManagerLocked().userForeground(userId); 17662 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17663 } else { 17664 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17665 } 17666 17667 if (needStart) { 17668 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17670 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17671 broadcastIntentLocked(null, null, intent, 17672 null, new IIntentReceiver.Stub() { 17673 @Override 17674 public void performReceive(Intent intent, int resultCode, String data, 17675 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17676 throws RemoteException { 17677 } 17678 }, 0, null, null, 17679 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17680 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17681 } 17682 } 17683 } finally { 17684 Binder.restoreCallingIdentity(ident); 17685 } 17686 17687 return true; 17688 } 17689 17690 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17691 long ident = Binder.clearCallingIdentity(); 17692 try { 17693 Intent intent; 17694 if (oldUserId >= 0) { 17695 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17696 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17697 int count = profiles.size(); 17698 for (int i = 0; i < count; i++) { 17699 int profileUserId = profiles.get(i).id; 17700 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17701 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17702 | Intent.FLAG_RECEIVER_FOREGROUND); 17703 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17704 broadcastIntentLocked(null, null, intent, 17705 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17706 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17707 } 17708 } 17709 if (newUserId >= 0) { 17710 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17711 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17712 int count = profiles.size(); 17713 for (int i = 0; i < count; i++) { 17714 int profileUserId = profiles.get(i).id; 17715 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17716 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17717 | Intent.FLAG_RECEIVER_FOREGROUND); 17718 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17719 broadcastIntentLocked(null, null, intent, 17720 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17721 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17722 } 17723 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17724 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17725 | Intent.FLAG_RECEIVER_FOREGROUND); 17726 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17727 broadcastIntentLocked(null, null, intent, 17728 null, null, 0, null, null, 17729 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17730 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17731 } 17732 } finally { 17733 Binder.restoreCallingIdentity(ident); 17734 } 17735 } 17736 17737 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17738 final int newUserId) { 17739 final int N = mUserSwitchObservers.beginBroadcast(); 17740 if (N > 0) { 17741 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17742 int mCount = 0; 17743 @Override 17744 public void sendResult(Bundle data) throws RemoteException { 17745 synchronized (ActivityManagerService.this) { 17746 if (mCurUserSwitchCallback == this) { 17747 mCount++; 17748 if (mCount == N) { 17749 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17750 } 17751 } 17752 } 17753 } 17754 }; 17755 synchronized (this) { 17756 uss.switching = true; 17757 mCurUserSwitchCallback = callback; 17758 } 17759 for (int i=0; i<N; i++) { 17760 try { 17761 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17762 newUserId, callback); 17763 } catch (RemoteException e) { 17764 } 17765 } 17766 } else { 17767 synchronized (this) { 17768 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17769 } 17770 } 17771 mUserSwitchObservers.finishBroadcast(); 17772 } 17773 17774 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17775 synchronized (this) { 17776 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17777 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17778 } 17779 } 17780 17781 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17782 mCurUserSwitchCallback = null; 17783 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17784 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17785 oldUserId, newUserId, uss)); 17786 } 17787 17788 void userInitialized(UserStartedState uss, int newUserId) { 17789 completeSwitchAndInitalize(uss, newUserId, true, false); 17790 } 17791 17792 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17793 completeSwitchAndInitalize(uss, newUserId, false, true); 17794 } 17795 17796 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17797 boolean clearInitializing, boolean clearSwitching) { 17798 boolean unfrozen = false; 17799 synchronized (this) { 17800 if (clearInitializing) { 17801 uss.initializing = false; 17802 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17803 } 17804 if (clearSwitching) { 17805 uss.switching = false; 17806 } 17807 if (!uss.switching && !uss.initializing) { 17808 mWindowManager.stopFreezingScreen(); 17809 unfrozen = true; 17810 } 17811 } 17812 if (unfrozen) { 17813 final int N = mUserSwitchObservers.beginBroadcast(); 17814 for (int i=0; i<N; i++) { 17815 try { 17816 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17817 } catch (RemoteException e) { 17818 } 17819 } 17820 mUserSwitchObservers.finishBroadcast(); 17821 } 17822 } 17823 17824 void scheduleStartProfilesLocked() { 17825 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17826 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17827 DateUtils.SECOND_IN_MILLIS); 17828 } 17829 } 17830 17831 void startProfilesLocked() { 17832 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17833 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17834 mCurrentUserId, false /* enabledOnly */); 17835 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17836 for (UserInfo user : profiles) { 17837 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17838 && user.id != mCurrentUserId) { 17839 toStart.add(user); 17840 } 17841 } 17842 final int n = toStart.size(); 17843 int i = 0; 17844 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17845 startUserInBackground(toStart.get(i).id); 17846 } 17847 if (i < n) { 17848 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17849 } 17850 } 17851 17852 void finishUserBoot(UserStartedState uss) { 17853 synchronized (this) { 17854 if (uss.mState == UserStartedState.STATE_BOOTING 17855 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17856 uss.mState = UserStartedState.STATE_RUNNING; 17857 final int userId = uss.mHandle.getIdentifier(); 17858 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17859 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17860 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17861 broadcastIntentLocked(null, null, intent, 17862 null, null, 0, null, null, 17863 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17864 true, false, MY_PID, Process.SYSTEM_UID, userId); 17865 } 17866 } 17867 } 17868 17869 void finishUserSwitch(UserStartedState uss) { 17870 synchronized (this) { 17871 finishUserBoot(uss); 17872 17873 startProfilesLocked(); 17874 17875 int num = mUserLru.size(); 17876 int i = 0; 17877 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17878 Integer oldUserId = mUserLru.get(i); 17879 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17880 if (oldUss == null) { 17881 // Shouldn't happen, but be sane if it does. 17882 mUserLru.remove(i); 17883 num--; 17884 continue; 17885 } 17886 if (oldUss.mState == UserStartedState.STATE_STOPPING 17887 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17888 // This user is already stopping, doesn't count. 17889 num--; 17890 i++; 17891 continue; 17892 } 17893 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17894 // Owner and current can't be stopped, but count as running. 17895 i++; 17896 continue; 17897 } 17898 // This is a user to be stopped. 17899 stopUserLocked(oldUserId, null); 17900 num--; 17901 i++; 17902 } 17903 } 17904 } 17905 17906 @Override 17907 public int stopUser(final int userId, final IStopUserCallback callback) { 17908 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17909 != PackageManager.PERMISSION_GRANTED) { 17910 String msg = "Permission Denial: switchUser() from pid=" 17911 + Binder.getCallingPid() 17912 + ", uid=" + Binder.getCallingUid() 17913 + " requires " + INTERACT_ACROSS_USERS_FULL; 17914 Slog.w(TAG, msg); 17915 throw new SecurityException(msg); 17916 } 17917 if (userId <= 0) { 17918 throw new IllegalArgumentException("Can't stop primary user " + userId); 17919 } 17920 synchronized (this) { 17921 return stopUserLocked(userId, callback); 17922 } 17923 } 17924 17925 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17926 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17927 if (mCurrentUserId == userId) { 17928 return ActivityManager.USER_OP_IS_CURRENT; 17929 } 17930 17931 final UserStartedState uss = mStartedUsers.get(userId); 17932 if (uss == null) { 17933 // User is not started, nothing to do... but we do need to 17934 // callback if requested. 17935 if (callback != null) { 17936 mHandler.post(new Runnable() { 17937 @Override 17938 public void run() { 17939 try { 17940 callback.userStopped(userId); 17941 } catch (RemoteException e) { 17942 } 17943 } 17944 }); 17945 } 17946 return ActivityManager.USER_OP_SUCCESS; 17947 } 17948 17949 if (callback != null) { 17950 uss.mStopCallbacks.add(callback); 17951 } 17952 17953 if (uss.mState != UserStartedState.STATE_STOPPING 17954 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17955 uss.mState = UserStartedState.STATE_STOPPING; 17956 updateStartedUserArrayLocked(); 17957 17958 long ident = Binder.clearCallingIdentity(); 17959 try { 17960 // We are going to broadcast ACTION_USER_STOPPING and then 17961 // once that is done send a final ACTION_SHUTDOWN and then 17962 // stop the user. 17963 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17964 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17965 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17966 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17967 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17968 // This is the result receiver for the final shutdown broadcast. 17969 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17970 @Override 17971 public void performReceive(Intent intent, int resultCode, String data, 17972 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17973 finishUserStop(uss); 17974 } 17975 }; 17976 // This is the result receiver for the initial stopping broadcast. 17977 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17978 @Override 17979 public void performReceive(Intent intent, int resultCode, String data, 17980 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17981 // On to the next. 17982 synchronized (ActivityManagerService.this) { 17983 if (uss.mState != UserStartedState.STATE_STOPPING) { 17984 // Whoops, we are being started back up. Abort, abort! 17985 return; 17986 } 17987 uss.mState = UserStartedState.STATE_SHUTDOWN; 17988 } 17989 mBatteryStatsService.noteEvent( 17990 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17991 Integer.toString(userId), userId); 17992 mSystemServiceManager.stopUser(userId); 17993 broadcastIntentLocked(null, null, shutdownIntent, 17994 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17995 true, false, MY_PID, Process.SYSTEM_UID, userId); 17996 } 17997 }; 17998 // Kick things off. 17999 broadcastIntentLocked(null, null, stoppingIntent, 18000 null, stoppingReceiver, 0, null, null, 18001 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18002 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18003 } finally { 18004 Binder.restoreCallingIdentity(ident); 18005 } 18006 } 18007 18008 return ActivityManager.USER_OP_SUCCESS; 18009 } 18010 18011 void finishUserStop(UserStartedState uss) { 18012 final int userId = uss.mHandle.getIdentifier(); 18013 boolean stopped; 18014 ArrayList<IStopUserCallback> callbacks; 18015 synchronized (this) { 18016 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18017 if (mStartedUsers.get(userId) != uss) { 18018 stopped = false; 18019 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18020 stopped = false; 18021 } else { 18022 stopped = true; 18023 // User can no longer run. 18024 mStartedUsers.remove(userId); 18025 mUserLru.remove(Integer.valueOf(userId)); 18026 updateStartedUserArrayLocked(); 18027 18028 // Clean up all state and processes associated with the user. 18029 // Kill all the processes for the user. 18030 forceStopUserLocked(userId, "finish user"); 18031 } 18032 18033 // Explicitly remove the old information in mRecentTasks. 18034 removeRecentTasksForUserLocked(userId); 18035 } 18036 18037 for (int i=0; i<callbacks.size(); i++) { 18038 try { 18039 if (stopped) callbacks.get(i).userStopped(userId); 18040 else callbacks.get(i).userStopAborted(userId); 18041 } catch (RemoteException e) { 18042 } 18043 } 18044 18045 if (stopped) { 18046 mSystemServiceManager.cleanupUser(userId); 18047 synchronized (this) { 18048 mStackSupervisor.removeUserLocked(userId); 18049 } 18050 } 18051 } 18052 18053 @Override 18054 public UserInfo getCurrentUser() { 18055 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18056 != PackageManager.PERMISSION_GRANTED) && ( 18057 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18058 != PackageManager.PERMISSION_GRANTED)) { 18059 String msg = "Permission Denial: getCurrentUser() from pid=" 18060 + Binder.getCallingPid() 18061 + ", uid=" + Binder.getCallingUid() 18062 + " requires " + INTERACT_ACROSS_USERS; 18063 Slog.w(TAG, msg); 18064 throw new SecurityException(msg); 18065 } 18066 synchronized (this) { 18067 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18068 } 18069 } 18070 18071 int getCurrentUserIdLocked() { 18072 return mCurrentUserId; 18073 } 18074 18075 @Override 18076 public boolean isUserRunning(int userId, boolean orStopped) { 18077 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18078 != PackageManager.PERMISSION_GRANTED) { 18079 String msg = "Permission Denial: isUserRunning() from pid=" 18080 + Binder.getCallingPid() 18081 + ", uid=" + Binder.getCallingUid() 18082 + " requires " + INTERACT_ACROSS_USERS; 18083 Slog.w(TAG, msg); 18084 throw new SecurityException(msg); 18085 } 18086 synchronized (this) { 18087 return isUserRunningLocked(userId, orStopped); 18088 } 18089 } 18090 18091 boolean isUserRunningLocked(int userId, boolean orStopped) { 18092 UserStartedState state = mStartedUsers.get(userId); 18093 if (state == null) { 18094 return false; 18095 } 18096 if (orStopped) { 18097 return true; 18098 } 18099 return state.mState != UserStartedState.STATE_STOPPING 18100 && state.mState != UserStartedState.STATE_SHUTDOWN; 18101 } 18102 18103 @Override 18104 public int[] getRunningUserIds() { 18105 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18106 != PackageManager.PERMISSION_GRANTED) { 18107 String msg = "Permission Denial: isUserRunning() from pid=" 18108 + Binder.getCallingPid() 18109 + ", uid=" + Binder.getCallingUid() 18110 + " requires " + INTERACT_ACROSS_USERS; 18111 Slog.w(TAG, msg); 18112 throw new SecurityException(msg); 18113 } 18114 synchronized (this) { 18115 return mStartedUserArray; 18116 } 18117 } 18118 18119 private void updateStartedUserArrayLocked() { 18120 int num = 0; 18121 for (int i=0; i<mStartedUsers.size(); i++) { 18122 UserStartedState uss = mStartedUsers.valueAt(i); 18123 // This list does not include stopping users. 18124 if (uss.mState != UserStartedState.STATE_STOPPING 18125 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18126 num++; 18127 } 18128 } 18129 mStartedUserArray = new int[num]; 18130 num = 0; 18131 for (int i=0; i<mStartedUsers.size(); i++) { 18132 UserStartedState uss = mStartedUsers.valueAt(i); 18133 if (uss.mState != UserStartedState.STATE_STOPPING 18134 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18135 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18136 num++; 18137 } 18138 } 18139 } 18140 18141 @Override 18142 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18143 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18144 != PackageManager.PERMISSION_GRANTED) { 18145 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18146 + Binder.getCallingPid() 18147 + ", uid=" + Binder.getCallingUid() 18148 + " requires " + INTERACT_ACROSS_USERS_FULL; 18149 Slog.w(TAG, msg); 18150 throw new SecurityException(msg); 18151 } 18152 18153 mUserSwitchObservers.register(observer); 18154 } 18155 18156 @Override 18157 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18158 mUserSwitchObservers.unregister(observer); 18159 } 18160 18161 private boolean userExists(int userId) { 18162 if (userId == 0) { 18163 return true; 18164 } 18165 UserManagerService ums = getUserManagerLocked(); 18166 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18167 } 18168 18169 int[] getUsersLocked() { 18170 UserManagerService ums = getUserManagerLocked(); 18171 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18172 } 18173 18174 UserManagerService getUserManagerLocked() { 18175 if (mUserManager == null) { 18176 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18177 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18178 } 18179 return mUserManager; 18180 } 18181 18182 private int applyUserId(int uid, int userId) { 18183 return UserHandle.getUid(userId, uid); 18184 } 18185 18186 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18187 if (info == null) return null; 18188 ApplicationInfo newInfo = new ApplicationInfo(info); 18189 newInfo.uid = applyUserId(info.uid, userId); 18190 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18191 + info.packageName; 18192 return newInfo; 18193 } 18194 18195 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18196 if (aInfo == null 18197 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18198 return aInfo; 18199 } 18200 18201 ActivityInfo info = new ActivityInfo(aInfo); 18202 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18203 return info; 18204 } 18205 18206 private final class LocalService extends ActivityManagerInternal { 18207 @Override 18208 public void goingToSleep() { 18209 ActivityManagerService.this.goingToSleep(); 18210 } 18211 18212 @Override 18213 public void wakingUp() { 18214 ActivityManagerService.this.wakingUp(); 18215 } 18216 18217 @Override 18218 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18219 String processName, String abiOverride, int uid, Runnable crashHandler) { 18220 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18221 processName, abiOverride, uid, crashHandler); 18222 } 18223 } 18224 18225 /** 18226 * An implementation of IAppTask, that allows an app to manage its own tasks via 18227 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18228 * only the process that calls getAppTasks() can call the AppTask methods. 18229 */ 18230 class AppTaskImpl extends IAppTask.Stub { 18231 private int mTaskId; 18232 private int mCallingUid; 18233 18234 public AppTaskImpl(int taskId, int callingUid) { 18235 mTaskId = taskId; 18236 mCallingUid = callingUid; 18237 } 18238 18239 private void checkCaller() { 18240 if (mCallingUid != Binder.getCallingUid()) { 18241 throw new SecurityException("Caller " + mCallingUid 18242 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18243 } 18244 } 18245 18246 @Override 18247 public void finishAndRemoveTask() { 18248 checkCaller(); 18249 18250 synchronized (ActivityManagerService.this) { 18251 long origId = Binder.clearCallingIdentity(); 18252 try { 18253 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18254 if (tr != null) { 18255 // Only kill the process if we are not a new document 18256 int flags = tr.getBaseIntent().getFlags(); 18257 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18258 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18259 removeTaskByIdLocked(mTaskId, 18260 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18261 } 18262 } finally { 18263 Binder.restoreCallingIdentity(origId); 18264 } 18265 } 18266 } 18267 18268 @Override 18269 public ActivityManager.RecentTaskInfo getTaskInfo() { 18270 checkCaller(); 18271 18272 synchronized (ActivityManagerService.this) { 18273 long origId = Binder.clearCallingIdentity(); 18274 try { 18275 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18276 if (tr != null) { 18277 return createRecentTaskInfoFromTaskRecord(tr); 18278 } 18279 } finally { 18280 Binder.restoreCallingIdentity(origId); 18281 } 18282 return null; 18283 } 18284 } 18285 18286 @Override 18287 public void setExcludeFromRecents(boolean exclude) { 18288 checkCaller(); 18289 18290 synchronized (ActivityManagerService.this) { 18291 long origId = Binder.clearCallingIdentity(); 18292 try { 18293 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18294 if (tr != null) { 18295 Intent intent = tr.getBaseIntent(); 18296 if (exclude) { 18297 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18298 } else { 18299 intent.setFlags(intent.getFlags() 18300 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18301 } 18302 } 18303 } finally { 18304 Binder.restoreCallingIdentity(origId); 18305 } 18306 } 18307 } 18308 } 18309} 18310