ActivityManagerService.java revision 2f1993ec460166413e7887f151630f6708077c0f
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * State of external calls telling us if the device is asleep. 941 */ 942 private boolean mWentToSleep = false; 943 944 /** 945 * State of external call telling us if the lock screen is shown. 946 */ 947 private boolean mLockScreenShown = false; 948 949 /** 950 * Set if we are shutting down the system, similar to sleeping. 951 */ 952 boolean mShuttingDown = false; 953 954 /** 955 * Current sequence id for oom_adj computation traversal. 956 */ 957 int mAdjSeq = 0; 958 959 /** 960 * Current sequence id for process LRU updating. 961 */ 962 int mLruSeq = 0; 963 964 /** 965 * Keep track of the non-cached/empty process we last found, to help 966 * determine how to distribute cached/empty processes next time. 967 */ 968 int mNumNonCachedProcs = 0; 969 970 /** 971 * Keep track of the number of cached hidden procs, to balance oom adj 972 * distribution between those and empty procs. 973 */ 974 int mNumCachedHiddenProcs = 0; 975 976 /** 977 * Keep track of the number of service processes we last found, to 978 * determine on the next iteration which should be B services. 979 */ 980 int mNumServiceProcs = 0; 981 int mNewNumAServiceProcs = 0; 982 int mNewNumServiceProcs = 0; 983 984 /** 985 * Allow the current computed overall memory level of the system to go down? 986 * This is set to false when we are killing processes for reasons other than 987 * memory management, so that the now smaller process list will not be taken as 988 * an indication that memory is tighter. 989 */ 990 boolean mAllowLowerMemLevel = false; 991 992 /** 993 * The last computed memory level, for holding when we are in a state that 994 * processes are going away for other reasons. 995 */ 996 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 997 998 /** 999 * The last total number of process we have, to determine if changes actually look 1000 * like a shrinking number of process due to lower RAM. 1001 */ 1002 int mLastNumProcesses; 1003 1004 /** 1005 * The uptime of the last time we performed idle maintenance. 1006 */ 1007 long mLastIdleTime = SystemClock.uptimeMillis(); 1008 1009 /** 1010 * Total time spent with RAM that has been added in the past since the last idle time. 1011 */ 1012 long mLowRamTimeSinceLastIdle = 0; 1013 1014 /** 1015 * If RAM is currently low, when that horrible situation started. 1016 */ 1017 long mLowRamStartTime = 0; 1018 1019 /** 1020 * For reporting to battery stats the current top application. 1021 */ 1022 private String mCurResumedPackage = null; 1023 private int mCurResumedUid = -1; 1024 1025 /** 1026 * For reporting to battery stats the apps currently running foreground 1027 * service. The ProcessMap is package/uid tuples; each of these contain 1028 * an array of the currently foreground processes. 1029 */ 1030 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1031 = new ProcessMap<ArrayList<ProcessRecord>>(); 1032 1033 /** 1034 * This is set if we had to do a delayed dexopt of an app before launching 1035 * it, to increase the ANR timeouts in that case. 1036 */ 1037 boolean mDidDexOpt; 1038 1039 /** 1040 * Set if the systemServer made a call to enterSafeMode. 1041 */ 1042 boolean mSafeMode; 1043 1044 String mDebugApp = null; 1045 boolean mWaitForDebugger = false; 1046 boolean mDebugTransient = false; 1047 String mOrigDebugApp = null; 1048 boolean mOrigWaitForDebugger = false; 1049 boolean mAlwaysFinishActivities = false; 1050 IActivityController mController = null; 1051 String mProfileApp = null; 1052 ProcessRecord mProfileProc = null; 1053 String mProfileFile; 1054 ParcelFileDescriptor mProfileFd; 1055 int mSamplingInterval = 0; 1056 boolean mAutoStopProfiler = false; 1057 int mProfileType = 0; 1058 String mOpenGlTraceApp = null; 1059 1060 static class ProcessChangeItem { 1061 static final int CHANGE_ACTIVITIES = 1<<0; 1062 static final int CHANGE_PROCESS_STATE = 1<<1; 1063 int changes; 1064 int uid; 1065 int pid; 1066 int processState; 1067 boolean foregroundActivities; 1068 } 1069 1070 final RemoteCallbackList<IProcessObserver> mProcessObservers 1071 = new RemoteCallbackList<IProcessObserver>(); 1072 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1073 1074 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1075 = new ArrayList<ProcessChangeItem>(); 1076 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1077 = new ArrayList<ProcessChangeItem>(); 1078 1079 /** 1080 * Runtime CPU use collection thread. This object's lock is used to 1081 * perform synchronization with the thread (notifying it to run). 1082 */ 1083 final Thread mProcessCpuThread; 1084 1085 /** 1086 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1087 * Must acquire this object's lock when accessing it. 1088 * NOTE: this lock will be held while doing long operations (trawling 1089 * through all processes in /proc), so it should never be acquired by 1090 * any critical paths such as when holding the main activity manager lock. 1091 */ 1092 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1093 MONITOR_THREAD_CPU_USAGE); 1094 final AtomicLong mLastCpuTime = new AtomicLong(0); 1095 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1096 1097 long mLastWriteTime = 0; 1098 1099 /** 1100 * Used to retain an update lock when the foreground activity is in 1101 * immersive mode. 1102 */ 1103 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1104 1105 /** 1106 * Set to true after the system has finished booting. 1107 */ 1108 boolean mBooted = false; 1109 1110 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1111 int mProcessLimitOverride = -1; 1112 1113 WindowManagerService mWindowManager; 1114 1115 final ActivityThread mSystemThread; 1116 1117 // Holds the current foreground user's id 1118 int mCurrentUserId = 0; 1119 // Holds the target user's id during a user switch 1120 int mTargetUserId = UserHandle.USER_NULL; 1121 // If there are multiple profiles for the current user, their ids are here 1122 // Currently only the primary user can have managed profiles 1123 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1124 1125 /** 1126 * Mapping from each known user ID to the profile group ID it is associated with. 1127 */ 1128 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1129 1130 private UserManagerService mUserManager; 1131 1132 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1133 final ProcessRecord mApp; 1134 final int mPid; 1135 final IApplicationThread mAppThread; 1136 1137 AppDeathRecipient(ProcessRecord app, int pid, 1138 IApplicationThread thread) { 1139 if (localLOGV) Slog.v( 1140 TAG, "New death recipient " + this 1141 + " for thread " + thread.asBinder()); 1142 mApp = app; 1143 mPid = pid; 1144 mAppThread = thread; 1145 } 1146 1147 @Override 1148 public void binderDied() { 1149 if (localLOGV) Slog.v( 1150 TAG, "Death received in " + this 1151 + " for thread " + mAppThread.asBinder()); 1152 synchronized(ActivityManagerService.this) { 1153 appDiedLocked(mApp, mPid, mAppThread); 1154 } 1155 } 1156 } 1157 1158 static final int SHOW_ERROR_MSG = 1; 1159 static final int SHOW_NOT_RESPONDING_MSG = 2; 1160 static final int SHOW_FACTORY_ERROR_MSG = 3; 1161 static final int UPDATE_CONFIGURATION_MSG = 4; 1162 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1163 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1164 static final int SERVICE_TIMEOUT_MSG = 12; 1165 static final int UPDATE_TIME_ZONE = 13; 1166 static final int SHOW_UID_ERROR_MSG = 14; 1167 static final int IM_FEELING_LUCKY_MSG = 15; 1168 static final int PROC_START_TIMEOUT_MSG = 20; 1169 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1170 static final int KILL_APPLICATION_MSG = 22; 1171 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1172 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1173 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1174 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1175 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1176 static final int CLEAR_DNS_CACHE_MSG = 28; 1177 static final int UPDATE_HTTP_PROXY_MSG = 29; 1178 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1179 static final int DISPATCH_PROCESSES_CHANGED = 31; 1180 static final int DISPATCH_PROCESS_DIED = 32; 1181 static final int REPORT_MEM_USAGE_MSG = 33; 1182 static final int REPORT_USER_SWITCH_MSG = 34; 1183 static final int CONTINUE_USER_SWITCH_MSG = 35; 1184 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1185 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1186 static final int PERSIST_URI_GRANTS_MSG = 38; 1187 static final int REQUEST_ALL_PSS_MSG = 39; 1188 static final int START_PROFILES_MSG = 40; 1189 static final int UPDATE_TIME = 41; 1190 static final int SYSTEM_USER_START_MSG = 42; 1191 static final int SYSTEM_USER_CURRENT_MSG = 43; 1192 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1193 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1194 static final int START_USER_SWITCH_MSG = 46; 1195 1196 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1197 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1198 static final int FIRST_COMPAT_MODE_MSG = 300; 1199 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1200 1201 AlertDialog mUidAlert; 1202 CompatModeDialog mCompatModeDialog; 1203 long mLastMemUsageReportTime = 0; 1204 1205 private LockToAppRequestDialog mLockToAppRequest; 1206 1207 /** 1208 * Flag whether the current user is a "monkey", i.e. whether 1209 * the UI is driven by a UI automation tool. 1210 */ 1211 private boolean mUserIsMonkey; 1212 1213 /** Flag whether the device has a Recents UI */ 1214 boolean mHasRecents; 1215 1216 /** The dimensions of the thumbnails in the Recents UI. */ 1217 int mThumbnailWidth; 1218 int mThumbnailHeight; 1219 1220 final ServiceThread mHandlerThread; 1221 final MainHandler mHandler; 1222 1223 final class MainHandler extends Handler { 1224 public MainHandler(Looper looper) { 1225 super(looper, null, true); 1226 } 1227 1228 @Override 1229 public void handleMessage(Message msg) { 1230 switch (msg.what) { 1231 case SHOW_ERROR_MSG: { 1232 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1233 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1234 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1235 synchronized (ActivityManagerService.this) { 1236 ProcessRecord proc = (ProcessRecord)data.get("app"); 1237 AppErrorResult res = (AppErrorResult) data.get("result"); 1238 if (proc != null && proc.crashDialog != null) { 1239 Slog.e(TAG, "App already has crash dialog: " + proc); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 boolean isBackground = (UserHandle.getAppId(proc.uid) 1246 >= Process.FIRST_APPLICATION_UID 1247 && proc.pid != MY_PID); 1248 for (int userId : mCurrentProfileIds) { 1249 isBackground &= (proc.userId != userId); 1250 } 1251 if (isBackground && !showBackground) { 1252 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 return; 1257 } 1258 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1259 Dialog d = new AppErrorDialog(mContext, 1260 ActivityManagerService.this, res, proc); 1261 d.show(); 1262 proc.crashDialog = d; 1263 } else { 1264 // The device is asleep, so just pretend that the user 1265 // saw a crash dialog and hit "force quit". 1266 if (res != null) { 1267 res.set(0); 1268 } 1269 } 1270 } 1271 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_NOT_RESPONDING_MSG: { 1275 synchronized (ActivityManagerService.this) { 1276 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1277 ProcessRecord proc = (ProcessRecord)data.get("app"); 1278 if (proc != null && proc.anrDialog != null) { 1279 Slog.e(TAG, "App already has anr dialog: " + proc); 1280 return; 1281 } 1282 1283 Intent intent = new Intent("android.intent.action.ANR"); 1284 if (!mProcessesReady) { 1285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1286 | Intent.FLAG_RECEIVER_FOREGROUND); 1287 } 1288 broadcastIntentLocked(null, null, intent, 1289 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1290 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1291 1292 if (mShowDialogs) { 1293 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1294 mContext, proc, (ActivityRecord)data.get("activity"), 1295 msg.arg1 != 0); 1296 d.show(); 1297 proc.anrDialog = d; 1298 } else { 1299 // Just kill the app if there is no dialog to be shown. 1300 killAppAtUsersRequest(proc, null); 1301 } 1302 } 1303 1304 ensureBootCompleted(); 1305 } break; 1306 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 synchronized (ActivityManagerService.this) { 1309 ProcessRecord proc = (ProcessRecord) data.get("app"); 1310 if (proc == null) { 1311 Slog.e(TAG, "App not found when showing strict mode dialog."); 1312 break; 1313 } 1314 if (proc.crashDialog != null) { 1315 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1316 return; 1317 } 1318 AppErrorResult res = (AppErrorResult) data.get("result"); 1319 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1320 Dialog d = new StrictModeViolationDialog(mContext, 1321 ActivityManagerService.this, res, proc); 1322 d.show(); 1323 proc.crashDialog = d; 1324 } else { 1325 // The device is asleep, so just pretend that the user 1326 // saw a crash dialog and hit "force quit". 1327 res.set(0); 1328 } 1329 } 1330 ensureBootCompleted(); 1331 } break; 1332 case SHOW_FACTORY_ERROR_MSG: { 1333 Dialog d = new FactoryErrorDialog( 1334 mContext, msg.getData().getCharSequence("msg")); 1335 d.show(); 1336 ensureBootCompleted(); 1337 } break; 1338 case UPDATE_CONFIGURATION_MSG: { 1339 final ContentResolver resolver = mContext.getContentResolver(); 1340 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1341 } break; 1342 case GC_BACKGROUND_PROCESSES_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 performAppGcsIfAppropriateLocked(); 1345 } 1346 } break; 1347 case WAIT_FOR_DEBUGGER_MSG: { 1348 synchronized (ActivityManagerService.this) { 1349 ProcessRecord app = (ProcessRecord)msg.obj; 1350 if (msg.arg1 != 0) { 1351 if (!app.waitedForDebugger) { 1352 Dialog d = new AppWaitingForDebuggerDialog( 1353 ActivityManagerService.this, 1354 mContext, app); 1355 app.waitDialog = d; 1356 app.waitedForDebugger = true; 1357 d.show(); 1358 } 1359 } else { 1360 if (app.waitDialog != null) { 1361 app.waitDialog.dismiss(); 1362 app.waitDialog = null; 1363 } 1364 } 1365 } 1366 } break; 1367 case SERVICE_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1373 return; 1374 } 1375 mServices.serviceTimeout((ProcessRecord)msg.obj); 1376 } break; 1377 case UPDATE_TIME_ZONE: { 1378 synchronized (ActivityManagerService.this) { 1379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1380 ProcessRecord r = mLruProcesses.get(i); 1381 if (r.thread != null) { 1382 try { 1383 r.thread.updateTimeZone(); 1384 } catch (RemoteException ex) { 1385 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1386 } 1387 } 1388 } 1389 } 1390 } break; 1391 case CLEAR_DNS_CACHE_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1394 ProcessRecord r = mLruProcesses.get(i); 1395 if (r.thread != null) { 1396 try { 1397 r.thread.clearDnsCache(); 1398 } catch (RemoteException ex) { 1399 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1400 } 1401 } 1402 } 1403 } 1404 } break; 1405 case UPDATE_HTTP_PROXY_MSG: { 1406 ProxyInfo proxy = (ProxyInfo)msg.obj; 1407 String host = ""; 1408 String port = ""; 1409 String exclList = ""; 1410 Uri pacFileUrl = Uri.EMPTY; 1411 if (proxy != null) { 1412 host = proxy.getHost(); 1413 port = Integer.toString(proxy.getPort()); 1414 exclList = proxy.getExclusionListAsString(); 1415 pacFileUrl = proxy.getPacFileUrl(); 1416 } 1417 synchronized (ActivityManagerService.this) { 1418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1419 ProcessRecord r = mLruProcesses.get(i); 1420 if (r.thread != null) { 1421 try { 1422 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1423 } catch (RemoteException ex) { 1424 Slog.w(TAG, "Failed to update http proxy for: " + 1425 r.info.processName); 1426 } 1427 } 1428 } 1429 } 1430 } break; 1431 case SHOW_UID_ERROR_MSG: { 1432 String title = "System UIDs Inconsistent"; 1433 String text = "UIDs on the system are inconsistent, you need to wipe your" 1434 + " data partition or your device will be unstable."; 1435 Log.e(TAG, title + ": " + text); 1436 if (mShowDialogs) { 1437 // XXX This is a temporary dialog, no need to localize. 1438 AlertDialog d = new BaseErrorDialog(mContext); 1439 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1440 d.setCancelable(false); 1441 d.setTitle(title); 1442 d.setMessage(text); 1443 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1444 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1445 mUidAlert = d; 1446 d.show(); 1447 } 1448 } break; 1449 case IM_FEELING_LUCKY_MSG: { 1450 if (mUidAlert != null) { 1451 mUidAlert.dismiss(); 1452 mUidAlert = null; 1453 } 1454 } break; 1455 case PROC_START_TIMEOUT_MSG: { 1456 if (mDidDexOpt) { 1457 mDidDexOpt = false; 1458 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1459 nmsg.obj = msg.obj; 1460 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1461 return; 1462 } 1463 ProcessRecord app = (ProcessRecord)msg.obj; 1464 synchronized (ActivityManagerService.this) { 1465 processStartTimedOutLocked(app); 1466 } 1467 } break; 1468 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1471 } 1472 } break; 1473 case KILL_APPLICATION_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 int appid = msg.arg1; 1476 boolean restart = (msg.arg2 == 1); 1477 Bundle bundle = (Bundle)msg.obj; 1478 String pkg = bundle.getString("pkg"); 1479 String reason = bundle.getString("reason"); 1480 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1481 false, UserHandle.USER_ALL, reason); 1482 } 1483 } break; 1484 case FINALIZE_PENDING_INTENT_MSG: { 1485 ((PendingIntentRecord)msg.obj).completeFinalize(); 1486 } break; 1487 case POST_HEAVY_NOTIFICATION_MSG: { 1488 INotificationManager inm = NotificationManager.getService(); 1489 if (inm == null) { 1490 return; 1491 } 1492 1493 ActivityRecord root = (ActivityRecord)msg.obj; 1494 ProcessRecord process = root.app; 1495 if (process == null) { 1496 return; 1497 } 1498 1499 try { 1500 Context context = mContext.createPackageContext(process.info.packageName, 0); 1501 String text = mContext.getString(R.string.heavy_weight_notification, 1502 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1503 Notification notification = new Notification(); 1504 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1505 notification.when = 0; 1506 notification.flags = Notification.FLAG_ONGOING_EVENT; 1507 notification.tickerText = text; 1508 notification.defaults = 0; // please be quiet 1509 notification.sound = null; 1510 notification.vibrate = null; 1511 notification.color = mContext.getResources().getColor( 1512 com.android.internal.R.color.system_notification_accent_color); 1513 notification.setLatestEventInfo(context, text, 1514 mContext.getText(R.string.heavy_weight_notification_detail), 1515 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1516 PendingIntent.FLAG_CANCEL_CURRENT, null, 1517 new UserHandle(root.userId))); 1518 1519 try { 1520 int[] outId = new int[1]; 1521 inm.enqueueNotificationWithTag("android", "android", null, 1522 R.string.heavy_weight_notification, 1523 notification, outId, root.userId); 1524 } catch (RuntimeException e) { 1525 Slog.w(ActivityManagerService.TAG, 1526 "Error showing notification for heavy-weight app", e); 1527 } catch (RemoteException e) { 1528 } 1529 } catch (NameNotFoundException e) { 1530 Slog.w(TAG, "Unable to create context for heavy notification", e); 1531 } 1532 } break; 1533 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1534 INotificationManager inm = NotificationManager.getService(); 1535 if (inm == null) { 1536 return; 1537 } 1538 try { 1539 inm.cancelNotificationWithTag("android", null, 1540 R.string.heavy_weight_notification, msg.arg1); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error canceling notification for service", e); 1544 } catch (RemoteException e) { 1545 } 1546 } break; 1547 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1548 synchronized (ActivityManagerService.this) { 1549 checkExcessivePowerUsageLocked(true); 1550 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1551 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1552 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1553 } 1554 } break; 1555 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1556 synchronized (ActivityManagerService.this) { 1557 ActivityRecord ar = (ActivityRecord)msg.obj; 1558 if (mCompatModeDialog != null) { 1559 if (mCompatModeDialog.mAppInfo.packageName.equals( 1560 ar.info.applicationInfo.packageName)) { 1561 return; 1562 } 1563 mCompatModeDialog.dismiss(); 1564 mCompatModeDialog = null; 1565 } 1566 if (ar != null && false) { 1567 if (mCompatModePackages.getPackageAskCompatModeLocked( 1568 ar.packageName)) { 1569 int mode = mCompatModePackages.computeCompatModeLocked( 1570 ar.info.applicationInfo); 1571 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1572 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1573 mCompatModeDialog = new CompatModeDialog( 1574 ActivityManagerService.this, mContext, 1575 ar.info.applicationInfo); 1576 mCompatModeDialog.show(); 1577 } 1578 } 1579 } 1580 } 1581 break; 1582 } 1583 case DISPATCH_PROCESSES_CHANGED: { 1584 dispatchProcessesChanged(); 1585 break; 1586 } 1587 case DISPATCH_PROCESS_DIED: { 1588 final int pid = msg.arg1; 1589 final int uid = msg.arg2; 1590 dispatchProcessDied(pid, uid); 1591 break; 1592 } 1593 case REPORT_MEM_USAGE_MSG: { 1594 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1595 Thread thread = new Thread() { 1596 @Override public void run() { 1597 final SparseArray<ProcessMemInfo> infoMap 1598 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1599 for (int i=0, N=memInfos.size(); i<N; i++) { 1600 ProcessMemInfo mi = memInfos.get(i); 1601 infoMap.put(mi.pid, mi); 1602 } 1603 updateCpuStatsNow(); 1604 synchronized (mProcessCpuTracker) { 1605 final int N = mProcessCpuTracker.countStats(); 1606 for (int i=0; i<N; i++) { 1607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1608 if (st.vsize > 0) { 1609 long pss = Debug.getPss(st.pid, null); 1610 if (pss > 0) { 1611 if (infoMap.indexOfKey(st.pid) < 0) { 1612 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1613 ProcessList.NATIVE_ADJ, -1, "native", null); 1614 mi.pss = pss; 1615 memInfos.add(mi); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 1622 long totalPss = 0; 1623 for (int i=0, N=memInfos.size(); i<N; i++) { 1624 ProcessMemInfo mi = memInfos.get(i); 1625 if (mi.pss == 0) { 1626 mi.pss = Debug.getPss(mi.pid, null); 1627 } 1628 totalPss += mi.pss; 1629 } 1630 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1631 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1632 if (lhs.oomAdj != rhs.oomAdj) { 1633 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1634 } 1635 if (lhs.pss != rhs.pss) { 1636 return lhs.pss < rhs.pss ? 1 : -1; 1637 } 1638 return 0; 1639 } 1640 }); 1641 1642 StringBuilder tag = new StringBuilder(128); 1643 StringBuilder stack = new StringBuilder(128); 1644 tag.append("Low on memory -- "); 1645 appendMemBucket(tag, totalPss, "total", false); 1646 appendMemBucket(stack, totalPss, "total", true); 1647 1648 StringBuilder logBuilder = new StringBuilder(1024); 1649 logBuilder.append("Low on memory:\n"); 1650 1651 boolean firstLine = true; 1652 int lastOomAdj = Integer.MIN_VALUE; 1653 for (int i=0, N=memInfos.size(); i<N; i++) { 1654 ProcessMemInfo mi = memInfos.get(i); 1655 1656 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1657 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1658 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1659 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1660 if (lastOomAdj != mi.oomAdj) { 1661 lastOomAdj = mi.oomAdj; 1662 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1663 tag.append(" / "); 1664 } 1665 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1666 if (firstLine) { 1667 stack.append(":"); 1668 firstLine = false; 1669 } 1670 stack.append("\n\t at "); 1671 } else { 1672 stack.append("$"); 1673 } 1674 } else { 1675 tag.append(" "); 1676 stack.append("$"); 1677 } 1678 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1679 appendMemBucket(tag, mi.pss, mi.name, false); 1680 } 1681 appendMemBucket(stack, mi.pss, mi.name, true); 1682 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1683 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1684 stack.append("("); 1685 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1686 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1687 stack.append(DUMP_MEM_OOM_LABEL[k]); 1688 stack.append(":"); 1689 stack.append(DUMP_MEM_OOM_ADJ[k]); 1690 } 1691 } 1692 stack.append(")"); 1693 } 1694 } 1695 1696 logBuilder.append(" "); 1697 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1698 logBuilder.append(' '); 1699 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1700 logBuilder.append(' '); 1701 ProcessList.appendRamKb(logBuilder, mi.pss); 1702 logBuilder.append(" kB: "); 1703 logBuilder.append(mi.name); 1704 logBuilder.append(" ("); 1705 logBuilder.append(mi.pid); 1706 logBuilder.append(") "); 1707 logBuilder.append(mi.adjType); 1708 logBuilder.append('\n'); 1709 if (mi.adjReason != null) { 1710 logBuilder.append(" "); 1711 logBuilder.append(mi.adjReason); 1712 logBuilder.append('\n'); 1713 } 1714 } 1715 1716 logBuilder.append(" "); 1717 ProcessList.appendRamKb(logBuilder, totalPss); 1718 logBuilder.append(" kB: TOTAL\n"); 1719 1720 long[] infos = new long[Debug.MEMINFO_COUNT]; 1721 Debug.getMemInfo(infos); 1722 logBuilder.append(" MemInfo: "); 1723 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1724 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1725 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1726 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1727 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1728 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1729 logBuilder.append(" ZRAM: "); 1730 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1731 logBuilder.append(" kB RAM, "); 1732 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1733 logBuilder.append(" kB swap total, "); 1734 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1735 logBuilder.append(" kB swap free\n"); 1736 } 1737 Slog.i(TAG, logBuilder.toString()); 1738 1739 StringBuilder dropBuilder = new StringBuilder(1024); 1740 /* 1741 StringWriter oomSw = new StringWriter(); 1742 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1743 StringWriter catSw = new StringWriter(); 1744 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1745 String[] emptyArgs = new String[] { }; 1746 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1747 oomPw.flush(); 1748 String oomString = oomSw.toString(); 1749 */ 1750 dropBuilder.append(stack); 1751 dropBuilder.append('\n'); 1752 dropBuilder.append('\n'); 1753 dropBuilder.append(logBuilder); 1754 dropBuilder.append('\n'); 1755 /* 1756 dropBuilder.append(oomString); 1757 dropBuilder.append('\n'); 1758 */ 1759 StringWriter catSw = new StringWriter(); 1760 synchronized (ActivityManagerService.this) { 1761 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1762 String[] emptyArgs = new String[] { }; 1763 catPw.println(); 1764 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1765 catPw.println(); 1766 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1767 false, false, null); 1768 catPw.println(); 1769 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1770 catPw.flush(); 1771 } 1772 dropBuilder.append(catSw.toString()); 1773 addErrorToDropBox("lowmem", null, "system_server", null, 1774 null, tag.toString(), dropBuilder.toString(), null, null); 1775 //Slog.i(TAG, "Sent to dropbox:"); 1776 //Slog.i(TAG, dropBuilder.toString()); 1777 synchronized (ActivityManagerService.this) { 1778 long now = SystemClock.uptimeMillis(); 1779 if (mLastMemUsageReportTime < now) { 1780 mLastMemUsageReportTime = now; 1781 } 1782 } 1783 } 1784 }; 1785 thread.start(); 1786 break; 1787 } 1788 case START_USER_SWITCH_MSG: { 1789 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1790 break; 1791 } 1792 case REPORT_USER_SWITCH_MSG: { 1793 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1794 break; 1795 } 1796 case CONTINUE_USER_SWITCH_MSG: { 1797 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1798 break; 1799 } 1800 case USER_SWITCH_TIMEOUT_MSG: { 1801 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1802 break; 1803 } 1804 case IMMERSIVE_MODE_LOCK_MSG: { 1805 final boolean nextState = (msg.arg1 != 0); 1806 if (mUpdateLock.isHeld() != nextState) { 1807 if (DEBUG_IMMERSIVE) { 1808 final ActivityRecord r = (ActivityRecord) msg.obj; 1809 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1810 } 1811 if (nextState) { 1812 mUpdateLock.acquire(); 1813 } else { 1814 mUpdateLock.release(); 1815 } 1816 } 1817 break; 1818 } 1819 case PERSIST_URI_GRANTS_MSG: { 1820 writeGrantedUriPermissions(); 1821 break; 1822 } 1823 case REQUEST_ALL_PSS_MSG: { 1824 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1825 break; 1826 } 1827 case START_PROFILES_MSG: { 1828 synchronized (ActivityManagerService.this) { 1829 startProfilesLocked(); 1830 } 1831 break; 1832 } 1833 case UPDATE_TIME: { 1834 synchronized (ActivityManagerService.this) { 1835 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1836 ProcessRecord r = mLruProcesses.get(i); 1837 if (r.thread != null) { 1838 try { 1839 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1840 } catch (RemoteException ex) { 1841 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1842 } 1843 } 1844 } 1845 } 1846 break; 1847 } 1848 case SYSTEM_USER_START_MSG: { 1849 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1850 Integer.toString(msg.arg1), msg.arg1); 1851 mSystemServiceManager.startUser(msg.arg1); 1852 break; 1853 } 1854 case SYSTEM_USER_CURRENT_MSG: { 1855 mBatteryStatsService.noteEvent( 1856 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1857 Integer.toString(msg.arg2), msg.arg2); 1858 mBatteryStatsService.noteEvent( 1859 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1860 Integer.toString(msg.arg1), msg.arg1); 1861 mSystemServiceManager.switchUser(msg.arg1); 1862 mLockToAppRequest.clearPrompt(); 1863 break; 1864 } 1865 case ENTER_ANIMATION_COMPLETE_MSG: { 1866 synchronized (ActivityManagerService.this) { 1867 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1868 if (r != null && r.app != null && r.app.thread != null) { 1869 try { 1870 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1871 } catch (RemoteException e) { 1872 } 1873 } 1874 } 1875 break; 1876 } 1877 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1878 enableScreenAfterBoot(); 1879 break; 1880 } 1881 } 1882 } 1883 }; 1884 1885 static final int COLLECT_PSS_BG_MSG = 1; 1886 1887 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1888 @Override 1889 public void handleMessage(Message msg) { 1890 switch (msg.what) { 1891 case COLLECT_PSS_BG_MSG: { 1892 long start = SystemClock.uptimeMillis(); 1893 MemInfoReader memInfo = null; 1894 synchronized (ActivityManagerService.this) { 1895 if (mFullPssPending) { 1896 mFullPssPending = false; 1897 memInfo = new MemInfoReader(); 1898 } 1899 } 1900 if (memInfo != null) { 1901 updateCpuStatsNow(); 1902 long nativeTotalPss = 0; 1903 synchronized (mProcessCpuTracker) { 1904 final int N = mProcessCpuTracker.countStats(); 1905 for (int j=0; j<N; j++) { 1906 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1907 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1908 // This is definitely an application process; skip it. 1909 continue; 1910 } 1911 synchronized (mPidsSelfLocked) { 1912 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1913 // This is one of our own processes; skip it. 1914 continue; 1915 } 1916 } 1917 nativeTotalPss += Debug.getPss(st.pid, null); 1918 } 1919 } 1920 memInfo.readMemInfo(); 1921 synchronized (ActivityManagerService.this) { 1922 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1923 + (SystemClock.uptimeMillis()-start) + "ms"); 1924 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1925 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1926 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1927 +memInfo.getSlabSizeKb(), 1928 nativeTotalPss); 1929 } 1930 } 1931 1932 int i=0, num=0; 1933 long[] tmp = new long[1]; 1934 do { 1935 ProcessRecord proc; 1936 int procState; 1937 int pid; 1938 synchronized (ActivityManagerService.this) { 1939 if (i >= mPendingPssProcesses.size()) { 1940 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1941 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1942 mPendingPssProcesses.clear(); 1943 return; 1944 } 1945 proc = mPendingPssProcesses.get(i); 1946 procState = proc.pssProcState; 1947 if (proc.thread != null && procState == proc.setProcState) { 1948 pid = proc.pid; 1949 } else { 1950 proc = null; 1951 pid = 0; 1952 } 1953 i++; 1954 } 1955 if (proc != null) { 1956 long pss = Debug.getPss(pid, tmp); 1957 synchronized (ActivityManagerService.this) { 1958 if (proc.thread != null && proc.setProcState == procState 1959 && proc.pid == pid) { 1960 num++; 1961 proc.lastPssTime = SystemClock.uptimeMillis(); 1962 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1963 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1964 + ": " + pss + " lastPss=" + proc.lastPss 1965 + " state=" + ProcessList.makeProcStateString(procState)); 1966 if (proc.initialIdlePss == 0) { 1967 proc.initialIdlePss = pss; 1968 } 1969 proc.lastPss = pss; 1970 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1971 proc.lastCachedPss = pss; 1972 } 1973 } 1974 } 1975 } 1976 } while (true); 1977 } 1978 } 1979 } 1980 }; 1981 1982 /** 1983 * Monitor for package changes and update our internal state. 1984 */ 1985 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1986 @Override 1987 public void onPackageRemoved(String packageName, int uid) { 1988 // Remove all tasks with activities in the specified package from the list of recent tasks 1989 final int eventUserId = getChangingUserId(); 1990 synchronized (ActivityManagerService.this) { 1991 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1992 TaskRecord tr = mRecentTasks.get(i); 1993 if (tr.userId != eventUserId) continue; 1994 1995 ComponentName cn = tr.intent.getComponent(); 1996 if (cn != null && cn.getPackageName().equals(packageName)) { 1997 // If the package name matches, remove the task and kill the process 1998 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1999 } 2000 } 2001 } 2002 } 2003 2004 @Override 2005 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2006 onPackageModified(packageName); 2007 return true; 2008 } 2009 2010 @Override 2011 public void onPackageModified(String packageName) { 2012 final int eventUserId = getChangingUserId(); 2013 final PackageManager pm = mContext.getPackageManager(); 2014 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2015 new ArrayList<Pair<Intent, Integer>>(); 2016 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2017 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2018 // Copy the list of recent tasks so that we don't hold onto the lock on 2019 // ActivityManagerService for long periods while checking if components exist. 2020 synchronized (ActivityManagerService.this) { 2021 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2022 TaskRecord tr = mRecentTasks.get(i); 2023 if (tr.userId != eventUserId) continue; 2024 2025 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2026 } 2027 } 2028 // Check the recent tasks and filter out all tasks with components that no longer exist. 2029 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2030 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2031 ComponentName cn = p.first.getComponent(); 2032 if (cn != null && cn.getPackageName().equals(packageName)) { 2033 if (componentsKnownToExist.contains(cn)) { 2034 // If we know that the component still exists in the package, then skip 2035 continue; 2036 } 2037 try { 2038 ActivityInfo info = pm.getActivityInfo(cn, eventUserId); 2039 if (info != null && info.isEnabled()) { 2040 componentsKnownToExist.add(cn); 2041 } else { 2042 tasksToRemove.add(p.second); 2043 } 2044 } catch (Exception e) {} 2045 } 2046 } 2047 // Prune all the tasks with removed components from the list of recent tasks 2048 synchronized (ActivityManagerService.this) { 2049 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2050 // Remove the task but don't kill the process (since other components in that 2051 // package may still be running and in the background) 2052 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2053 } 2054 } 2055 } 2056 2057 @Override 2058 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2059 // Force stop the specified packages 2060 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2061 if (packages != null) { 2062 for (String pkg : packages) { 2063 synchronized (ActivityManagerService.this) { 2064 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2065 userId, "finished booting")) { 2066 return true; 2067 } 2068 } 2069 } 2070 } 2071 return false; 2072 } 2073 }; 2074 2075 public void setSystemProcess() { 2076 try { 2077 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2078 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2079 ServiceManager.addService("meminfo", new MemBinder(this)); 2080 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2081 ServiceManager.addService("dbinfo", new DbBinder(this)); 2082 if (MONITOR_CPU_USAGE) { 2083 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2084 } 2085 ServiceManager.addService("permission", new PermissionController(this)); 2086 2087 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2088 "android", STOCK_PM_FLAGS); 2089 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2090 2091 synchronized (this) { 2092 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2093 app.persistent = true; 2094 app.pid = MY_PID; 2095 app.maxAdj = ProcessList.SYSTEM_ADJ; 2096 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2097 mProcessNames.put(app.processName, app.uid, app); 2098 synchronized (mPidsSelfLocked) { 2099 mPidsSelfLocked.put(app.pid, app); 2100 } 2101 updateLruProcessLocked(app, false, null); 2102 updateOomAdjLocked(); 2103 } 2104 } catch (PackageManager.NameNotFoundException e) { 2105 throw new RuntimeException( 2106 "Unable to find android system package", e); 2107 } 2108 } 2109 2110 public void setWindowManager(WindowManagerService wm) { 2111 mWindowManager = wm; 2112 mStackSupervisor.setWindowManager(wm); 2113 } 2114 2115 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2116 mUsageStatsService = usageStatsManager; 2117 } 2118 2119 public void startObservingNativeCrashes() { 2120 final NativeCrashListener ncl = new NativeCrashListener(this); 2121 ncl.start(); 2122 } 2123 2124 public IAppOpsService getAppOpsService() { 2125 return mAppOpsService; 2126 } 2127 2128 static class MemBinder extends Binder { 2129 ActivityManagerService mActivityManagerService; 2130 MemBinder(ActivityManagerService activityManagerService) { 2131 mActivityManagerService = activityManagerService; 2132 } 2133 2134 @Override 2135 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2136 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2137 != PackageManager.PERMISSION_GRANTED) { 2138 pw.println("Permission Denial: can't dump meminfo from from pid=" 2139 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2140 + " without permission " + android.Manifest.permission.DUMP); 2141 return; 2142 } 2143 2144 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2145 } 2146 } 2147 2148 static class GraphicsBinder extends Binder { 2149 ActivityManagerService mActivityManagerService; 2150 GraphicsBinder(ActivityManagerService activityManagerService) { 2151 mActivityManagerService = activityManagerService; 2152 } 2153 2154 @Override 2155 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2156 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2157 != PackageManager.PERMISSION_GRANTED) { 2158 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2159 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2160 + " without permission " + android.Manifest.permission.DUMP); 2161 return; 2162 } 2163 2164 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2165 } 2166 } 2167 2168 static class DbBinder extends Binder { 2169 ActivityManagerService mActivityManagerService; 2170 DbBinder(ActivityManagerService activityManagerService) { 2171 mActivityManagerService = activityManagerService; 2172 } 2173 2174 @Override 2175 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2176 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2177 != PackageManager.PERMISSION_GRANTED) { 2178 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2179 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2180 + " without permission " + android.Manifest.permission.DUMP); 2181 return; 2182 } 2183 2184 mActivityManagerService.dumpDbInfo(fd, pw, args); 2185 } 2186 } 2187 2188 static class CpuBinder extends Binder { 2189 ActivityManagerService mActivityManagerService; 2190 CpuBinder(ActivityManagerService activityManagerService) { 2191 mActivityManagerService = activityManagerService; 2192 } 2193 2194 @Override 2195 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2196 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2197 != PackageManager.PERMISSION_GRANTED) { 2198 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2199 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2200 + " without permission " + android.Manifest.permission.DUMP); 2201 return; 2202 } 2203 2204 synchronized (mActivityManagerService.mProcessCpuTracker) { 2205 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2206 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2207 SystemClock.uptimeMillis())); 2208 } 2209 } 2210 } 2211 2212 public static final class Lifecycle extends SystemService { 2213 private final ActivityManagerService mService; 2214 2215 public Lifecycle(Context context) { 2216 super(context); 2217 mService = new ActivityManagerService(context); 2218 } 2219 2220 @Override 2221 public void onStart() { 2222 mService.start(); 2223 } 2224 2225 public ActivityManagerService getService() { 2226 return mService; 2227 } 2228 } 2229 2230 // Note: This method is invoked on the main thread but may need to attach various 2231 // handlers to other threads. So take care to be explicit about the looper. 2232 public ActivityManagerService(Context systemContext) { 2233 mContext = systemContext; 2234 mFactoryTest = FactoryTest.getMode(); 2235 mSystemThread = ActivityThread.currentActivityThread(); 2236 2237 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2238 2239 mHandlerThread = new ServiceThread(TAG, 2240 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2241 mHandlerThread.start(); 2242 mHandler = new MainHandler(mHandlerThread.getLooper()); 2243 2244 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2245 "foreground", BROADCAST_FG_TIMEOUT, false); 2246 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2247 "background", BROADCAST_BG_TIMEOUT, true); 2248 mBroadcastQueues[0] = mFgBroadcastQueue; 2249 mBroadcastQueues[1] = mBgBroadcastQueue; 2250 2251 mServices = new ActiveServices(this); 2252 mProviderMap = new ProviderMap(this); 2253 2254 // TODO: Move creation of battery stats service outside of activity manager service. 2255 File dataDir = Environment.getDataDirectory(); 2256 File systemDir = new File(dataDir, "system"); 2257 systemDir.mkdirs(); 2258 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2259 mBatteryStatsService.getActiveStatistics().readLocked(); 2260 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2261 mOnBattery = DEBUG_POWER ? true 2262 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2263 mBatteryStatsService.getActiveStatistics().setCallback(this); 2264 2265 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2266 2267 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2268 2269 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2270 2271 // User 0 is the first and only user that runs at boot. 2272 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2273 mUserLru.add(Integer.valueOf(0)); 2274 updateStartedUserArrayLocked(); 2275 2276 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2277 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2278 2279 mConfiguration.setToDefaults(); 2280 mConfiguration.setLocale(Locale.getDefault()); 2281 2282 mConfigurationSeq = mConfiguration.seq = 1; 2283 mProcessCpuTracker.init(); 2284 2285 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2286 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2287 mStackSupervisor = new ActivityStackSupervisor(this); 2288 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2289 2290 mProcessCpuThread = new Thread("CpuTracker") { 2291 @Override 2292 public void run() { 2293 while (true) { 2294 try { 2295 try { 2296 synchronized(this) { 2297 final long now = SystemClock.uptimeMillis(); 2298 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2299 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2300 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2301 // + ", write delay=" + nextWriteDelay); 2302 if (nextWriteDelay < nextCpuDelay) { 2303 nextCpuDelay = nextWriteDelay; 2304 } 2305 if (nextCpuDelay > 0) { 2306 mProcessCpuMutexFree.set(true); 2307 this.wait(nextCpuDelay); 2308 } 2309 } 2310 } catch (InterruptedException e) { 2311 } 2312 updateCpuStatsNow(); 2313 } catch (Exception e) { 2314 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2315 } 2316 } 2317 } 2318 }; 2319 2320 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2321 2322 Watchdog.getInstance().addMonitor(this); 2323 Watchdog.getInstance().addThread(mHandler); 2324 } 2325 2326 public void setSystemServiceManager(SystemServiceManager mgr) { 2327 mSystemServiceManager = mgr; 2328 } 2329 2330 private void start() { 2331 Process.removeAllProcessGroups(); 2332 mProcessCpuThread.start(); 2333 2334 mBatteryStatsService.publish(mContext); 2335 mAppOpsService.publish(mContext); 2336 Slog.d("AppOps", "AppOpsService published"); 2337 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2338 } 2339 2340 public void initPowerManagement() { 2341 mStackSupervisor.initPowerManagement(); 2342 mBatteryStatsService.initPowerManagement(); 2343 } 2344 2345 @Override 2346 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2347 throws RemoteException { 2348 if (code == SYSPROPS_TRANSACTION) { 2349 // We need to tell all apps about the system property change. 2350 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2351 synchronized(this) { 2352 final int NP = mProcessNames.getMap().size(); 2353 for (int ip=0; ip<NP; ip++) { 2354 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2355 final int NA = apps.size(); 2356 for (int ia=0; ia<NA; ia++) { 2357 ProcessRecord app = apps.valueAt(ia); 2358 if (app.thread != null) { 2359 procs.add(app.thread.asBinder()); 2360 } 2361 } 2362 } 2363 } 2364 2365 int N = procs.size(); 2366 for (int i=0; i<N; i++) { 2367 Parcel data2 = Parcel.obtain(); 2368 try { 2369 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2370 } catch (RemoteException e) { 2371 } 2372 data2.recycle(); 2373 } 2374 } 2375 try { 2376 return super.onTransact(code, data, reply, flags); 2377 } catch (RuntimeException e) { 2378 // The activity manager only throws security exceptions, so let's 2379 // log all others. 2380 if (!(e instanceof SecurityException)) { 2381 Slog.wtf(TAG, "Activity Manager Crash", e); 2382 } 2383 throw e; 2384 } 2385 } 2386 2387 void updateCpuStats() { 2388 final long now = SystemClock.uptimeMillis(); 2389 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2390 return; 2391 } 2392 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2393 synchronized (mProcessCpuThread) { 2394 mProcessCpuThread.notify(); 2395 } 2396 } 2397 } 2398 2399 void updateCpuStatsNow() { 2400 synchronized (mProcessCpuTracker) { 2401 mProcessCpuMutexFree.set(false); 2402 final long now = SystemClock.uptimeMillis(); 2403 boolean haveNewCpuStats = false; 2404 2405 if (MONITOR_CPU_USAGE && 2406 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2407 mLastCpuTime.set(now); 2408 haveNewCpuStats = true; 2409 mProcessCpuTracker.update(); 2410 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2411 //Slog.i(TAG, "Total CPU usage: " 2412 // + mProcessCpu.getTotalCpuPercent() + "%"); 2413 2414 // Slog the cpu usage if the property is set. 2415 if ("true".equals(SystemProperties.get("events.cpu"))) { 2416 int user = mProcessCpuTracker.getLastUserTime(); 2417 int system = mProcessCpuTracker.getLastSystemTime(); 2418 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2419 int irq = mProcessCpuTracker.getLastIrqTime(); 2420 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2421 int idle = mProcessCpuTracker.getLastIdleTime(); 2422 2423 int total = user + system + iowait + irq + softIrq + idle; 2424 if (total == 0) total = 1; 2425 2426 EventLog.writeEvent(EventLogTags.CPU, 2427 ((user+system+iowait+irq+softIrq) * 100) / total, 2428 (user * 100) / total, 2429 (system * 100) / total, 2430 (iowait * 100) / total, 2431 (irq * 100) / total, 2432 (softIrq * 100) / total); 2433 } 2434 } 2435 2436 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2437 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2438 synchronized(bstats) { 2439 synchronized(mPidsSelfLocked) { 2440 if (haveNewCpuStats) { 2441 if (mOnBattery) { 2442 int perc = bstats.startAddingCpuLocked(); 2443 int totalUTime = 0; 2444 int totalSTime = 0; 2445 final int N = mProcessCpuTracker.countStats(); 2446 for (int i=0; i<N; i++) { 2447 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2448 if (!st.working) { 2449 continue; 2450 } 2451 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2452 int otherUTime = (st.rel_utime*perc)/100; 2453 int otherSTime = (st.rel_stime*perc)/100; 2454 totalUTime += otherUTime; 2455 totalSTime += otherSTime; 2456 if (pr != null) { 2457 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2458 if (ps == null || !ps.isActive()) { 2459 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2460 pr.info.uid, pr.processName); 2461 } 2462 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2463 st.rel_stime-otherSTime); 2464 ps.addSpeedStepTimes(cpuSpeedTimes); 2465 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2466 } else { 2467 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2468 if (ps == null || !ps.isActive()) { 2469 st.batteryStats = ps = bstats.getProcessStatsLocked( 2470 bstats.mapUid(st.uid), st.name); 2471 } 2472 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2473 st.rel_stime-otherSTime); 2474 ps.addSpeedStepTimes(cpuSpeedTimes); 2475 } 2476 } 2477 bstats.finishAddingCpuLocked(perc, totalUTime, 2478 totalSTime, cpuSpeedTimes); 2479 } 2480 } 2481 } 2482 2483 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2484 mLastWriteTime = now; 2485 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2486 } 2487 } 2488 } 2489 } 2490 2491 @Override 2492 public void batteryNeedsCpuUpdate() { 2493 updateCpuStatsNow(); 2494 } 2495 2496 @Override 2497 public void batteryPowerChanged(boolean onBattery) { 2498 // When plugging in, update the CPU stats first before changing 2499 // the plug state. 2500 updateCpuStatsNow(); 2501 synchronized (this) { 2502 synchronized(mPidsSelfLocked) { 2503 mOnBattery = DEBUG_POWER ? true : onBattery; 2504 } 2505 } 2506 } 2507 2508 /** 2509 * Initialize the application bind args. These are passed to each 2510 * process when the bindApplication() IPC is sent to the process. They're 2511 * lazily setup to make sure the services are running when they're asked for. 2512 */ 2513 private HashMap<String, IBinder> getCommonServicesLocked() { 2514 if (mAppBindArgs == null) { 2515 mAppBindArgs = new HashMap<String, IBinder>(); 2516 2517 // Setup the application init args 2518 mAppBindArgs.put("package", ServiceManager.getService("package")); 2519 mAppBindArgs.put("window", ServiceManager.getService("window")); 2520 mAppBindArgs.put(Context.ALARM_SERVICE, 2521 ServiceManager.getService(Context.ALARM_SERVICE)); 2522 } 2523 return mAppBindArgs; 2524 } 2525 2526 final void setFocusedActivityLocked(ActivityRecord r) { 2527 if (mFocusedActivity != r) { 2528 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2529 mFocusedActivity = r; 2530 if (r.task != null && r.task.voiceInteractor != null) { 2531 startRunningVoiceLocked(); 2532 } else { 2533 finishRunningVoiceLocked(); 2534 } 2535 mStackSupervisor.setFocusedStack(r); 2536 if (r != null) { 2537 mWindowManager.setFocusedApp(r.appToken, true); 2538 } 2539 applyUpdateLockStateLocked(r); 2540 } 2541 } 2542 2543 final void clearFocusedActivity(ActivityRecord r) { 2544 if (mFocusedActivity == r) { 2545 mFocusedActivity = null; 2546 } 2547 } 2548 2549 @Override 2550 public void setFocusedStack(int stackId) { 2551 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2552 synchronized (ActivityManagerService.this) { 2553 ActivityStack stack = mStackSupervisor.getStack(stackId); 2554 if (stack != null) { 2555 ActivityRecord r = stack.topRunningActivityLocked(null); 2556 if (r != null) { 2557 setFocusedActivityLocked(r); 2558 } 2559 } 2560 } 2561 } 2562 2563 @Override 2564 public void notifyActivityDrawn(IBinder token) { 2565 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2566 synchronized (this) { 2567 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2568 if (r != null) { 2569 r.task.stack.notifyActivityDrawnLocked(r); 2570 } 2571 } 2572 } 2573 2574 final void applyUpdateLockStateLocked(ActivityRecord r) { 2575 // Modifications to the UpdateLock state are done on our handler, outside 2576 // the activity manager's locks. The new state is determined based on the 2577 // state *now* of the relevant activity record. The object is passed to 2578 // the handler solely for logging detail, not to be consulted/modified. 2579 final boolean nextState = r != null && r.immersive; 2580 mHandler.sendMessage( 2581 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2582 } 2583 2584 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2585 Message msg = Message.obtain(); 2586 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2587 msg.obj = r.task.askedCompatMode ? null : r; 2588 mHandler.sendMessage(msg); 2589 } 2590 2591 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2592 String what, Object obj, ProcessRecord srcApp) { 2593 app.lastActivityTime = now; 2594 2595 if (app.activities.size() > 0) { 2596 // Don't want to touch dependent processes that are hosting activities. 2597 return index; 2598 } 2599 2600 int lrui = mLruProcesses.lastIndexOf(app); 2601 if (lrui < 0) { 2602 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2603 + what + " " + obj + " from " + srcApp); 2604 return index; 2605 } 2606 2607 if (lrui >= index) { 2608 // Don't want to cause this to move dependent processes *back* in the 2609 // list as if they were less frequently used. 2610 return index; 2611 } 2612 2613 if (lrui >= mLruProcessActivityStart) { 2614 // Don't want to touch dependent processes that are hosting activities. 2615 return index; 2616 } 2617 2618 mLruProcesses.remove(lrui); 2619 if (index > 0) { 2620 index--; 2621 } 2622 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2623 + " in LRU list: " + app); 2624 mLruProcesses.add(index, app); 2625 return index; 2626 } 2627 2628 final void removeLruProcessLocked(ProcessRecord app) { 2629 int lrui = mLruProcesses.lastIndexOf(app); 2630 if (lrui >= 0) { 2631 if (!app.killed) { 2632 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2633 Process.killProcessQuiet(app.pid); 2634 Process.killProcessGroup(app.info.uid, app.pid); 2635 } 2636 if (lrui <= mLruProcessActivityStart) { 2637 mLruProcessActivityStart--; 2638 } 2639 if (lrui <= mLruProcessServiceStart) { 2640 mLruProcessServiceStart--; 2641 } 2642 mLruProcesses.remove(lrui); 2643 } 2644 } 2645 2646 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2647 ProcessRecord client) { 2648 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2649 || app.treatLikeActivity; 2650 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2651 if (!activityChange && hasActivity) { 2652 // The process has activities, so we are only allowing activity-based adjustments 2653 // to move it. It should be kept in the front of the list with other 2654 // processes that have activities, and we don't want those to change their 2655 // order except due to activity operations. 2656 return; 2657 } 2658 2659 mLruSeq++; 2660 final long now = SystemClock.uptimeMillis(); 2661 app.lastActivityTime = now; 2662 2663 // First a quick reject: if the app is already at the position we will 2664 // put it, then there is nothing to do. 2665 if (hasActivity) { 2666 final int N = mLruProcesses.size(); 2667 if (N > 0 && mLruProcesses.get(N-1) == app) { 2668 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2669 return; 2670 } 2671 } else { 2672 if (mLruProcessServiceStart > 0 2673 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2674 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2675 return; 2676 } 2677 } 2678 2679 int lrui = mLruProcesses.lastIndexOf(app); 2680 2681 if (app.persistent && lrui >= 0) { 2682 // We don't care about the position of persistent processes, as long as 2683 // they are in the list. 2684 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2685 return; 2686 } 2687 2688 /* In progress: compute new position first, so we can avoid doing work 2689 if the process is not actually going to move. Not yet working. 2690 int addIndex; 2691 int nextIndex; 2692 boolean inActivity = false, inService = false; 2693 if (hasActivity) { 2694 // Process has activities, put it at the very tipsy-top. 2695 addIndex = mLruProcesses.size(); 2696 nextIndex = mLruProcessServiceStart; 2697 inActivity = true; 2698 } else if (hasService) { 2699 // Process has services, put it at the top of the service list. 2700 addIndex = mLruProcessActivityStart; 2701 nextIndex = mLruProcessServiceStart; 2702 inActivity = true; 2703 inService = true; 2704 } else { 2705 // Process not otherwise of interest, it goes to the top of the non-service area. 2706 addIndex = mLruProcessServiceStart; 2707 if (client != null) { 2708 int clientIndex = mLruProcesses.lastIndexOf(client); 2709 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2710 + app); 2711 if (clientIndex >= 0 && addIndex > clientIndex) { 2712 addIndex = clientIndex; 2713 } 2714 } 2715 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2716 } 2717 2718 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2719 + mLruProcessActivityStart + "): " + app); 2720 */ 2721 2722 if (lrui >= 0) { 2723 if (lrui < mLruProcessActivityStart) { 2724 mLruProcessActivityStart--; 2725 } 2726 if (lrui < mLruProcessServiceStart) { 2727 mLruProcessServiceStart--; 2728 } 2729 /* 2730 if (addIndex > lrui) { 2731 addIndex--; 2732 } 2733 if (nextIndex > lrui) { 2734 nextIndex--; 2735 } 2736 */ 2737 mLruProcesses.remove(lrui); 2738 } 2739 2740 /* 2741 mLruProcesses.add(addIndex, app); 2742 if (inActivity) { 2743 mLruProcessActivityStart++; 2744 } 2745 if (inService) { 2746 mLruProcessActivityStart++; 2747 } 2748 */ 2749 2750 int nextIndex; 2751 if (hasActivity) { 2752 final int N = mLruProcesses.size(); 2753 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2754 // Process doesn't have activities, but has clients with 2755 // activities... move it up, but one below the top (the top 2756 // should always have a real activity). 2757 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2758 mLruProcesses.add(N-1, app); 2759 // To keep it from spamming the LRU list (by making a bunch of clients), 2760 // we will push down any other entries owned by the app. 2761 final int uid = app.info.uid; 2762 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2763 ProcessRecord subProc = mLruProcesses.get(i); 2764 if (subProc.info.uid == uid) { 2765 // We want to push this one down the list. If the process after 2766 // it is for the same uid, however, don't do so, because we don't 2767 // want them internally to be re-ordered. 2768 if (mLruProcesses.get(i-1).info.uid != uid) { 2769 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2770 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2771 ProcessRecord tmp = mLruProcesses.get(i); 2772 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2773 mLruProcesses.set(i-1, tmp); 2774 i--; 2775 } 2776 } else { 2777 // A gap, we can stop here. 2778 break; 2779 } 2780 } 2781 } else { 2782 // Process has activities, put it at the very tipsy-top. 2783 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2784 mLruProcesses.add(app); 2785 } 2786 nextIndex = mLruProcessServiceStart; 2787 } else if (hasService) { 2788 // Process has services, put it at the top of the service list. 2789 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2790 mLruProcesses.add(mLruProcessActivityStart, app); 2791 nextIndex = mLruProcessServiceStart; 2792 mLruProcessActivityStart++; 2793 } else { 2794 // Process not otherwise of interest, it goes to the top of the non-service area. 2795 int index = mLruProcessServiceStart; 2796 if (client != null) { 2797 // If there is a client, don't allow the process to be moved up higher 2798 // in the list than that client. 2799 int clientIndex = mLruProcesses.lastIndexOf(client); 2800 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2801 + " when updating " + app); 2802 if (clientIndex <= lrui) { 2803 // Don't allow the client index restriction to push it down farther in the 2804 // list than it already is. 2805 clientIndex = lrui; 2806 } 2807 if (clientIndex >= 0 && index > clientIndex) { 2808 index = clientIndex; 2809 } 2810 } 2811 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2812 mLruProcesses.add(index, app); 2813 nextIndex = index-1; 2814 mLruProcessActivityStart++; 2815 mLruProcessServiceStart++; 2816 } 2817 2818 // If the app is currently using a content provider or service, 2819 // bump those processes as well. 2820 for (int j=app.connections.size()-1; j>=0; j--) { 2821 ConnectionRecord cr = app.connections.valueAt(j); 2822 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2823 && cr.binding.service.app != null 2824 && cr.binding.service.app.lruSeq != mLruSeq 2825 && !cr.binding.service.app.persistent) { 2826 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2827 "service connection", cr, app); 2828 } 2829 } 2830 for (int j=app.conProviders.size()-1; j>=0; j--) { 2831 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2832 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2833 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2834 "provider reference", cpr, app); 2835 } 2836 } 2837 } 2838 2839 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2840 if (uid == Process.SYSTEM_UID) { 2841 // The system gets to run in any process. If there are multiple 2842 // processes with the same uid, just pick the first (this 2843 // should never happen). 2844 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2845 if (procs == null) return null; 2846 final int N = procs.size(); 2847 for (int i = 0; i < N; i++) { 2848 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2849 } 2850 } 2851 ProcessRecord proc = mProcessNames.get(processName, uid); 2852 if (false && proc != null && !keepIfLarge 2853 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2854 && proc.lastCachedPss >= 4000) { 2855 // Turn this condition on to cause killing to happen regularly, for testing. 2856 if (proc.baseProcessTracker != null) { 2857 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2858 } 2859 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2860 } else if (proc != null && !keepIfLarge 2861 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2862 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2863 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2864 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2865 if (proc.baseProcessTracker != null) { 2866 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2867 } 2868 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2869 } 2870 } 2871 return proc; 2872 } 2873 2874 void ensurePackageDexOpt(String packageName) { 2875 IPackageManager pm = AppGlobals.getPackageManager(); 2876 try { 2877 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2878 mDidDexOpt = true; 2879 } 2880 } catch (RemoteException e) { 2881 } 2882 } 2883 2884 boolean isNextTransitionForward() { 2885 int transit = mWindowManager.getPendingAppTransition(); 2886 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2887 || transit == AppTransition.TRANSIT_TASK_OPEN 2888 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2889 } 2890 2891 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2892 String processName, String abiOverride, int uid, Runnable crashHandler) { 2893 synchronized(this) { 2894 ApplicationInfo info = new ApplicationInfo(); 2895 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2896 // For isolated processes, the former contains the parent's uid and the latter the 2897 // actual uid of the isolated process. 2898 // In the special case introduced by this method (which is, starting an isolated 2899 // process directly from the SystemServer without an actual parent app process) the 2900 // closest thing to a parent's uid is SYSTEM_UID. 2901 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2902 // the |isolated| logic in the ProcessRecord constructor. 2903 info.uid = Process.SYSTEM_UID; 2904 info.processName = processName; 2905 info.className = entryPoint; 2906 info.packageName = "android"; 2907 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2908 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2909 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2910 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2911 crashHandler); 2912 return proc != null ? proc.pid : 0; 2913 } 2914 } 2915 2916 final ProcessRecord startProcessLocked(String processName, 2917 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2918 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2919 boolean isolated, boolean keepIfLarge) { 2920 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2921 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2922 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2923 null /* crashHandler */); 2924 } 2925 2926 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2927 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2928 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2929 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2930 long startTime = SystemClock.elapsedRealtime(); 2931 ProcessRecord app; 2932 if (!isolated) { 2933 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2934 checkTime(startTime, "startProcess: after getProcessRecord"); 2935 } else { 2936 // If this is an isolated process, it can't re-use an existing process. 2937 app = null; 2938 } 2939 // We don't have to do anything more if: 2940 // (1) There is an existing application record; and 2941 // (2) The caller doesn't think it is dead, OR there is no thread 2942 // object attached to it so we know it couldn't have crashed; and 2943 // (3) There is a pid assigned to it, so it is either starting or 2944 // already running. 2945 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2946 + " app=" + app + " knownToBeDead=" + knownToBeDead 2947 + " thread=" + (app != null ? app.thread : null) 2948 + " pid=" + (app != null ? app.pid : -1)); 2949 if (app != null && app.pid > 0) { 2950 if (!knownToBeDead || app.thread == null) { 2951 // We already have the app running, or are waiting for it to 2952 // come up (we have a pid but not yet its thread), so keep it. 2953 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2954 // If this is a new package in the process, add the package to the list 2955 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2956 checkTime(startTime, "startProcess: done, added package to proc"); 2957 return app; 2958 } 2959 2960 // An application record is attached to a previous process, 2961 // clean it up now. 2962 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2963 checkTime(startTime, "startProcess: bad proc running, killing"); 2964 Process.killProcessGroup(app.info.uid, app.pid); 2965 handleAppDiedLocked(app, true, true); 2966 checkTime(startTime, "startProcess: done killing old proc"); 2967 } 2968 2969 String hostingNameStr = hostingName != null 2970 ? hostingName.flattenToShortString() : null; 2971 2972 if (!isolated) { 2973 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2974 // If we are in the background, then check to see if this process 2975 // is bad. If so, we will just silently fail. 2976 if (mBadProcesses.get(info.processName, info.uid) != null) { 2977 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2978 + "/" + info.processName); 2979 return null; 2980 } 2981 } else { 2982 // When the user is explicitly starting a process, then clear its 2983 // crash count so that we won't make it bad until they see at 2984 // least one crash dialog again, and make the process good again 2985 // if it had been bad. 2986 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2987 + "/" + info.processName); 2988 mProcessCrashTimes.remove(info.processName, info.uid); 2989 if (mBadProcesses.get(info.processName, info.uid) != null) { 2990 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2991 UserHandle.getUserId(info.uid), info.uid, 2992 info.processName); 2993 mBadProcesses.remove(info.processName, info.uid); 2994 if (app != null) { 2995 app.bad = false; 2996 } 2997 } 2998 } 2999 } 3000 3001 if (app == null) { 3002 checkTime(startTime, "startProcess: creating new process record"); 3003 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3004 app.crashHandler = crashHandler; 3005 if (app == null) { 3006 Slog.w(TAG, "Failed making new process record for " 3007 + processName + "/" + info.uid + " isolated=" + isolated); 3008 return null; 3009 } 3010 mProcessNames.put(processName, app.uid, app); 3011 if (isolated) { 3012 mIsolatedProcesses.put(app.uid, app); 3013 } 3014 checkTime(startTime, "startProcess: done creating new process record"); 3015 } else { 3016 // If this is a new package in the process, add the package to the list 3017 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3018 checkTime(startTime, "startProcess: added package to existing proc"); 3019 } 3020 3021 // If the system is not ready yet, then hold off on starting this 3022 // process until it is. 3023 if (!mProcessesReady 3024 && !isAllowedWhileBooting(info) 3025 && !allowWhileBooting) { 3026 if (!mProcessesOnHold.contains(app)) { 3027 mProcessesOnHold.add(app); 3028 } 3029 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3030 checkTime(startTime, "startProcess: returning with proc on hold"); 3031 return app; 3032 } 3033 3034 checkTime(startTime, "startProcess: stepping in to startProcess"); 3035 startProcessLocked( 3036 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3037 checkTime(startTime, "startProcess: done starting proc!"); 3038 return (app.pid != 0) ? app : null; 3039 } 3040 3041 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3042 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3043 } 3044 3045 private final void startProcessLocked(ProcessRecord app, 3046 String hostingType, String hostingNameStr) { 3047 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3048 null /* entryPoint */, null /* entryPointArgs */); 3049 } 3050 3051 private final void startProcessLocked(ProcessRecord app, String hostingType, 3052 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3053 long startTime = SystemClock.elapsedRealtime(); 3054 if (app.pid > 0 && app.pid != MY_PID) { 3055 checkTime(startTime, "startProcess: removing from pids map"); 3056 synchronized (mPidsSelfLocked) { 3057 mPidsSelfLocked.remove(app.pid); 3058 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3059 } 3060 checkTime(startTime, "startProcess: done removing from pids map"); 3061 app.setPid(0); 3062 } 3063 3064 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3065 "startProcessLocked removing on hold: " + app); 3066 mProcessesOnHold.remove(app); 3067 3068 checkTime(startTime, "startProcess: starting to update cpu stats"); 3069 updateCpuStats(); 3070 checkTime(startTime, "startProcess: done updating cpu stats"); 3071 3072 try { 3073 int uid = app.uid; 3074 3075 int[] gids = null; 3076 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3077 if (!app.isolated) { 3078 int[] permGids = null; 3079 try { 3080 checkTime(startTime, "startProcess: getting gids from package manager"); 3081 final PackageManager pm = mContext.getPackageManager(); 3082 permGids = pm.getPackageGids(app.info.packageName); 3083 3084 if (Environment.isExternalStorageEmulated()) { 3085 checkTime(startTime, "startProcess: checking external storage perm"); 3086 if (pm.checkPermission( 3087 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3088 app.info.packageName) == PERMISSION_GRANTED) { 3089 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3090 } else { 3091 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3092 } 3093 } 3094 } catch (PackageManager.NameNotFoundException e) { 3095 Slog.w(TAG, "Unable to retrieve gids", e); 3096 } 3097 3098 /* 3099 * Add shared application and profile GIDs so applications can share some 3100 * resources like shared libraries and access user-wide resources 3101 */ 3102 if (permGids == null) { 3103 gids = new int[2]; 3104 } else { 3105 gids = new int[permGids.length + 2]; 3106 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3107 } 3108 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3109 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3110 } 3111 checkTime(startTime, "startProcess: building args"); 3112 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3113 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3114 && mTopComponent != null 3115 && app.processName.equals(mTopComponent.getPackageName())) { 3116 uid = 0; 3117 } 3118 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3119 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3120 uid = 0; 3121 } 3122 } 3123 int debugFlags = 0; 3124 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3125 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3126 // Also turn on CheckJNI for debuggable apps. It's quite 3127 // awkward to turn on otherwise. 3128 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3129 } 3130 // Run the app in safe mode if its manifest requests so or the 3131 // system is booted in safe mode. 3132 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3133 mSafeMode == true) { 3134 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3135 } 3136 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3137 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3138 } 3139 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3140 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3141 } 3142 if ("1".equals(SystemProperties.get("debug.assert"))) { 3143 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3144 } 3145 3146 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3147 if (requiredAbi == null) { 3148 requiredAbi = Build.SUPPORTED_ABIS[0]; 3149 } 3150 3151 String instructionSet = null; 3152 if (app.info.primaryCpuAbi != null) { 3153 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3154 } 3155 3156 // Start the process. It will either succeed and return a result containing 3157 // the PID of the new process, or else throw a RuntimeException. 3158 boolean isActivityProcess = (entryPoint == null); 3159 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3160 checkTime(startTime, "startProcess: asking zygote to start proc"); 3161 Process.ProcessStartResult startResult = Process.start(entryPoint, 3162 app.processName, uid, uid, gids, debugFlags, mountExternal, 3163 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3164 entryPointArgs); 3165 checkTime(startTime, "startProcess: returned from zygote!"); 3166 3167 if (app.isolated) { 3168 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3169 } 3170 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3171 checkTime(startTime, "startProcess: done updating battery stats"); 3172 3173 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3174 UserHandle.getUserId(uid), startResult.pid, uid, 3175 app.processName, hostingType, 3176 hostingNameStr != null ? hostingNameStr : ""); 3177 3178 if (app.persistent) { 3179 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3180 } 3181 3182 checkTime(startTime, "startProcess: building log message"); 3183 StringBuilder buf = mStringBuilder; 3184 buf.setLength(0); 3185 buf.append("Start proc "); 3186 buf.append(app.processName); 3187 if (!isActivityProcess) { 3188 buf.append(" ["); 3189 buf.append(entryPoint); 3190 buf.append("]"); 3191 } 3192 buf.append(" for "); 3193 buf.append(hostingType); 3194 if (hostingNameStr != null) { 3195 buf.append(" "); 3196 buf.append(hostingNameStr); 3197 } 3198 buf.append(": pid="); 3199 buf.append(startResult.pid); 3200 buf.append(" uid="); 3201 buf.append(uid); 3202 buf.append(" gids={"); 3203 if (gids != null) { 3204 for (int gi=0; gi<gids.length; gi++) { 3205 if (gi != 0) buf.append(", "); 3206 buf.append(gids[gi]); 3207 3208 } 3209 } 3210 buf.append("}"); 3211 if (requiredAbi != null) { 3212 buf.append(" abi="); 3213 buf.append(requiredAbi); 3214 } 3215 Slog.i(TAG, buf.toString()); 3216 app.setPid(startResult.pid); 3217 app.usingWrapper = startResult.usingWrapper; 3218 app.removed = false; 3219 app.killed = false; 3220 app.killedByAm = false; 3221 checkTime(startTime, "startProcess: starting to update pids map"); 3222 synchronized (mPidsSelfLocked) { 3223 this.mPidsSelfLocked.put(startResult.pid, app); 3224 if (isActivityProcess) { 3225 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3226 msg.obj = app; 3227 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3228 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3229 } 3230 } 3231 checkTime(startTime, "startProcess: done updating pids map"); 3232 } catch (RuntimeException e) { 3233 // XXX do better error recovery. 3234 app.setPid(0); 3235 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3236 if (app.isolated) { 3237 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3238 } 3239 Slog.e(TAG, "Failure starting process " + app.processName, e); 3240 } 3241 } 3242 3243 void updateUsageStats(ActivityRecord component, boolean resumed) { 3244 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3245 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3246 if (resumed) { 3247 if (mUsageStatsService != null) { 3248 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3249 UsageEvents.Event.MOVE_TO_FOREGROUND); 3250 } 3251 synchronized (stats) { 3252 stats.noteActivityResumedLocked(component.app.uid); 3253 } 3254 } else { 3255 if (mUsageStatsService != null) { 3256 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3257 UsageEvents.Event.MOVE_TO_BACKGROUND); 3258 } 3259 synchronized (stats) { 3260 stats.noteActivityPausedLocked(component.app.uid); 3261 } 3262 } 3263 } 3264 3265 Intent getHomeIntent() { 3266 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3267 intent.setComponent(mTopComponent); 3268 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3269 intent.addCategory(Intent.CATEGORY_HOME); 3270 } 3271 return intent; 3272 } 3273 3274 boolean startHomeActivityLocked(int userId) { 3275 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3276 && mTopAction == null) { 3277 // We are running in factory test mode, but unable to find 3278 // the factory test app, so just sit around displaying the 3279 // error message and don't try to start anything. 3280 return false; 3281 } 3282 Intent intent = getHomeIntent(); 3283 ActivityInfo aInfo = 3284 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3285 if (aInfo != null) { 3286 intent.setComponent(new ComponentName( 3287 aInfo.applicationInfo.packageName, aInfo.name)); 3288 // Don't do this if the home app is currently being 3289 // instrumented. 3290 aInfo = new ActivityInfo(aInfo); 3291 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3292 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3293 aInfo.applicationInfo.uid, true); 3294 if (app == null || app.instrumentationClass == null) { 3295 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3296 mStackSupervisor.startHomeActivity(intent, aInfo); 3297 } 3298 } 3299 3300 return true; 3301 } 3302 3303 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3304 ActivityInfo ai = null; 3305 ComponentName comp = intent.getComponent(); 3306 try { 3307 if (comp != null) { 3308 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3309 } else { 3310 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3311 intent, 3312 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3313 flags, userId); 3314 3315 if (info != null) { 3316 ai = info.activityInfo; 3317 } 3318 } 3319 } catch (RemoteException e) { 3320 // ignore 3321 } 3322 3323 return ai; 3324 } 3325 3326 /** 3327 * Starts the "new version setup screen" if appropriate. 3328 */ 3329 void startSetupActivityLocked() { 3330 // Only do this once per boot. 3331 if (mCheckedForSetup) { 3332 return; 3333 } 3334 3335 // We will show this screen if the current one is a different 3336 // version than the last one shown, and we are not running in 3337 // low-level factory test mode. 3338 final ContentResolver resolver = mContext.getContentResolver(); 3339 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3340 Settings.Global.getInt(resolver, 3341 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3342 mCheckedForSetup = true; 3343 3344 // See if we should be showing the platform update setup UI. 3345 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3346 List<ResolveInfo> ris = mContext.getPackageManager() 3347 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3348 3349 // We don't allow third party apps to replace this. 3350 ResolveInfo ri = null; 3351 for (int i=0; ris != null && i<ris.size(); i++) { 3352 if ((ris.get(i).activityInfo.applicationInfo.flags 3353 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3354 ri = ris.get(i); 3355 break; 3356 } 3357 } 3358 3359 if (ri != null) { 3360 String vers = ri.activityInfo.metaData != null 3361 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3362 : null; 3363 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3364 vers = ri.activityInfo.applicationInfo.metaData.getString( 3365 Intent.METADATA_SETUP_VERSION); 3366 } 3367 String lastVers = Settings.Secure.getString( 3368 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3369 if (vers != null && !vers.equals(lastVers)) { 3370 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3371 intent.setComponent(new ComponentName( 3372 ri.activityInfo.packageName, ri.activityInfo.name)); 3373 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3374 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3375 null); 3376 } 3377 } 3378 } 3379 } 3380 3381 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3382 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3383 } 3384 3385 void enforceNotIsolatedCaller(String caller) { 3386 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3387 throw new SecurityException("Isolated process not allowed to call " + caller); 3388 } 3389 } 3390 3391 void enforceShellRestriction(String restriction, int userHandle) { 3392 if (Binder.getCallingUid() == Process.SHELL_UID) { 3393 if (userHandle < 0 3394 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3395 throw new SecurityException("Shell does not have permission to access user " 3396 + userHandle); 3397 } 3398 } 3399 } 3400 3401 @Override 3402 public int getFrontActivityScreenCompatMode() { 3403 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3404 synchronized (this) { 3405 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3406 } 3407 } 3408 3409 @Override 3410 public void setFrontActivityScreenCompatMode(int mode) { 3411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3412 "setFrontActivityScreenCompatMode"); 3413 synchronized (this) { 3414 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3415 } 3416 } 3417 3418 @Override 3419 public int getPackageScreenCompatMode(String packageName) { 3420 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3421 synchronized (this) { 3422 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3423 } 3424 } 3425 3426 @Override 3427 public void setPackageScreenCompatMode(String packageName, int mode) { 3428 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3429 "setPackageScreenCompatMode"); 3430 synchronized (this) { 3431 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3432 } 3433 } 3434 3435 @Override 3436 public boolean getPackageAskScreenCompat(String packageName) { 3437 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3438 synchronized (this) { 3439 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3440 } 3441 } 3442 3443 @Override 3444 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3445 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3446 "setPackageAskScreenCompat"); 3447 synchronized (this) { 3448 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3449 } 3450 } 3451 3452 private void dispatchProcessesChanged() { 3453 int N; 3454 synchronized (this) { 3455 N = mPendingProcessChanges.size(); 3456 if (mActiveProcessChanges.length < N) { 3457 mActiveProcessChanges = new ProcessChangeItem[N]; 3458 } 3459 mPendingProcessChanges.toArray(mActiveProcessChanges); 3460 mAvailProcessChanges.addAll(mPendingProcessChanges); 3461 mPendingProcessChanges.clear(); 3462 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3463 } 3464 3465 int i = mProcessObservers.beginBroadcast(); 3466 while (i > 0) { 3467 i--; 3468 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3469 if (observer != null) { 3470 try { 3471 for (int j=0; j<N; j++) { 3472 ProcessChangeItem item = mActiveProcessChanges[j]; 3473 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3474 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3475 + item.pid + " uid=" + item.uid + ": " 3476 + item.foregroundActivities); 3477 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3478 item.foregroundActivities); 3479 } 3480 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3481 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3482 + item.pid + " uid=" + item.uid + ": " + item.processState); 3483 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3484 } 3485 } 3486 } catch (RemoteException e) { 3487 } 3488 } 3489 } 3490 mProcessObservers.finishBroadcast(); 3491 } 3492 3493 private void dispatchProcessDied(int pid, int uid) { 3494 int i = mProcessObservers.beginBroadcast(); 3495 while (i > 0) { 3496 i--; 3497 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3498 if (observer != null) { 3499 try { 3500 observer.onProcessDied(pid, uid); 3501 } catch (RemoteException e) { 3502 } 3503 } 3504 } 3505 mProcessObservers.finishBroadcast(); 3506 } 3507 3508 @Override 3509 public final int startActivity(IApplicationThread caller, String callingPackage, 3510 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3511 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3512 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3513 resultWho, requestCode, startFlags, profilerInfo, options, 3514 UserHandle.getCallingUserId()); 3515 } 3516 3517 @Override 3518 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3519 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3520 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3521 enforceNotIsolatedCaller("startActivity"); 3522 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3523 false, ALLOW_FULL_ONLY, "startActivity", null); 3524 // TODO: Switch to user app stacks here. 3525 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3526 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3527 profilerInfo, null, null, options, userId, null, null); 3528 } 3529 3530 @Override 3531 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3532 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3533 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3534 3535 // This is very dangerous -- it allows you to perform a start activity (including 3536 // permission grants) as any app that may launch one of your own activities. So 3537 // we will only allow this to be done from activities that are part of the core framework, 3538 // and then only when they are running as the system. 3539 final ActivityRecord sourceRecord; 3540 final int targetUid; 3541 final String targetPackage; 3542 synchronized (this) { 3543 if (resultTo == null) { 3544 throw new SecurityException("Must be called from an activity"); 3545 } 3546 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3547 if (sourceRecord == null) { 3548 throw new SecurityException("Called with bad activity token: " + resultTo); 3549 } 3550 if (!sourceRecord.info.packageName.equals("android")) { 3551 throw new SecurityException( 3552 "Must be called from an activity that is declared in the android package"); 3553 } 3554 if (sourceRecord.app == null) { 3555 throw new SecurityException("Called without a process attached to activity"); 3556 } 3557 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3558 // This is still okay, as long as this activity is running under the 3559 // uid of the original calling activity. 3560 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3561 throw new SecurityException( 3562 "Calling activity in uid " + sourceRecord.app.uid 3563 + " must be system uid or original calling uid " 3564 + sourceRecord.launchedFromUid); 3565 } 3566 } 3567 targetUid = sourceRecord.launchedFromUid; 3568 targetPackage = sourceRecord.launchedFromPackage; 3569 } 3570 3571 // TODO: Switch to user app stacks here. 3572 try { 3573 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3574 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3575 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3576 return ret; 3577 } catch (SecurityException e) { 3578 // XXX need to figure out how to propagate to original app. 3579 // A SecurityException here is generally actually a fault of the original 3580 // calling activity (such as a fairly granting permissions), so propagate it 3581 // back to them. 3582 /* 3583 StringBuilder msg = new StringBuilder(); 3584 msg.append("While launching"); 3585 msg.append(intent.toString()); 3586 msg.append(": "); 3587 msg.append(e.getMessage()); 3588 */ 3589 throw e; 3590 } 3591 } 3592 3593 @Override 3594 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3595 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3596 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3597 enforceNotIsolatedCaller("startActivityAndWait"); 3598 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3599 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3600 WaitResult res = new WaitResult(); 3601 // TODO: Switch to user app stacks here. 3602 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3603 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3604 options, userId, null, null); 3605 return res; 3606 } 3607 3608 @Override 3609 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3610 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3611 int startFlags, Configuration config, Bundle options, int userId) { 3612 enforceNotIsolatedCaller("startActivityWithConfig"); 3613 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3614 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3615 // TODO: Switch to user app stacks here. 3616 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3617 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3618 null, null, config, options, userId, null, null); 3619 return ret; 3620 } 3621 3622 @Override 3623 public int startActivityIntentSender(IApplicationThread caller, 3624 IntentSender intent, Intent fillInIntent, String resolvedType, 3625 IBinder resultTo, String resultWho, int requestCode, 3626 int flagsMask, int flagsValues, Bundle options) { 3627 enforceNotIsolatedCaller("startActivityIntentSender"); 3628 // Refuse possible leaked file descriptors 3629 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3630 throw new IllegalArgumentException("File descriptors passed in Intent"); 3631 } 3632 3633 IIntentSender sender = intent.getTarget(); 3634 if (!(sender instanceof PendingIntentRecord)) { 3635 throw new IllegalArgumentException("Bad PendingIntent object"); 3636 } 3637 3638 PendingIntentRecord pir = (PendingIntentRecord)sender; 3639 3640 synchronized (this) { 3641 // If this is coming from the currently resumed activity, it is 3642 // effectively saying that app switches are allowed at this point. 3643 final ActivityStack stack = getFocusedStack(); 3644 if (stack.mResumedActivity != null && 3645 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3646 mAppSwitchesAllowedTime = 0; 3647 } 3648 } 3649 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3650 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3651 return ret; 3652 } 3653 3654 @Override 3655 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3656 Intent intent, String resolvedType, IVoiceInteractionSession session, 3657 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3658 Bundle options, int userId) { 3659 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3660 != PackageManager.PERMISSION_GRANTED) { 3661 String msg = "Permission Denial: startVoiceActivity() from pid=" 3662 + Binder.getCallingPid() 3663 + ", uid=" + Binder.getCallingUid() 3664 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3665 Slog.w(TAG, msg); 3666 throw new SecurityException(msg); 3667 } 3668 if (session == null || interactor == null) { 3669 throw new NullPointerException("null session or interactor"); 3670 } 3671 userId = handleIncomingUser(callingPid, callingUid, userId, 3672 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3673 // TODO: Switch to user app stacks here. 3674 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3675 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3676 null, options, userId, null, null); 3677 } 3678 3679 @Override 3680 public boolean startNextMatchingActivity(IBinder callingActivity, 3681 Intent intent, Bundle options) { 3682 // Refuse possible leaked file descriptors 3683 if (intent != null && intent.hasFileDescriptors() == true) { 3684 throw new IllegalArgumentException("File descriptors passed in Intent"); 3685 } 3686 3687 synchronized (this) { 3688 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3689 if (r == null) { 3690 ActivityOptions.abort(options); 3691 return false; 3692 } 3693 if (r.app == null || r.app.thread == null) { 3694 // The caller is not running... d'oh! 3695 ActivityOptions.abort(options); 3696 return false; 3697 } 3698 intent = new Intent(intent); 3699 // The caller is not allowed to change the data. 3700 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3701 // And we are resetting to find the next component... 3702 intent.setComponent(null); 3703 3704 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3705 3706 ActivityInfo aInfo = null; 3707 try { 3708 List<ResolveInfo> resolves = 3709 AppGlobals.getPackageManager().queryIntentActivities( 3710 intent, r.resolvedType, 3711 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3712 UserHandle.getCallingUserId()); 3713 3714 // Look for the original activity in the list... 3715 final int N = resolves != null ? resolves.size() : 0; 3716 for (int i=0; i<N; i++) { 3717 ResolveInfo rInfo = resolves.get(i); 3718 if (rInfo.activityInfo.packageName.equals(r.packageName) 3719 && rInfo.activityInfo.name.equals(r.info.name)) { 3720 // We found the current one... the next matching is 3721 // after it. 3722 i++; 3723 if (i<N) { 3724 aInfo = resolves.get(i).activityInfo; 3725 } 3726 if (debug) { 3727 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3728 + "/" + r.info.name); 3729 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3730 + "/" + aInfo.name); 3731 } 3732 break; 3733 } 3734 } 3735 } catch (RemoteException e) { 3736 } 3737 3738 if (aInfo == null) { 3739 // Nobody who is next! 3740 ActivityOptions.abort(options); 3741 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3742 return false; 3743 } 3744 3745 intent.setComponent(new ComponentName( 3746 aInfo.applicationInfo.packageName, aInfo.name)); 3747 intent.setFlags(intent.getFlags()&~( 3748 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3749 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3750 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3751 Intent.FLAG_ACTIVITY_NEW_TASK)); 3752 3753 // Okay now we need to start the new activity, replacing the 3754 // currently running activity. This is a little tricky because 3755 // we want to start the new one as if the current one is finished, 3756 // but not finish the current one first so that there is no flicker. 3757 // And thus... 3758 final boolean wasFinishing = r.finishing; 3759 r.finishing = true; 3760 3761 // Propagate reply information over to the new activity. 3762 final ActivityRecord resultTo = r.resultTo; 3763 final String resultWho = r.resultWho; 3764 final int requestCode = r.requestCode; 3765 r.resultTo = null; 3766 if (resultTo != null) { 3767 resultTo.removeResultsLocked(r, resultWho, requestCode); 3768 } 3769 3770 final long origId = Binder.clearCallingIdentity(); 3771 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3772 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3773 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3774 -1, r.launchedFromUid, 0, options, false, null, null, null); 3775 Binder.restoreCallingIdentity(origId); 3776 3777 r.finishing = wasFinishing; 3778 if (res != ActivityManager.START_SUCCESS) { 3779 return false; 3780 } 3781 return true; 3782 } 3783 } 3784 3785 @Override 3786 public final int startActivityFromRecents(int taskId, Bundle options) { 3787 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3788 String msg = "Permission Denial: startActivityFromRecents called without " + 3789 START_TASKS_FROM_RECENTS; 3790 Slog.w(TAG, msg); 3791 throw new SecurityException(msg); 3792 } 3793 return startActivityFromRecentsInner(taskId, options); 3794 } 3795 3796 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3797 final TaskRecord task; 3798 final int callingUid; 3799 final String callingPackage; 3800 final Intent intent; 3801 final int userId; 3802 synchronized (this) { 3803 task = recentTaskForIdLocked(taskId); 3804 if (task == null) { 3805 throw new IllegalArgumentException("Task " + taskId + " not found."); 3806 } 3807 callingUid = task.mCallingUid; 3808 callingPackage = task.mCallingPackage; 3809 intent = task.intent; 3810 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3811 userId = task.userId; 3812 } 3813 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3814 options, userId, null, task); 3815 } 3816 3817 final int startActivityInPackage(int uid, String callingPackage, 3818 Intent intent, String resolvedType, IBinder resultTo, 3819 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3820 IActivityContainer container, TaskRecord inTask) { 3821 3822 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3823 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3824 3825 // TODO: Switch to user app stacks here. 3826 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3827 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3828 null, null, null, options, userId, container, inTask); 3829 return ret; 3830 } 3831 3832 @Override 3833 public final int startActivities(IApplicationThread caller, String callingPackage, 3834 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3835 int userId) { 3836 enforceNotIsolatedCaller("startActivities"); 3837 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3838 false, ALLOW_FULL_ONLY, "startActivity", null); 3839 // TODO: Switch to user app stacks here. 3840 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3841 resolvedTypes, resultTo, options, userId); 3842 return ret; 3843 } 3844 3845 final int startActivitiesInPackage(int uid, String callingPackage, 3846 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3847 Bundle options, int userId) { 3848 3849 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3850 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3851 // TODO: Switch to user app stacks here. 3852 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3853 resultTo, options, userId); 3854 return ret; 3855 } 3856 3857 //explicitly remove thd old information in mRecentTasks when removing existing user. 3858 private void removeRecentTasksForUserLocked(int userId) { 3859 if(userId <= 0) { 3860 Slog.i(TAG, "Can't remove recent task on user " + userId); 3861 return; 3862 } 3863 3864 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3865 TaskRecord tr = mRecentTasks.get(i); 3866 if (tr.userId == userId) { 3867 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3868 + " when finishing user" + userId); 3869 mRecentTasks.remove(i); 3870 tr.removedFromRecents(mTaskPersister); 3871 } 3872 } 3873 3874 // Remove tasks from persistent storage. 3875 mTaskPersister.wakeup(null, true); 3876 } 3877 3878 // Sort by taskId 3879 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3880 @Override 3881 public int compare(TaskRecord lhs, TaskRecord rhs) { 3882 return rhs.taskId - lhs.taskId; 3883 } 3884 }; 3885 3886 // Extract the affiliates of the chain containing mRecentTasks[start]. 3887 private int processNextAffiliateChain(int start) { 3888 final TaskRecord startTask = mRecentTasks.get(start); 3889 final int affiliateId = startTask.mAffiliatedTaskId; 3890 3891 // Quick identification of isolated tasks. I.e. those not launched behind. 3892 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3893 startTask.mNextAffiliate == null) { 3894 // There is still a slim chance that there are other tasks that point to this task 3895 // and that the chain is so messed up that this task no longer points to them but 3896 // the gain of this optimization outweighs the risk. 3897 startTask.inRecents = true; 3898 return start + 1; 3899 } 3900 3901 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3902 mTmpRecents.clear(); 3903 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3904 final TaskRecord task = mRecentTasks.get(i); 3905 if (task.mAffiliatedTaskId == affiliateId) { 3906 mRecentTasks.remove(i); 3907 mTmpRecents.add(task); 3908 } 3909 } 3910 3911 // Sort them all by taskId. That is the order they were create in and that order will 3912 // always be correct. 3913 Collections.sort(mTmpRecents, mTaskRecordComparator); 3914 3915 // Go through and fix up the linked list. 3916 // The first one is the end of the chain and has no next. 3917 final TaskRecord first = mTmpRecents.get(0); 3918 first.inRecents = true; 3919 if (first.mNextAffiliate != null) { 3920 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3921 first.setNextAffiliate(null); 3922 mTaskPersister.wakeup(first, false); 3923 } 3924 // Everything in the middle is doubly linked from next to prev. 3925 final int tmpSize = mTmpRecents.size(); 3926 for (int i = 0; i < tmpSize - 1; ++i) { 3927 final TaskRecord next = mTmpRecents.get(i); 3928 final TaskRecord prev = mTmpRecents.get(i + 1); 3929 if (next.mPrevAffiliate != prev) { 3930 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3931 " setting prev=" + prev); 3932 next.setPrevAffiliate(prev); 3933 mTaskPersister.wakeup(next, false); 3934 } 3935 if (prev.mNextAffiliate != next) { 3936 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3937 " setting next=" + next); 3938 prev.setNextAffiliate(next); 3939 mTaskPersister.wakeup(prev, false); 3940 } 3941 prev.inRecents = true; 3942 } 3943 // The last one is the beginning of the list and has no prev. 3944 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3945 if (last.mPrevAffiliate != null) { 3946 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3947 last.setPrevAffiliate(null); 3948 mTaskPersister.wakeup(last, false); 3949 } 3950 3951 // Insert the group back into mRecentTasks at start. 3952 mRecentTasks.addAll(start, mTmpRecents); 3953 3954 // Let the caller know where we left off. 3955 return start + tmpSize; 3956 } 3957 3958 /** 3959 * Update the recent tasks lists: make sure tasks should still be here (their 3960 * applications / activities still exist), update their availability, fixup ordering 3961 * of affiliations. 3962 */ 3963 void cleanupRecentTasksLocked(int userId) { 3964 if (mRecentTasks == null) { 3965 // Happens when called from the packagemanager broadcast before boot. 3966 return; 3967 } 3968 3969 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3970 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3971 final IPackageManager pm = AppGlobals.getPackageManager(); 3972 final ActivityInfo dummyAct = new ActivityInfo(); 3973 final ApplicationInfo dummyApp = new ApplicationInfo(); 3974 3975 int N = mRecentTasks.size(); 3976 3977 int[] users = userId == UserHandle.USER_ALL 3978 ? getUsersLocked() : new int[] { userId }; 3979 for (int user : users) { 3980 for (int i = 0; i < N; i++) { 3981 TaskRecord task = mRecentTasks.get(i); 3982 if (task.userId != user) { 3983 // Only look at tasks for the user ID of interest. 3984 continue; 3985 } 3986 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3987 // This situation is broken, and we should just get rid of it now. 3988 mRecentTasks.remove(i); 3989 task.removedFromRecents(mTaskPersister); 3990 i--; 3991 N--; 3992 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3993 continue; 3994 } 3995 // Check whether this activity is currently available. 3996 if (task.realActivity != null) { 3997 ActivityInfo ai = availActCache.get(task.realActivity); 3998 if (ai == null) { 3999 try { 4000 ai = pm.getActivityInfo(task.realActivity, 4001 PackageManager.GET_UNINSTALLED_PACKAGES 4002 | PackageManager.GET_DISABLED_COMPONENTS, user); 4003 } catch (RemoteException e) { 4004 // Will never happen. 4005 continue; 4006 } 4007 if (ai == null) { 4008 ai = dummyAct; 4009 } 4010 availActCache.put(task.realActivity, ai); 4011 } 4012 if (ai == dummyAct) { 4013 // This could be either because the activity no longer exists, or the 4014 // app is temporarily gone. For the former we want to remove the recents 4015 // entry; for the latter we want to mark it as unavailable. 4016 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4017 if (app == null) { 4018 try { 4019 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4020 PackageManager.GET_UNINSTALLED_PACKAGES 4021 | PackageManager.GET_DISABLED_COMPONENTS, user); 4022 } catch (RemoteException e) { 4023 // Will never happen. 4024 continue; 4025 } 4026 if (app == null) { 4027 app = dummyApp; 4028 } 4029 availAppCache.put(task.realActivity.getPackageName(), app); 4030 } 4031 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4032 // Doesn't exist any more! Good-bye. 4033 mRecentTasks.remove(i); 4034 task.removedFromRecents(mTaskPersister); 4035 i--; 4036 N--; 4037 Slog.w(TAG, "Removing no longer valid recent: " + task); 4038 continue; 4039 } else { 4040 // Otherwise just not available for now. 4041 if (task.isAvailable) { 4042 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4043 + task); 4044 } 4045 task.isAvailable = false; 4046 } 4047 } else { 4048 if (!ai.enabled || !ai.applicationInfo.enabled 4049 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4050 if (task.isAvailable) { 4051 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4052 + task + " (enabled=" + ai.enabled + "/" 4053 + ai.applicationInfo.enabled + " flags=" 4054 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4055 } 4056 task.isAvailable = false; 4057 } else { 4058 if (!task.isAvailable) { 4059 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4060 + task); 4061 } 4062 task.isAvailable = true; 4063 } 4064 } 4065 } 4066 } 4067 } 4068 4069 // Verify the affiliate chain for each task. 4070 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4071 } 4072 4073 mTmpRecents.clear(); 4074 // mRecentTasks is now in sorted, affiliated order. 4075 } 4076 4077 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4078 int N = mRecentTasks.size(); 4079 TaskRecord top = task; 4080 int topIndex = taskIndex; 4081 while (top.mNextAffiliate != null && topIndex > 0) { 4082 top = top.mNextAffiliate; 4083 topIndex--; 4084 } 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4086 + topIndex + " from intial " + taskIndex); 4087 // Find the end of the chain, doing a sanity check along the way. 4088 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4089 int endIndex = topIndex; 4090 TaskRecord prev = top; 4091 while (endIndex < N) { 4092 TaskRecord cur = mRecentTasks.get(endIndex); 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4094 + endIndex + " " + cur); 4095 if (cur == top) { 4096 // Verify start of the chain. 4097 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4098 Slog.wtf(TAG, "Bad chain @" + endIndex 4099 + ": first task has next affiliate: " + prev); 4100 sane = false; 4101 break; 4102 } 4103 } else { 4104 // Verify middle of the chain's next points back to the one before. 4105 if (cur.mNextAffiliate != prev 4106 || cur.mNextAffiliateTaskId != prev.taskId) { 4107 Slog.wtf(TAG, "Bad chain @" + endIndex 4108 + ": middle task " + cur + " @" + endIndex 4109 + " has bad next affiliate " 4110 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4111 + ", expected " + prev); 4112 sane = false; 4113 break; 4114 } 4115 } 4116 if (cur.mPrevAffiliateTaskId == -1) { 4117 // Chain ends here. 4118 if (cur.mPrevAffiliate != null) { 4119 Slog.wtf(TAG, "Bad chain @" + endIndex 4120 + ": last task " + cur + " has previous affiliate " 4121 + cur.mPrevAffiliate); 4122 sane = false; 4123 } 4124 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4125 break; 4126 } else { 4127 // Verify middle of the chain's prev points to a valid item. 4128 if (cur.mPrevAffiliate == null) { 4129 Slog.wtf(TAG, "Bad chain @" + endIndex 4130 + ": task " + cur + " has previous affiliate " 4131 + cur.mPrevAffiliate + " but should be id " 4132 + cur.mPrevAffiliate); 4133 sane = false; 4134 break; 4135 } 4136 } 4137 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": task " + cur + " has affiliated id " 4140 + cur.mAffiliatedTaskId + " but should be " 4141 + task.mAffiliatedTaskId); 4142 sane = false; 4143 break; 4144 } 4145 prev = cur; 4146 endIndex++; 4147 if (endIndex >= N) { 4148 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4149 + ": last task " + prev); 4150 sane = false; 4151 break; 4152 } 4153 } 4154 if (sane) { 4155 if (endIndex < taskIndex) { 4156 Slog.wtf(TAG, "Bad chain @" + endIndex 4157 + ": did not extend to task " + task + " @" + taskIndex); 4158 sane = false; 4159 } 4160 } 4161 if (sane) { 4162 // All looks good, we can just move all of the affiliated tasks 4163 // to the top. 4164 for (int i=topIndex; i<=endIndex; i++) { 4165 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4166 + " from " + i + " to " + (i-topIndex)); 4167 TaskRecord cur = mRecentTasks.remove(i); 4168 mRecentTasks.add(i-topIndex, cur); 4169 } 4170 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4171 + " to " + endIndex); 4172 return true; 4173 } 4174 4175 // Whoops, couldn't do it. 4176 return false; 4177 } 4178 4179 final void addRecentTaskLocked(TaskRecord task) { 4180 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4181 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4182 4183 int N = mRecentTasks.size(); 4184 // Quick case: check if the top-most recent task is the same. 4185 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4186 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4187 return; 4188 } 4189 // Another quick case: check if this is part of a set of affiliated 4190 // tasks that are at the top. 4191 if (isAffiliated && N > 0 && task.inRecents 4192 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4193 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4194 + " at top when adding " + task); 4195 return; 4196 } 4197 // Another quick case: never add voice sessions. 4198 if (task.voiceSession != null) { 4199 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4200 return; 4201 } 4202 4203 boolean needAffiliationFix = false; 4204 4205 // Slightly less quick case: the task is already in recents, so all we need 4206 // to do is move it. 4207 if (task.inRecents) { 4208 int taskIndex = mRecentTasks.indexOf(task); 4209 if (taskIndex >= 0) { 4210 if (!isAffiliated) { 4211 // Simple case: this is not an affiliated task, so we just move it to the front. 4212 mRecentTasks.remove(taskIndex); 4213 mRecentTasks.add(0, task); 4214 notifyTaskPersisterLocked(task, false); 4215 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4216 + " from " + taskIndex); 4217 return; 4218 } else { 4219 // More complicated: need to keep all affiliated tasks together. 4220 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4221 // All went well. 4222 return; 4223 } 4224 4225 // Uh oh... something bad in the affiliation chain, try to rebuild 4226 // everything and then go through our general path of adding a new task. 4227 needAffiliationFix = true; 4228 } 4229 } else { 4230 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4231 needAffiliationFix = true; 4232 } 4233 } 4234 4235 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4236 trimRecentsForTask(task, true); 4237 4238 N = mRecentTasks.size(); 4239 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4240 final TaskRecord tr = mRecentTasks.remove(N - 1); 4241 tr.removedFromRecents(mTaskPersister); 4242 N--; 4243 } 4244 task.inRecents = true; 4245 if (!isAffiliated || needAffiliationFix) { 4246 // If this is a simple non-affiliated task, or we had some failure trying to 4247 // handle it as part of an affilated task, then just place it at the top. 4248 mRecentTasks.add(0, task); 4249 } else if (isAffiliated) { 4250 // If this is a new affiliated task, then move all of the affiliated tasks 4251 // to the front and insert this new one. 4252 TaskRecord other = task.mNextAffiliate; 4253 if (other == null) { 4254 other = task.mPrevAffiliate; 4255 } 4256 if (other != null) { 4257 int otherIndex = mRecentTasks.indexOf(other); 4258 if (otherIndex >= 0) { 4259 // Insert new task at appropriate location. 4260 int taskIndex; 4261 if (other == task.mNextAffiliate) { 4262 // We found the index of our next affiliation, which is who is 4263 // before us in the list, so add after that point. 4264 taskIndex = otherIndex+1; 4265 } else { 4266 // We found the index of our previous affiliation, which is who is 4267 // after us in the list, so add at their position. 4268 taskIndex = otherIndex; 4269 } 4270 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4271 + taskIndex + ": " + task); 4272 mRecentTasks.add(taskIndex, task); 4273 4274 // Now move everything to the front. 4275 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4276 // All went well. 4277 return; 4278 } 4279 4280 // Uh oh... something bad in the affiliation chain, try to rebuild 4281 // everything and then go through our general path of adding a new task. 4282 needAffiliationFix = true; 4283 } else { 4284 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4285 + other); 4286 needAffiliationFix = true; 4287 } 4288 } else { 4289 if (DEBUG_RECENTS) Slog.d(TAG, 4290 "addRecent: adding affiliated task without next/prev:" + task); 4291 needAffiliationFix = true; 4292 } 4293 } 4294 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4295 4296 if (needAffiliationFix) { 4297 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4298 cleanupRecentTasksLocked(task.userId); 4299 } 4300 } 4301 4302 /** 4303 * If needed, remove oldest existing entries in recents that are for the same kind 4304 * of task as the given one. 4305 */ 4306 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4307 int N = mRecentTasks.size(); 4308 final Intent intent = task.intent; 4309 final boolean document = intent != null && intent.isDocument(); 4310 4311 int maxRecents = task.maxRecents - 1; 4312 for (int i=0; i<N; i++) { 4313 final TaskRecord tr = mRecentTasks.get(i); 4314 if (task != tr) { 4315 if (task.userId != tr.userId) { 4316 continue; 4317 } 4318 if (i > MAX_RECENT_BITMAPS) { 4319 tr.freeLastThumbnail(); 4320 } 4321 final Intent trIntent = tr.intent; 4322 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4323 (intent == null || !intent.filterEquals(trIntent))) { 4324 continue; 4325 } 4326 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4327 if (document && trIsDocument) { 4328 // These are the same document activity (not necessarily the same doc). 4329 if (maxRecents > 0) { 4330 --maxRecents; 4331 continue; 4332 } 4333 // Hit the maximum number of documents for this task. Fall through 4334 // and remove this document from recents. 4335 } else if (document || trIsDocument) { 4336 // Only one of these is a document. Not the droid we're looking for. 4337 continue; 4338 } 4339 } 4340 4341 if (!doTrim) { 4342 // If the caller is not actually asking for a trim, just tell them we reached 4343 // a point where the trim would happen. 4344 return i; 4345 } 4346 4347 // Either task and tr are the same or, their affinities match or their intents match 4348 // and neither of them is a document, or they are documents using the same activity 4349 // and their maxRecents has been reached. 4350 tr.disposeThumbnail(); 4351 mRecentTasks.remove(i); 4352 if (task != tr) { 4353 tr.removedFromRecents(mTaskPersister); 4354 } 4355 i--; 4356 N--; 4357 if (task.intent == null) { 4358 // If the new recent task we are adding is not fully 4359 // specified, then replace it with the existing recent task. 4360 task = tr; 4361 } 4362 notifyTaskPersisterLocked(tr, false); 4363 } 4364 4365 return -1; 4366 } 4367 4368 @Override 4369 public void reportActivityFullyDrawn(IBinder token) { 4370 synchronized (this) { 4371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4372 if (r == null) { 4373 return; 4374 } 4375 r.reportFullyDrawnLocked(); 4376 } 4377 } 4378 4379 @Override 4380 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4381 synchronized (this) { 4382 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4383 if (r == null) { 4384 return; 4385 } 4386 final long origId = Binder.clearCallingIdentity(); 4387 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4388 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4389 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4390 if (config != null) { 4391 r.frozenBeforeDestroy = true; 4392 if (!updateConfigurationLocked(config, r, false, false)) { 4393 mStackSupervisor.resumeTopActivitiesLocked(); 4394 } 4395 } 4396 Binder.restoreCallingIdentity(origId); 4397 } 4398 } 4399 4400 @Override 4401 public int getRequestedOrientation(IBinder token) { 4402 synchronized (this) { 4403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4404 if (r == null) { 4405 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4406 } 4407 return mWindowManager.getAppOrientation(r.appToken); 4408 } 4409 } 4410 4411 /** 4412 * This is the internal entry point for handling Activity.finish(). 4413 * 4414 * @param token The Binder token referencing the Activity we want to finish. 4415 * @param resultCode Result code, if any, from this Activity. 4416 * @param resultData Result data (Intent), if any, from this Activity. 4417 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4418 * the root Activity in the task. 4419 * 4420 * @return Returns true if the activity successfully finished, or false if it is still running. 4421 */ 4422 @Override 4423 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4424 boolean finishTask) { 4425 // Refuse possible leaked file descriptors 4426 if (resultData != null && resultData.hasFileDescriptors() == true) { 4427 throw new IllegalArgumentException("File descriptors passed in Intent"); 4428 } 4429 4430 synchronized(this) { 4431 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4432 if (r == null) { 4433 return true; 4434 } 4435 // Keep track of the root activity of the task before we finish it 4436 TaskRecord tr = r.task; 4437 ActivityRecord rootR = tr.getRootActivity(); 4438 // Do not allow task to finish in Lock Task mode. 4439 if (tr == mStackSupervisor.mLockTaskModeTask) { 4440 if (rootR == r) { 4441 mStackSupervisor.showLockTaskToast(); 4442 return false; 4443 } 4444 } 4445 if (mController != null) { 4446 // Find the first activity that is not finishing. 4447 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4448 if (next != null) { 4449 // ask watcher if this is allowed 4450 boolean resumeOK = true; 4451 try { 4452 resumeOK = mController.activityResuming(next.packageName); 4453 } catch (RemoteException e) { 4454 mController = null; 4455 Watchdog.getInstance().setActivityController(null); 4456 } 4457 4458 if (!resumeOK) { 4459 return false; 4460 } 4461 } 4462 } 4463 final long origId = Binder.clearCallingIdentity(); 4464 try { 4465 boolean res; 4466 if (finishTask && r == rootR) { 4467 // If requested, remove the task that is associated to this activity only if it 4468 // was the root activity in the task. The result code and data is ignored because 4469 // we don't support returning them across task boundaries. 4470 res = removeTaskByIdLocked(tr.taskId, 0); 4471 } else { 4472 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4473 resultData, "app-request", true); 4474 } 4475 return res; 4476 } finally { 4477 Binder.restoreCallingIdentity(origId); 4478 } 4479 } 4480 } 4481 4482 @Override 4483 public final void finishHeavyWeightApp() { 4484 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4485 != PackageManager.PERMISSION_GRANTED) { 4486 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4487 + Binder.getCallingPid() 4488 + ", uid=" + Binder.getCallingUid() 4489 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4490 Slog.w(TAG, msg); 4491 throw new SecurityException(msg); 4492 } 4493 4494 synchronized(this) { 4495 if (mHeavyWeightProcess == null) { 4496 return; 4497 } 4498 4499 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4500 mHeavyWeightProcess.activities); 4501 for (int i=0; i<activities.size(); i++) { 4502 ActivityRecord r = activities.get(i); 4503 if (!r.finishing) { 4504 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4505 null, "finish-heavy", true); 4506 } 4507 } 4508 4509 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4510 mHeavyWeightProcess.userId, 0)); 4511 mHeavyWeightProcess = null; 4512 } 4513 } 4514 4515 @Override 4516 public void crashApplication(int uid, int initialPid, String packageName, 4517 String message) { 4518 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4519 != PackageManager.PERMISSION_GRANTED) { 4520 String msg = "Permission Denial: crashApplication() from pid=" 4521 + Binder.getCallingPid() 4522 + ", uid=" + Binder.getCallingUid() 4523 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4524 Slog.w(TAG, msg); 4525 throw new SecurityException(msg); 4526 } 4527 4528 synchronized(this) { 4529 ProcessRecord proc = null; 4530 4531 // Figure out which process to kill. We don't trust that initialPid 4532 // still has any relation to current pids, so must scan through the 4533 // list. 4534 synchronized (mPidsSelfLocked) { 4535 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4536 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4537 if (p.uid != uid) { 4538 continue; 4539 } 4540 if (p.pid == initialPid) { 4541 proc = p; 4542 break; 4543 } 4544 if (p.pkgList.containsKey(packageName)) { 4545 proc = p; 4546 } 4547 } 4548 } 4549 4550 if (proc == null) { 4551 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4552 + " initialPid=" + initialPid 4553 + " packageName=" + packageName); 4554 return; 4555 } 4556 4557 if (proc.thread != null) { 4558 if (proc.pid == Process.myPid()) { 4559 Log.w(TAG, "crashApplication: trying to crash self!"); 4560 return; 4561 } 4562 long ident = Binder.clearCallingIdentity(); 4563 try { 4564 proc.thread.scheduleCrash(message); 4565 } catch (RemoteException e) { 4566 } 4567 Binder.restoreCallingIdentity(ident); 4568 } 4569 } 4570 } 4571 4572 @Override 4573 public final void finishSubActivity(IBinder token, String resultWho, 4574 int requestCode) { 4575 synchronized(this) { 4576 final long origId = Binder.clearCallingIdentity(); 4577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4578 if (r != null) { 4579 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4580 } 4581 Binder.restoreCallingIdentity(origId); 4582 } 4583 } 4584 4585 @Override 4586 public boolean finishActivityAffinity(IBinder token) { 4587 synchronized(this) { 4588 final long origId = Binder.clearCallingIdentity(); 4589 try { 4590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4591 4592 ActivityRecord rootR = r.task.getRootActivity(); 4593 // Do not allow task to finish in Lock Task mode. 4594 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4595 if (rootR == r) { 4596 mStackSupervisor.showLockTaskToast(); 4597 return false; 4598 } 4599 } 4600 boolean res = false; 4601 if (r != null) { 4602 res = r.task.stack.finishActivityAffinityLocked(r); 4603 } 4604 return res; 4605 } finally { 4606 Binder.restoreCallingIdentity(origId); 4607 } 4608 } 4609 } 4610 4611 @Override 4612 public void finishVoiceTask(IVoiceInteractionSession session) { 4613 synchronized(this) { 4614 final long origId = Binder.clearCallingIdentity(); 4615 try { 4616 mStackSupervisor.finishVoiceTask(session); 4617 } finally { 4618 Binder.restoreCallingIdentity(origId); 4619 } 4620 } 4621 4622 } 4623 4624 @Override 4625 public boolean releaseActivityInstance(IBinder token) { 4626 synchronized(this) { 4627 final long origId = Binder.clearCallingIdentity(); 4628 try { 4629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4630 if (r.task == null || r.task.stack == null) { 4631 return false; 4632 } 4633 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4634 } finally { 4635 Binder.restoreCallingIdentity(origId); 4636 } 4637 } 4638 } 4639 4640 @Override 4641 public void releaseSomeActivities(IApplicationThread appInt) { 4642 synchronized(this) { 4643 final long origId = Binder.clearCallingIdentity(); 4644 try { 4645 ProcessRecord app = getRecordForAppLocked(appInt); 4646 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4647 } finally { 4648 Binder.restoreCallingIdentity(origId); 4649 } 4650 } 4651 } 4652 4653 @Override 4654 public boolean willActivityBeVisible(IBinder token) { 4655 synchronized(this) { 4656 ActivityStack stack = ActivityRecord.getStackLocked(token); 4657 if (stack != null) { 4658 return stack.willActivityBeVisibleLocked(token); 4659 } 4660 return false; 4661 } 4662 } 4663 4664 @Override 4665 public void overridePendingTransition(IBinder token, String packageName, 4666 int enterAnim, int exitAnim) { 4667 synchronized(this) { 4668 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4669 if (self == null) { 4670 return; 4671 } 4672 4673 final long origId = Binder.clearCallingIdentity(); 4674 4675 if (self.state == ActivityState.RESUMED 4676 || self.state == ActivityState.PAUSING) { 4677 mWindowManager.overridePendingAppTransition(packageName, 4678 enterAnim, exitAnim, null); 4679 } 4680 4681 Binder.restoreCallingIdentity(origId); 4682 } 4683 } 4684 4685 /** 4686 * Main function for removing an existing process from the activity manager 4687 * as a result of that process going away. Clears out all connections 4688 * to the process. 4689 */ 4690 private final void handleAppDiedLocked(ProcessRecord app, 4691 boolean restarting, boolean allowRestart) { 4692 int pid = app.pid; 4693 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4694 if (!kept && !restarting) { 4695 removeLruProcessLocked(app); 4696 if (pid > 0) { 4697 ProcessList.remove(pid); 4698 } 4699 } 4700 4701 if (mProfileProc == app) { 4702 clearProfilerLocked(); 4703 } 4704 4705 // Remove this application's activities from active lists. 4706 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4707 4708 app.activities.clear(); 4709 4710 if (app.instrumentationClass != null) { 4711 Slog.w(TAG, "Crash of app " + app.processName 4712 + " running instrumentation " + app.instrumentationClass); 4713 Bundle info = new Bundle(); 4714 info.putString("shortMsg", "Process crashed."); 4715 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4716 } 4717 4718 if (!restarting) { 4719 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4720 // If there was nothing to resume, and we are not already 4721 // restarting this process, but there is a visible activity that 4722 // is hosted by the process... then make sure all visible 4723 // activities are running, taking care of restarting this 4724 // process. 4725 if (hasVisibleActivities) { 4726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4727 } 4728 } 4729 } 4730 } 4731 4732 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4733 IBinder threadBinder = thread.asBinder(); 4734 // Find the application record. 4735 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4736 ProcessRecord rec = mLruProcesses.get(i); 4737 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4738 return i; 4739 } 4740 } 4741 return -1; 4742 } 4743 4744 final ProcessRecord getRecordForAppLocked( 4745 IApplicationThread thread) { 4746 if (thread == null) { 4747 return null; 4748 } 4749 4750 int appIndex = getLRURecordIndexForAppLocked(thread); 4751 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4752 } 4753 4754 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4755 // If there are no longer any background processes running, 4756 // and the app that died was not running instrumentation, 4757 // then tell everyone we are now low on memory. 4758 boolean haveBg = false; 4759 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4760 ProcessRecord rec = mLruProcesses.get(i); 4761 if (rec.thread != null 4762 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4763 haveBg = true; 4764 break; 4765 } 4766 } 4767 4768 if (!haveBg) { 4769 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4770 if (doReport) { 4771 long now = SystemClock.uptimeMillis(); 4772 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4773 doReport = false; 4774 } else { 4775 mLastMemUsageReportTime = now; 4776 } 4777 } 4778 final ArrayList<ProcessMemInfo> memInfos 4779 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4780 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4781 long now = SystemClock.uptimeMillis(); 4782 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4783 ProcessRecord rec = mLruProcesses.get(i); 4784 if (rec == dyingProc || rec.thread == null) { 4785 continue; 4786 } 4787 if (doReport) { 4788 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4789 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4790 } 4791 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4792 // The low memory report is overriding any current 4793 // state for a GC request. Make sure to do 4794 // heavy/important/visible/foreground processes first. 4795 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4796 rec.lastRequestedGc = 0; 4797 } else { 4798 rec.lastRequestedGc = rec.lastLowMemory; 4799 } 4800 rec.reportLowMemory = true; 4801 rec.lastLowMemory = now; 4802 mProcessesToGc.remove(rec); 4803 addProcessToGcListLocked(rec); 4804 } 4805 } 4806 if (doReport) { 4807 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4808 mHandler.sendMessage(msg); 4809 } 4810 scheduleAppGcsLocked(); 4811 } 4812 } 4813 4814 final void appDiedLocked(ProcessRecord app) { 4815 appDiedLocked(app, app.pid, app.thread); 4816 } 4817 4818 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4819 // First check if this ProcessRecord is actually active for the pid. 4820 synchronized (mPidsSelfLocked) { 4821 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4822 if (curProc != app) { 4823 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4824 return; 4825 } 4826 } 4827 4828 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4829 synchronized (stats) { 4830 stats.noteProcessDiedLocked(app.info.uid, pid); 4831 } 4832 4833 Process.killProcessQuiet(pid); 4834 Process.killProcessGroup(app.info.uid, pid); 4835 app.killed = true; 4836 4837 // Clean up already done if the process has been re-started. 4838 if (app.pid == pid && app.thread != null && 4839 app.thread.asBinder() == thread.asBinder()) { 4840 boolean doLowMem = app.instrumentationClass == null; 4841 boolean doOomAdj = doLowMem; 4842 if (!app.killedByAm) { 4843 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4844 + ") has died"); 4845 mAllowLowerMemLevel = true; 4846 } else { 4847 // Note that we always want to do oom adj to update our state with the 4848 // new number of procs. 4849 mAllowLowerMemLevel = false; 4850 doLowMem = false; 4851 } 4852 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4853 if (DEBUG_CLEANUP) Slog.v( 4854 TAG, "Dying app: " + app + ", pid: " + pid 4855 + ", thread: " + thread.asBinder()); 4856 handleAppDiedLocked(app, false, true); 4857 4858 if (doOomAdj) { 4859 updateOomAdjLocked(); 4860 } 4861 if (doLowMem) { 4862 doLowMemReportIfNeededLocked(app); 4863 } 4864 } else if (app.pid != pid) { 4865 // A new process has already been started. 4866 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4867 + ") has died and restarted (pid " + app.pid + ")."); 4868 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4869 } else if (DEBUG_PROCESSES) { 4870 Slog.d(TAG, "Received spurious death notification for thread " 4871 + thread.asBinder()); 4872 } 4873 } 4874 4875 /** 4876 * If a stack trace dump file is configured, dump process stack traces. 4877 * @param clearTraces causes the dump file to be erased prior to the new 4878 * traces being written, if true; when false, the new traces will be 4879 * appended to any existing file content. 4880 * @param firstPids of dalvik VM processes to dump stack traces for first 4881 * @param lastPids of dalvik VM processes to dump stack traces for last 4882 * @param nativeProcs optional list of native process names to dump stack crawls 4883 * @return file containing stack traces, or null if no dump file is configured 4884 */ 4885 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4886 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4887 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4888 if (tracesPath == null || tracesPath.length() == 0) { 4889 return null; 4890 } 4891 4892 File tracesFile = new File(tracesPath); 4893 try { 4894 File tracesDir = tracesFile.getParentFile(); 4895 if (!tracesDir.exists()) { 4896 tracesDir.mkdirs(); 4897 if (!SELinux.restorecon(tracesDir)) { 4898 return null; 4899 } 4900 } 4901 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4902 4903 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4904 tracesFile.createNewFile(); 4905 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4906 } catch (IOException e) { 4907 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4908 return null; 4909 } 4910 4911 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4912 return tracesFile; 4913 } 4914 4915 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4916 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4917 // Use a FileObserver to detect when traces finish writing. 4918 // The order of traces is considered important to maintain for legibility. 4919 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4920 @Override 4921 public synchronized void onEvent(int event, String path) { notify(); } 4922 }; 4923 4924 try { 4925 observer.startWatching(); 4926 4927 // First collect all of the stacks of the most important pids. 4928 if (firstPids != null) { 4929 try { 4930 int num = firstPids.size(); 4931 for (int i = 0; i < num; i++) { 4932 synchronized (observer) { 4933 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4934 observer.wait(200); // Wait for write-close, give up after 200msec 4935 } 4936 } 4937 } catch (InterruptedException e) { 4938 Log.wtf(TAG, e); 4939 } 4940 } 4941 4942 // Next collect the stacks of the native pids 4943 if (nativeProcs != null) { 4944 int[] pids = Process.getPidsForCommands(nativeProcs); 4945 if (pids != null) { 4946 for (int pid : pids) { 4947 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4948 } 4949 } 4950 } 4951 4952 // Lastly, measure CPU usage. 4953 if (processCpuTracker != null) { 4954 processCpuTracker.init(); 4955 System.gc(); 4956 processCpuTracker.update(); 4957 try { 4958 synchronized (processCpuTracker) { 4959 processCpuTracker.wait(500); // measure over 1/2 second. 4960 } 4961 } catch (InterruptedException e) { 4962 } 4963 processCpuTracker.update(); 4964 4965 // We'll take the stack crawls of just the top apps using CPU. 4966 final int N = processCpuTracker.countWorkingStats(); 4967 int numProcs = 0; 4968 for (int i=0; i<N && numProcs<5; i++) { 4969 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4970 if (lastPids.indexOfKey(stats.pid) >= 0) { 4971 numProcs++; 4972 try { 4973 synchronized (observer) { 4974 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4975 observer.wait(200); // Wait for write-close, give up after 200msec 4976 } 4977 } catch (InterruptedException e) { 4978 Log.wtf(TAG, e); 4979 } 4980 4981 } 4982 } 4983 } 4984 } finally { 4985 observer.stopWatching(); 4986 } 4987 } 4988 4989 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4990 if (true || IS_USER_BUILD) { 4991 return; 4992 } 4993 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4994 if (tracesPath == null || tracesPath.length() == 0) { 4995 return; 4996 } 4997 4998 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4999 StrictMode.allowThreadDiskWrites(); 5000 try { 5001 final File tracesFile = new File(tracesPath); 5002 final File tracesDir = tracesFile.getParentFile(); 5003 final File tracesTmp = new File(tracesDir, "__tmp__"); 5004 try { 5005 if (!tracesDir.exists()) { 5006 tracesDir.mkdirs(); 5007 if (!SELinux.restorecon(tracesDir.getPath())) { 5008 return; 5009 } 5010 } 5011 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5012 5013 if (tracesFile.exists()) { 5014 tracesTmp.delete(); 5015 tracesFile.renameTo(tracesTmp); 5016 } 5017 StringBuilder sb = new StringBuilder(); 5018 Time tobj = new Time(); 5019 tobj.set(System.currentTimeMillis()); 5020 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5021 sb.append(": "); 5022 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5023 sb.append(" since "); 5024 sb.append(msg); 5025 FileOutputStream fos = new FileOutputStream(tracesFile); 5026 fos.write(sb.toString().getBytes()); 5027 if (app == null) { 5028 fos.write("\n*** No application process!".getBytes()); 5029 } 5030 fos.close(); 5031 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5032 } catch (IOException e) { 5033 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5034 return; 5035 } 5036 5037 if (app != null) { 5038 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5039 firstPids.add(app.pid); 5040 dumpStackTraces(tracesPath, firstPids, null, null, null); 5041 } 5042 5043 File lastTracesFile = null; 5044 File curTracesFile = null; 5045 for (int i=9; i>=0; i--) { 5046 String name = String.format(Locale.US, "slow%02d.txt", i); 5047 curTracesFile = new File(tracesDir, name); 5048 if (curTracesFile.exists()) { 5049 if (lastTracesFile != null) { 5050 curTracesFile.renameTo(lastTracesFile); 5051 } else { 5052 curTracesFile.delete(); 5053 } 5054 } 5055 lastTracesFile = curTracesFile; 5056 } 5057 tracesFile.renameTo(curTracesFile); 5058 if (tracesTmp.exists()) { 5059 tracesTmp.renameTo(tracesFile); 5060 } 5061 } finally { 5062 StrictMode.setThreadPolicy(oldPolicy); 5063 } 5064 } 5065 5066 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5067 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5068 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5069 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5070 5071 if (mController != null) { 5072 try { 5073 // 0 == continue, -1 = kill process immediately 5074 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5075 if (res < 0 && app.pid != MY_PID) { 5076 app.kill("anr", true); 5077 } 5078 } catch (RemoteException e) { 5079 mController = null; 5080 Watchdog.getInstance().setActivityController(null); 5081 } 5082 } 5083 5084 long anrTime = SystemClock.uptimeMillis(); 5085 if (MONITOR_CPU_USAGE) { 5086 updateCpuStatsNow(); 5087 } 5088 5089 synchronized (this) { 5090 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5091 if (mShuttingDown) { 5092 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5093 return; 5094 } else if (app.notResponding) { 5095 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5096 return; 5097 } else if (app.crashing) { 5098 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5099 return; 5100 } 5101 5102 // In case we come through here for the same app before completing 5103 // this one, mark as anring now so we will bail out. 5104 app.notResponding = true; 5105 5106 // Log the ANR to the event log. 5107 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5108 app.processName, app.info.flags, annotation); 5109 5110 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5111 firstPids.add(app.pid); 5112 5113 int parentPid = app.pid; 5114 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5115 if (parentPid != app.pid) firstPids.add(parentPid); 5116 5117 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5118 5119 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5120 ProcessRecord r = mLruProcesses.get(i); 5121 if (r != null && r.thread != null) { 5122 int pid = r.pid; 5123 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5124 if (r.persistent) { 5125 firstPids.add(pid); 5126 } else { 5127 lastPids.put(pid, Boolean.TRUE); 5128 } 5129 } 5130 } 5131 } 5132 } 5133 5134 // Log the ANR to the main log. 5135 StringBuilder info = new StringBuilder(); 5136 info.setLength(0); 5137 info.append("ANR in ").append(app.processName); 5138 if (activity != null && activity.shortComponentName != null) { 5139 info.append(" (").append(activity.shortComponentName).append(")"); 5140 } 5141 info.append("\n"); 5142 info.append("PID: ").append(app.pid).append("\n"); 5143 if (annotation != null) { 5144 info.append("Reason: ").append(annotation).append("\n"); 5145 } 5146 if (parent != null && parent != activity) { 5147 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5148 } 5149 5150 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5151 5152 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5153 NATIVE_STACKS_OF_INTEREST); 5154 5155 String cpuInfo = null; 5156 if (MONITOR_CPU_USAGE) { 5157 updateCpuStatsNow(); 5158 synchronized (mProcessCpuTracker) { 5159 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5160 } 5161 info.append(processCpuTracker.printCurrentLoad()); 5162 info.append(cpuInfo); 5163 } 5164 5165 info.append(processCpuTracker.printCurrentState(anrTime)); 5166 5167 Slog.e(TAG, info.toString()); 5168 if (tracesFile == null) { 5169 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5170 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5171 } 5172 5173 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5174 cpuInfo, tracesFile, null); 5175 5176 if (mController != null) { 5177 try { 5178 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5179 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5180 if (res != 0) { 5181 if (res < 0 && app.pid != MY_PID) { 5182 app.kill("anr", true); 5183 } else { 5184 synchronized (this) { 5185 mServices.scheduleServiceTimeoutLocked(app); 5186 } 5187 } 5188 return; 5189 } 5190 } catch (RemoteException e) { 5191 mController = null; 5192 Watchdog.getInstance().setActivityController(null); 5193 } 5194 } 5195 5196 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5197 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5198 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5199 5200 synchronized (this) { 5201 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5202 app.kill("bg anr", true); 5203 return; 5204 } 5205 5206 // Set the app's notResponding state, and look up the errorReportReceiver 5207 makeAppNotRespondingLocked(app, 5208 activity != null ? activity.shortComponentName : null, 5209 annotation != null ? "ANR " + annotation : "ANR", 5210 info.toString()); 5211 5212 // Bring up the infamous App Not Responding dialog 5213 Message msg = Message.obtain(); 5214 HashMap<String, Object> map = new HashMap<String, Object>(); 5215 msg.what = SHOW_NOT_RESPONDING_MSG; 5216 msg.obj = map; 5217 msg.arg1 = aboveSystem ? 1 : 0; 5218 map.put("app", app); 5219 if (activity != null) { 5220 map.put("activity", activity); 5221 } 5222 5223 mHandler.sendMessage(msg); 5224 } 5225 } 5226 5227 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5228 if (!mLaunchWarningShown) { 5229 mLaunchWarningShown = true; 5230 mHandler.post(new Runnable() { 5231 @Override 5232 public void run() { 5233 synchronized (ActivityManagerService.this) { 5234 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5235 d.show(); 5236 mHandler.postDelayed(new Runnable() { 5237 @Override 5238 public void run() { 5239 synchronized (ActivityManagerService.this) { 5240 d.dismiss(); 5241 mLaunchWarningShown = false; 5242 } 5243 } 5244 }, 4000); 5245 } 5246 } 5247 }); 5248 } 5249 } 5250 5251 @Override 5252 public boolean clearApplicationUserData(final String packageName, 5253 final IPackageDataObserver observer, int userId) { 5254 enforceNotIsolatedCaller("clearApplicationUserData"); 5255 int uid = Binder.getCallingUid(); 5256 int pid = Binder.getCallingPid(); 5257 userId = handleIncomingUser(pid, uid, 5258 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5259 long callingId = Binder.clearCallingIdentity(); 5260 try { 5261 IPackageManager pm = AppGlobals.getPackageManager(); 5262 int pkgUid = -1; 5263 synchronized(this) { 5264 try { 5265 pkgUid = pm.getPackageUid(packageName, userId); 5266 } catch (RemoteException e) { 5267 } 5268 if (pkgUid == -1) { 5269 Slog.w(TAG, "Invalid packageName: " + packageName); 5270 if (observer != null) { 5271 try { 5272 observer.onRemoveCompleted(packageName, false); 5273 } catch (RemoteException e) { 5274 Slog.i(TAG, "Observer no longer exists."); 5275 } 5276 } 5277 return false; 5278 } 5279 if (uid == pkgUid || checkComponentPermission( 5280 android.Manifest.permission.CLEAR_APP_USER_DATA, 5281 pid, uid, -1, true) 5282 == PackageManager.PERMISSION_GRANTED) { 5283 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5284 } else { 5285 throw new SecurityException("PID " + pid + " does not have permission " 5286 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5287 + " of package " + packageName); 5288 } 5289 5290 // Remove all tasks match the cleared application package and user 5291 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5292 final TaskRecord tr = mRecentTasks.get(i); 5293 final String taskPackageName = 5294 tr.getBaseIntent().getComponent().getPackageName(); 5295 if (tr.userId != userId) continue; 5296 if (!taskPackageName.equals(packageName)) continue; 5297 removeTaskByIdLocked(tr.taskId, 0); 5298 } 5299 } 5300 5301 try { 5302 // Clear application user data 5303 pm.clearApplicationUserData(packageName, observer, userId); 5304 5305 synchronized(this) { 5306 // Remove all permissions granted from/to this package 5307 removeUriPermissionsForPackageLocked(packageName, userId, true); 5308 } 5309 5310 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5311 Uri.fromParts("package", packageName, null)); 5312 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5313 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5314 null, null, 0, null, null, null, false, false, userId); 5315 } catch (RemoteException e) { 5316 } 5317 } finally { 5318 Binder.restoreCallingIdentity(callingId); 5319 } 5320 return true; 5321 } 5322 5323 @Override 5324 public void killBackgroundProcesses(final String packageName, int userId) { 5325 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5326 != PackageManager.PERMISSION_GRANTED && 5327 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5328 != PackageManager.PERMISSION_GRANTED) { 5329 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5330 + Binder.getCallingPid() 5331 + ", uid=" + Binder.getCallingUid() 5332 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5333 Slog.w(TAG, msg); 5334 throw new SecurityException(msg); 5335 } 5336 5337 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5338 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5339 long callingId = Binder.clearCallingIdentity(); 5340 try { 5341 IPackageManager pm = AppGlobals.getPackageManager(); 5342 synchronized(this) { 5343 int appId = -1; 5344 try { 5345 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5346 } catch (RemoteException e) { 5347 } 5348 if (appId == -1) { 5349 Slog.w(TAG, "Invalid packageName: " + packageName); 5350 return; 5351 } 5352 killPackageProcessesLocked(packageName, appId, userId, 5353 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5354 } 5355 } finally { 5356 Binder.restoreCallingIdentity(callingId); 5357 } 5358 } 5359 5360 @Override 5361 public void killAllBackgroundProcesses() { 5362 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5363 != PackageManager.PERMISSION_GRANTED) { 5364 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5365 + Binder.getCallingPid() 5366 + ", uid=" + Binder.getCallingUid() 5367 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5368 Slog.w(TAG, msg); 5369 throw new SecurityException(msg); 5370 } 5371 5372 long callingId = Binder.clearCallingIdentity(); 5373 try { 5374 synchronized(this) { 5375 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5376 final int NP = mProcessNames.getMap().size(); 5377 for (int ip=0; ip<NP; ip++) { 5378 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5379 final int NA = apps.size(); 5380 for (int ia=0; ia<NA; ia++) { 5381 ProcessRecord app = apps.valueAt(ia); 5382 if (app.persistent) { 5383 // we don't kill persistent processes 5384 continue; 5385 } 5386 if (app.removed) { 5387 procs.add(app); 5388 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5389 app.removed = true; 5390 procs.add(app); 5391 } 5392 } 5393 } 5394 5395 int N = procs.size(); 5396 for (int i=0; i<N; i++) { 5397 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5398 } 5399 mAllowLowerMemLevel = true; 5400 updateOomAdjLocked(); 5401 doLowMemReportIfNeededLocked(null); 5402 } 5403 } finally { 5404 Binder.restoreCallingIdentity(callingId); 5405 } 5406 } 5407 5408 @Override 5409 public void forceStopPackage(final String packageName, int userId) { 5410 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5411 != PackageManager.PERMISSION_GRANTED) { 5412 String msg = "Permission Denial: forceStopPackage() from pid=" 5413 + Binder.getCallingPid() 5414 + ", uid=" + Binder.getCallingUid() 5415 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5416 Slog.w(TAG, msg); 5417 throw new SecurityException(msg); 5418 } 5419 final int callingPid = Binder.getCallingPid(); 5420 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5421 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5422 long callingId = Binder.clearCallingIdentity(); 5423 try { 5424 IPackageManager pm = AppGlobals.getPackageManager(); 5425 synchronized(this) { 5426 int[] users = userId == UserHandle.USER_ALL 5427 ? getUsersLocked() : new int[] { userId }; 5428 for (int user : users) { 5429 int pkgUid = -1; 5430 try { 5431 pkgUid = pm.getPackageUid(packageName, user); 5432 } catch (RemoteException e) { 5433 } 5434 if (pkgUid == -1) { 5435 Slog.w(TAG, "Invalid packageName: " + packageName); 5436 continue; 5437 } 5438 try { 5439 pm.setPackageStoppedState(packageName, true, user); 5440 } catch (RemoteException e) { 5441 } catch (IllegalArgumentException e) { 5442 Slog.w(TAG, "Failed trying to unstop package " 5443 + packageName + ": " + e); 5444 } 5445 if (isUserRunningLocked(user, false)) { 5446 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5447 } 5448 } 5449 } 5450 } finally { 5451 Binder.restoreCallingIdentity(callingId); 5452 } 5453 } 5454 5455 @Override 5456 public void addPackageDependency(String packageName) { 5457 synchronized (this) { 5458 int callingPid = Binder.getCallingPid(); 5459 if (callingPid == Process.myPid()) { 5460 // Yeah, um, no. 5461 Slog.w(TAG, "Can't addPackageDependency on system process"); 5462 return; 5463 } 5464 ProcessRecord proc; 5465 synchronized (mPidsSelfLocked) { 5466 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5467 } 5468 if (proc != null) { 5469 if (proc.pkgDeps == null) { 5470 proc.pkgDeps = new ArraySet<String>(1); 5471 } 5472 proc.pkgDeps.add(packageName); 5473 } 5474 } 5475 } 5476 5477 /* 5478 * The pkg name and app id have to be specified. 5479 */ 5480 @Override 5481 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5482 if (pkg == null) { 5483 return; 5484 } 5485 // Make sure the uid is valid. 5486 if (appid < 0) { 5487 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5488 return; 5489 } 5490 int callerUid = Binder.getCallingUid(); 5491 // Only the system server can kill an application 5492 if (callerUid == Process.SYSTEM_UID) { 5493 // Post an aysnc message to kill the application 5494 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5495 msg.arg1 = appid; 5496 msg.arg2 = 0; 5497 Bundle bundle = new Bundle(); 5498 bundle.putString("pkg", pkg); 5499 bundle.putString("reason", reason); 5500 msg.obj = bundle; 5501 mHandler.sendMessage(msg); 5502 } else { 5503 throw new SecurityException(callerUid + " cannot kill pkg: " + 5504 pkg); 5505 } 5506 } 5507 5508 @Override 5509 public void closeSystemDialogs(String reason) { 5510 enforceNotIsolatedCaller("closeSystemDialogs"); 5511 5512 final int pid = Binder.getCallingPid(); 5513 final int uid = Binder.getCallingUid(); 5514 final long origId = Binder.clearCallingIdentity(); 5515 try { 5516 synchronized (this) { 5517 // Only allow this from foreground processes, so that background 5518 // applications can't abuse it to prevent system UI from being shown. 5519 if (uid >= Process.FIRST_APPLICATION_UID) { 5520 ProcessRecord proc; 5521 synchronized (mPidsSelfLocked) { 5522 proc = mPidsSelfLocked.get(pid); 5523 } 5524 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5525 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5526 + " from background process " + proc); 5527 return; 5528 } 5529 } 5530 closeSystemDialogsLocked(reason); 5531 } 5532 } finally { 5533 Binder.restoreCallingIdentity(origId); 5534 } 5535 } 5536 5537 void closeSystemDialogsLocked(String reason) { 5538 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5540 | Intent.FLAG_RECEIVER_FOREGROUND); 5541 if (reason != null) { 5542 intent.putExtra("reason", reason); 5543 } 5544 mWindowManager.closeSystemDialogs(reason); 5545 5546 mStackSupervisor.closeSystemDialogsLocked(); 5547 5548 broadcastIntentLocked(null, null, intent, null, 5549 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5550 Process.SYSTEM_UID, UserHandle.USER_ALL); 5551 } 5552 5553 @Override 5554 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5555 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5556 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5557 for (int i=pids.length-1; i>=0; i--) { 5558 ProcessRecord proc; 5559 int oomAdj; 5560 synchronized (this) { 5561 synchronized (mPidsSelfLocked) { 5562 proc = mPidsSelfLocked.get(pids[i]); 5563 oomAdj = proc != null ? proc.setAdj : 0; 5564 } 5565 } 5566 infos[i] = new Debug.MemoryInfo(); 5567 Debug.getMemoryInfo(pids[i], infos[i]); 5568 if (proc != null) { 5569 synchronized (this) { 5570 if (proc.thread != null && proc.setAdj == oomAdj) { 5571 // Record this for posterity if the process has been stable. 5572 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5573 infos[i].getTotalUss(), false, proc.pkgList); 5574 } 5575 } 5576 } 5577 } 5578 return infos; 5579 } 5580 5581 @Override 5582 public long[] getProcessPss(int[] pids) { 5583 enforceNotIsolatedCaller("getProcessPss"); 5584 long[] pss = new long[pids.length]; 5585 for (int i=pids.length-1; i>=0; i--) { 5586 ProcessRecord proc; 5587 int oomAdj; 5588 synchronized (this) { 5589 synchronized (mPidsSelfLocked) { 5590 proc = mPidsSelfLocked.get(pids[i]); 5591 oomAdj = proc != null ? proc.setAdj : 0; 5592 } 5593 } 5594 long[] tmpUss = new long[1]; 5595 pss[i] = Debug.getPss(pids[i], tmpUss); 5596 if (proc != null) { 5597 synchronized (this) { 5598 if (proc.thread != null && proc.setAdj == oomAdj) { 5599 // Record this for posterity if the process has been stable. 5600 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5601 } 5602 } 5603 } 5604 } 5605 return pss; 5606 } 5607 5608 @Override 5609 public void killApplicationProcess(String processName, int uid) { 5610 if (processName == null) { 5611 return; 5612 } 5613 5614 int callerUid = Binder.getCallingUid(); 5615 // Only the system server can kill an application 5616 if (callerUid == Process.SYSTEM_UID) { 5617 synchronized (this) { 5618 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5619 if (app != null && app.thread != null) { 5620 try { 5621 app.thread.scheduleSuicide(); 5622 } catch (RemoteException e) { 5623 // If the other end already died, then our work here is done. 5624 } 5625 } else { 5626 Slog.w(TAG, "Process/uid not found attempting kill of " 5627 + processName + " / " + uid); 5628 } 5629 } 5630 } else { 5631 throw new SecurityException(callerUid + " cannot kill app process: " + 5632 processName); 5633 } 5634 } 5635 5636 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5637 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5638 false, true, false, false, UserHandle.getUserId(uid), reason); 5639 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5640 Uri.fromParts("package", packageName, null)); 5641 if (!mProcessesReady) { 5642 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5643 | Intent.FLAG_RECEIVER_FOREGROUND); 5644 } 5645 intent.putExtra(Intent.EXTRA_UID, uid); 5646 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5647 broadcastIntentLocked(null, null, intent, 5648 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5649 false, false, 5650 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5651 } 5652 5653 private void forceStopUserLocked(int userId, String reason) { 5654 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5655 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5656 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5657 | Intent.FLAG_RECEIVER_FOREGROUND); 5658 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5659 broadcastIntentLocked(null, null, intent, 5660 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5661 false, false, 5662 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5663 } 5664 5665 private final boolean killPackageProcessesLocked(String packageName, int appId, 5666 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5667 boolean doit, boolean evenPersistent, String reason) { 5668 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5669 5670 // Remove all processes this package may have touched: all with the 5671 // same UID (except for the system or root user), and all whose name 5672 // matches the package name. 5673 final int NP = mProcessNames.getMap().size(); 5674 for (int ip=0; ip<NP; ip++) { 5675 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5676 final int NA = apps.size(); 5677 for (int ia=0; ia<NA; ia++) { 5678 ProcessRecord app = apps.valueAt(ia); 5679 if (app.persistent && !evenPersistent) { 5680 // we don't kill persistent processes 5681 continue; 5682 } 5683 if (app.removed) { 5684 if (doit) { 5685 procs.add(app); 5686 } 5687 continue; 5688 } 5689 5690 // Skip process if it doesn't meet our oom adj requirement. 5691 if (app.setAdj < minOomAdj) { 5692 continue; 5693 } 5694 5695 // If no package is specified, we call all processes under the 5696 // give user id. 5697 if (packageName == null) { 5698 if (app.userId != userId) { 5699 continue; 5700 } 5701 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5702 continue; 5703 } 5704 // Package has been specified, we want to hit all processes 5705 // that match it. We need to qualify this by the processes 5706 // that are running under the specified app and user ID. 5707 } else { 5708 final boolean isDep = app.pkgDeps != null 5709 && app.pkgDeps.contains(packageName); 5710 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5711 continue; 5712 } 5713 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5714 continue; 5715 } 5716 if (!app.pkgList.containsKey(packageName) && !isDep) { 5717 continue; 5718 } 5719 } 5720 5721 // Process has passed all conditions, kill it! 5722 if (!doit) { 5723 return true; 5724 } 5725 app.removed = true; 5726 procs.add(app); 5727 } 5728 } 5729 5730 int N = procs.size(); 5731 for (int i=0; i<N; i++) { 5732 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5733 } 5734 updateOomAdjLocked(); 5735 return N > 0; 5736 } 5737 5738 private final boolean forceStopPackageLocked(String name, int appId, 5739 boolean callerWillRestart, boolean purgeCache, boolean doit, 5740 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5741 int i; 5742 int N; 5743 5744 if (userId == UserHandle.USER_ALL && name == null) { 5745 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5746 } 5747 5748 if (appId < 0 && name != null) { 5749 try { 5750 appId = UserHandle.getAppId( 5751 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5752 } catch (RemoteException e) { 5753 } 5754 } 5755 5756 if (doit) { 5757 if (name != null) { 5758 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5759 + " user=" + userId + ": " + reason); 5760 } else { 5761 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5762 } 5763 5764 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5765 for (int ip=pmap.size()-1; ip>=0; ip--) { 5766 SparseArray<Long> ba = pmap.valueAt(ip); 5767 for (i=ba.size()-1; i>=0; i--) { 5768 boolean remove = false; 5769 final int entUid = ba.keyAt(i); 5770 if (name != null) { 5771 if (userId == UserHandle.USER_ALL) { 5772 if (UserHandle.getAppId(entUid) == appId) { 5773 remove = true; 5774 } 5775 } else { 5776 if (entUid == UserHandle.getUid(userId, appId)) { 5777 remove = true; 5778 } 5779 } 5780 } else if (UserHandle.getUserId(entUid) == userId) { 5781 remove = true; 5782 } 5783 if (remove) { 5784 ba.removeAt(i); 5785 } 5786 } 5787 if (ba.size() == 0) { 5788 pmap.removeAt(ip); 5789 } 5790 } 5791 } 5792 5793 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5794 -100, callerWillRestart, true, doit, evenPersistent, 5795 name == null ? ("stop user " + userId) : ("stop " + name)); 5796 5797 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5798 if (!doit) { 5799 return true; 5800 } 5801 didSomething = true; 5802 } 5803 5804 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5805 if (!doit) { 5806 return true; 5807 } 5808 didSomething = true; 5809 } 5810 5811 if (name == null) { 5812 // Remove all sticky broadcasts from this user. 5813 mStickyBroadcasts.remove(userId); 5814 } 5815 5816 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5817 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5818 userId, providers)) { 5819 if (!doit) { 5820 return true; 5821 } 5822 didSomething = true; 5823 } 5824 N = providers.size(); 5825 for (i=0; i<N; i++) { 5826 removeDyingProviderLocked(null, providers.get(i), true); 5827 } 5828 5829 // Remove transient permissions granted from/to this package/user 5830 removeUriPermissionsForPackageLocked(name, userId, false); 5831 5832 if (name == null || uninstalling) { 5833 // Remove pending intents. For now we only do this when force 5834 // stopping users, because we have some problems when doing this 5835 // for packages -- app widgets are not currently cleaned up for 5836 // such packages, so they can be left with bad pending intents. 5837 if (mIntentSenderRecords.size() > 0) { 5838 Iterator<WeakReference<PendingIntentRecord>> it 5839 = mIntentSenderRecords.values().iterator(); 5840 while (it.hasNext()) { 5841 WeakReference<PendingIntentRecord> wpir = it.next(); 5842 if (wpir == null) { 5843 it.remove(); 5844 continue; 5845 } 5846 PendingIntentRecord pir = wpir.get(); 5847 if (pir == null) { 5848 it.remove(); 5849 continue; 5850 } 5851 if (name == null) { 5852 // Stopping user, remove all objects for the user. 5853 if (pir.key.userId != userId) { 5854 // Not the same user, skip it. 5855 continue; 5856 } 5857 } else { 5858 if (UserHandle.getAppId(pir.uid) != appId) { 5859 // Different app id, skip it. 5860 continue; 5861 } 5862 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5863 // Different user, skip it. 5864 continue; 5865 } 5866 if (!pir.key.packageName.equals(name)) { 5867 // Different package, skip it. 5868 continue; 5869 } 5870 } 5871 if (!doit) { 5872 return true; 5873 } 5874 didSomething = true; 5875 it.remove(); 5876 pir.canceled = true; 5877 if (pir.key.activity != null) { 5878 pir.key.activity.pendingResults.remove(pir.ref); 5879 } 5880 } 5881 } 5882 } 5883 5884 if (doit) { 5885 if (purgeCache && name != null) { 5886 AttributeCache ac = AttributeCache.instance(); 5887 if (ac != null) { 5888 ac.removePackage(name); 5889 } 5890 } 5891 if (mBooted) { 5892 mStackSupervisor.resumeTopActivitiesLocked(); 5893 mStackSupervisor.scheduleIdleLocked(); 5894 } 5895 } 5896 5897 return didSomething; 5898 } 5899 5900 private final boolean removeProcessLocked(ProcessRecord app, 5901 boolean callerWillRestart, boolean allowRestart, String reason) { 5902 final String name = app.processName; 5903 final int uid = app.uid; 5904 if (DEBUG_PROCESSES) Slog.d( 5905 TAG, "Force removing proc " + app.toShortString() + " (" + name 5906 + "/" + uid + ")"); 5907 5908 mProcessNames.remove(name, uid); 5909 mIsolatedProcesses.remove(app.uid); 5910 if (mHeavyWeightProcess == app) { 5911 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5912 mHeavyWeightProcess.userId, 0)); 5913 mHeavyWeightProcess = null; 5914 } 5915 boolean needRestart = false; 5916 if (app.pid > 0 && app.pid != MY_PID) { 5917 int pid = app.pid; 5918 synchronized (mPidsSelfLocked) { 5919 mPidsSelfLocked.remove(pid); 5920 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5921 } 5922 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5923 if (app.isolated) { 5924 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5925 } 5926 app.kill(reason, true); 5927 handleAppDiedLocked(app, true, allowRestart); 5928 removeLruProcessLocked(app); 5929 5930 if (app.persistent && !app.isolated) { 5931 if (!callerWillRestart) { 5932 addAppLocked(app.info, false, null /* ABI override */); 5933 } else { 5934 needRestart = true; 5935 } 5936 } 5937 } else { 5938 mRemovedProcesses.add(app); 5939 } 5940 5941 return needRestart; 5942 } 5943 5944 private final void processStartTimedOutLocked(ProcessRecord app) { 5945 final int pid = app.pid; 5946 boolean gone = false; 5947 synchronized (mPidsSelfLocked) { 5948 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5949 if (knownApp != null && knownApp.thread == null) { 5950 mPidsSelfLocked.remove(pid); 5951 gone = true; 5952 } 5953 } 5954 5955 if (gone) { 5956 Slog.w(TAG, "Process " + app + " failed to attach"); 5957 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5958 pid, app.uid, app.processName); 5959 mProcessNames.remove(app.processName, app.uid); 5960 mIsolatedProcesses.remove(app.uid); 5961 if (mHeavyWeightProcess == app) { 5962 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5963 mHeavyWeightProcess.userId, 0)); 5964 mHeavyWeightProcess = null; 5965 } 5966 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5967 if (app.isolated) { 5968 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5969 } 5970 // Take care of any launching providers waiting for this process. 5971 checkAppInLaunchingProvidersLocked(app, true); 5972 // Take care of any services that are waiting for the process. 5973 mServices.processStartTimedOutLocked(app); 5974 app.kill("start timeout", true); 5975 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5976 Slog.w(TAG, "Unattached app died before backup, skipping"); 5977 try { 5978 IBackupManager bm = IBackupManager.Stub.asInterface( 5979 ServiceManager.getService(Context.BACKUP_SERVICE)); 5980 bm.agentDisconnected(app.info.packageName); 5981 } catch (RemoteException e) { 5982 // Can't happen; the backup manager is local 5983 } 5984 } 5985 if (isPendingBroadcastProcessLocked(pid)) { 5986 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5987 skipPendingBroadcastLocked(pid); 5988 } 5989 } else { 5990 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5991 } 5992 } 5993 5994 private final boolean attachApplicationLocked(IApplicationThread thread, 5995 int pid) { 5996 5997 // Find the application record that is being attached... either via 5998 // the pid if we are running in multiple processes, or just pull the 5999 // next app record if we are emulating process with anonymous threads. 6000 ProcessRecord app; 6001 if (pid != MY_PID && pid >= 0) { 6002 synchronized (mPidsSelfLocked) { 6003 app = mPidsSelfLocked.get(pid); 6004 } 6005 } else { 6006 app = null; 6007 } 6008 6009 if (app == null) { 6010 Slog.w(TAG, "No pending application record for pid " + pid 6011 + " (IApplicationThread " + thread + "); dropping process"); 6012 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6013 if (pid > 0 && pid != MY_PID) { 6014 Process.killProcessQuiet(pid); 6015 //TODO: Process.killProcessGroup(app.info.uid, pid); 6016 } else { 6017 try { 6018 thread.scheduleExit(); 6019 } catch (Exception e) { 6020 // Ignore exceptions. 6021 } 6022 } 6023 return false; 6024 } 6025 6026 // If this application record is still attached to a previous 6027 // process, clean it up now. 6028 if (app.thread != null) { 6029 handleAppDiedLocked(app, true, true); 6030 } 6031 6032 // Tell the process all about itself. 6033 6034 if (localLOGV) Slog.v( 6035 TAG, "Binding process pid " + pid + " to record " + app); 6036 6037 final String processName = app.processName; 6038 try { 6039 AppDeathRecipient adr = new AppDeathRecipient( 6040 app, pid, thread); 6041 thread.asBinder().linkToDeath(adr, 0); 6042 app.deathRecipient = adr; 6043 } catch (RemoteException e) { 6044 app.resetPackageList(mProcessStats); 6045 startProcessLocked(app, "link fail", processName); 6046 return false; 6047 } 6048 6049 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6050 6051 app.makeActive(thread, mProcessStats); 6052 app.curAdj = app.setAdj = -100; 6053 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6054 app.forcingToForeground = null; 6055 updateProcessForegroundLocked(app, false, false); 6056 app.hasShownUi = false; 6057 app.debugging = false; 6058 app.cached = false; 6059 6060 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6061 6062 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6063 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6064 6065 if (!normalMode) { 6066 Slog.i(TAG, "Launching preboot mode app: " + app); 6067 } 6068 6069 if (localLOGV) Slog.v( 6070 TAG, "New app record " + app 6071 + " thread=" + thread.asBinder() + " pid=" + pid); 6072 try { 6073 int testMode = IApplicationThread.DEBUG_OFF; 6074 if (mDebugApp != null && mDebugApp.equals(processName)) { 6075 testMode = mWaitForDebugger 6076 ? IApplicationThread.DEBUG_WAIT 6077 : IApplicationThread.DEBUG_ON; 6078 app.debugging = true; 6079 if (mDebugTransient) { 6080 mDebugApp = mOrigDebugApp; 6081 mWaitForDebugger = mOrigWaitForDebugger; 6082 } 6083 } 6084 String profileFile = app.instrumentationProfileFile; 6085 ParcelFileDescriptor profileFd = null; 6086 int samplingInterval = 0; 6087 boolean profileAutoStop = false; 6088 if (mProfileApp != null && mProfileApp.equals(processName)) { 6089 mProfileProc = app; 6090 profileFile = mProfileFile; 6091 profileFd = mProfileFd; 6092 samplingInterval = mSamplingInterval; 6093 profileAutoStop = mAutoStopProfiler; 6094 } 6095 boolean enableOpenGlTrace = false; 6096 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6097 enableOpenGlTrace = true; 6098 mOpenGlTraceApp = null; 6099 } 6100 6101 // If the app is being launched for restore or full backup, set it up specially 6102 boolean isRestrictedBackupMode = false; 6103 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6104 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6105 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6106 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6107 } 6108 6109 ensurePackageDexOpt(app.instrumentationInfo != null 6110 ? app.instrumentationInfo.packageName 6111 : app.info.packageName); 6112 if (app.instrumentationClass != null) { 6113 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6114 } 6115 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6116 + processName + " with config " + mConfiguration); 6117 ApplicationInfo appInfo = app.instrumentationInfo != null 6118 ? app.instrumentationInfo : app.info; 6119 app.compat = compatibilityInfoForPackageLocked(appInfo); 6120 if (profileFd != null) { 6121 profileFd = profileFd.dup(); 6122 } 6123 ProfilerInfo profilerInfo = profileFile == null ? null 6124 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6125 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6126 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6127 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6128 isRestrictedBackupMode || !normalMode, app.persistent, 6129 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6130 mCoreSettingsObserver.getCoreSettingsLocked()); 6131 updateLruProcessLocked(app, false, null); 6132 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6133 } catch (Exception e) { 6134 // todo: Yikes! What should we do? For now we will try to 6135 // start another process, but that could easily get us in 6136 // an infinite loop of restarting processes... 6137 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6138 6139 app.resetPackageList(mProcessStats); 6140 app.unlinkDeathRecipient(); 6141 startProcessLocked(app, "bind fail", processName); 6142 return false; 6143 } 6144 6145 // Remove this record from the list of starting applications. 6146 mPersistentStartingProcesses.remove(app); 6147 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6148 "Attach application locked removing on hold: " + app); 6149 mProcessesOnHold.remove(app); 6150 6151 boolean badApp = false; 6152 boolean didSomething = false; 6153 6154 // See if the top visible activity is waiting to run in this process... 6155 if (normalMode) { 6156 try { 6157 if (mStackSupervisor.attachApplicationLocked(app)) { 6158 didSomething = true; 6159 } 6160 } catch (Exception e) { 6161 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6162 badApp = true; 6163 } 6164 } 6165 6166 // Find any services that should be running in this process... 6167 if (!badApp) { 6168 try { 6169 didSomething |= mServices.attachApplicationLocked(app, processName); 6170 } catch (Exception e) { 6171 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6172 badApp = true; 6173 } 6174 } 6175 6176 // Check if a next-broadcast receiver is in this process... 6177 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6178 try { 6179 didSomething |= sendPendingBroadcastsLocked(app); 6180 } catch (Exception e) { 6181 // If the app died trying to launch the receiver we declare it 'bad' 6182 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6183 badApp = true; 6184 } 6185 } 6186 6187 // Check whether the next backup agent is in this process... 6188 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6189 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6190 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6191 try { 6192 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6193 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6194 mBackupTarget.backupMode); 6195 } catch (Exception e) { 6196 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6197 badApp = true; 6198 } 6199 } 6200 6201 if (badApp) { 6202 app.kill("error during init", true); 6203 handleAppDiedLocked(app, false, true); 6204 return false; 6205 } 6206 6207 if (!didSomething) { 6208 updateOomAdjLocked(); 6209 } 6210 6211 return true; 6212 } 6213 6214 @Override 6215 public final void attachApplication(IApplicationThread thread) { 6216 synchronized (this) { 6217 int callingPid = Binder.getCallingPid(); 6218 final long origId = Binder.clearCallingIdentity(); 6219 attachApplicationLocked(thread, callingPid); 6220 Binder.restoreCallingIdentity(origId); 6221 } 6222 } 6223 6224 @Override 6225 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6226 final long origId = Binder.clearCallingIdentity(); 6227 synchronized (this) { 6228 ActivityStack stack = ActivityRecord.getStackLocked(token); 6229 if (stack != null) { 6230 ActivityRecord r = 6231 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6232 if (stopProfiling) { 6233 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6234 try { 6235 mProfileFd.close(); 6236 } catch (IOException e) { 6237 } 6238 clearProfilerLocked(); 6239 } 6240 } 6241 } 6242 } 6243 Binder.restoreCallingIdentity(origId); 6244 } 6245 6246 void postEnableScreenAfterBootLocked() { 6247 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6248 } 6249 6250 void enableScreenAfterBoot() { 6251 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6252 SystemClock.uptimeMillis()); 6253 mWindowManager.enableScreenAfterBoot(); 6254 6255 synchronized (this) { 6256 updateEventDispatchingLocked(); 6257 } 6258 } 6259 6260 @Override 6261 public void showBootMessage(final CharSequence msg, final boolean always) { 6262 enforceNotIsolatedCaller("showBootMessage"); 6263 mWindowManager.showBootMessage(msg, always); 6264 } 6265 6266 @Override 6267 public void keyguardWaitingForActivityDrawn() { 6268 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6269 final long token = Binder.clearCallingIdentity(); 6270 try { 6271 synchronized (this) { 6272 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6273 mWindowManager.keyguardWaitingForActivityDrawn(); 6274 if (mLockScreenShown) { 6275 mLockScreenShown = false; 6276 comeOutOfSleepIfNeededLocked(); 6277 } 6278 } 6279 } finally { 6280 Binder.restoreCallingIdentity(token); 6281 } 6282 } 6283 6284 final void finishBooting() { 6285 synchronized (this) { 6286 if (!mBootAnimationComplete) { 6287 mCallFinishBooting = true; 6288 return; 6289 } 6290 mCallFinishBooting = false; 6291 } 6292 6293 // Register receivers to handle package update events 6294 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6295 6296 // Let system services know. 6297 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6298 6299 synchronized (this) { 6300 // Ensure that any processes we had put on hold are now started 6301 // up. 6302 final int NP = mProcessesOnHold.size(); 6303 if (NP > 0) { 6304 ArrayList<ProcessRecord> procs = 6305 new ArrayList<ProcessRecord>(mProcessesOnHold); 6306 for (int ip=0; ip<NP; ip++) { 6307 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6308 + procs.get(ip)); 6309 startProcessLocked(procs.get(ip), "on-hold", null); 6310 } 6311 } 6312 6313 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6314 // Start looking for apps that are abusing wake locks. 6315 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6316 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6317 // Tell anyone interested that we are done booting! 6318 SystemProperties.set("sys.boot_completed", "1"); 6319 SystemProperties.set("dev.bootcomplete", "1"); 6320 for (int i=0; i<mStartedUsers.size(); i++) { 6321 UserStartedState uss = mStartedUsers.valueAt(i); 6322 if (uss.mState == UserStartedState.STATE_BOOTING) { 6323 uss.mState = UserStartedState.STATE_RUNNING; 6324 final int userId = mStartedUsers.keyAt(i); 6325 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6326 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6327 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6328 broadcastIntentLocked(null, null, intent, null, 6329 new IIntentReceiver.Stub() { 6330 @Override 6331 public void performReceive(Intent intent, int resultCode, 6332 String data, Bundle extras, boolean ordered, 6333 boolean sticky, int sendingUser) { 6334 synchronized (ActivityManagerService.this) { 6335 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6336 true, false); 6337 } 6338 } 6339 }, 6340 0, null, null, 6341 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6342 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6343 userId); 6344 } 6345 } 6346 scheduleStartProfilesLocked(); 6347 } 6348 } 6349 } 6350 6351 @Override 6352 public void bootAnimationComplete() { 6353 final boolean callFinishBooting; 6354 synchronized (this) { 6355 callFinishBooting = mCallFinishBooting; 6356 mBootAnimationComplete = true; 6357 } 6358 if (callFinishBooting) { 6359 finishBooting(); 6360 } 6361 } 6362 6363 final void ensureBootCompleted() { 6364 boolean booting; 6365 boolean enableScreen; 6366 synchronized (this) { 6367 booting = mBooting; 6368 mBooting = false; 6369 enableScreen = !mBooted; 6370 mBooted = true; 6371 } 6372 6373 if (booting) { 6374 finishBooting(); 6375 } 6376 6377 if (enableScreen) { 6378 enableScreenAfterBoot(); 6379 } 6380 } 6381 6382 @Override 6383 public final void activityResumed(IBinder token) { 6384 final long origId = Binder.clearCallingIdentity(); 6385 synchronized(this) { 6386 ActivityStack stack = ActivityRecord.getStackLocked(token); 6387 if (stack != null) { 6388 ActivityRecord.activityResumedLocked(token); 6389 } 6390 } 6391 Binder.restoreCallingIdentity(origId); 6392 } 6393 6394 @Override 6395 public final void activityPaused(IBinder token) { 6396 final long origId = Binder.clearCallingIdentity(); 6397 synchronized(this) { 6398 ActivityStack stack = ActivityRecord.getStackLocked(token); 6399 if (stack != null) { 6400 stack.activityPausedLocked(token, false); 6401 } 6402 } 6403 Binder.restoreCallingIdentity(origId); 6404 } 6405 6406 @Override 6407 public final void activityStopped(IBinder token, Bundle icicle, 6408 PersistableBundle persistentState, CharSequence description) { 6409 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6410 6411 // Refuse possible leaked file descriptors 6412 if (icicle != null && icicle.hasFileDescriptors()) { 6413 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6414 } 6415 6416 final long origId = Binder.clearCallingIdentity(); 6417 6418 synchronized (this) { 6419 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6420 if (r != null) { 6421 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6422 } 6423 } 6424 6425 trimApplications(); 6426 6427 Binder.restoreCallingIdentity(origId); 6428 } 6429 6430 @Override 6431 public final void activityDestroyed(IBinder token) { 6432 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6433 synchronized (this) { 6434 ActivityStack stack = ActivityRecord.getStackLocked(token); 6435 if (stack != null) { 6436 stack.activityDestroyedLocked(token); 6437 } 6438 } 6439 } 6440 6441 @Override 6442 public final void backgroundResourcesReleased(IBinder token) { 6443 final long origId = Binder.clearCallingIdentity(); 6444 try { 6445 synchronized (this) { 6446 ActivityStack stack = ActivityRecord.getStackLocked(token); 6447 if (stack != null) { 6448 stack.backgroundResourcesReleased(token); 6449 } 6450 } 6451 } finally { 6452 Binder.restoreCallingIdentity(origId); 6453 } 6454 } 6455 6456 @Override 6457 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6458 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6459 } 6460 6461 @Override 6462 public final void notifyEnterAnimationComplete(IBinder token) { 6463 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6464 } 6465 6466 @Override 6467 public String getCallingPackage(IBinder token) { 6468 synchronized (this) { 6469 ActivityRecord r = getCallingRecordLocked(token); 6470 return r != null ? r.info.packageName : null; 6471 } 6472 } 6473 6474 @Override 6475 public ComponentName getCallingActivity(IBinder token) { 6476 synchronized (this) { 6477 ActivityRecord r = getCallingRecordLocked(token); 6478 return r != null ? r.intent.getComponent() : null; 6479 } 6480 } 6481 6482 private ActivityRecord getCallingRecordLocked(IBinder token) { 6483 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6484 if (r == null) { 6485 return null; 6486 } 6487 return r.resultTo; 6488 } 6489 6490 @Override 6491 public ComponentName getActivityClassForToken(IBinder token) { 6492 synchronized(this) { 6493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6494 if (r == null) { 6495 return null; 6496 } 6497 return r.intent.getComponent(); 6498 } 6499 } 6500 6501 @Override 6502 public String getPackageForToken(IBinder token) { 6503 synchronized(this) { 6504 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6505 if (r == null) { 6506 return null; 6507 } 6508 return r.packageName; 6509 } 6510 } 6511 6512 @Override 6513 public IIntentSender getIntentSender(int type, 6514 String packageName, IBinder token, String resultWho, 6515 int requestCode, Intent[] intents, String[] resolvedTypes, 6516 int flags, Bundle options, int userId) { 6517 enforceNotIsolatedCaller("getIntentSender"); 6518 // Refuse possible leaked file descriptors 6519 if (intents != null) { 6520 if (intents.length < 1) { 6521 throw new IllegalArgumentException("Intents array length must be >= 1"); 6522 } 6523 for (int i=0; i<intents.length; i++) { 6524 Intent intent = intents[i]; 6525 if (intent != null) { 6526 if (intent.hasFileDescriptors()) { 6527 throw new IllegalArgumentException("File descriptors passed in Intent"); 6528 } 6529 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6530 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6531 throw new IllegalArgumentException( 6532 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6533 } 6534 intents[i] = new Intent(intent); 6535 } 6536 } 6537 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6538 throw new IllegalArgumentException( 6539 "Intent array length does not match resolvedTypes length"); 6540 } 6541 } 6542 if (options != null) { 6543 if (options.hasFileDescriptors()) { 6544 throw new IllegalArgumentException("File descriptors passed in options"); 6545 } 6546 } 6547 6548 synchronized(this) { 6549 int callingUid = Binder.getCallingUid(); 6550 int origUserId = userId; 6551 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6552 type == ActivityManager.INTENT_SENDER_BROADCAST, 6553 ALLOW_NON_FULL, "getIntentSender", null); 6554 if (origUserId == UserHandle.USER_CURRENT) { 6555 // We don't want to evaluate this until the pending intent is 6556 // actually executed. However, we do want to always do the 6557 // security checking for it above. 6558 userId = UserHandle.USER_CURRENT; 6559 } 6560 try { 6561 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6562 int uid = AppGlobals.getPackageManager() 6563 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6564 if (!UserHandle.isSameApp(callingUid, uid)) { 6565 String msg = "Permission Denial: getIntentSender() from pid=" 6566 + Binder.getCallingPid() 6567 + ", uid=" + Binder.getCallingUid() 6568 + ", (need uid=" + uid + ")" 6569 + " is not allowed to send as package " + packageName; 6570 Slog.w(TAG, msg); 6571 throw new SecurityException(msg); 6572 } 6573 } 6574 6575 return getIntentSenderLocked(type, packageName, callingUid, userId, 6576 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6577 6578 } catch (RemoteException e) { 6579 throw new SecurityException(e); 6580 } 6581 } 6582 } 6583 6584 IIntentSender getIntentSenderLocked(int type, String packageName, 6585 int callingUid, int userId, IBinder token, String resultWho, 6586 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6587 Bundle options) { 6588 if (DEBUG_MU) 6589 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6590 ActivityRecord activity = null; 6591 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6592 activity = ActivityRecord.isInStackLocked(token); 6593 if (activity == null) { 6594 return null; 6595 } 6596 if (activity.finishing) { 6597 return null; 6598 } 6599 } 6600 6601 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6602 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6603 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6604 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6605 |PendingIntent.FLAG_UPDATE_CURRENT); 6606 6607 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6608 type, packageName, activity, resultWho, 6609 requestCode, intents, resolvedTypes, flags, options, userId); 6610 WeakReference<PendingIntentRecord> ref; 6611 ref = mIntentSenderRecords.get(key); 6612 PendingIntentRecord rec = ref != null ? ref.get() : null; 6613 if (rec != null) { 6614 if (!cancelCurrent) { 6615 if (updateCurrent) { 6616 if (rec.key.requestIntent != null) { 6617 rec.key.requestIntent.replaceExtras(intents != null ? 6618 intents[intents.length - 1] : null); 6619 } 6620 if (intents != null) { 6621 intents[intents.length-1] = rec.key.requestIntent; 6622 rec.key.allIntents = intents; 6623 rec.key.allResolvedTypes = resolvedTypes; 6624 } else { 6625 rec.key.allIntents = null; 6626 rec.key.allResolvedTypes = null; 6627 } 6628 } 6629 return rec; 6630 } 6631 rec.canceled = true; 6632 mIntentSenderRecords.remove(key); 6633 } 6634 if (noCreate) { 6635 return rec; 6636 } 6637 rec = new PendingIntentRecord(this, key, callingUid); 6638 mIntentSenderRecords.put(key, rec.ref); 6639 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6640 if (activity.pendingResults == null) { 6641 activity.pendingResults 6642 = new HashSet<WeakReference<PendingIntentRecord>>(); 6643 } 6644 activity.pendingResults.add(rec.ref); 6645 } 6646 return rec; 6647 } 6648 6649 @Override 6650 public void cancelIntentSender(IIntentSender sender) { 6651 if (!(sender instanceof PendingIntentRecord)) { 6652 return; 6653 } 6654 synchronized(this) { 6655 PendingIntentRecord rec = (PendingIntentRecord)sender; 6656 try { 6657 int uid = AppGlobals.getPackageManager() 6658 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6659 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6660 String msg = "Permission Denial: cancelIntentSender() from pid=" 6661 + Binder.getCallingPid() 6662 + ", uid=" + Binder.getCallingUid() 6663 + " is not allowed to cancel packges " 6664 + rec.key.packageName; 6665 Slog.w(TAG, msg); 6666 throw new SecurityException(msg); 6667 } 6668 } catch (RemoteException e) { 6669 throw new SecurityException(e); 6670 } 6671 cancelIntentSenderLocked(rec, true); 6672 } 6673 } 6674 6675 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6676 rec.canceled = true; 6677 mIntentSenderRecords.remove(rec.key); 6678 if (cleanActivity && rec.key.activity != null) { 6679 rec.key.activity.pendingResults.remove(rec.ref); 6680 } 6681 } 6682 6683 @Override 6684 public String getPackageForIntentSender(IIntentSender pendingResult) { 6685 if (!(pendingResult instanceof PendingIntentRecord)) { 6686 return null; 6687 } 6688 try { 6689 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6690 return res.key.packageName; 6691 } catch (ClassCastException e) { 6692 } 6693 return null; 6694 } 6695 6696 @Override 6697 public int getUidForIntentSender(IIntentSender sender) { 6698 if (sender instanceof PendingIntentRecord) { 6699 try { 6700 PendingIntentRecord res = (PendingIntentRecord)sender; 6701 return res.uid; 6702 } catch (ClassCastException e) { 6703 } 6704 } 6705 return -1; 6706 } 6707 6708 @Override 6709 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6710 if (!(pendingResult instanceof PendingIntentRecord)) { 6711 return false; 6712 } 6713 try { 6714 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6715 if (res.key.allIntents == null) { 6716 return false; 6717 } 6718 for (int i=0; i<res.key.allIntents.length; i++) { 6719 Intent intent = res.key.allIntents[i]; 6720 if (intent.getPackage() != null && intent.getComponent() != null) { 6721 return false; 6722 } 6723 } 6724 return true; 6725 } catch (ClassCastException e) { 6726 } 6727 return false; 6728 } 6729 6730 @Override 6731 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6732 if (!(pendingResult instanceof PendingIntentRecord)) { 6733 return false; 6734 } 6735 try { 6736 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6737 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6738 return true; 6739 } 6740 return false; 6741 } catch (ClassCastException e) { 6742 } 6743 return false; 6744 } 6745 6746 @Override 6747 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6748 if (!(pendingResult instanceof PendingIntentRecord)) { 6749 return null; 6750 } 6751 try { 6752 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6753 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6754 } catch (ClassCastException e) { 6755 } 6756 return null; 6757 } 6758 6759 @Override 6760 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6761 if (!(pendingResult instanceof PendingIntentRecord)) { 6762 return null; 6763 } 6764 try { 6765 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6766 Intent intent = res.key.requestIntent; 6767 if (intent != null) { 6768 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6769 || res.lastTagPrefix.equals(prefix))) { 6770 return res.lastTag; 6771 } 6772 res.lastTagPrefix = prefix; 6773 StringBuilder sb = new StringBuilder(128); 6774 if (prefix != null) { 6775 sb.append(prefix); 6776 } 6777 if (intent.getAction() != null) { 6778 sb.append(intent.getAction()); 6779 } else if (intent.getComponent() != null) { 6780 intent.getComponent().appendShortString(sb); 6781 } else { 6782 sb.append("?"); 6783 } 6784 return res.lastTag = sb.toString(); 6785 } 6786 } catch (ClassCastException e) { 6787 } 6788 return null; 6789 } 6790 6791 @Override 6792 public void setProcessLimit(int max) { 6793 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6794 "setProcessLimit()"); 6795 synchronized (this) { 6796 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6797 mProcessLimitOverride = max; 6798 } 6799 trimApplications(); 6800 } 6801 6802 @Override 6803 public int getProcessLimit() { 6804 synchronized (this) { 6805 return mProcessLimitOverride; 6806 } 6807 } 6808 6809 void foregroundTokenDied(ForegroundToken token) { 6810 synchronized (ActivityManagerService.this) { 6811 synchronized (mPidsSelfLocked) { 6812 ForegroundToken cur 6813 = mForegroundProcesses.get(token.pid); 6814 if (cur != token) { 6815 return; 6816 } 6817 mForegroundProcesses.remove(token.pid); 6818 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6819 if (pr == null) { 6820 return; 6821 } 6822 pr.forcingToForeground = null; 6823 updateProcessForegroundLocked(pr, false, false); 6824 } 6825 updateOomAdjLocked(); 6826 } 6827 } 6828 6829 @Override 6830 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6831 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6832 "setProcessForeground()"); 6833 synchronized(this) { 6834 boolean changed = false; 6835 6836 synchronized (mPidsSelfLocked) { 6837 ProcessRecord pr = mPidsSelfLocked.get(pid); 6838 if (pr == null && isForeground) { 6839 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6840 return; 6841 } 6842 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6843 if (oldToken != null) { 6844 oldToken.token.unlinkToDeath(oldToken, 0); 6845 mForegroundProcesses.remove(pid); 6846 if (pr != null) { 6847 pr.forcingToForeground = null; 6848 } 6849 changed = true; 6850 } 6851 if (isForeground && token != null) { 6852 ForegroundToken newToken = new ForegroundToken() { 6853 @Override 6854 public void binderDied() { 6855 foregroundTokenDied(this); 6856 } 6857 }; 6858 newToken.pid = pid; 6859 newToken.token = token; 6860 try { 6861 token.linkToDeath(newToken, 0); 6862 mForegroundProcesses.put(pid, newToken); 6863 pr.forcingToForeground = token; 6864 changed = true; 6865 } catch (RemoteException e) { 6866 // If the process died while doing this, we will later 6867 // do the cleanup with the process death link. 6868 } 6869 } 6870 } 6871 6872 if (changed) { 6873 updateOomAdjLocked(); 6874 } 6875 } 6876 } 6877 6878 // ========================================================= 6879 // PERMISSIONS 6880 // ========================================================= 6881 6882 static class PermissionController extends IPermissionController.Stub { 6883 ActivityManagerService mActivityManagerService; 6884 PermissionController(ActivityManagerService activityManagerService) { 6885 mActivityManagerService = activityManagerService; 6886 } 6887 6888 @Override 6889 public boolean checkPermission(String permission, int pid, int uid) { 6890 return mActivityManagerService.checkPermission(permission, pid, 6891 uid) == PackageManager.PERMISSION_GRANTED; 6892 } 6893 } 6894 6895 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6896 @Override 6897 public int checkComponentPermission(String permission, int pid, int uid, 6898 int owningUid, boolean exported) { 6899 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6900 owningUid, exported); 6901 } 6902 6903 @Override 6904 public Object getAMSLock() { 6905 return ActivityManagerService.this; 6906 } 6907 } 6908 6909 /** 6910 * This can be called with or without the global lock held. 6911 */ 6912 int checkComponentPermission(String permission, int pid, int uid, 6913 int owningUid, boolean exported) { 6914 // We might be performing an operation on behalf of an indirect binder 6915 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6916 // client identity accordingly before proceeding. 6917 Identity tlsIdentity = sCallerIdentity.get(); 6918 if (tlsIdentity != null) { 6919 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6920 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6921 uid = tlsIdentity.uid; 6922 pid = tlsIdentity.pid; 6923 } 6924 6925 if (pid == MY_PID) { 6926 return PackageManager.PERMISSION_GRANTED; 6927 } 6928 6929 return ActivityManager.checkComponentPermission(permission, uid, 6930 owningUid, exported); 6931 } 6932 6933 /** 6934 * As the only public entry point for permissions checking, this method 6935 * can enforce the semantic that requesting a check on a null global 6936 * permission is automatically denied. (Internally a null permission 6937 * string is used when calling {@link #checkComponentPermission} in cases 6938 * when only uid-based security is needed.) 6939 * 6940 * This can be called with or without the global lock held. 6941 */ 6942 @Override 6943 public int checkPermission(String permission, int pid, int uid) { 6944 if (permission == null) { 6945 return PackageManager.PERMISSION_DENIED; 6946 } 6947 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6948 } 6949 6950 /** 6951 * Binder IPC calls go through the public entry point. 6952 * This can be called with or without the global lock held. 6953 */ 6954 int checkCallingPermission(String permission) { 6955 return checkPermission(permission, 6956 Binder.getCallingPid(), 6957 UserHandle.getAppId(Binder.getCallingUid())); 6958 } 6959 6960 /** 6961 * This can be called with or without the global lock held. 6962 */ 6963 void enforceCallingPermission(String permission, String func) { 6964 if (checkCallingPermission(permission) 6965 == PackageManager.PERMISSION_GRANTED) { 6966 return; 6967 } 6968 6969 String msg = "Permission Denial: " + func + " from pid=" 6970 + Binder.getCallingPid() 6971 + ", uid=" + Binder.getCallingUid() 6972 + " requires " + permission; 6973 Slog.w(TAG, msg); 6974 throw new SecurityException(msg); 6975 } 6976 6977 /** 6978 * Determine if UID is holding permissions required to access {@link Uri} in 6979 * the given {@link ProviderInfo}. Final permission checking is always done 6980 * in {@link ContentProvider}. 6981 */ 6982 private final boolean checkHoldingPermissionsLocked( 6983 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6984 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6985 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6986 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6987 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6988 != PERMISSION_GRANTED) { 6989 return false; 6990 } 6991 } 6992 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6993 } 6994 6995 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6996 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6997 if (pi.applicationInfo.uid == uid) { 6998 return true; 6999 } else if (!pi.exported) { 7000 return false; 7001 } 7002 7003 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7004 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7005 try { 7006 // check if target holds top-level <provider> permissions 7007 if (!readMet && pi.readPermission != null && considerUidPermissions 7008 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7009 readMet = true; 7010 } 7011 if (!writeMet && pi.writePermission != null && considerUidPermissions 7012 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7013 writeMet = true; 7014 } 7015 7016 // track if unprotected read/write is allowed; any denied 7017 // <path-permission> below removes this ability 7018 boolean allowDefaultRead = pi.readPermission == null; 7019 boolean allowDefaultWrite = pi.writePermission == null; 7020 7021 // check if target holds any <path-permission> that match uri 7022 final PathPermission[] pps = pi.pathPermissions; 7023 if (pps != null) { 7024 final String path = grantUri.uri.getPath(); 7025 int i = pps.length; 7026 while (i > 0 && (!readMet || !writeMet)) { 7027 i--; 7028 PathPermission pp = pps[i]; 7029 if (pp.match(path)) { 7030 if (!readMet) { 7031 final String pprperm = pp.getReadPermission(); 7032 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7033 + pprperm + " for " + pp.getPath() 7034 + ": match=" + pp.match(path) 7035 + " check=" + pm.checkUidPermission(pprperm, uid)); 7036 if (pprperm != null) { 7037 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7038 == PERMISSION_GRANTED) { 7039 readMet = true; 7040 } else { 7041 allowDefaultRead = false; 7042 } 7043 } 7044 } 7045 if (!writeMet) { 7046 final String ppwperm = pp.getWritePermission(); 7047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7048 + ppwperm + " for " + pp.getPath() 7049 + ": match=" + pp.match(path) 7050 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7051 if (ppwperm != null) { 7052 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7053 == PERMISSION_GRANTED) { 7054 writeMet = true; 7055 } else { 7056 allowDefaultWrite = false; 7057 } 7058 } 7059 } 7060 } 7061 } 7062 } 7063 7064 // grant unprotected <provider> read/write, if not blocked by 7065 // <path-permission> above 7066 if (allowDefaultRead) readMet = true; 7067 if (allowDefaultWrite) writeMet = true; 7068 7069 } catch (RemoteException e) { 7070 return false; 7071 } 7072 7073 return readMet && writeMet; 7074 } 7075 7076 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7077 ProviderInfo pi = null; 7078 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7079 if (cpr != null) { 7080 pi = cpr.info; 7081 } else { 7082 try { 7083 pi = AppGlobals.getPackageManager().resolveContentProvider( 7084 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7085 } catch (RemoteException ex) { 7086 } 7087 } 7088 return pi; 7089 } 7090 7091 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7092 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7093 if (targetUris != null) { 7094 return targetUris.get(grantUri); 7095 } 7096 return null; 7097 } 7098 7099 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7100 String targetPkg, int targetUid, GrantUri grantUri) { 7101 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7102 if (targetUris == null) { 7103 targetUris = Maps.newArrayMap(); 7104 mGrantedUriPermissions.put(targetUid, targetUris); 7105 } 7106 7107 UriPermission perm = targetUris.get(grantUri); 7108 if (perm == null) { 7109 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7110 targetUris.put(grantUri, perm); 7111 } 7112 7113 return perm; 7114 } 7115 7116 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7117 final int modeFlags) { 7118 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7119 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7120 : UriPermission.STRENGTH_OWNED; 7121 7122 // Root gets to do everything. 7123 if (uid == 0) { 7124 return true; 7125 } 7126 7127 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7128 if (perms == null) return false; 7129 7130 // First look for exact match 7131 final UriPermission exactPerm = perms.get(grantUri); 7132 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7133 return true; 7134 } 7135 7136 // No exact match, look for prefixes 7137 final int N = perms.size(); 7138 for (int i = 0; i < N; i++) { 7139 final UriPermission perm = perms.valueAt(i); 7140 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7141 && perm.getStrength(modeFlags) >= minStrength) { 7142 return true; 7143 } 7144 } 7145 7146 return false; 7147 } 7148 7149 /** 7150 * @param uri This uri must NOT contain an embedded userId. 7151 * @param userId The userId in which the uri is to be resolved. 7152 */ 7153 @Override 7154 public int checkUriPermission(Uri uri, int pid, int uid, 7155 final int modeFlags, int userId) { 7156 enforceNotIsolatedCaller("checkUriPermission"); 7157 7158 // Another redirected-binder-call permissions check as in 7159 // {@link checkComponentPermission}. 7160 Identity tlsIdentity = sCallerIdentity.get(); 7161 if (tlsIdentity != null) { 7162 uid = tlsIdentity.uid; 7163 pid = tlsIdentity.pid; 7164 } 7165 7166 // Our own process gets to do everything. 7167 if (pid == MY_PID) { 7168 return PackageManager.PERMISSION_GRANTED; 7169 } 7170 synchronized (this) { 7171 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7172 ? PackageManager.PERMISSION_GRANTED 7173 : PackageManager.PERMISSION_DENIED; 7174 } 7175 } 7176 7177 /** 7178 * Check if the targetPkg can be granted permission to access uri by 7179 * the callingUid using the given modeFlags. Throws a security exception 7180 * if callingUid is not allowed to do this. Returns the uid of the target 7181 * if the URI permission grant should be performed; returns -1 if it is not 7182 * needed (for example targetPkg already has permission to access the URI). 7183 * If you already know the uid of the target, you can supply it in 7184 * lastTargetUid else set that to -1. 7185 */ 7186 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7187 final int modeFlags, int lastTargetUid) { 7188 if (!Intent.isAccessUriMode(modeFlags)) { 7189 return -1; 7190 } 7191 7192 if (targetPkg != null) { 7193 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7194 "Checking grant " + targetPkg + " permission to " + grantUri); 7195 } 7196 7197 final IPackageManager pm = AppGlobals.getPackageManager(); 7198 7199 // If this is not a content: uri, we can't do anything with it. 7200 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7201 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7202 "Can't grant URI permission for non-content URI: " + grantUri); 7203 return -1; 7204 } 7205 7206 final String authority = grantUri.uri.getAuthority(); 7207 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7208 if (pi == null) { 7209 Slog.w(TAG, "No content provider found for permission check: " + 7210 grantUri.uri.toSafeString()); 7211 return -1; 7212 } 7213 7214 int targetUid = lastTargetUid; 7215 if (targetUid < 0 && targetPkg != null) { 7216 try { 7217 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7218 if (targetUid < 0) { 7219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7220 "Can't grant URI permission no uid for: " + targetPkg); 7221 return -1; 7222 } 7223 } catch (RemoteException ex) { 7224 return -1; 7225 } 7226 } 7227 7228 if (targetUid >= 0) { 7229 // First... does the target actually need this permission? 7230 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7231 // No need to grant the target this permission. 7232 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7233 "Target " + targetPkg + " already has full permission to " + grantUri); 7234 return -1; 7235 } 7236 } else { 7237 // First... there is no target package, so can anyone access it? 7238 boolean allowed = pi.exported; 7239 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7240 if (pi.readPermission != null) { 7241 allowed = false; 7242 } 7243 } 7244 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7245 if (pi.writePermission != null) { 7246 allowed = false; 7247 } 7248 } 7249 if (allowed) { 7250 return -1; 7251 } 7252 } 7253 7254 /* There is a special cross user grant if: 7255 * - The target is on another user. 7256 * - Apps on the current user can access the uri without any uid permissions. 7257 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7258 * grant uri permissions. 7259 */ 7260 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7261 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7262 modeFlags, false /*without considering the uid permissions*/); 7263 7264 // Second... is the provider allowing granting of URI permissions? 7265 if (!specialCrossUserGrant) { 7266 if (!pi.grantUriPermissions) { 7267 throw new SecurityException("Provider " + pi.packageName 7268 + "/" + pi.name 7269 + " does not allow granting of Uri permissions (uri " 7270 + grantUri + ")"); 7271 } 7272 if (pi.uriPermissionPatterns != null) { 7273 final int N = pi.uriPermissionPatterns.length; 7274 boolean allowed = false; 7275 for (int i=0; i<N; i++) { 7276 if (pi.uriPermissionPatterns[i] != null 7277 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7278 allowed = true; 7279 break; 7280 } 7281 } 7282 if (!allowed) { 7283 throw new SecurityException("Provider " + pi.packageName 7284 + "/" + pi.name 7285 + " does not allow granting of permission to path of Uri " 7286 + grantUri); 7287 } 7288 } 7289 } 7290 7291 // Third... does the caller itself have permission to access 7292 // this uri? 7293 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7294 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7295 // Require they hold a strong enough Uri permission 7296 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7297 throw new SecurityException("Uid " + callingUid 7298 + " does not have permission to uri " + grantUri); 7299 } 7300 } 7301 } 7302 return targetUid; 7303 } 7304 7305 /** 7306 * @param uri This uri must NOT contain an embedded userId. 7307 * @param userId The userId in which the uri is to be resolved. 7308 */ 7309 @Override 7310 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7311 final int modeFlags, int userId) { 7312 enforceNotIsolatedCaller("checkGrantUriPermission"); 7313 synchronized(this) { 7314 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7315 new GrantUri(userId, uri, false), modeFlags, -1); 7316 } 7317 } 7318 7319 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7320 final int modeFlags, UriPermissionOwner owner) { 7321 if (!Intent.isAccessUriMode(modeFlags)) { 7322 return; 7323 } 7324 7325 // So here we are: the caller has the assumed permission 7326 // to the uri, and the target doesn't. Let's now give this to 7327 // the target. 7328 7329 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7330 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7331 7332 final String authority = grantUri.uri.getAuthority(); 7333 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7334 if (pi == null) { 7335 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7336 return; 7337 } 7338 7339 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7340 grantUri.prefix = true; 7341 } 7342 final UriPermission perm = findOrCreateUriPermissionLocked( 7343 pi.packageName, targetPkg, targetUid, grantUri); 7344 perm.grantModes(modeFlags, owner); 7345 } 7346 7347 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7348 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7349 if (targetPkg == null) { 7350 throw new NullPointerException("targetPkg"); 7351 } 7352 int targetUid; 7353 final IPackageManager pm = AppGlobals.getPackageManager(); 7354 try { 7355 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7356 } catch (RemoteException ex) { 7357 return; 7358 } 7359 7360 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7361 targetUid); 7362 if (targetUid < 0) { 7363 return; 7364 } 7365 7366 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7367 owner); 7368 } 7369 7370 static class NeededUriGrants extends ArrayList<GrantUri> { 7371 final String targetPkg; 7372 final int targetUid; 7373 final int flags; 7374 7375 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7376 this.targetPkg = targetPkg; 7377 this.targetUid = targetUid; 7378 this.flags = flags; 7379 } 7380 } 7381 7382 /** 7383 * Like checkGrantUriPermissionLocked, but takes an Intent. 7384 */ 7385 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7386 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7387 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7388 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7389 + " clip=" + (intent != null ? intent.getClipData() : null) 7390 + " from " + intent + "; flags=0x" 7391 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7392 7393 if (targetPkg == null) { 7394 throw new NullPointerException("targetPkg"); 7395 } 7396 7397 if (intent == null) { 7398 return null; 7399 } 7400 Uri data = intent.getData(); 7401 ClipData clip = intent.getClipData(); 7402 if (data == null && clip == null) { 7403 return null; 7404 } 7405 // Default userId for uris in the intent (if they don't specify it themselves) 7406 int contentUserHint = intent.getContentUserHint(); 7407 if (contentUserHint == UserHandle.USER_CURRENT) { 7408 contentUserHint = UserHandle.getUserId(callingUid); 7409 } 7410 final IPackageManager pm = AppGlobals.getPackageManager(); 7411 int targetUid; 7412 if (needed != null) { 7413 targetUid = needed.targetUid; 7414 } else { 7415 try { 7416 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7417 } catch (RemoteException ex) { 7418 return null; 7419 } 7420 if (targetUid < 0) { 7421 if (DEBUG_URI_PERMISSION) { 7422 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7423 + " on user " + targetUserId); 7424 } 7425 return null; 7426 } 7427 } 7428 if (data != null) { 7429 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7430 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7431 targetUid); 7432 if (targetUid > 0) { 7433 if (needed == null) { 7434 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7435 } 7436 needed.add(grantUri); 7437 } 7438 } 7439 if (clip != null) { 7440 for (int i=0; i<clip.getItemCount(); i++) { 7441 Uri uri = clip.getItemAt(i).getUri(); 7442 if (uri != null) { 7443 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7444 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7445 targetUid); 7446 if (targetUid > 0) { 7447 if (needed == null) { 7448 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7449 } 7450 needed.add(grantUri); 7451 } 7452 } else { 7453 Intent clipIntent = clip.getItemAt(i).getIntent(); 7454 if (clipIntent != null) { 7455 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7456 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7457 if (newNeeded != null) { 7458 needed = newNeeded; 7459 } 7460 } 7461 } 7462 } 7463 } 7464 7465 return needed; 7466 } 7467 7468 /** 7469 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7470 */ 7471 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7472 UriPermissionOwner owner) { 7473 if (needed != null) { 7474 for (int i=0; i<needed.size(); i++) { 7475 GrantUri grantUri = needed.get(i); 7476 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7477 grantUri, needed.flags, owner); 7478 } 7479 } 7480 } 7481 7482 void grantUriPermissionFromIntentLocked(int callingUid, 7483 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7484 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7485 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7486 if (needed == null) { 7487 return; 7488 } 7489 7490 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7491 } 7492 7493 /** 7494 * @param uri This uri must NOT contain an embedded userId. 7495 * @param userId The userId in which the uri is to be resolved. 7496 */ 7497 @Override 7498 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7499 final int modeFlags, int userId) { 7500 enforceNotIsolatedCaller("grantUriPermission"); 7501 GrantUri grantUri = new GrantUri(userId, uri, false); 7502 synchronized(this) { 7503 final ProcessRecord r = getRecordForAppLocked(caller); 7504 if (r == null) { 7505 throw new SecurityException("Unable to find app for caller " 7506 + caller 7507 + " when granting permission to uri " + grantUri); 7508 } 7509 if (targetPkg == null) { 7510 throw new IllegalArgumentException("null target"); 7511 } 7512 if (grantUri == null) { 7513 throw new IllegalArgumentException("null uri"); 7514 } 7515 7516 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7517 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7518 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7519 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7520 7521 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7522 UserHandle.getUserId(r.uid)); 7523 } 7524 } 7525 7526 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7527 if (perm.modeFlags == 0) { 7528 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7529 perm.targetUid); 7530 if (perms != null) { 7531 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7532 "Removing " + perm.targetUid + " permission to " + perm.uri); 7533 7534 perms.remove(perm.uri); 7535 if (perms.isEmpty()) { 7536 mGrantedUriPermissions.remove(perm.targetUid); 7537 } 7538 } 7539 } 7540 } 7541 7542 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7543 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7544 7545 final IPackageManager pm = AppGlobals.getPackageManager(); 7546 final String authority = grantUri.uri.getAuthority(); 7547 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7548 if (pi == null) { 7549 Slog.w(TAG, "No content provider found for permission revoke: " 7550 + grantUri.toSafeString()); 7551 return; 7552 } 7553 7554 // Does the caller have this permission on the URI? 7555 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7556 // If they don't have direct access to the URI, then revoke any 7557 // ownerless URI permissions that have been granted to them. 7558 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7559 if (perms != null) { 7560 boolean persistChanged = false; 7561 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7562 final UriPermission perm = it.next(); 7563 if (perm.uri.sourceUserId == grantUri.sourceUserId 7564 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7565 if (DEBUG_URI_PERMISSION) 7566 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7567 " permission to " + perm.uri); 7568 persistChanged |= perm.revokeModes( 7569 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7570 if (perm.modeFlags == 0) { 7571 it.remove(); 7572 } 7573 } 7574 } 7575 if (perms.isEmpty()) { 7576 mGrantedUriPermissions.remove(callingUid); 7577 } 7578 if (persistChanged) { 7579 schedulePersistUriGrants(); 7580 } 7581 } 7582 return; 7583 } 7584 7585 boolean persistChanged = false; 7586 7587 // Go through all of the permissions and remove any that match. 7588 int N = mGrantedUriPermissions.size(); 7589 for (int i = 0; i < N; i++) { 7590 final int targetUid = mGrantedUriPermissions.keyAt(i); 7591 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7592 7593 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7594 final UriPermission perm = it.next(); 7595 if (perm.uri.sourceUserId == grantUri.sourceUserId 7596 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7597 if (DEBUG_URI_PERMISSION) 7598 Slog.v(TAG, 7599 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7600 persistChanged |= perm.revokeModes( 7601 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7602 if (perm.modeFlags == 0) { 7603 it.remove(); 7604 } 7605 } 7606 } 7607 7608 if (perms.isEmpty()) { 7609 mGrantedUriPermissions.remove(targetUid); 7610 N--; 7611 i--; 7612 } 7613 } 7614 7615 if (persistChanged) { 7616 schedulePersistUriGrants(); 7617 } 7618 } 7619 7620 /** 7621 * @param uri This uri must NOT contain an embedded userId. 7622 * @param userId The userId in which the uri is to be resolved. 7623 */ 7624 @Override 7625 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7626 int userId) { 7627 enforceNotIsolatedCaller("revokeUriPermission"); 7628 synchronized(this) { 7629 final ProcessRecord r = getRecordForAppLocked(caller); 7630 if (r == null) { 7631 throw new SecurityException("Unable to find app for caller " 7632 + caller 7633 + " when revoking permission to uri " + uri); 7634 } 7635 if (uri == null) { 7636 Slog.w(TAG, "revokeUriPermission: null uri"); 7637 return; 7638 } 7639 7640 if (!Intent.isAccessUriMode(modeFlags)) { 7641 return; 7642 } 7643 7644 final IPackageManager pm = AppGlobals.getPackageManager(); 7645 final String authority = uri.getAuthority(); 7646 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7647 if (pi == null) { 7648 Slog.w(TAG, "No content provider found for permission revoke: " 7649 + uri.toSafeString()); 7650 return; 7651 } 7652 7653 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7654 } 7655 } 7656 7657 /** 7658 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7659 * given package. 7660 * 7661 * @param packageName Package name to match, or {@code null} to apply to all 7662 * packages. 7663 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7664 * to all users. 7665 * @param persistable If persistable grants should be removed. 7666 */ 7667 private void removeUriPermissionsForPackageLocked( 7668 String packageName, int userHandle, boolean persistable) { 7669 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7670 throw new IllegalArgumentException("Must narrow by either package or user"); 7671 } 7672 7673 boolean persistChanged = false; 7674 7675 int N = mGrantedUriPermissions.size(); 7676 for (int i = 0; i < N; i++) { 7677 final int targetUid = mGrantedUriPermissions.keyAt(i); 7678 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7679 7680 // Only inspect grants matching user 7681 if (userHandle == UserHandle.USER_ALL 7682 || userHandle == UserHandle.getUserId(targetUid)) { 7683 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7684 final UriPermission perm = it.next(); 7685 7686 // Only inspect grants matching package 7687 if (packageName == null || perm.sourcePkg.equals(packageName) 7688 || perm.targetPkg.equals(packageName)) { 7689 persistChanged |= perm.revokeModes(persistable 7690 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7691 7692 // Only remove when no modes remain; any persisted grants 7693 // will keep this alive. 7694 if (perm.modeFlags == 0) { 7695 it.remove(); 7696 } 7697 } 7698 } 7699 7700 if (perms.isEmpty()) { 7701 mGrantedUriPermissions.remove(targetUid); 7702 N--; 7703 i--; 7704 } 7705 } 7706 } 7707 7708 if (persistChanged) { 7709 schedulePersistUriGrants(); 7710 } 7711 } 7712 7713 @Override 7714 public IBinder newUriPermissionOwner(String name) { 7715 enforceNotIsolatedCaller("newUriPermissionOwner"); 7716 synchronized(this) { 7717 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7718 return owner.getExternalTokenLocked(); 7719 } 7720 } 7721 7722 /** 7723 * @param uri This uri must NOT contain an embedded userId. 7724 * @param sourceUserId The userId in which the uri is to be resolved. 7725 * @param targetUserId The userId of the app that receives the grant. 7726 */ 7727 @Override 7728 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7729 final int modeFlags, int sourceUserId, int targetUserId) { 7730 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7731 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7732 synchronized(this) { 7733 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7734 if (owner == null) { 7735 throw new IllegalArgumentException("Unknown owner: " + token); 7736 } 7737 if (fromUid != Binder.getCallingUid()) { 7738 if (Binder.getCallingUid() != Process.myUid()) { 7739 // Only system code can grant URI permissions on behalf 7740 // of other users. 7741 throw new SecurityException("nice try"); 7742 } 7743 } 7744 if (targetPkg == null) { 7745 throw new IllegalArgumentException("null target"); 7746 } 7747 if (uri == null) { 7748 throw new IllegalArgumentException("null uri"); 7749 } 7750 7751 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7752 modeFlags, owner, targetUserId); 7753 } 7754 } 7755 7756 /** 7757 * @param uri This uri must NOT contain an embedded userId. 7758 * @param userId The userId in which the uri is to be resolved. 7759 */ 7760 @Override 7761 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7762 synchronized(this) { 7763 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7764 if (owner == null) { 7765 throw new IllegalArgumentException("Unknown owner: " + token); 7766 } 7767 7768 if (uri == null) { 7769 owner.removeUriPermissionsLocked(mode); 7770 } else { 7771 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7772 } 7773 } 7774 } 7775 7776 private void schedulePersistUriGrants() { 7777 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7778 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7779 10 * DateUtils.SECOND_IN_MILLIS); 7780 } 7781 } 7782 7783 private void writeGrantedUriPermissions() { 7784 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7785 7786 // Snapshot permissions so we can persist without lock 7787 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7788 synchronized (this) { 7789 final int size = mGrantedUriPermissions.size(); 7790 for (int i = 0; i < size; i++) { 7791 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7792 for (UriPermission perm : perms.values()) { 7793 if (perm.persistedModeFlags != 0) { 7794 persist.add(perm.snapshot()); 7795 } 7796 } 7797 } 7798 } 7799 7800 FileOutputStream fos = null; 7801 try { 7802 fos = mGrantFile.startWrite(); 7803 7804 XmlSerializer out = new FastXmlSerializer(); 7805 out.setOutput(fos, "utf-8"); 7806 out.startDocument(null, true); 7807 out.startTag(null, TAG_URI_GRANTS); 7808 for (UriPermission.Snapshot perm : persist) { 7809 out.startTag(null, TAG_URI_GRANT); 7810 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7811 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7812 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7813 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7814 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7815 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7816 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7817 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7818 out.endTag(null, TAG_URI_GRANT); 7819 } 7820 out.endTag(null, TAG_URI_GRANTS); 7821 out.endDocument(); 7822 7823 mGrantFile.finishWrite(fos); 7824 } catch (IOException e) { 7825 if (fos != null) { 7826 mGrantFile.failWrite(fos); 7827 } 7828 } 7829 } 7830 7831 private void readGrantedUriPermissionsLocked() { 7832 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7833 7834 final long now = System.currentTimeMillis(); 7835 7836 FileInputStream fis = null; 7837 try { 7838 fis = mGrantFile.openRead(); 7839 final XmlPullParser in = Xml.newPullParser(); 7840 in.setInput(fis, null); 7841 7842 int type; 7843 while ((type = in.next()) != END_DOCUMENT) { 7844 final String tag = in.getName(); 7845 if (type == START_TAG) { 7846 if (TAG_URI_GRANT.equals(tag)) { 7847 final int sourceUserId; 7848 final int targetUserId; 7849 final int userHandle = readIntAttribute(in, 7850 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7851 if (userHandle != UserHandle.USER_NULL) { 7852 // For backwards compatibility. 7853 sourceUserId = userHandle; 7854 targetUserId = userHandle; 7855 } else { 7856 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7857 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7858 } 7859 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7860 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7861 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7862 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7863 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7864 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7865 7866 // Sanity check that provider still belongs to source package 7867 final ProviderInfo pi = getProviderInfoLocked( 7868 uri.getAuthority(), sourceUserId); 7869 if (pi != null && sourcePkg.equals(pi.packageName)) { 7870 int targetUid = -1; 7871 try { 7872 targetUid = AppGlobals.getPackageManager() 7873 .getPackageUid(targetPkg, targetUserId); 7874 } catch (RemoteException e) { 7875 } 7876 if (targetUid != -1) { 7877 final UriPermission perm = findOrCreateUriPermissionLocked( 7878 sourcePkg, targetPkg, targetUid, 7879 new GrantUri(sourceUserId, uri, prefix)); 7880 perm.initPersistedModes(modeFlags, createdTime); 7881 } 7882 } else { 7883 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7884 + " but instead found " + pi); 7885 } 7886 } 7887 } 7888 } 7889 } catch (FileNotFoundException e) { 7890 // Missing grants is okay 7891 } catch (IOException e) { 7892 Log.wtf(TAG, "Failed reading Uri grants", e); 7893 } catch (XmlPullParserException e) { 7894 Log.wtf(TAG, "Failed reading Uri grants", e); 7895 } finally { 7896 IoUtils.closeQuietly(fis); 7897 } 7898 } 7899 7900 /** 7901 * @param uri This uri must NOT contain an embedded userId. 7902 * @param userId The userId in which the uri is to be resolved. 7903 */ 7904 @Override 7905 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7906 enforceNotIsolatedCaller("takePersistableUriPermission"); 7907 7908 Preconditions.checkFlagsArgument(modeFlags, 7909 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7910 7911 synchronized (this) { 7912 final int callingUid = Binder.getCallingUid(); 7913 boolean persistChanged = false; 7914 GrantUri grantUri = new GrantUri(userId, uri, false); 7915 7916 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7917 new GrantUri(userId, uri, false)); 7918 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7919 new GrantUri(userId, uri, true)); 7920 7921 final boolean exactValid = (exactPerm != null) 7922 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7923 final boolean prefixValid = (prefixPerm != null) 7924 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7925 7926 if (!(exactValid || prefixValid)) { 7927 throw new SecurityException("No persistable permission grants found for UID " 7928 + callingUid + " and Uri " + grantUri.toSafeString()); 7929 } 7930 7931 if (exactValid) { 7932 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7933 } 7934 if (prefixValid) { 7935 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7936 } 7937 7938 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7939 7940 if (persistChanged) { 7941 schedulePersistUriGrants(); 7942 } 7943 } 7944 } 7945 7946 /** 7947 * @param uri This uri must NOT contain an embedded userId. 7948 * @param userId The userId in which the uri is to be resolved. 7949 */ 7950 @Override 7951 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7952 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7953 7954 Preconditions.checkFlagsArgument(modeFlags, 7955 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7956 7957 synchronized (this) { 7958 final int callingUid = Binder.getCallingUid(); 7959 boolean persistChanged = false; 7960 7961 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7962 new GrantUri(userId, uri, false)); 7963 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7964 new GrantUri(userId, uri, true)); 7965 if (exactPerm == null && prefixPerm == null) { 7966 throw new SecurityException("No permission grants found for UID " + callingUid 7967 + " and Uri " + uri.toSafeString()); 7968 } 7969 7970 if (exactPerm != null) { 7971 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7972 removeUriPermissionIfNeededLocked(exactPerm); 7973 } 7974 if (prefixPerm != null) { 7975 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7976 removeUriPermissionIfNeededLocked(prefixPerm); 7977 } 7978 7979 if (persistChanged) { 7980 schedulePersistUriGrants(); 7981 } 7982 } 7983 } 7984 7985 /** 7986 * Prune any older {@link UriPermission} for the given UID until outstanding 7987 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7988 * 7989 * @return if any mutations occured that require persisting. 7990 */ 7991 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7992 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7993 if (perms == null) return false; 7994 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7995 7996 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7997 for (UriPermission perm : perms.values()) { 7998 if (perm.persistedModeFlags != 0) { 7999 persisted.add(perm); 8000 } 8001 } 8002 8003 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8004 if (trimCount <= 0) return false; 8005 8006 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8007 for (int i = 0; i < trimCount; i++) { 8008 final UriPermission perm = persisted.get(i); 8009 8010 if (DEBUG_URI_PERMISSION) { 8011 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8012 } 8013 8014 perm.releasePersistableModes(~0); 8015 removeUriPermissionIfNeededLocked(perm); 8016 } 8017 8018 return true; 8019 } 8020 8021 @Override 8022 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8023 String packageName, boolean incoming) { 8024 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8025 Preconditions.checkNotNull(packageName, "packageName"); 8026 8027 final int callingUid = Binder.getCallingUid(); 8028 final IPackageManager pm = AppGlobals.getPackageManager(); 8029 try { 8030 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8031 if (packageUid != callingUid) { 8032 throw new SecurityException( 8033 "Package " + packageName + " does not belong to calling UID " + callingUid); 8034 } 8035 } catch (RemoteException e) { 8036 throw new SecurityException("Failed to verify package name ownership"); 8037 } 8038 8039 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8040 synchronized (this) { 8041 if (incoming) { 8042 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8043 callingUid); 8044 if (perms == null) { 8045 Slog.w(TAG, "No permission grants found for " + packageName); 8046 } else { 8047 for (UriPermission perm : perms.values()) { 8048 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8049 result.add(perm.buildPersistedPublicApiObject()); 8050 } 8051 } 8052 } 8053 } else { 8054 final int size = mGrantedUriPermissions.size(); 8055 for (int i = 0; i < size; i++) { 8056 final ArrayMap<GrantUri, UriPermission> perms = 8057 mGrantedUriPermissions.valueAt(i); 8058 for (UriPermission perm : perms.values()) { 8059 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8060 result.add(perm.buildPersistedPublicApiObject()); 8061 } 8062 } 8063 } 8064 } 8065 } 8066 return new ParceledListSlice<android.content.UriPermission>(result); 8067 } 8068 8069 @Override 8070 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8071 synchronized (this) { 8072 ProcessRecord app = 8073 who != null ? getRecordForAppLocked(who) : null; 8074 if (app == null) return; 8075 8076 Message msg = Message.obtain(); 8077 msg.what = WAIT_FOR_DEBUGGER_MSG; 8078 msg.obj = app; 8079 msg.arg1 = waiting ? 1 : 0; 8080 mHandler.sendMessage(msg); 8081 } 8082 } 8083 8084 @Override 8085 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8086 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8087 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8088 outInfo.availMem = Process.getFreeMemory(); 8089 outInfo.totalMem = Process.getTotalMemory(); 8090 outInfo.threshold = homeAppMem; 8091 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8092 outInfo.hiddenAppThreshold = cachedAppMem; 8093 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8094 ProcessList.SERVICE_ADJ); 8095 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8096 ProcessList.VISIBLE_APP_ADJ); 8097 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8098 ProcessList.FOREGROUND_APP_ADJ); 8099 } 8100 8101 // ========================================================= 8102 // TASK MANAGEMENT 8103 // ========================================================= 8104 8105 @Override 8106 public List<IAppTask> getAppTasks(String callingPackage) { 8107 int callingUid = Binder.getCallingUid(); 8108 long ident = Binder.clearCallingIdentity(); 8109 8110 synchronized(this) { 8111 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8112 try { 8113 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8114 8115 final int N = mRecentTasks.size(); 8116 for (int i = 0; i < N; i++) { 8117 TaskRecord tr = mRecentTasks.get(i); 8118 // Skip tasks that do not match the caller. We don't need to verify 8119 // callingPackage, because we are also limiting to callingUid and know 8120 // that will limit to the correct security sandbox. 8121 if (tr.effectiveUid != callingUid) { 8122 continue; 8123 } 8124 Intent intent = tr.getBaseIntent(); 8125 if (intent == null || 8126 !callingPackage.equals(intent.getComponent().getPackageName())) { 8127 continue; 8128 } 8129 ActivityManager.RecentTaskInfo taskInfo = 8130 createRecentTaskInfoFromTaskRecord(tr); 8131 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8132 list.add(taskImpl); 8133 } 8134 } finally { 8135 Binder.restoreCallingIdentity(ident); 8136 } 8137 return list; 8138 } 8139 } 8140 8141 @Override 8142 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8143 final int callingUid = Binder.getCallingUid(); 8144 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8145 8146 synchronized(this) { 8147 if (localLOGV) Slog.v( 8148 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8149 8150 final boolean allowed = checkCallingPermission( 8151 android.Manifest.permission.GET_TASKS) 8152 == PackageManager.PERMISSION_GRANTED; 8153 if (!allowed) { 8154 Slog.w(TAG, "getTasks: caller " + callingUid 8155 + " does not hold GET_TASKS; limiting output"); 8156 } 8157 8158 // TODO: Improve with MRU list from all ActivityStacks. 8159 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8160 } 8161 8162 return list; 8163 } 8164 8165 TaskRecord getMostRecentTask() { 8166 return mRecentTasks.get(0); 8167 } 8168 8169 /** 8170 * Creates a new RecentTaskInfo from a TaskRecord. 8171 */ 8172 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8173 // Update the task description to reflect any changes in the task stack 8174 tr.updateTaskDescription(); 8175 8176 // Compose the recent task info 8177 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8178 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8179 rti.persistentId = tr.taskId; 8180 rti.baseIntent = new Intent(tr.getBaseIntent()); 8181 rti.origActivity = tr.origActivity; 8182 rti.description = tr.lastDescription; 8183 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8184 rti.userId = tr.userId; 8185 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8186 rti.firstActiveTime = tr.firstActiveTime; 8187 rti.lastActiveTime = tr.lastActiveTime; 8188 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8189 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8190 return rti; 8191 } 8192 8193 @Override 8194 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8195 final int callingUid = Binder.getCallingUid(); 8196 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8197 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8198 8199 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8200 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8201 synchronized (this) { 8202 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8203 == PackageManager.PERMISSION_GRANTED; 8204 if (!allowed) { 8205 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8206 + " does not hold GET_TASKS; limiting output"); 8207 } 8208 final boolean detailed = checkCallingPermission( 8209 android.Manifest.permission.GET_DETAILED_TASKS) 8210 == PackageManager.PERMISSION_GRANTED; 8211 8212 final int N = mRecentTasks.size(); 8213 ArrayList<ActivityManager.RecentTaskInfo> res 8214 = new ArrayList<ActivityManager.RecentTaskInfo>( 8215 maxNum < N ? maxNum : N); 8216 8217 final Set<Integer> includedUsers; 8218 if (includeProfiles) { 8219 includedUsers = getProfileIdsLocked(userId); 8220 } else { 8221 includedUsers = new HashSet<Integer>(); 8222 } 8223 includedUsers.add(Integer.valueOf(userId)); 8224 8225 for (int i=0; i<N && maxNum > 0; i++) { 8226 TaskRecord tr = mRecentTasks.get(i); 8227 // Only add calling user or related users recent tasks 8228 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8229 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8230 continue; 8231 } 8232 8233 // Return the entry if desired by the caller. We always return 8234 // the first entry, because callers always expect this to be the 8235 // foreground app. We may filter others if the caller has 8236 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8237 // we should exclude the entry. 8238 8239 if (i == 0 8240 || withExcluded 8241 || (tr.intent == null) 8242 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8243 == 0)) { 8244 if (!allowed) { 8245 // If the caller doesn't have the GET_TASKS permission, then only 8246 // allow them to see a small subset of tasks -- their own and home. 8247 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8248 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8249 continue; 8250 } 8251 } 8252 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8253 if (tr.stack != null && tr.stack.isHomeStack()) { 8254 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8255 continue; 8256 } 8257 } 8258 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8259 // Don't include auto remove tasks that are finished or finishing. 8260 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8261 + tr); 8262 continue; 8263 } 8264 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8265 && !tr.isAvailable) { 8266 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8267 continue; 8268 } 8269 8270 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8271 if (!detailed) { 8272 rti.baseIntent.replaceExtras((Bundle)null); 8273 } 8274 8275 res.add(rti); 8276 maxNum--; 8277 } 8278 } 8279 return res; 8280 } 8281 } 8282 8283 private TaskRecord recentTaskForIdLocked(int id) { 8284 final int N = mRecentTasks.size(); 8285 for (int i=0; i<N; i++) { 8286 TaskRecord tr = mRecentTasks.get(i); 8287 if (tr.taskId == id) { 8288 return tr; 8289 } 8290 } 8291 return null; 8292 } 8293 8294 @Override 8295 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8296 synchronized (this) { 8297 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8298 "getTaskThumbnail()"); 8299 TaskRecord tr = recentTaskForIdLocked(id); 8300 if (tr != null) { 8301 return tr.getTaskThumbnailLocked(); 8302 } 8303 } 8304 return null; 8305 } 8306 8307 @Override 8308 public int addAppTask(IBinder activityToken, Intent intent, 8309 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8310 final int callingUid = Binder.getCallingUid(); 8311 final long callingIdent = Binder.clearCallingIdentity(); 8312 8313 try { 8314 synchronized (this) { 8315 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8316 if (r == null) { 8317 throw new IllegalArgumentException("Activity does not exist; token=" 8318 + activityToken); 8319 } 8320 ComponentName comp = intent.getComponent(); 8321 if (comp == null) { 8322 throw new IllegalArgumentException("Intent " + intent 8323 + " must specify explicit component"); 8324 } 8325 if (thumbnail.getWidth() != mThumbnailWidth 8326 || thumbnail.getHeight() != mThumbnailHeight) { 8327 throw new IllegalArgumentException("Bad thumbnail size: got " 8328 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8329 + mThumbnailWidth + "x" + mThumbnailHeight); 8330 } 8331 if (intent.getSelector() != null) { 8332 intent.setSelector(null); 8333 } 8334 if (intent.getSourceBounds() != null) { 8335 intent.setSourceBounds(null); 8336 } 8337 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8338 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8339 // The caller has added this as an auto-remove task... that makes no 8340 // sense, so turn off auto-remove. 8341 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8342 } 8343 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8344 // Must be a new task. 8345 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8346 } 8347 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8348 mLastAddedTaskActivity = null; 8349 } 8350 ActivityInfo ainfo = mLastAddedTaskActivity; 8351 if (ainfo == null) { 8352 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8353 comp, 0, UserHandle.getUserId(callingUid)); 8354 if (ainfo.applicationInfo.uid != callingUid) { 8355 throw new SecurityException( 8356 "Can't add task for another application: target uid=" 8357 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8358 } 8359 } 8360 8361 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8362 intent, description); 8363 8364 int trimIdx = trimRecentsForTask(task, false); 8365 if (trimIdx >= 0) { 8366 // If this would have caused a trim, then we'll abort because that 8367 // means it would be added at the end of the list but then just removed. 8368 return -1; 8369 } 8370 8371 final int N = mRecentTasks.size(); 8372 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8373 final TaskRecord tr = mRecentTasks.remove(N - 1); 8374 tr.removedFromRecents(mTaskPersister); 8375 } 8376 8377 task.inRecents = true; 8378 mRecentTasks.add(task); 8379 r.task.stack.addTask(task, false, false); 8380 8381 task.setLastThumbnail(thumbnail); 8382 task.freeLastThumbnail(); 8383 8384 return task.taskId; 8385 } 8386 } finally { 8387 Binder.restoreCallingIdentity(callingIdent); 8388 } 8389 } 8390 8391 @Override 8392 public Point getAppTaskThumbnailSize() { 8393 synchronized (this) { 8394 return new Point(mThumbnailWidth, mThumbnailHeight); 8395 } 8396 } 8397 8398 @Override 8399 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8400 synchronized (this) { 8401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8402 if (r != null) { 8403 r.setTaskDescription(td); 8404 r.task.updateTaskDescription(); 8405 } 8406 } 8407 } 8408 8409 @Override 8410 public Bitmap getTaskDescriptionIcon(String filename) { 8411 if (!FileUtils.isValidExtFilename(filename) 8412 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8413 throw new IllegalArgumentException("Bad filename: " + filename); 8414 } 8415 return mTaskPersister.getTaskDescriptionIcon(filename); 8416 } 8417 8418 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8419 mRecentTasks.remove(tr); 8420 tr.removedFromRecents(mTaskPersister); 8421 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8422 Intent baseIntent = new Intent( 8423 tr.intent != null ? tr.intent : tr.affinityIntent); 8424 ComponentName component = baseIntent.getComponent(); 8425 if (component == null) { 8426 Slog.w(TAG, "Now component for base intent of task: " + tr); 8427 return; 8428 } 8429 8430 // Find any running services associated with this app. 8431 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8432 8433 if (killProcesses) { 8434 // Find any running processes associated with this app. 8435 final String pkg = component.getPackageName(); 8436 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8437 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8438 for (int i=0; i<pmap.size(); i++) { 8439 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8440 for (int j=0; j<uids.size(); j++) { 8441 ProcessRecord proc = uids.valueAt(j); 8442 if (proc.userId != tr.userId) { 8443 continue; 8444 } 8445 if (!proc.pkgList.containsKey(pkg)) { 8446 continue; 8447 } 8448 procs.add(proc); 8449 } 8450 } 8451 8452 // Kill the running processes. 8453 for (int i=0; i<procs.size(); i++) { 8454 ProcessRecord pr = procs.get(i); 8455 if (pr == mHomeProcess) { 8456 // Don't kill the home process along with tasks from the same package. 8457 continue; 8458 } 8459 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8460 pr.kill("remove task", true); 8461 } else { 8462 pr.waitingToKill = "remove task"; 8463 } 8464 } 8465 } 8466 } 8467 8468 /** 8469 * Removes the task with the specified task id. 8470 * 8471 * @param taskId Identifier of the task to be removed. 8472 * @param flags Additional operational flags. May be 0 or 8473 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8474 * @return Returns true if the given task was found and removed. 8475 */ 8476 private boolean removeTaskByIdLocked(int taskId, int flags) { 8477 TaskRecord tr = recentTaskForIdLocked(taskId); 8478 if (tr != null) { 8479 tr.removeTaskActivitiesLocked(); 8480 cleanUpRemovedTaskLocked(tr, flags); 8481 if (tr.isPersistable) { 8482 notifyTaskPersisterLocked(null, true); 8483 } 8484 return true; 8485 } 8486 return false; 8487 } 8488 8489 @Override 8490 public boolean removeTask(int taskId, int flags) { 8491 synchronized (this) { 8492 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8493 "removeTask()"); 8494 long ident = Binder.clearCallingIdentity(); 8495 try { 8496 return removeTaskByIdLocked(taskId, flags); 8497 } finally { 8498 Binder.restoreCallingIdentity(ident); 8499 } 8500 } 8501 } 8502 8503 /** 8504 * TODO: Add mController hook 8505 */ 8506 @Override 8507 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8508 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8509 "moveTaskToFront()"); 8510 8511 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8512 synchronized(this) { 8513 moveTaskToFrontLocked(taskId, flags, options); 8514 } 8515 } 8516 8517 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8518 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8519 Binder.getCallingUid(), -1, -1, "Task to front")) { 8520 ActivityOptions.abort(options); 8521 return; 8522 } 8523 final long origId = Binder.clearCallingIdentity(); 8524 try { 8525 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8526 if (task == null) { 8527 return; 8528 } 8529 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8530 mStackSupervisor.showLockTaskToast(); 8531 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8532 return; 8533 } 8534 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8535 if (prev != null && prev.isRecentsActivity()) { 8536 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8537 } 8538 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8539 } finally { 8540 Binder.restoreCallingIdentity(origId); 8541 } 8542 ActivityOptions.abort(options); 8543 } 8544 8545 @Override 8546 public void moveTaskToBack(int taskId) { 8547 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8548 "moveTaskToBack()"); 8549 8550 synchronized(this) { 8551 TaskRecord tr = recentTaskForIdLocked(taskId); 8552 if (tr != null) { 8553 if (tr == mStackSupervisor.mLockTaskModeTask) { 8554 mStackSupervisor.showLockTaskToast(); 8555 return; 8556 } 8557 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8558 ActivityStack stack = tr.stack; 8559 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8560 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8561 Binder.getCallingUid(), -1, -1, "Task to back")) { 8562 return; 8563 } 8564 } 8565 final long origId = Binder.clearCallingIdentity(); 8566 try { 8567 stack.moveTaskToBackLocked(taskId, null); 8568 } finally { 8569 Binder.restoreCallingIdentity(origId); 8570 } 8571 } 8572 } 8573 } 8574 8575 /** 8576 * Moves an activity, and all of the other activities within the same task, to the bottom 8577 * of the history stack. The activity's order within the task is unchanged. 8578 * 8579 * @param token A reference to the activity we wish to move 8580 * @param nonRoot If false then this only works if the activity is the root 8581 * of a task; if true it will work for any activity in a task. 8582 * @return Returns true if the move completed, false if not. 8583 */ 8584 @Override 8585 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8586 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8587 synchronized(this) { 8588 final long origId = Binder.clearCallingIdentity(); 8589 try { 8590 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8591 if (taskId >= 0) { 8592 if ((mStackSupervisor.mLockTaskModeTask != null) 8593 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8594 mStackSupervisor.showLockTaskToast(); 8595 return false; 8596 } 8597 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8598 } 8599 } finally { 8600 Binder.restoreCallingIdentity(origId); 8601 } 8602 } 8603 return false; 8604 } 8605 8606 @Override 8607 public void moveTaskBackwards(int task) { 8608 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8609 "moveTaskBackwards()"); 8610 8611 synchronized(this) { 8612 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8613 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8614 return; 8615 } 8616 final long origId = Binder.clearCallingIdentity(); 8617 moveTaskBackwardsLocked(task); 8618 Binder.restoreCallingIdentity(origId); 8619 } 8620 } 8621 8622 private final void moveTaskBackwardsLocked(int task) { 8623 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8624 } 8625 8626 @Override 8627 public IBinder getHomeActivityToken() throws RemoteException { 8628 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8629 "getHomeActivityToken()"); 8630 synchronized (this) { 8631 return mStackSupervisor.getHomeActivityToken(); 8632 } 8633 } 8634 8635 @Override 8636 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8637 IActivityContainerCallback callback) throws RemoteException { 8638 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8639 "createActivityContainer()"); 8640 synchronized (this) { 8641 if (parentActivityToken == null) { 8642 throw new IllegalArgumentException("parent token must not be null"); 8643 } 8644 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8645 if (r == null) { 8646 return null; 8647 } 8648 if (callback == null) { 8649 throw new IllegalArgumentException("callback must not be null"); 8650 } 8651 return mStackSupervisor.createActivityContainer(r, callback); 8652 } 8653 } 8654 8655 @Override 8656 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8657 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8658 "deleteActivityContainer()"); 8659 synchronized (this) { 8660 mStackSupervisor.deleteActivityContainer(container); 8661 } 8662 } 8663 8664 @Override 8665 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8666 throws RemoteException { 8667 synchronized (this) { 8668 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8669 if (stack != null) { 8670 return stack.mActivityContainer; 8671 } 8672 return null; 8673 } 8674 } 8675 8676 @Override 8677 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8678 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8679 "moveTaskToStack()"); 8680 if (stackId == HOME_STACK_ID) { 8681 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8682 new RuntimeException("here").fillInStackTrace()); 8683 } 8684 synchronized (this) { 8685 long ident = Binder.clearCallingIdentity(); 8686 try { 8687 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8688 + stackId + " toTop=" + toTop); 8689 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8690 } finally { 8691 Binder.restoreCallingIdentity(ident); 8692 } 8693 } 8694 } 8695 8696 @Override 8697 public void resizeStack(int stackBoxId, Rect bounds) { 8698 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8699 "resizeStackBox()"); 8700 long ident = Binder.clearCallingIdentity(); 8701 try { 8702 mWindowManager.resizeStack(stackBoxId, bounds); 8703 } finally { 8704 Binder.restoreCallingIdentity(ident); 8705 } 8706 } 8707 8708 @Override 8709 public List<StackInfo> getAllStackInfos() { 8710 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8711 "getAllStackInfos()"); 8712 long ident = Binder.clearCallingIdentity(); 8713 try { 8714 synchronized (this) { 8715 return mStackSupervisor.getAllStackInfosLocked(); 8716 } 8717 } finally { 8718 Binder.restoreCallingIdentity(ident); 8719 } 8720 } 8721 8722 @Override 8723 public StackInfo getStackInfo(int stackId) { 8724 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8725 "getStackInfo()"); 8726 long ident = Binder.clearCallingIdentity(); 8727 try { 8728 synchronized (this) { 8729 return mStackSupervisor.getStackInfoLocked(stackId); 8730 } 8731 } finally { 8732 Binder.restoreCallingIdentity(ident); 8733 } 8734 } 8735 8736 @Override 8737 public boolean isInHomeStack(int taskId) { 8738 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8739 "getStackInfo()"); 8740 long ident = Binder.clearCallingIdentity(); 8741 try { 8742 synchronized (this) { 8743 TaskRecord tr = recentTaskForIdLocked(taskId); 8744 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8745 } 8746 } finally { 8747 Binder.restoreCallingIdentity(ident); 8748 } 8749 } 8750 8751 @Override 8752 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8753 synchronized(this) { 8754 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8755 } 8756 } 8757 8758 private boolean isLockTaskAuthorized(String pkg) { 8759 final DevicePolicyManager dpm = (DevicePolicyManager) 8760 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8761 try { 8762 int uid = mContext.getPackageManager().getPackageUid(pkg, 8763 Binder.getCallingUserHandle().getIdentifier()); 8764 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8765 } catch (NameNotFoundException e) { 8766 return false; 8767 } 8768 } 8769 8770 void startLockTaskMode(TaskRecord task) { 8771 final String pkg; 8772 synchronized (this) { 8773 pkg = task.intent.getComponent().getPackageName(); 8774 } 8775 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8776 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8777 final TaskRecord taskRecord = task; 8778 mHandler.post(new Runnable() { 8779 @Override 8780 public void run() { 8781 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8782 } 8783 }); 8784 return; 8785 } 8786 long ident = Binder.clearCallingIdentity(); 8787 try { 8788 synchronized (this) { 8789 // Since we lost lock on task, make sure it is still there. 8790 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8791 if (task != null) { 8792 if (!isSystemInitiated 8793 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8794 throw new IllegalArgumentException("Invalid task, not in foreground"); 8795 } 8796 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8797 } 8798 } 8799 } finally { 8800 Binder.restoreCallingIdentity(ident); 8801 } 8802 } 8803 8804 @Override 8805 public void startLockTaskMode(int taskId) { 8806 final TaskRecord task; 8807 long ident = Binder.clearCallingIdentity(); 8808 try { 8809 synchronized (this) { 8810 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8811 } 8812 } finally { 8813 Binder.restoreCallingIdentity(ident); 8814 } 8815 if (task != null) { 8816 startLockTaskMode(task); 8817 } 8818 } 8819 8820 @Override 8821 public void startLockTaskMode(IBinder token) { 8822 final TaskRecord task; 8823 long ident = Binder.clearCallingIdentity(); 8824 try { 8825 synchronized (this) { 8826 final ActivityRecord r = ActivityRecord.forToken(token); 8827 if (r == null) { 8828 return; 8829 } 8830 task = r.task; 8831 } 8832 } finally { 8833 Binder.restoreCallingIdentity(ident); 8834 } 8835 if (task != null) { 8836 startLockTaskMode(task); 8837 } 8838 } 8839 8840 @Override 8841 public void startLockTaskModeOnCurrent() throws RemoteException { 8842 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8843 "startLockTaskModeOnCurrent"); 8844 ActivityRecord r = null; 8845 synchronized (this) { 8846 r = mStackSupervisor.topRunningActivityLocked(); 8847 } 8848 startLockTaskMode(r.task); 8849 } 8850 8851 @Override 8852 public void stopLockTaskMode() { 8853 // Verify that the user matches the package of the intent for the TaskRecord 8854 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8855 // and stopLockTaskMode. 8856 final int callingUid = Binder.getCallingUid(); 8857 if (callingUid != Process.SYSTEM_UID) { 8858 try { 8859 String pkg = 8860 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8861 int uid = mContext.getPackageManager().getPackageUid(pkg, 8862 Binder.getCallingUserHandle().getIdentifier()); 8863 if (uid != callingUid) { 8864 throw new SecurityException("Invalid uid, expected " + uid); 8865 } 8866 } catch (NameNotFoundException e) { 8867 Log.d(TAG, "stopLockTaskMode " + e); 8868 return; 8869 } 8870 } 8871 long ident = Binder.clearCallingIdentity(); 8872 try { 8873 Log.d(TAG, "stopLockTaskMode"); 8874 // Stop lock task 8875 synchronized (this) { 8876 mStackSupervisor.setLockTaskModeLocked(null, false); 8877 } 8878 } finally { 8879 Binder.restoreCallingIdentity(ident); 8880 } 8881 } 8882 8883 @Override 8884 public void stopLockTaskModeOnCurrent() throws RemoteException { 8885 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8886 "stopLockTaskModeOnCurrent"); 8887 long ident = Binder.clearCallingIdentity(); 8888 try { 8889 stopLockTaskMode(); 8890 } finally { 8891 Binder.restoreCallingIdentity(ident); 8892 } 8893 } 8894 8895 @Override 8896 public boolean isInLockTaskMode() { 8897 synchronized (this) { 8898 return mStackSupervisor.isInLockTaskMode(); 8899 } 8900 } 8901 8902 // ========================================================= 8903 // CONTENT PROVIDERS 8904 // ========================================================= 8905 8906 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8907 List<ProviderInfo> providers = null; 8908 try { 8909 providers = AppGlobals.getPackageManager(). 8910 queryContentProviders(app.processName, app.uid, 8911 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8912 } catch (RemoteException ex) { 8913 } 8914 if (DEBUG_MU) 8915 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8916 int userId = app.userId; 8917 if (providers != null) { 8918 int N = providers.size(); 8919 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8920 for (int i=0; i<N; i++) { 8921 ProviderInfo cpi = 8922 (ProviderInfo)providers.get(i); 8923 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8924 cpi.name, cpi.flags); 8925 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8926 // This is a singleton provider, but a user besides the 8927 // default user is asking to initialize a process it runs 8928 // in... well, no, it doesn't actually run in this process, 8929 // it runs in the process of the default user. Get rid of it. 8930 providers.remove(i); 8931 N--; 8932 i--; 8933 continue; 8934 } 8935 8936 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8937 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8938 if (cpr == null) { 8939 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8940 mProviderMap.putProviderByClass(comp, cpr); 8941 } 8942 if (DEBUG_MU) 8943 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8944 app.pubProviders.put(cpi.name, cpr); 8945 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8946 // Don't add this if it is a platform component that is marked 8947 // to run in multiple processes, because this is actually 8948 // part of the framework so doesn't make sense to track as a 8949 // separate apk in the process. 8950 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8951 mProcessStats); 8952 } 8953 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8954 } 8955 } 8956 return providers; 8957 } 8958 8959 /** 8960 * Check if {@link ProcessRecord} has a possible chance at accessing the 8961 * given {@link ProviderInfo}. Final permission checking is always done 8962 * in {@link ContentProvider}. 8963 */ 8964 private final String checkContentProviderPermissionLocked( 8965 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8966 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8967 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8968 boolean checkedGrants = false; 8969 if (checkUser) { 8970 // Looking for cross-user grants before enforcing the typical cross-users permissions 8971 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8972 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8973 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8974 return null; 8975 } 8976 checkedGrants = true; 8977 } 8978 userId = handleIncomingUser(callingPid, callingUid, userId, 8979 false, ALLOW_NON_FULL, 8980 "checkContentProviderPermissionLocked " + cpi.authority, null); 8981 if (userId != tmpTargetUserId) { 8982 // When we actually went to determine the final targer user ID, this ended 8983 // up different than our initial check for the authority. This is because 8984 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8985 // SELF. So we need to re-check the grants again. 8986 checkedGrants = false; 8987 } 8988 } 8989 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8990 cpi.applicationInfo.uid, cpi.exported) 8991 == PackageManager.PERMISSION_GRANTED) { 8992 return null; 8993 } 8994 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8995 cpi.applicationInfo.uid, cpi.exported) 8996 == PackageManager.PERMISSION_GRANTED) { 8997 return null; 8998 } 8999 9000 PathPermission[] pps = cpi.pathPermissions; 9001 if (pps != null) { 9002 int i = pps.length; 9003 while (i > 0) { 9004 i--; 9005 PathPermission pp = pps[i]; 9006 String pprperm = pp.getReadPermission(); 9007 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9008 cpi.applicationInfo.uid, cpi.exported) 9009 == PackageManager.PERMISSION_GRANTED) { 9010 return null; 9011 } 9012 String ppwperm = pp.getWritePermission(); 9013 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9014 cpi.applicationInfo.uid, cpi.exported) 9015 == PackageManager.PERMISSION_GRANTED) { 9016 return null; 9017 } 9018 } 9019 } 9020 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9021 return null; 9022 } 9023 9024 String msg; 9025 if (!cpi.exported) { 9026 msg = "Permission Denial: opening provider " + cpi.name 9027 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9028 + ", uid=" + callingUid + ") that is not exported from uid " 9029 + cpi.applicationInfo.uid; 9030 } else { 9031 msg = "Permission Denial: opening provider " + cpi.name 9032 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9033 + ", uid=" + callingUid + ") requires " 9034 + cpi.readPermission + " or " + cpi.writePermission; 9035 } 9036 Slog.w(TAG, msg); 9037 return msg; 9038 } 9039 9040 /** 9041 * Returns if the ContentProvider has granted a uri to callingUid 9042 */ 9043 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9044 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9045 if (perms != null) { 9046 for (int i=perms.size()-1; i>=0; i--) { 9047 GrantUri grantUri = perms.keyAt(i); 9048 if (grantUri.sourceUserId == userId || !checkUser) { 9049 if (matchesProvider(grantUri.uri, cpi)) { 9050 return true; 9051 } 9052 } 9053 } 9054 } 9055 return false; 9056 } 9057 9058 /** 9059 * Returns true if the uri authority is one of the authorities specified in the provider. 9060 */ 9061 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9062 String uriAuth = uri.getAuthority(); 9063 String cpiAuth = cpi.authority; 9064 if (cpiAuth.indexOf(';') == -1) { 9065 return cpiAuth.equals(uriAuth); 9066 } 9067 String[] cpiAuths = cpiAuth.split(";"); 9068 int length = cpiAuths.length; 9069 for (int i = 0; i < length; i++) { 9070 if (cpiAuths[i].equals(uriAuth)) return true; 9071 } 9072 return false; 9073 } 9074 9075 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9076 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9077 if (r != null) { 9078 for (int i=0; i<r.conProviders.size(); i++) { 9079 ContentProviderConnection conn = r.conProviders.get(i); 9080 if (conn.provider == cpr) { 9081 if (DEBUG_PROVIDER) Slog.v(TAG, 9082 "Adding provider requested by " 9083 + r.processName + " from process " 9084 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9085 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9086 if (stable) { 9087 conn.stableCount++; 9088 conn.numStableIncs++; 9089 } else { 9090 conn.unstableCount++; 9091 conn.numUnstableIncs++; 9092 } 9093 return conn; 9094 } 9095 } 9096 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9097 if (stable) { 9098 conn.stableCount = 1; 9099 conn.numStableIncs = 1; 9100 } else { 9101 conn.unstableCount = 1; 9102 conn.numUnstableIncs = 1; 9103 } 9104 cpr.connections.add(conn); 9105 r.conProviders.add(conn); 9106 return conn; 9107 } 9108 cpr.addExternalProcessHandleLocked(externalProcessToken); 9109 return null; 9110 } 9111 9112 boolean decProviderCountLocked(ContentProviderConnection conn, 9113 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9114 if (conn != null) { 9115 cpr = conn.provider; 9116 if (DEBUG_PROVIDER) Slog.v(TAG, 9117 "Removing provider requested by " 9118 + conn.client.processName + " from process " 9119 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9120 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9121 if (stable) { 9122 conn.stableCount--; 9123 } else { 9124 conn.unstableCount--; 9125 } 9126 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9127 cpr.connections.remove(conn); 9128 conn.client.conProviders.remove(conn); 9129 return true; 9130 } 9131 return false; 9132 } 9133 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9134 return false; 9135 } 9136 9137 private void checkTime(long startTime, String where) { 9138 long now = SystemClock.elapsedRealtime(); 9139 if ((now-startTime) > 1000) { 9140 // If we are taking more than a second, log about it. 9141 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9142 } 9143 } 9144 9145 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9146 String name, IBinder token, boolean stable, int userId) { 9147 ContentProviderRecord cpr; 9148 ContentProviderConnection conn = null; 9149 ProviderInfo cpi = null; 9150 9151 synchronized(this) { 9152 long startTime = SystemClock.elapsedRealtime(); 9153 9154 ProcessRecord r = null; 9155 if (caller != null) { 9156 r = getRecordForAppLocked(caller); 9157 if (r == null) { 9158 throw new SecurityException( 9159 "Unable to find app for caller " + caller 9160 + " (pid=" + Binder.getCallingPid() 9161 + ") when getting content provider " + name); 9162 } 9163 } 9164 9165 boolean checkCrossUser = true; 9166 9167 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9168 9169 // First check if this content provider has been published... 9170 cpr = mProviderMap.getProviderByName(name, userId); 9171 // If that didn't work, check if it exists for user 0 and then 9172 // verify that it's a singleton provider before using it. 9173 if (cpr == null && userId != UserHandle.USER_OWNER) { 9174 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9175 if (cpr != null) { 9176 cpi = cpr.info; 9177 if (isSingleton(cpi.processName, cpi.applicationInfo, 9178 cpi.name, cpi.flags) 9179 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9180 userId = UserHandle.USER_OWNER; 9181 checkCrossUser = false; 9182 } else { 9183 cpr = null; 9184 cpi = null; 9185 } 9186 } 9187 } 9188 9189 boolean providerRunning = cpr != null; 9190 if (providerRunning) { 9191 cpi = cpr.info; 9192 String msg; 9193 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9194 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9195 != null) { 9196 throw new SecurityException(msg); 9197 } 9198 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9199 9200 if (r != null && cpr.canRunHere(r)) { 9201 // This provider has been published or is in the process 9202 // of being published... but it is also allowed to run 9203 // in the caller's process, so don't make a connection 9204 // and just let the caller instantiate its own instance. 9205 ContentProviderHolder holder = cpr.newHolder(null); 9206 // don't give caller the provider object, it needs 9207 // to make its own. 9208 holder.provider = null; 9209 return holder; 9210 } 9211 9212 final long origId = Binder.clearCallingIdentity(); 9213 9214 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9215 9216 // In this case the provider instance already exists, so we can 9217 // return it right away. 9218 conn = incProviderCountLocked(r, cpr, token, stable); 9219 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9220 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9221 // If this is a perceptible app accessing the provider, 9222 // make sure to count it as being accessed and thus 9223 // back up on the LRU list. This is good because 9224 // content providers are often expensive to start. 9225 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9226 updateLruProcessLocked(cpr.proc, false, null); 9227 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9228 } 9229 } 9230 9231 if (cpr.proc != null) { 9232 if (false) { 9233 if (cpr.name.flattenToShortString().equals( 9234 "com.android.providers.calendar/.CalendarProvider2")) { 9235 Slog.v(TAG, "****************** KILLING " 9236 + cpr.name.flattenToShortString()); 9237 Process.killProcess(cpr.proc.pid); 9238 } 9239 } 9240 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9241 boolean success = updateOomAdjLocked(cpr.proc); 9242 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9243 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9244 // NOTE: there is still a race here where a signal could be 9245 // pending on the process even though we managed to update its 9246 // adj level. Not sure what to do about this, but at least 9247 // the race is now smaller. 9248 if (!success) { 9249 // Uh oh... it looks like the provider's process 9250 // has been killed on us. We need to wait for a new 9251 // process to be started, and make sure its death 9252 // doesn't kill our process. 9253 Slog.i(TAG, 9254 "Existing provider " + cpr.name.flattenToShortString() 9255 + " is crashing; detaching " + r); 9256 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9257 checkTime(startTime, "getContentProviderImpl: before appDied"); 9258 appDiedLocked(cpr.proc); 9259 checkTime(startTime, "getContentProviderImpl: after appDied"); 9260 if (!lastRef) { 9261 // This wasn't the last ref our process had on 9262 // the provider... we have now been killed, bail. 9263 return null; 9264 } 9265 providerRunning = false; 9266 conn = null; 9267 } 9268 } 9269 9270 Binder.restoreCallingIdentity(origId); 9271 } 9272 9273 boolean singleton; 9274 if (!providerRunning) { 9275 try { 9276 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9277 cpi = AppGlobals.getPackageManager(). 9278 resolveContentProvider(name, 9279 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9280 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9281 } catch (RemoteException ex) { 9282 } 9283 if (cpi == null) { 9284 return null; 9285 } 9286 // If the provider is a singleton AND 9287 // (it's a call within the same user || the provider is a 9288 // privileged app) 9289 // Then allow connecting to the singleton provider 9290 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9291 cpi.name, cpi.flags) 9292 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9293 if (singleton) { 9294 userId = UserHandle.USER_OWNER; 9295 } 9296 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9297 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9298 9299 String msg; 9300 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9301 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9302 != null) { 9303 throw new SecurityException(msg); 9304 } 9305 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9306 9307 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9308 && !cpi.processName.equals("system")) { 9309 // If this content provider does not run in the system 9310 // process, and the system is not yet ready to run other 9311 // processes, then fail fast instead of hanging. 9312 throw new IllegalArgumentException( 9313 "Attempt to launch content provider before system ready"); 9314 } 9315 9316 // Make sure that the user who owns this provider is started. If not, 9317 // we don't want to allow it to run. 9318 if (mStartedUsers.get(userId) == null) { 9319 Slog.w(TAG, "Unable to launch app " 9320 + cpi.applicationInfo.packageName + "/" 9321 + cpi.applicationInfo.uid + " for provider " 9322 + name + ": user " + userId + " is stopped"); 9323 return null; 9324 } 9325 9326 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9327 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9328 cpr = mProviderMap.getProviderByClass(comp, userId); 9329 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9330 final boolean firstClass = cpr == null; 9331 if (firstClass) { 9332 try { 9333 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9334 ApplicationInfo ai = 9335 AppGlobals.getPackageManager(). 9336 getApplicationInfo( 9337 cpi.applicationInfo.packageName, 9338 STOCK_PM_FLAGS, userId); 9339 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9340 if (ai == null) { 9341 Slog.w(TAG, "No package info for content provider " 9342 + cpi.name); 9343 return null; 9344 } 9345 ai = getAppInfoForUser(ai, userId); 9346 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9347 } catch (RemoteException ex) { 9348 // pm is in same process, this will never happen. 9349 } 9350 } 9351 9352 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9353 9354 if (r != null && cpr.canRunHere(r)) { 9355 // If this is a multiprocess provider, then just return its 9356 // info and allow the caller to instantiate it. Only do 9357 // this if the provider is the same user as the caller's 9358 // process, or can run as root (so can be in any process). 9359 return cpr.newHolder(null); 9360 } 9361 9362 if (DEBUG_PROVIDER) { 9363 RuntimeException e = new RuntimeException("here"); 9364 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9365 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9366 } 9367 9368 // This is single process, and our app is now connecting to it. 9369 // See if we are already in the process of launching this 9370 // provider. 9371 final int N = mLaunchingProviders.size(); 9372 int i; 9373 for (i=0; i<N; i++) { 9374 if (mLaunchingProviders.get(i) == cpr) { 9375 break; 9376 } 9377 } 9378 9379 // If the provider is not already being launched, then get it 9380 // started. 9381 if (i >= N) { 9382 final long origId = Binder.clearCallingIdentity(); 9383 9384 try { 9385 // Content provider is now in use, its package can't be stopped. 9386 try { 9387 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9388 AppGlobals.getPackageManager().setPackageStoppedState( 9389 cpr.appInfo.packageName, false, userId); 9390 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9391 } catch (RemoteException e) { 9392 } catch (IllegalArgumentException e) { 9393 Slog.w(TAG, "Failed trying to unstop package " 9394 + cpr.appInfo.packageName + ": " + e); 9395 } 9396 9397 // Use existing process if already started 9398 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9399 ProcessRecord proc = getProcessRecordLocked( 9400 cpi.processName, cpr.appInfo.uid, false); 9401 if (proc != null && proc.thread != null) { 9402 if (DEBUG_PROVIDER) { 9403 Slog.d(TAG, "Installing in existing process " + proc); 9404 } 9405 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9406 proc.pubProviders.put(cpi.name, cpr); 9407 try { 9408 proc.thread.scheduleInstallProvider(cpi); 9409 } catch (RemoteException e) { 9410 } 9411 } else { 9412 checkTime(startTime, "getContentProviderImpl: before start process"); 9413 proc = startProcessLocked(cpi.processName, 9414 cpr.appInfo, false, 0, "content provider", 9415 new ComponentName(cpi.applicationInfo.packageName, 9416 cpi.name), false, false, false); 9417 checkTime(startTime, "getContentProviderImpl: after start process"); 9418 if (proc == null) { 9419 Slog.w(TAG, "Unable to launch app " 9420 + cpi.applicationInfo.packageName + "/" 9421 + cpi.applicationInfo.uid + " for provider " 9422 + name + ": process is bad"); 9423 return null; 9424 } 9425 } 9426 cpr.launchingApp = proc; 9427 mLaunchingProviders.add(cpr); 9428 } finally { 9429 Binder.restoreCallingIdentity(origId); 9430 } 9431 } 9432 9433 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9434 9435 // Make sure the provider is published (the same provider class 9436 // may be published under multiple names). 9437 if (firstClass) { 9438 mProviderMap.putProviderByClass(comp, cpr); 9439 } 9440 9441 mProviderMap.putProviderByName(name, cpr); 9442 conn = incProviderCountLocked(r, cpr, token, stable); 9443 if (conn != null) { 9444 conn.waiting = true; 9445 } 9446 } 9447 checkTime(startTime, "getContentProviderImpl: done!"); 9448 } 9449 9450 // Wait for the provider to be published... 9451 synchronized (cpr) { 9452 while (cpr.provider == null) { 9453 if (cpr.launchingApp == null) { 9454 Slog.w(TAG, "Unable to launch app " 9455 + cpi.applicationInfo.packageName + "/" 9456 + cpi.applicationInfo.uid + " for provider " 9457 + name + ": launching app became null"); 9458 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9459 UserHandle.getUserId(cpi.applicationInfo.uid), 9460 cpi.applicationInfo.packageName, 9461 cpi.applicationInfo.uid, name); 9462 return null; 9463 } 9464 try { 9465 if (DEBUG_MU) { 9466 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9467 + cpr.launchingApp); 9468 } 9469 if (conn != null) { 9470 conn.waiting = true; 9471 } 9472 cpr.wait(); 9473 } catch (InterruptedException ex) { 9474 } finally { 9475 if (conn != null) { 9476 conn.waiting = false; 9477 } 9478 } 9479 } 9480 } 9481 return cpr != null ? cpr.newHolder(conn) : null; 9482 } 9483 9484 @Override 9485 public final ContentProviderHolder getContentProvider( 9486 IApplicationThread caller, String name, int userId, boolean stable) { 9487 enforceNotIsolatedCaller("getContentProvider"); 9488 if (caller == null) { 9489 String msg = "null IApplicationThread when getting content provider " 9490 + name; 9491 Slog.w(TAG, msg); 9492 throw new SecurityException(msg); 9493 } 9494 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9495 // with cross-user grant. 9496 return getContentProviderImpl(caller, name, null, stable, userId); 9497 } 9498 9499 public ContentProviderHolder getContentProviderExternal( 9500 String name, int userId, IBinder token) { 9501 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9502 "Do not have permission in call getContentProviderExternal()"); 9503 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9504 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9505 return getContentProviderExternalUnchecked(name, token, userId); 9506 } 9507 9508 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9509 IBinder token, int userId) { 9510 return getContentProviderImpl(null, name, token, true, userId); 9511 } 9512 9513 /** 9514 * Drop a content provider from a ProcessRecord's bookkeeping 9515 */ 9516 public void removeContentProvider(IBinder connection, boolean stable) { 9517 enforceNotIsolatedCaller("removeContentProvider"); 9518 long ident = Binder.clearCallingIdentity(); 9519 try { 9520 synchronized (this) { 9521 ContentProviderConnection conn; 9522 try { 9523 conn = (ContentProviderConnection)connection; 9524 } catch (ClassCastException e) { 9525 String msg ="removeContentProvider: " + connection 9526 + " not a ContentProviderConnection"; 9527 Slog.w(TAG, msg); 9528 throw new IllegalArgumentException(msg); 9529 } 9530 if (conn == null) { 9531 throw new NullPointerException("connection is null"); 9532 } 9533 if (decProviderCountLocked(conn, null, null, stable)) { 9534 updateOomAdjLocked(); 9535 } 9536 } 9537 } finally { 9538 Binder.restoreCallingIdentity(ident); 9539 } 9540 } 9541 9542 public void removeContentProviderExternal(String name, IBinder token) { 9543 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9544 "Do not have permission in call removeContentProviderExternal()"); 9545 int userId = UserHandle.getCallingUserId(); 9546 long ident = Binder.clearCallingIdentity(); 9547 try { 9548 removeContentProviderExternalUnchecked(name, token, userId); 9549 } finally { 9550 Binder.restoreCallingIdentity(ident); 9551 } 9552 } 9553 9554 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9555 synchronized (this) { 9556 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9557 if(cpr == null) { 9558 //remove from mProvidersByClass 9559 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9560 return; 9561 } 9562 9563 //update content provider record entry info 9564 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9565 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9566 if (localCpr.hasExternalProcessHandles()) { 9567 if (localCpr.removeExternalProcessHandleLocked(token)) { 9568 updateOomAdjLocked(); 9569 } else { 9570 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9571 + " with no external reference for token: " 9572 + token + "."); 9573 } 9574 } else { 9575 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9576 + " with no external references."); 9577 } 9578 } 9579 } 9580 9581 public final void publishContentProviders(IApplicationThread caller, 9582 List<ContentProviderHolder> providers) { 9583 if (providers == null) { 9584 return; 9585 } 9586 9587 enforceNotIsolatedCaller("publishContentProviders"); 9588 synchronized (this) { 9589 final ProcessRecord r = getRecordForAppLocked(caller); 9590 if (DEBUG_MU) 9591 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9592 if (r == null) { 9593 throw new SecurityException( 9594 "Unable to find app for caller " + caller 9595 + " (pid=" + Binder.getCallingPid() 9596 + ") when publishing content providers"); 9597 } 9598 9599 final long origId = Binder.clearCallingIdentity(); 9600 9601 final int N = providers.size(); 9602 for (int i=0; i<N; i++) { 9603 ContentProviderHolder src = providers.get(i); 9604 if (src == null || src.info == null || src.provider == null) { 9605 continue; 9606 } 9607 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9608 if (DEBUG_MU) 9609 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9610 if (dst != null) { 9611 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9612 mProviderMap.putProviderByClass(comp, dst); 9613 String names[] = dst.info.authority.split(";"); 9614 for (int j = 0; j < names.length; j++) { 9615 mProviderMap.putProviderByName(names[j], dst); 9616 } 9617 9618 int NL = mLaunchingProviders.size(); 9619 int j; 9620 for (j=0; j<NL; j++) { 9621 if (mLaunchingProviders.get(j) == dst) { 9622 mLaunchingProviders.remove(j); 9623 j--; 9624 NL--; 9625 } 9626 } 9627 synchronized (dst) { 9628 dst.provider = src.provider; 9629 dst.proc = r; 9630 dst.notifyAll(); 9631 } 9632 updateOomAdjLocked(r); 9633 } 9634 } 9635 9636 Binder.restoreCallingIdentity(origId); 9637 } 9638 } 9639 9640 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9641 ContentProviderConnection conn; 9642 try { 9643 conn = (ContentProviderConnection)connection; 9644 } catch (ClassCastException e) { 9645 String msg ="refContentProvider: " + connection 9646 + " not a ContentProviderConnection"; 9647 Slog.w(TAG, msg); 9648 throw new IllegalArgumentException(msg); 9649 } 9650 if (conn == null) { 9651 throw new NullPointerException("connection is null"); 9652 } 9653 9654 synchronized (this) { 9655 if (stable > 0) { 9656 conn.numStableIncs += stable; 9657 } 9658 stable = conn.stableCount + stable; 9659 if (stable < 0) { 9660 throw new IllegalStateException("stableCount < 0: " + stable); 9661 } 9662 9663 if (unstable > 0) { 9664 conn.numUnstableIncs += unstable; 9665 } 9666 unstable = conn.unstableCount + unstable; 9667 if (unstable < 0) { 9668 throw new IllegalStateException("unstableCount < 0: " + unstable); 9669 } 9670 9671 if ((stable+unstable) <= 0) { 9672 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9673 + stable + " unstable=" + unstable); 9674 } 9675 conn.stableCount = stable; 9676 conn.unstableCount = unstable; 9677 return !conn.dead; 9678 } 9679 } 9680 9681 public void unstableProviderDied(IBinder connection) { 9682 ContentProviderConnection conn; 9683 try { 9684 conn = (ContentProviderConnection)connection; 9685 } catch (ClassCastException e) { 9686 String msg ="refContentProvider: " + connection 9687 + " not a ContentProviderConnection"; 9688 Slog.w(TAG, msg); 9689 throw new IllegalArgumentException(msg); 9690 } 9691 if (conn == null) { 9692 throw new NullPointerException("connection is null"); 9693 } 9694 9695 // Safely retrieve the content provider associated with the connection. 9696 IContentProvider provider; 9697 synchronized (this) { 9698 provider = conn.provider.provider; 9699 } 9700 9701 if (provider == null) { 9702 // Um, yeah, we're way ahead of you. 9703 return; 9704 } 9705 9706 // Make sure the caller is being honest with us. 9707 if (provider.asBinder().pingBinder()) { 9708 // Er, no, still looks good to us. 9709 synchronized (this) { 9710 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9711 + " says " + conn + " died, but we don't agree"); 9712 return; 9713 } 9714 } 9715 9716 // Well look at that! It's dead! 9717 synchronized (this) { 9718 if (conn.provider.provider != provider) { 9719 // But something changed... good enough. 9720 return; 9721 } 9722 9723 ProcessRecord proc = conn.provider.proc; 9724 if (proc == null || proc.thread == null) { 9725 // Seems like the process is already cleaned up. 9726 return; 9727 } 9728 9729 // As far as we're concerned, this is just like receiving a 9730 // death notification... just a bit prematurely. 9731 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9732 + ") early provider death"); 9733 final long ident = Binder.clearCallingIdentity(); 9734 try { 9735 appDiedLocked(proc); 9736 } finally { 9737 Binder.restoreCallingIdentity(ident); 9738 } 9739 } 9740 } 9741 9742 @Override 9743 public void appNotRespondingViaProvider(IBinder connection) { 9744 enforceCallingPermission( 9745 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9746 9747 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9748 if (conn == null) { 9749 Slog.w(TAG, "ContentProviderConnection is null"); 9750 return; 9751 } 9752 9753 final ProcessRecord host = conn.provider.proc; 9754 if (host == null) { 9755 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9756 return; 9757 } 9758 9759 final long token = Binder.clearCallingIdentity(); 9760 try { 9761 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9762 } finally { 9763 Binder.restoreCallingIdentity(token); 9764 } 9765 } 9766 9767 public final void installSystemProviders() { 9768 List<ProviderInfo> providers; 9769 synchronized (this) { 9770 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9771 providers = generateApplicationProvidersLocked(app); 9772 if (providers != null) { 9773 for (int i=providers.size()-1; i>=0; i--) { 9774 ProviderInfo pi = (ProviderInfo)providers.get(i); 9775 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9776 Slog.w(TAG, "Not installing system proc provider " + pi.name 9777 + ": not system .apk"); 9778 providers.remove(i); 9779 } 9780 } 9781 } 9782 } 9783 if (providers != null) { 9784 mSystemThread.installSystemProviders(providers); 9785 } 9786 9787 mCoreSettingsObserver = new CoreSettingsObserver(this); 9788 9789 //mUsageStatsService.monitorPackages(); 9790 } 9791 9792 /** 9793 * Allows apps to retrieve the MIME type of a URI. 9794 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9795 * users, then it does not need permission to access the ContentProvider. 9796 * Either, it needs cross-user uri grants. 9797 * 9798 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9799 * 9800 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9801 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9802 */ 9803 public String getProviderMimeType(Uri uri, int userId) { 9804 enforceNotIsolatedCaller("getProviderMimeType"); 9805 final String name = uri.getAuthority(); 9806 int callingUid = Binder.getCallingUid(); 9807 int callingPid = Binder.getCallingPid(); 9808 long ident = 0; 9809 boolean clearedIdentity = false; 9810 userId = unsafeConvertIncomingUser(userId); 9811 if (canClearIdentity(callingPid, callingUid, userId)) { 9812 clearedIdentity = true; 9813 ident = Binder.clearCallingIdentity(); 9814 } 9815 ContentProviderHolder holder = null; 9816 try { 9817 holder = getContentProviderExternalUnchecked(name, null, userId); 9818 if (holder != null) { 9819 return holder.provider.getType(uri); 9820 } 9821 } catch (RemoteException e) { 9822 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9823 return null; 9824 } finally { 9825 // We need to clear the identity to call removeContentProviderExternalUnchecked 9826 if (!clearedIdentity) { 9827 ident = Binder.clearCallingIdentity(); 9828 } 9829 try { 9830 if (holder != null) { 9831 removeContentProviderExternalUnchecked(name, null, userId); 9832 } 9833 } finally { 9834 Binder.restoreCallingIdentity(ident); 9835 } 9836 } 9837 9838 return null; 9839 } 9840 9841 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9842 if (UserHandle.getUserId(callingUid) == userId) { 9843 return true; 9844 } 9845 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9846 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9847 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9848 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9849 return true; 9850 } 9851 return false; 9852 } 9853 9854 // ========================================================= 9855 // GLOBAL MANAGEMENT 9856 // ========================================================= 9857 9858 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9859 boolean isolated, int isolatedUid) { 9860 String proc = customProcess != null ? customProcess : info.processName; 9861 BatteryStatsImpl.Uid.Proc ps = null; 9862 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9863 int uid = info.uid; 9864 if (isolated) { 9865 if (isolatedUid == 0) { 9866 int userId = UserHandle.getUserId(uid); 9867 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9868 while (true) { 9869 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9870 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9871 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9872 } 9873 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9874 mNextIsolatedProcessUid++; 9875 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9876 // No process for this uid, use it. 9877 break; 9878 } 9879 stepsLeft--; 9880 if (stepsLeft <= 0) { 9881 return null; 9882 } 9883 } 9884 } else { 9885 // Special case for startIsolatedProcess (internal only), where 9886 // the uid of the isolated process is specified by the caller. 9887 uid = isolatedUid; 9888 } 9889 } 9890 return new ProcessRecord(stats, info, proc, uid); 9891 } 9892 9893 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9894 String abiOverride) { 9895 ProcessRecord app; 9896 if (!isolated) { 9897 app = getProcessRecordLocked(info.processName, info.uid, true); 9898 } else { 9899 app = null; 9900 } 9901 9902 if (app == null) { 9903 app = newProcessRecordLocked(info, null, isolated, 0); 9904 mProcessNames.put(info.processName, app.uid, app); 9905 if (isolated) { 9906 mIsolatedProcesses.put(app.uid, app); 9907 } 9908 updateLruProcessLocked(app, false, null); 9909 updateOomAdjLocked(); 9910 } 9911 9912 // This package really, really can not be stopped. 9913 try { 9914 AppGlobals.getPackageManager().setPackageStoppedState( 9915 info.packageName, false, UserHandle.getUserId(app.uid)); 9916 } catch (RemoteException e) { 9917 } catch (IllegalArgumentException e) { 9918 Slog.w(TAG, "Failed trying to unstop package " 9919 + info.packageName + ": " + e); 9920 } 9921 9922 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9923 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9924 app.persistent = true; 9925 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9926 } 9927 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9928 mPersistentStartingProcesses.add(app); 9929 startProcessLocked(app, "added application", app.processName, abiOverride, 9930 null /* entryPoint */, null /* entryPointArgs */); 9931 } 9932 9933 return app; 9934 } 9935 9936 public void unhandledBack() { 9937 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9938 "unhandledBack()"); 9939 9940 synchronized(this) { 9941 final long origId = Binder.clearCallingIdentity(); 9942 try { 9943 getFocusedStack().unhandledBackLocked(); 9944 } finally { 9945 Binder.restoreCallingIdentity(origId); 9946 } 9947 } 9948 } 9949 9950 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9951 enforceNotIsolatedCaller("openContentUri"); 9952 final int userId = UserHandle.getCallingUserId(); 9953 String name = uri.getAuthority(); 9954 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9955 ParcelFileDescriptor pfd = null; 9956 if (cph != null) { 9957 // We record the binder invoker's uid in thread-local storage before 9958 // going to the content provider to open the file. Later, in the code 9959 // that handles all permissions checks, we look for this uid and use 9960 // that rather than the Activity Manager's own uid. The effect is that 9961 // we do the check against the caller's permissions even though it looks 9962 // to the content provider like the Activity Manager itself is making 9963 // the request. 9964 sCallerIdentity.set(new Identity( 9965 Binder.getCallingPid(), Binder.getCallingUid())); 9966 try { 9967 pfd = cph.provider.openFile(null, uri, "r", null); 9968 } catch (FileNotFoundException e) { 9969 // do nothing; pfd will be returned null 9970 } finally { 9971 // Ensure that whatever happens, we clean up the identity state 9972 sCallerIdentity.remove(); 9973 } 9974 9975 // We've got the fd now, so we're done with the provider. 9976 removeContentProviderExternalUnchecked(name, null, userId); 9977 } else { 9978 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9979 } 9980 return pfd; 9981 } 9982 9983 // Actually is sleeping or shutting down or whatever else in the future 9984 // is an inactive state. 9985 public boolean isSleepingOrShuttingDown() { 9986 return isSleeping() || mShuttingDown; 9987 } 9988 9989 public boolean isSleeping() { 9990 return mSleeping; 9991 } 9992 9993 void goingToSleep() { 9994 synchronized(this) { 9995 mWentToSleep = true; 9996 goToSleepIfNeededLocked(); 9997 } 9998 } 9999 10000 void finishRunningVoiceLocked() { 10001 if (mRunningVoice) { 10002 mRunningVoice = false; 10003 goToSleepIfNeededLocked(); 10004 } 10005 } 10006 10007 void goToSleepIfNeededLocked() { 10008 if (mWentToSleep && !mRunningVoice) { 10009 if (!mSleeping) { 10010 mSleeping = true; 10011 mStackSupervisor.goingToSleepLocked(); 10012 10013 // Initialize the wake times of all processes. 10014 checkExcessivePowerUsageLocked(false); 10015 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10016 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10017 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10018 } 10019 } 10020 } 10021 10022 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10023 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10024 // Never persist the home stack. 10025 return; 10026 } 10027 mTaskPersister.wakeup(task, flush); 10028 } 10029 10030 @Override 10031 public boolean shutdown(int timeout) { 10032 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10033 != PackageManager.PERMISSION_GRANTED) { 10034 throw new SecurityException("Requires permission " 10035 + android.Manifest.permission.SHUTDOWN); 10036 } 10037 10038 boolean timedout = false; 10039 10040 synchronized(this) { 10041 mShuttingDown = true; 10042 updateEventDispatchingLocked(); 10043 timedout = mStackSupervisor.shutdownLocked(timeout); 10044 } 10045 10046 mAppOpsService.shutdown(); 10047 if (mUsageStatsService != null) { 10048 mUsageStatsService.prepareShutdown(); 10049 } 10050 mBatteryStatsService.shutdown(); 10051 synchronized (this) { 10052 mProcessStats.shutdownLocked(); 10053 } 10054 notifyTaskPersisterLocked(null, true); 10055 10056 return timedout; 10057 } 10058 10059 public final void activitySlept(IBinder token) { 10060 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10061 10062 final long origId = Binder.clearCallingIdentity(); 10063 10064 synchronized (this) { 10065 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10066 if (r != null) { 10067 mStackSupervisor.activitySleptLocked(r); 10068 } 10069 } 10070 10071 Binder.restoreCallingIdentity(origId); 10072 } 10073 10074 void logLockScreen(String msg) { 10075 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10076 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10077 mWentToSleep + " mSleeping=" + mSleeping); 10078 } 10079 10080 private void comeOutOfSleepIfNeededLocked() { 10081 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10082 if (mSleeping) { 10083 mSleeping = false; 10084 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10085 } 10086 } 10087 } 10088 10089 void wakingUp() { 10090 synchronized(this) { 10091 mWentToSleep = false; 10092 comeOutOfSleepIfNeededLocked(); 10093 } 10094 } 10095 10096 void startRunningVoiceLocked() { 10097 if (!mRunningVoice) { 10098 mRunningVoice = true; 10099 comeOutOfSleepIfNeededLocked(); 10100 } 10101 } 10102 10103 private void updateEventDispatchingLocked() { 10104 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10105 } 10106 10107 public void setLockScreenShown(boolean shown) { 10108 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10109 != PackageManager.PERMISSION_GRANTED) { 10110 throw new SecurityException("Requires permission " 10111 + android.Manifest.permission.DEVICE_POWER); 10112 } 10113 10114 synchronized(this) { 10115 long ident = Binder.clearCallingIdentity(); 10116 try { 10117 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10118 mLockScreenShown = shown; 10119 comeOutOfSleepIfNeededLocked(); 10120 } finally { 10121 Binder.restoreCallingIdentity(ident); 10122 } 10123 } 10124 } 10125 10126 @Override 10127 public void stopAppSwitches() { 10128 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10129 != PackageManager.PERMISSION_GRANTED) { 10130 throw new SecurityException("Requires permission " 10131 + android.Manifest.permission.STOP_APP_SWITCHES); 10132 } 10133 10134 synchronized(this) { 10135 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10136 + APP_SWITCH_DELAY_TIME; 10137 mDidAppSwitch = false; 10138 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10139 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10140 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10141 } 10142 } 10143 10144 public void resumeAppSwitches() { 10145 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10146 != PackageManager.PERMISSION_GRANTED) { 10147 throw new SecurityException("Requires permission " 10148 + android.Manifest.permission.STOP_APP_SWITCHES); 10149 } 10150 10151 synchronized(this) { 10152 // Note that we don't execute any pending app switches... we will 10153 // let those wait until either the timeout, or the next start 10154 // activity request. 10155 mAppSwitchesAllowedTime = 0; 10156 } 10157 } 10158 10159 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10160 int callingPid, int callingUid, String name) { 10161 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10162 return true; 10163 } 10164 10165 int perm = checkComponentPermission( 10166 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10167 sourceUid, -1, true); 10168 if (perm == PackageManager.PERMISSION_GRANTED) { 10169 return true; 10170 } 10171 10172 // If the actual IPC caller is different from the logical source, then 10173 // also see if they are allowed to control app switches. 10174 if (callingUid != -1 && callingUid != sourceUid) { 10175 perm = checkComponentPermission( 10176 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10177 callingUid, -1, true); 10178 if (perm == PackageManager.PERMISSION_GRANTED) { 10179 return true; 10180 } 10181 } 10182 10183 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10184 return false; 10185 } 10186 10187 public void setDebugApp(String packageName, boolean waitForDebugger, 10188 boolean persistent) { 10189 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10190 "setDebugApp()"); 10191 10192 long ident = Binder.clearCallingIdentity(); 10193 try { 10194 // Note that this is not really thread safe if there are multiple 10195 // callers into it at the same time, but that's not a situation we 10196 // care about. 10197 if (persistent) { 10198 final ContentResolver resolver = mContext.getContentResolver(); 10199 Settings.Global.putString( 10200 resolver, Settings.Global.DEBUG_APP, 10201 packageName); 10202 Settings.Global.putInt( 10203 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10204 waitForDebugger ? 1 : 0); 10205 } 10206 10207 synchronized (this) { 10208 if (!persistent) { 10209 mOrigDebugApp = mDebugApp; 10210 mOrigWaitForDebugger = mWaitForDebugger; 10211 } 10212 mDebugApp = packageName; 10213 mWaitForDebugger = waitForDebugger; 10214 mDebugTransient = !persistent; 10215 if (packageName != null) { 10216 forceStopPackageLocked(packageName, -1, false, false, true, true, 10217 false, UserHandle.USER_ALL, "set debug app"); 10218 } 10219 } 10220 } finally { 10221 Binder.restoreCallingIdentity(ident); 10222 } 10223 } 10224 10225 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10226 synchronized (this) { 10227 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10228 if (!isDebuggable) { 10229 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10230 throw new SecurityException("Process not debuggable: " + app.packageName); 10231 } 10232 } 10233 10234 mOpenGlTraceApp = processName; 10235 } 10236 } 10237 10238 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10239 synchronized (this) { 10240 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10241 if (!isDebuggable) { 10242 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10243 throw new SecurityException("Process not debuggable: " + app.packageName); 10244 } 10245 } 10246 mProfileApp = processName; 10247 mProfileFile = profilerInfo.profileFile; 10248 if (mProfileFd != null) { 10249 try { 10250 mProfileFd.close(); 10251 } catch (IOException e) { 10252 } 10253 mProfileFd = null; 10254 } 10255 mProfileFd = profilerInfo.profileFd; 10256 mSamplingInterval = profilerInfo.samplingInterval; 10257 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10258 mProfileType = 0; 10259 } 10260 } 10261 10262 @Override 10263 public void setAlwaysFinish(boolean enabled) { 10264 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10265 "setAlwaysFinish()"); 10266 10267 Settings.Global.putInt( 10268 mContext.getContentResolver(), 10269 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10270 10271 synchronized (this) { 10272 mAlwaysFinishActivities = enabled; 10273 } 10274 } 10275 10276 @Override 10277 public void setActivityController(IActivityController controller) { 10278 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10279 "setActivityController()"); 10280 synchronized (this) { 10281 mController = controller; 10282 Watchdog.getInstance().setActivityController(controller); 10283 } 10284 } 10285 10286 @Override 10287 public void setUserIsMonkey(boolean userIsMonkey) { 10288 synchronized (this) { 10289 synchronized (mPidsSelfLocked) { 10290 final int callingPid = Binder.getCallingPid(); 10291 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10292 if (precessRecord == null) { 10293 throw new SecurityException("Unknown process: " + callingPid); 10294 } 10295 if (precessRecord.instrumentationUiAutomationConnection == null) { 10296 throw new SecurityException("Only an instrumentation process " 10297 + "with a UiAutomation can call setUserIsMonkey"); 10298 } 10299 } 10300 mUserIsMonkey = userIsMonkey; 10301 } 10302 } 10303 10304 @Override 10305 public boolean isUserAMonkey() { 10306 synchronized (this) { 10307 // If there is a controller also implies the user is a monkey. 10308 return (mUserIsMonkey || mController != null); 10309 } 10310 } 10311 10312 public void requestBugReport() { 10313 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10314 SystemProperties.set("ctl.start", "bugreport"); 10315 } 10316 10317 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10318 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10319 } 10320 10321 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10322 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10323 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10324 } 10325 return KEY_DISPATCHING_TIMEOUT; 10326 } 10327 10328 @Override 10329 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10330 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10331 != PackageManager.PERMISSION_GRANTED) { 10332 throw new SecurityException("Requires permission " 10333 + android.Manifest.permission.FILTER_EVENTS); 10334 } 10335 ProcessRecord proc; 10336 long timeout; 10337 synchronized (this) { 10338 synchronized (mPidsSelfLocked) { 10339 proc = mPidsSelfLocked.get(pid); 10340 } 10341 timeout = getInputDispatchingTimeoutLocked(proc); 10342 } 10343 10344 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10345 return -1; 10346 } 10347 10348 return timeout; 10349 } 10350 10351 /** 10352 * Handle input dispatching timeouts. 10353 * Returns whether input dispatching should be aborted or not. 10354 */ 10355 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10356 final ActivityRecord activity, final ActivityRecord parent, 10357 final boolean aboveSystem, String reason) { 10358 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10359 != PackageManager.PERMISSION_GRANTED) { 10360 throw new SecurityException("Requires permission " 10361 + android.Manifest.permission.FILTER_EVENTS); 10362 } 10363 10364 final String annotation; 10365 if (reason == null) { 10366 annotation = "Input dispatching timed out"; 10367 } else { 10368 annotation = "Input dispatching timed out (" + reason + ")"; 10369 } 10370 10371 if (proc != null) { 10372 synchronized (this) { 10373 if (proc.debugging) { 10374 return false; 10375 } 10376 10377 if (mDidDexOpt) { 10378 // Give more time since we were dexopting. 10379 mDidDexOpt = false; 10380 return false; 10381 } 10382 10383 if (proc.instrumentationClass != null) { 10384 Bundle info = new Bundle(); 10385 info.putString("shortMsg", "keyDispatchingTimedOut"); 10386 info.putString("longMsg", annotation); 10387 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10388 return true; 10389 } 10390 } 10391 mHandler.post(new Runnable() { 10392 @Override 10393 public void run() { 10394 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10395 } 10396 }); 10397 } 10398 10399 return true; 10400 } 10401 10402 public Bundle getAssistContextExtras(int requestType) { 10403 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10404 "getAssistContextExtras()"); 10405 PendingAssistExtras pae; 10406 Bundle extras = new Bundle(); 10407 synchronized (this) { 10408 ActivityRecord activity = getFocusedStack().mResumedActivity; 10409 if (activity == null) { 10410 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10411 return null; 10412 } 10413 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10414 if (activity.app == null || activity.app.thread == null) { 10415 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10416 return extras; 10417 } 10418 if (activity.app.pid == Binder.getCallingPid()) { 10419 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10420 return extras; 10421 } 10422 pae = new PendingAssistExtras(activity); 10423 try { 10424 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10425 requestType); 10426 mPendingAssistExtras.add(pae); 10427 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10428 } catch (RemoteException e) { 10429 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10430 return extras; 10431 } 10432 } 10433 synchronized (pae) { 10434 while (!pae.haveResult) { 10435 try { 10436 pae.wait(); 10437 } catch (InterruptedException e) { 10438 } 10439 } 10440 if (pae.result != null) { 10441 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10442 } 10443 } 10444 synchronized (this) { 10445 mPendingAssistExtras.remove(pae); 10446 mHandler.removeCallbacks(pae); 10447 } 10448 return extras; 10449 } 10450 10451 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10452 PendingAssistExtras pae = (PendingAssistExtras)token; 10453 synchronized (pae) { 10454 pae.result = extras; 10455 pae.haveResult = true; 10456 pae.notifyAll(); 10457 } 10458 } 10459 10460 public void registerProcessObserver(IProcessObserver observer) { 10461 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10462 "registerProcessObserver()"); 10463 synchronized (this) { 10464 mProcessObservers.register(observer); 10465 } 10466 } 10467 10468 @Override 10469 public void unregisterProcessObserver(IProcessObserver observer) { 10470 synchronized (this) { 10471 mProcessObservers.unregister(observer); 10472 } 10473 } 10474 10475 @Override 10476 public boolean convertFromTranslucent(IBinder token) { 10477 final long origId = Binder.clearCallingIdentity(); 10478 try { 10479 synchronized (this) { 10480 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10481 if (r == null) { 10482 return false; 10483 } 10484 final boolean translucentChanged = r.changeWindowTranslucency(true); 10485 if (translucentChanged) { 10486 r.task.stack.releaseBackgroundResources(); 10487 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10488 } 10489 mWindowManager.setAppFullscreen(token, true); 10490 return translucentChanged; 10491 } 10492 } finally { 10493 Binder.restoreCallingIdentity(origId); 10494 } 10495 } 10496 10497 @Override 10498 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10499 final long origId = Binder.clearCallingIdentity(); 10500 try { 10501 synchronized (this) { 10502 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10503 if (r == null) { 10504 return false; 10505 } 10506 int index = r.task.mActivities.lastIndexOf(r); 10507 if (index > 0) { 10508 ActivityRecord under = r.task.mActivities.get(index - 1); 10509 under.returningOptions = options; 10510 } 10511 final boolean translucentChanged = r.changeWindowTranslucency(false); 10512 if (translucentChanged) { 10513 r.task.stack.convertToTranslucent(r); 10514 } 10515 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10516 mWindowManager.setAppFullscreen(token, false); 10517 return translucentChanged; 10518 } 10519 } finally { 10520 Binder.restoreCallingIdentity(origId); 10521 } 10522 } 10523 10524 @Override 10525 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10526 final long origId = Binder.clearCallingIdentity(); 10527 try { 10528 synchronized (this) { 10529 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10530 if (r != null) { 10531 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10532 } 10533 } 10534 return false; 10535 } finally { 10536 Binder.restoreCallingIdentity(origId); 10537 } 10538 } 10539 10540 @Override 10541 public boolean isBackgroundVisibleBehind(IBinder token) { 10542 final long origId = Binder.clearCallingIdentity(); 10543 try { 10544 synchronized (this) { 10545 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10546 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10547 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10548 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10549 return visible; 10550 } 10551 } finally { 10552 Binder.restoreCallingIdentity(origId); 10553 } 10554 } 10555 10556 @Override 10557 public ActivityOptions getActivityOptions(IBinder token) { 10558 final long origId = Binder.clearCallingIdentity(); 10559 try { 10560 synchronized (this) { 10561 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10562 if (r != null) { 10563 final ActivityOptions activityOptions = r.pendingOptions; 10564 r.pendingOptions = null; 10565 return activityOptions; 10566 } 10567 return null; 10568 } 10569 } finally { 10570 Binder.restoreCallingIdentity(origId); 10571 } 10572 } 10573 10574 @Override 10575 public void setImmersive(IBinder token, boolean immersive) { 10576 synchronized(this) { 10577 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10578 if (r == null) { 10579 throw new IllegalArgumentException(); 10580 } 10581 r.immersive = immersive; 10582 10583 // update associated state if we're frontmost 10584 if (r == mFocusedActivity) { 10585 if (DEBUG_IMMERSIVE) { 10586 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10587 } 10588 applyUpdateLockStateLocked(r); 10589 } 10590 } 10591 } 10592 10593 @Override 10594 public boolean isImmersive(IBinder token) { 10595 synchronized (this) { 10596 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10597 if (r == null) { 10598 throw new IllegalArgumentException(); 10599 } 10600 return r.immersive; 10601 } 10602 } 10603 10604 public boolean isTopActivityImmersive() { 10605 enforceNotIsolatedCaller("startActivity"); 10606 synchronized (this) { 10607 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10608 return (r != null) ? r.immersive : false; 10609 } 10610 } 10611 10612 @Override 10613 public boolean isTopOfTask(IBinder token) { 10614 synchronized (this) { 10615 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10616 if (r == null) { 10617 throw new IllegalArgumentException(); 10618 } 10619 return r.task.getTopActivity() == r; 10620 } 10621 } 10622 10623 public final void enterSafeMode() { 10624 synchronized(this) { 10625 // It only makes sense to do this before the system is ready 10626 // and started launching other packages. 10627 if (!mSystemReady) { 10628 try { 10629 AppGlobals.getPackageManager().enterSafeMode(); 10630 } catch (RemoteException e) { 10631 } 10632 } 10633 10634 mSafeMode = true; 10635 } 10636 } 10637 10638 public final void showSafeModeOverlay() { 10639 View v = LayoutInflater.from(mContext).inflate( 10640 com.android.internal.R.layout.safe_mode, null); 10641 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10642 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10643 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10644 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10645 lp.gravity = Gravity.BOTTOM | Gravity.START; 10646 lp.format = v.getBackground().getOpacity(); 10647 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10648 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10649 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10650 ((WindowManager)mContext.getSystemService( 10651 Context.WINDOW_SERVICE)).addView(v, lp); 10652 } 10653 10654 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10655 if (!(sender instanceof PendingIntentRecord)) { 10656 return; 10657 } 10658 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10659 synchronized (stats) { 10660 if (mBatteryStatsService.isOnBattery()) { 10661 mBatteryStatsService.enforceCallingPermission(); 10662 PendingIntentRecord rec = (PendingIntentRecord)sender; 10663 int MY_UID = Binder.getCallingUid(); 10664 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10665 BatteryStatsImpl.Uid.Pkg pkg = 10666 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10667 sourcePkg != null ? sourcePkg : rec.key.packageName); 10668 pkg.incWakeupsLocked(); 10669 } 10670 } 10671 } 10672 10673 public boolean killPids(int[] pids, String pReason, boolean secure) { 10674 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10675 throw new SecurityException("killPids only available to the system"); 10676 } 10677 String reason = (pReason == null) ? "Unknown" : pReason; 10678 // XXX Note: don't acquire main activity lock here, because the window 10679 // manager calls in with its locks held. 10680 10681 boolean killed = false; 10682 synchronized (mPidsSelfLocked) { 10683 int[] types = new int[pids.length]; 10684 int worstType = 0; 10685 for (int i=0; i<pids.length; i++) { 10686 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10687 if (proc != null) { 10688 int type = proc.setAdj; 10689 types[i] = type; 10690 if (type > worstType) { 10691 worstType = type; 10692 } 10693 } 10694 } 10695 10696 // If the worst oom_adj is somewhere in the cached proc LRU range, 10697 // then constrain it so we will kill all cached procs. 10698 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10699 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10700 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10701 } 10702 10703 // If this is not a secure call, don't let it kill processes that 10704 // are important. 10705 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10706 worstType = ProcessList.SERVICE_ADJ; 10707 } 10708 10709 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10710 for (int i=0; i<pids.length; i++) { 10711 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10712 if (proc == null) { 10713 continue; 10714 } 10715 int adj = proc.setAdj; 10716 if (adj >= worstType && !proc.killedByAm) { 10717 proc.kill(reason, true); 10718 killed = true; 10719 } 10720 } 10721 } 10722 return killed; 10723 } 10724 10725 @Override 10726 public void killUid(int uid, String reason) { 10727 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10728 throw new SecurityException("killUid only available to the system"); 10729 } 10730 synchronized (this) { 10731 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10732 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10733 reason != null ? reason : "kill uid"); 10734 } 10735 } 10736 10737 @Override 10738 public boolean killProcessesBelowForeground(String reason) { 10739 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10740 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10741 } 10742 10743 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10744 } 10745 10746 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10747 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10748 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10749 } 10750 10751 boolean killed = false; 10752 synchronized (mPidsSelfLocked) { 10753 final int size = mPidsSelfLocked.size(); 10754 for (int i = 0; i < size; i++) { 10755 final int pid = mPidsSelfLocked.keyAt(i); 10756 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10757 if (proc == null) continue; 10758 10759 final int adj = proc.setAdj; 10760 if (adj > belowAdj && !proc.killedByAm) { 10761 proc.kill(reason, true); 10762 killed = true; 10763 } 10764 } 10765 } 10766 return killed; 10767 } 10768 10769 @Override 10770 public void hang(final IBinder who, boolean allowRestart) { 10771 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10772 != PackageManager.PERMISSION_GRANTED) { 10773 throw new SecurityException("Requires permission " 10774 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10775 } 10776 10777 final IBinder.DeathRecipient death = new DeathRecipient() { 10778 @Override 10779 public void binderDied() { 10780 synchronized (this) { 10781 notifyAll(); 10782 } 10783 } 10784 }; 10785 10786 try { 10787 who.linkToDeath(death, 0); 10788 } catch (RemoteException e) { 10789 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10790 return; 10791 } 10792 10793 synchronized (this) { 10794 Watchdog.getInstance().setAllowRestart(allowRestart); 10795 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10796 synchronized (death) { 10797 while (who.isBinderAlive()) { 10798 try { 10799 death.wait(); 10800 } catch (InterruptedException e) { 10801 } 10802 } 10803 } 10804 Watchdog.getInstance().setAllowRestart(true); 10805 } 10806 } 10807 10808 @Override 10809 public void restart() { 10810 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10811 != PackageManager.PERMISSION_GRANTED) { 10812 throw new SecurityException("Requires permission " 10813 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10814 } 10815 10816 Log.i(TAG, "Sending shutdown broadcast..."); 10817 10818 BroadcastReceiver br = new BroadcastReceiver() { 10819 @Override public void onReceive(Context context, Intent intent) { 10820 // Now the broadcast is done, finish up the low-level shutdown. 10821 Log.i(TAG, "Shutting down activity manager..."); 10822 shutdown(10000); 10823 Log.i(TAG, "Shutdown complete, restarting!"); 10824 Process.killProcess(Process.myPid()); 10825 System.exit(10); 10826 } 10827 }; 10828 10829 // First send the high-level shut down broadcast. 10830 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10831 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10832 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10833 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10834 mContext.sendOrderedBroadcastAsUser(intent, 10835 UserHandle.ALL, null, br, mHandler, 0, null, null); 10836 */ 10837 br.onReceive(mContext, intent); 10838 } 10839 10840 private long getLowRamTimeSinceIdle(long now) { 10841 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10842 } 10843 10844 @Override 10845 public void performIdleMaintenance() { 10846 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10847 != PackageManager.PERMISSION_GRANTED) { 10848 throw new SecurityException("Requires permission " 10849 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10850 } 10851 10852 synchronized (this) { 10853 final long now = SystemClock.uptimeMillis(); 10854 final long timeSinceLastIdle = now - mLastIdleTime; 10855 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10856 mLastIdleTime = now; 10857 mLowRamTimeSinceLastIdle = 0; 10858 if (mLowRamStartTime != 0) { 10859 mLowRamStartTime = now; 10860 } 10861 10862 StringBuilder sb = new StringBuilder(128); 10863 sb.append("Idle maintenance over "); 10864 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10865 sb.append(" low RAM for "); 10866 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10867 Slog.i(TAG, sb.toString()); 10868 10869 // If at least 1/3 of our time since the last idle period has been spent 10870 // with RAM low, then we want to kill processes. 10871 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10872 10873 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10874 ProcessRecord proc = mLruProcesses.get(i); 10875 if (proc.notCachedSinceIdle) { 10876 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10877 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10878 if (doKilling && proc.initialIdlePss != 0 10879 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10880 proc.kill("idle maint (pss " + proc.lastPss 10881 + " from " + proc.initialIdlePss + ")", true); 10882 } 10883 } 10884 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10885 proc.notCachedSinceIdle = true; 10886 proc.initialIdlePss = 0; 10887 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10888 isSleeping(), now); 10889 } 10890 } 10891 10892 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10893 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10894 } 10895 } 10896 10897 private void retrieveSettings() { 10898 final ContentResolver resolver = mContext.getContentResolver(); 10899 String debugApp = Settings.Global.getString( 10900 resolver, Settings.Global.DEBUG_APP); 10901 boolean waitForDebugger = Settings.Global.getInt( 10902 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10903 boolean alwaysFinishActivities = Settings.Global.getInt( 10904 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10905 boolean forceRtl = Settings.Global.getInt( 10906 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10907 // Transfer any global setting for forcing RTL layout, into a System Property 10908 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10909 10910 Configuration configuration = new Configuration(); 10911 Settings.System.getConfiguration(resolver, configuration); 10912 if (forceRtl) { 10913 // This will take care of setting the correct layout direction flags 10914 configuration.setLayoutDirection(configuration.locale); 10915 } 10916 10917 synchronized (this) { 10918 mDebugApp = mOrigDebugApp = debugApp; 10919 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10920 mAlwaysFinishActivities = alwaysFinishActivities; 10921 // This happens before any activities are started, so we can 10922 // change mConfiguration in-place. 10923 updateConfigurationLocked(configuration, null, false, true); 10924 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10925 } 10926 } 10927 10928 /** Loads resources after the current configuration has been set. */ 10929 private void loadResourcesOnSystemReady() { 10930 final Resources res = mContext.getResources(); 10931 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10932 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10933 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10934 } 10935 10936 public boolean testIsSystemReady() { 10937 // no need to synchronize(this) just to read & return the value 10938 return mSystemReady; 10939 } 10940 10941 private static File getCalledPreBootReceiversFile() { 10942 File dataDir = Environment.getDataDirectory(); 10943 File systemDir = new File(dataDir, "system"); 10944 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10945 return fname; 10946 } 10947 10948 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10949 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10950 File file = getCalledPreBootReceiversFile(); 10951 FileInputStream fis = null; 10952 try { 10953 fis = new FileInputStream(file); 10954 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10955 int fvers = dis.readInt(); 10956 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10957 String vers = dis.readUTF(); 10958 String codename = dis.readUTF(); 10959 String build = dis.readUTF(); 10960 if (android.os.Build.VERSION.RELEASE.equals(vers) 10961 && android.os.Build.VERSION.CODENAME.equals(codename) 10962 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10963 int num = dis.readInt(); 10964 while (num > 0) { 10965 num--; 10966 String pkg = dis.readUTF(); 10967 String cls = dis.readUTF(); 10968 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10969 } 10970 } 10971 } 10972 } catch (FileNotFoundException e) { 10973 } catch (IOException e) { 10974 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10975 } finally { 10976 if (fis != null) { 10977 try { 10978 fis.close(); 10979 } catch (IOException e) { 10980 } 10981 } 10982 } 10983 return lastDoneReceivers; 10984 } 10985 10986 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10987 File file = getCalledPreBootReceiversFile(); 10988 FileOutputStream fos = null; 10989 DataOutputStream dos = null; 10990 try { 10991 fos = new FileOutputStream(file); 10992 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10993 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10994 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10995 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10996 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10997 dos.writeInt(list.size()); 10998 for (int i=0; i<list.size(); i++) { 10999 dos.writeUTF(list.get(i).getPackageName()); 11000 dos.writeUTF(list.get(i).getClassName()); 11001 } 11002 } catch (IOException e) { 11003 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11004 file.delete(); 11005 } finally { 11006 FileUtils.sync(fos); 11007 if (dos != null) { 11008 try { 11009 dos.close(); 11010 } catch (IOException e) { 11011 // TODO Auto-generated catch block 11012 e.printStackTrace(); 11013 } 11014 } 11015 } 11016 } 11017 11018 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11019 ArrayList<ComponentName> doneReceivers, int userId) { 11020 boolean waitingUpdate = false; 11021 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11022 List<ResolveInfo> ris = null; 11023 try { 11024 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11025 intent, null, 0, userId); 11026 } catch (RemoteException e) { 11027 } 11028 if (ris != null) { 11029 for (int i=ris.size()-1; i>=0; i--) { 11030 if ((ris.get(i).activityInfo.applicationInfo.flags 11031 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11032 ris.remove(i); 11033 } 11034 } 11035 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11036 11037 // For User 0, load the version number. When delivering to a new user, deliver 11038 // to all receivers. 11039 if (userId == UserHandle.USER_OWNER) { 11040 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11041 for (int i=0; i<ris.size(); i++) { 11042 ActivityInfo ai = ris.get(i).activityInfo; 11043 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11044 if (lastDoneReceivers.contains(comp)) { 11045 // We already did the pre boot receiver for this app with the current 11046 // platform version, so don't do it again... 11047 ris.remove(i); 11048 i--; 11049 // ...however, do keep it as one that has been done, so we don't 11050 // forget about it when rewriting the file of last done receivers. 11051 doneReceivers.add(comp); 11052 } 11053 } 11054 } 11055 11056 // If primary user, send broadcast to all available users, else just to userId 11057 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11058 : new int[] { userId }; 11059 for (int i = 0; i < ris.size(); i++) { 11060 ActivityInfo ai = ris.get(i).activityInfo; 11061 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11062 doneReceivers.add(comp); 11063 intent.setComponent(comp); 11064 for (int j=0; j<users.length; j++) { 11065 IIntentReceiver finisher = null; 11066 // On last receiver and user, set up a completion callback 11067 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11068 finisher = new IIntentReceiver.Stub() { 11069 public void performReceive(Intent intent, int resultCode, 11070 String data, Bundle extras, boolean ordered, 11071 boolean sticky, int sendingUser) { 11072 // The raw IIntentReceiver interface is called 11073 // with the AM lock held, so redispatch to 11074 // execute our code without the lock. 11075 mHandler.post(onFinishCallback); 11076 } 11077 }; 11078 } 11079 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11080 + " for user " + users[j]); 11081 broadcastIntentLocked(null, null, intent, null, finisher, 11082 0, null, null, null, AppOpsManager.OP_NONE, 11083 true, false, MY_PID, Process.SYSTEM_UID, 11084 users[j]); 11085 if (finisher != null) { 11086 waitingUpdate = true; 11087 } 11088 } 11089 } 11090 } 11091 11092 return waitingUpdate; 11093 } 11094 11095 public void systemReady(final Runnable goingCallback) { 11096 synchronized(this) { 11097 if (mSystemReady) { 11098 // If we're done calling all the receivers, run the next "boot phase" passed in 11099 // by the SystemServer 11100 if (goingCallback != null) { 11101 goingCallback.run(); 11102 } 11103 return; 11104 } 11105 11106 // Make sure we have the current profile info, since it is needed for 11107 // security checks. 11108 updateCurrentProfileIdsLocked(); 11109 11110 if (mRecentTasks == null) { 11111 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11112 if (!mRecentTasks.isEmpty()) { 11113 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11114 } 11115 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11116 mTaskPersister.startPersisting(); 11117 } 11118 11119 // Check to see if there are any update receivers to run. 11120 if (!mDidUpdate) { 11121 if (mWaitingUpdate) { 11122 return; 11123 } 11124 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11125 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11126 public void run() { 11127 synchronized (ActivityManagerService.this) { 11128 mDidUpdate = true; 11129 } 11130 writeLastDonePreBootReceivers(doneReceivers); 11131 showBootMessage(mContext.getText( 11132 R.string.android_upgrading_complete), 11133 false); 11134 systemReady(goingCallback); 11135 } 11136 }, doneReceivers, UserHandle.USER_OWNER); 11137 11138 if (mWaitingUpdate) { 11139 return; 11140 } 11141 mDidUpdate = true; 11142 } 11143 11144 mAppOpsService.systemReady(); 11145 mSystemReady = true; 11146 } 11147 11148 ArrayList<ProcessRecord> procsToKill = null; 11149 synchronized(mPidsSelfLocked) { 11150 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11151 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11152 if (!isAllowedWhileBooting(proc.info)){ 11153 if (procsToKill == null) { 11154 procsToKill = new ArrayList<ProcessRecord>(); 11155 } 11156 procsToKill.add(proc); 11157 } 11158 } 11159 } 11160 11161 synchronized(this) { 11162 if (procsToKill != null) { 11163 for (int i=procsToKill.size()-1; i>=0; i--) { 11164 ProcessRecord proc = procsToKill.get(i); 11165 Slog.i(TAG, "Removing system update proc: " + proc); 11166 removeProcessLocked(proc, true, false, "system update done"); 11167 } 11168 } 11169 11170 // Now that we have cleaned up any update processes, we 11171 // are ready to start launching real processes and know that 11172 // we won't trample on them any more. 11173 mProcessesReady = true; 11174 } 11175 11176 Slog.i(TAG, "System now ready"); 11177 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11178 SystemClock.uptimeMillis()); 11179 11180 synchronized(this) { 11181 // Make sure we have no pre-ready processes sitting around. 11182 11183 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11184 ResolveInfo ri = mContext.getPackageManager() 11185 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11186 STOCK_PM_FLAGS); 11187 CharSequence errorMsg = null; 11188 if (ri != null) { 11189 ActivityInfo ai = ri.activityInfo; 11190 ApplicationInfo app = ai.applicationInfo; 11191 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11192 mTopAction = Intent.ACTION_FACTORY_TEST; 11193 mTopData = null; 11194 mTopComponent = new ComponentName(app.packageName, 11195 ai.name); 11196 } else { 11197 errorMsg = mContext.getResources().getText( 11198 com.android.internal.R.string.factorytest_not_system); 11199 } 11200 } else { 11201 errorMsg = mContext.getResources().getText( 11202 com.android.internal.R.string.factorytest_no_action); 11203 } 11204 if (errorMsg != null) { 11205 mTopAction = null; 11206 mTopData = null; 11207 mTopComponent = null; 11208 Message msg = Message.obtain(); 11209 msg.what = SHOW_FACTORY_ERROR_MSG; 11210 msg.getData().putCharSequence("msg", errorMsg); 11211 mHandler.sendMessage(msg); 11212 } 11213 } 11214 } 11215 11216 retrieveSettings(); 11217 loadResourcesOnSystemReady(); 11218 11219 synchronized (this) { 11220 readGrantedUriPermissionsLocked(); 11221 } 11222 11223 if (goingCallback != null) goingCallback.run(); 11224 11225 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11226 Integer.toString(mCurrentUserId), mCurrentUserId); 11227 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11228 Integer.toString(mCurrentUserId), mCurrentUserId); 11229 mSystemServiceManager.startUser(mCurrentUserId); 11230 11231 synchronized (this) { 11232 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11233 try { 11234 List apps = AppGlobals.getPackageManager(). 11235 getPersistentApplications(STOCK_PM_FLAGS); 11236 if (apps != null) { 11237 int N = apps.size(); 11238 int i; 11239 for (i=0; i<N; i++) { 11240 ApplicationInfo info 11241 = (ApplicationInfo)apps.get(i); 11242 if (info != null && 11243 !info.packageName.equals("android")) { 11244 addAppLocked(info, false, null /* ABI override */); 11245 } 11246 } 11247 } 11248 } catch (RemoteException ex) { 11249 // pm is in same process, this will never happen. 11250 } 11251 } 11252 11253 // Start up initial activity. 11254 mBooting = true; 11255 11256 try { 11257 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11258 Message msg = Message.obtain(); 11259 msg.what = SHOW_UID_ERROR_MSG; 11260 mHandler.sendMessage(msg); 11261 } 11262 } catch (RemoteException e) { 11263 } 11264 11265 long ident = Binder.clearCallingIdentity(); 11266 try { 11267 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11268 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11269 | Intent.FLAG_RECEIVER_FOREGROUND); 11270 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11271 broadcastIntentLocked(null, null, intent, 11272 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11273 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11274 intent = new Intent(Intent.ACTION_USER_STARTING); 11275 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11276 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11277 broadcastIntentLocked(null, null, intent, 11278 null, new IIntentReceiver.Stub() { 11279 @Override 11280 public void performReceive(Intent intent, int resultCode, String data, 11281 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11282 throws RemoteException { 11283 } 11284 }, 0, null, null, 11285 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11286 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11287 } catch (Throwable t) { 11288 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11289 } finally { 11290 Binder.restoreCallingIdentity(ident); 11291 } 11292 mStackSupervisor.resumeTopActivitiesLocked(); 11293 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11294 } 11295 } 11296 11297 private boolean makeAppCrashingLocked(ProcessRecord app, 11298 String shortMsg, String longMsg, String stackTrace) { 11299 app.crashing = true; 11300 app.crashingReport = generateProcessError(app, 11301 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11302 startAppProblemLocked(app); 11303 app.stopFreezingAllLocked(); 11304 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11305 } 11306 11307 private void makeAppNotRespondingLocked(ProcessRecord app, 11308 String activity, String shortMsg, String longMsg) { 11309 app.notResponding = true; 11310 app.notRespondingReport = generateProcessError(app, 11311 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11312 activity, shortMsg, longMsg, null); 11313 startAppProblemLocked(app); 11314 app.stopFreezingAllLocked(); 11315 } 11316 11317 /** 11318 * Generate a process error record, suitable for attachment to a ProcessRecord. 11319 * 11320 * @param app The ProcessRecord in which the error occurred. 11321 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11322 * ActivityManager.AppErrorStateInfo 11323 * @param activity The activity associated with the crash, if known. 11324 * @param shortMsg Short message describing the crash. 11325 * @param longMsg Long message describing the crash. 11326 * @param stackTrace Full crash stack trace, may be null. 11327 * 11328 * @return Returns a fully-formed AppErrorStateInfo record. 11329 */ 11330 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11331 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11332 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11333 11334 report.condition = condition; 11335 report.processName = app.processName; 11336 report.pid = app.pid; 11337 report.uid = app.info.uid; 11338 report.tag = activity; 11339 report.shortMsg = shortMsg; 11340 report.longMsg = longMsg; 11341 report.stackTrace = stackTrace; 11342 11343 return report; 11344 } 11345 11346 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11347 synchronized (this) { 11348 app.crashing = false; 11349 app.crashingReport = null; 11350 app.notResponding = false; 11351 app.notRespondingReport = null; 11352 if (app.anrDialog == fromDialog) { 11353 app.anrDialog = null; 11354 } 11355 if (app.waitDialog == fromDialog) { 11356 app.waitDialog = null; 11357 } 11358 if (app.pid > 0 && app.pid != MY_PID) { 11359 handleAppCrashLocked(app, null, null, null); 11360 app.kill("user request after error", true); 11361 } 11362 } 11363 } 11364 11365 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11366 String stackTrace) { 11367 long now = SystemClock.uptimeMillis(); 11368 11369 Long crashTime; 11370 if (!app.isolated) { 11371 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11372 } else { 11373 crashTime = null; 11374 } 11375 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11376 // This process loses! 11377 Slog.w(TAG, "Process " + app.info.processName 11378 + " has crashed too many times: killing!"); 11379 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11380 app.userId, app.info.processName, app.uid); 11381 mStackSupervisor.handleAppCrashLocked(app); 11382 if (!app.persistent) { 11383 // We don't want to start this process again until the user 11384 // explicitly does so... but for persistent process, we really 11385 // need to keep it running. If a persistent process is actually 11386 // repeatedly crashing, then badness for everyone. 11387 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11388 app.info.processName); 11389 if (!app.isolated) { 11390 // XXX We don't have a way to mark isolated processes 11391 // as bad, since they don't have a peristent identity. 11392 mBadProcesses.put(app.info.processName, app.uid, 11393 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11394 mProcessCrashTimes.remove(app.info.processName, app.uid); 11395 } 11396 app.bad = true; 11397 app.removed = true; 11398 // Don't let services in this process be restarted and potentially 11399 // annoy the user repeatedly. Unless it is persistent, since those 11400 // processes run critical code. 11401 removeProcessLocked(app, false, false, "crash"); 11402 mStackSupervisor.resumeTopActivitiesLocked(); 11403 return false; 11404 } 11405 mStackSupervisor.resumeTopActivitiesLocked(); 11406 } else { 11407 mStackSupervisor.finishTopRunningActivityLocked(app); 11408 } 11409 11410 // Bump up the crash count of any services currently running in the proc. 11411 for (int i=app.services.size()-1; i>=0; i--) { 11412 // Any services running in the application need to be placed 11413 // back in the pending list. 11414 ServiceRecord sr = app.services.valueAt(i); 11415 sr.crashCount++; 11416 } 11417 11418 // If the crashing process is what we consider to be the "home process" and it has been 11419 // replaced by a third-party app, clear the package preferred activities from packages 11420 // with a home activity running in the process to prevent a repeatedly crashing app 11421 // from blocking the user to manually clear the list. 11422 final ArrayList<ActivityRecord> activities = app.activities; 11423 if (app == mHomeProcess && activities.size() > 0 11424 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11425 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11426 final ActivityRecord r = activities.get(activityNdx); 11427 if (r.isHomeActivity()) { 11428 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11429 try { 11430 ActivityThread.getPackageManager() 11431 .clearPackagePreferredActivities(r.packageName); 11432 } catch (RemoteException c) { 11433 // pm is in same process, this will never happen. 11434 } 11435 } 11436 } 11437 } 11438 11439 if (!app.isolated) { 11440 // XXX Can't keep track of crash times for isolated processes, 11441 // because they don't have a perisistent identity. 11442 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11443 } 11444 11445 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11446 return true; 11447 } 11448 11449 void startAppProblemLocked(ProcessRecord app) { 11450 // If this app is not running under the current user, then we 11451 // can't give it a report button because that would require 11452 // launching the report UI under a different user. 11453 app.errorReportReceiver = null; 11454 11455 for (int userId : mCurrentProfileIds) { 11456 if (app.userId == userId) { 11457 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11458 mContext, app.info.packageName, app.info.flags); 11459 } 11460 } 11461 skipCurrentReceiverLocked(app); 11462 } 11463 11464 void skipCurrentReceiverLocked(ProcessRecord app) { 11465 for (BroadcastQueue queue : mBroadcastQueues) { 11466 queue.skipCurrentReceiverLocked(app); 11467 } 11468 } 11469 11470 /** 11471 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11472 * The application process will exit immediately after this call returns. 11473 * @param app object of the crashing app, null for the system server 11474 * @param crashInfo describing the exception 11475 */ 11476 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11477 ProcessRecord r = findAppProcess(app, "Crash"); 11478 final String processName = app == null ? "system_server" 11479 : (r == null ? "unknown" : r.processName); 11480 11481 handleApplicationCrashInner("crash", r, processName, crashInfo); 11482 } 11483 11484 /* Native crash reporting uses this inner version because it needs to be somewhat 11485 * decoupled from the AM-managed cleanup lifecycle 11486 */ 11487 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11488 ApplicationErrorReport.CrashInfo crashInfo) { 11489 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11490 UserHandle.getUserId(Binder.getCallingUid()), processName, 11491 r == null ? -1 : r.info.flags, 11492 crashInfo.exceptionClassName, 11493 crashInfo.exceptionMessage, 11494 crashInfo.throwFileName, 11495 crashInfo.throwLineNumber); 11496 11497 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11498 11499 crashApplication(r, crashInfo); 11500 } 11501 11502 public void handleApplicationStrictModeViolation( 11503 IBinder app, 11504 int violationMask, 11505 StrictMode.ViolationInfo info) { 11506 ProcessRecord r = findAppProcess(app, "StrictMode"); 11507 if (r == null) { 11508 return; 11509 } 11510 11511 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11512 Integer stackFingerprint = info.hashCode(); 11513 boolean logIt = true; 11514 synchronized (mAlreadyLoggedViolatedStacks) { 11515 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11516 logIt = false; 11517 // TODO: sub-sample into EventLog for these, with 11518 // the info.durationMillis? Then we'd get 11519 // the relative pain numbers, without logging all 11520 // the stack traces repeatedly. We'd want to do 11521 // likewise in the client code, which also does 11522 // dup suppression, before the Binder call. 11523 } else { 11524 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11525 mAlreadyLoggedViolatedStacks.clear(); 11526 } 11527 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11528 } 11529 } 11530 if (logIt) { 11531 logStrictModeViolationToDropBox(r, info); 11532 } 11533 } 11534 11535 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11536 AppErrorResult result = new AppErrorResult(); 11537 synchronized (this) { 11538 final long origId = Binder.clearCallingIdentity(); 11539 11540 Message msg = Message.obtain(); 11541 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11542 HashMap<String, Object> data = new HashMap<String, Object>(); 11543 data.put("result", result); 11544 data.put("app", r); 11545 data.put("violationMask", violationMask); 11546 data.put("info", info); 11547 msg.obj = data; 11548 mHandler.sendMessage(msg); 11549 11550 Binder.restoreCallingIdentity(origId); 11551 } 11552 int res = result.get(); 11553 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11554 } 11555 } 11556 11557 // Depending on the policy in effect, there could be a bunch of 11558 // these in quick succession so we try to batch these together to 11559 // minimize disk writes, number of dropbox entries, and maximize 11560 // compression, by having more fewer, larger records. 11561 private void logStrictModeViolationToDropBox( 11562 ProcessRecord process, 11563 StrictMode.ViolationInfo info) { 11564 if (info == null) { 11565 return; 11566 } 11567 final boolean isSystemApp = process == null || 11568 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11569 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11570 final String processName = process == null ? "unknown" : process.processName; 11571 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11572 final DropBoxManager dbox = (DropBoxManager) 11573 mContext.getSystemService(Context.DROPBOX_SERVICE); 11574 11575 // Exit early if the dropbox isn't configured to accept this report type. 11576 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11577 11578 boolean bufferWasEmpty; 11579 boolean needsFlush; 11580 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11581 synchronized (sb) { 11582 bufferWasEmpty = sb.length() == 0; 11583 appendDropBoxProcessHeaders(process, processName, sb); 11584 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11585 sb.append("System-App: ").append(isSystemApp).append("\n"); 11586 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11587 if (info.violationNumThisLoop != 0) { 11588 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11589 } 11590 if (info.numAnimationsRunning != 0) { 11591 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11592 } 11593 if (info.broadcastIntentAction != null) { 11594 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11595 } 11596 if (info.durationMillis != -1) { 11597 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11598 } 11599 if (info.numInstances != -1) { 11600 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11601 } 11602 if (info.tags != null) { 11603 for (String tag : info.tags) { 11604 sb.append("Span-Tag: ").append(tag).append("\n"); 11605 } 11606 } 11607 sb.append("\n"); 11608 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11609 sb.append(info.crashInfo.stackTrace); 11610 } 11611 sb.append("\n"); 11612 11613 // Only buffer up to ~64k. Various logging bits truncate 11614 // things at 128k. 11615 needsFlush = (sb.length() > 64 * 1024); 11616 } 11617 11618 // Flush immediately if the buffer's grown too large, or this 11619 // is a non-system app. Non-system apps are isolated with a 11620 // different tag & policy and not batched. 11621 // 11622 // Batching is useful during internal testing with 11623 // StrictMode settings turned up high. Without batching, 11624 // thousands of separate files could be created on boot. 11625 if (!isSystemApp || needsFlush) { 11626 new Thread("Error dump: " + dropboxTag) { 11627 @Override 11628 public void run() { 11629 String report; 11630 synchronized (sb) { 11631 report = sb.toString(); 11632 sb.delete(0, sb.length()); 11633 sb.trimToSize(); 11634 } 11635 if (report.length() != 0) { 11636 dbox.addText(dropboxTag, report); 11637 } 11638 } 11639 }.start(); 11640 return; 11641 } 11642 11643 // System app batching: 11644 if (!bufferWasEmpty) { 11645 // An existing dropbox-writing thread is outstanding, so 11646 // we don't need to start it up. The existing thread will 11647 // catch the buffer appends we just did. 11648 return; 11649 } 11650 11651 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11652 // (After this point, we shouldn't access AMS internal data structures.) 11653 new Thread("Error dump: " + dropboxTag) { 11654 @Override 11655 public void run() { 11656 // 5 second sleep to let stacks arrive and be batched together 11657 try { 11658 Thread.sleep(5000); // 5 seconds 11659 } catch (InterruptedException e) {} 11660 11661 String errorReport; 11662 synchronized (mStrictModeBuffer) { 11663 errorReport = mStrictModeBuffer.toString(); 11664 if (errorReport.length() == 0) { 11665 return; 11666 } 11667 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11668 mStrictModeBuffer.trimToSize(); 11669 } 11670 dbox.addText(dropboxTag, errorReport); 11671 } 11672 }.start(); 11673 } 11674 11675 /** 11676 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11677 * @param app object of the crashing app, null for the system server 11678 * @param tag reported by the caller 11679 * @param system whether this wtf is coming from the system 11680 * @param crashInfo describing the context of the error 11681 * @return true if the process should exit immediately (WTF is fatal) 11682 */ 11683 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11684 final ApplicationErrorReport.CrashInfo crashInfo) { 11685 final ProcessRecord r = findAppProcess(app, "WTF"); 11686 final String processName = app == null ? "system_server" 11687 : (r == null ? "unknown" : r.processName); 11688 11689 EventLog.writeEvent(EventLogTags.AM_WTF, 11690 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11691 processName, 11692 r == null ? -1 : r.info.flags, 11693 tag, crashInfo.exceptionMessage); 11694 11695 if (system) { 11696 // If this is coming from the system, we could very well have low-level 11697 // system locks held, so we want to do this all asynchronously. And we 11698 // never want this to become fatal, so there is that too. 11699 mHandler.post(new Runnable() { 11700 @Override public void run() { 11701 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11702 crashInfo); 11703 } 11704 }); 11705 return false; 11706 } 11707 11708 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11709 11710 if (r != null && r.pid != Process.myPid() && 11711 Settings.Global.getInt(mContext.getContentResolver(), 11712 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11713 crashApplication(r, crashInfo); 11714 return true; 11715 } else { 11716 return false; 11717 } 11718 } 11719 11720 /** 11721 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11722 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11723 */ 11724 private ProcessRecord findAppProcess(IBinder app, String reason) { 11725 if (app == null) { 11726 return null; 11727 } 11728 11729 synchronized (this) { 11730 final int NP = mProcessNames.getMap().size(); 11731 for (int ip=0; ip<NP; ip++) { 11732 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11733 final int NA = apps.size(); 11734 for (int ia=0; ia<NA; ia++) { 11735 ProcessRecord p = apps.valueAt(ia); 11736 if (p.thread != null && p.thread.asBinder() == app) { 11737 return p; 11738 } 11739 } 11740 } 11741 11742 Slog.w(TAG, "Can't find mystery application for " + reason 11743 + " from pid=" + Binder.getCallingPid() 11744 + " uid=" + Binder.getCallingUid() + ": " + app); 11745 return null; 11746 } 11747 } 11748 11749 /** 11750 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11751 * to append various headers to the dropbox log text. 11752 */ 11753 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11754 StringBuilder sb) { 11755 // Watchdog thread ends up invoking this function (with 11756 // a null ProcessRecord) to add the stack file to dropbox. 11757 // Do not acquire a lock on this (am) in such cases, as it 11758 // could cause a potential deadlock, if and when watchdog 11759 // is invoked due to unavailability of lock on am and it 11760 // would prevent watchdog from killing system_server. 11761 if (process == null) { 11762 sb.append("Process: ").append(processName).append("\n"); 11763 return; 11764 } 11765 // Note: ProcessRecord 'process' is guarded by the service 11766 // instance. (notably process.pkgList, which could otherwise change 11767 // concurrently during execution of this method) 11768 synchronized (this) { 11769 sb.append("Process: ").append(processName).append("\n"); 11770 int flags = process.info.flags; 11771 IPackageManager pm = AppGlobals.getPackageManager(); 11772 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11773 for (int ip=0; ip<process.pkgList.size(); ip++) { 11774 String pkg = process.pkgList.keyAt(ip); 11775 sb.append("Package: ").append(pkg); 11776 try { 11777 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11778 if (pi != null) { 11779 sb.append(" v").append(pi.versionCode); 11780 if (pi.versionName != null) { 11781 sb.append(" (").append(pi.versionName).append(")"); 11782 } 11783 } 11784 } catch (RemoteException e) { 11785 Slog.e(TAG, "Error getting package info: " + pkg, e); 11786 } 11787 sb.append("\n"); 11788 } 11789 } 11790 } 11791 11792 private static String processClass(ProcessRecord process) { 11793 if (process == null || process.pid == MY_PID) { 11794 return "system_server"; 11795 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11796 return "system_app"; 11797 } else { 11798 return "data_app"; 11799 } 11800 } 11801 11802 /** 11803 * Write a description of an error (crash, WTF, ANR) to the drop box. 11804 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11805 * @param process which caused the error, null means the system server 11806 * @param activity which triggered the error, null if unknown 11807 * @param parent activity related to the error, null if unknown 11808 * @param subject line related to the error, null if absent 11809 * @param report in long form describing the error, null if absent 11810 * @param logFile to include in the report, null if none 11811 * @param crashInfo giving an application stack trace, null if absent 11812 */ 11813 public void addErrorToDropBox(String eventType, 11814 ProcessRecord process, String processName, ActivityRecord activity, 11815 ActivityRecord parent, String subject, 11816 final String report, final File logFile, 11817 final ApplicationErrorReport.CrashInfo crashInfo) { 11818 // NOTE -- this must never acquire the ActivityManagerService lock, 11819 // otherwise the watchdog may be prevented from resetting the system. 11820 11821 final String dropboxTag = processClass(process) + "_" + eventType; 11822 final DropBoxManager dbox = (DropBoxManager) 11823 mContext.getSystemService(Context.DROPBOX_SERVICE); 11824 11825 // Exit early if the dropbox isn't configured to accept this report type. 11826 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11827 11828 final StringBuilder sb = new StringBuilder(1024); 11829 appendDropBoxProcessHeaders(process, processName, sb); 11830 if (activity != null) { 11831 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11832 } 11833 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11834 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11835 } 11836 if (parent != null && parent != activity) { 11837 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11838 } 11839 if (subject != null) { 11840 sb.append("Subject: ").append(subject).append("\n"); 11841 } 11842 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11843 if (Debug.isDebuggerConnected()) { 11844 sb.append("Debugger: Connected\n"); 11845 } 11846 sb.append("\n"); 11847 11848 // Do the rest in a worker thread to avoid blocking the caller on I/O 11849 // (After this point, we shouldn't access AMS internal data structures.) 11850 Thread worker = new Thread("Error dump: " + dropboxTag) { 11851 @Override 11852 public void run() { 11853 if (report != null) { 11854 sb.append(report); 11855 } 11856 if (logFile != null) { 11857 try { 11858 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11859 "\n\n[[TRUNCATED]]")); 11860 } catch (IOException e) { 11861 Slog.e(TAG, "Error reading " + logFile, e); 11862 } 11863 } 11864 if (crashInfo != null && crashInfo.stackTrace != null) { 11865 sb.append(crashInfo.stackTrace); 11866 } 11867 11868 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11869 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11870 if (lines > 0) { 11871 sb.append("\n"); 11872 11873 // Merge several logcat streams, and take the last N lines 11874 InputStreamReader input = null; 11875 try { 11876 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11877 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11878 "-b", "crash", 11879 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11880 11881 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11882 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11883 input = new InputStreamReader(logcat.getInputStream()); 11884 11885 int num; 11886 char[] buf = new char[8192]; 11887 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11888 } catch (IOException e) { 11889 Slog.e(TAG, "Error running logcat", e); 11890 } finally { 11891 if (input != null) try { input.close(); } catch (IOException e) {} 11892 } 11893 } 11894 11895 dbox.addText(dropboxTag, sb.toString()); 11896 } 11897 }; 11898 11899 if (process == null) { 11900 // If process is null, we are being called from some internal code 11901 // and may be about to die -- run this synchronously. 11902 worker.run(); 11903 } else { 11904 worker.start(); 11905 } 11906 } 11907 11908 /** 11909 * Bring up the "unexpected error" dialog box for a crashing app. 11910 * Deal with edge cases (intercepts from instrumented applications, 11911 * ActivityController, error intent receivers, that sort of thing). 11912 * @param r the application crashing 11913 * @param crashInfo describing the failure 11914 */ 11915 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11916 long timeMillis = System.currentTimeMillis(); 11917 String shortMsg = crashInfo.exceptionClassName; 11918 String longMsg = crashInfo.exceptionMessage; 11919 String stackTrace = crashInfo.stackTrace; 11920 if (shortMsg != null && longMsg != null) { 11921 longMsg = shortMsg + ": " + longMsg; 11922 } else if (shortMsg != null) { 11923 longMsg = shortMsg; 11924 } 11925 11926 AppErrorResult result = new AppErrorResult(); 11927 synchronized (this) { 11928 if (mController != null) { 11929 try { 11930 String name = r != null ? r.processName : null; 11931 int pid = r != null ? r.pid : Binder.getCallingPid(); 11932 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11933 if (!mController.appCrashed(name, pid, 11934 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11935 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11936 && "Native crash".equals(crashInfo.exceptionClassName)) { 11937 Slog.w(TAG, "Skip killing native crashed app " + name 11938 + "(" + pid + ") during testing"); 11939 } else { 11940 Slog.w(TAG, "Force-killing crashed app " + name 11941 + " at watcher's request"); 11942 if (r != null) { 11943 r.kill("crash", true); 11944 } else { 11945 // Huh. 11946 Process.killProcess(pid); 11947 Process.killProcessGroup(uid, pid); 11948 } 11949 } 11950 return; 11951 } 11952 } catch (RemoteException e) { 11953 mController = null; 11954 Watchdog.getInstance().setActivityController(null); 11955 } 11956 } 11957 11958 final long origId = Binder.clearCallingIdentity(); 11959 11960 // If this process is running instrumentation, finish it. 11961 if (r != null && r.instrumentationClass != null) { 11962 Slog.w(TAG, "Error in app " + r.processName 11963 + " running instrumentation " + r.instrumentationClass + ":"); 11964 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11965 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11966 Bundle info = new Bundle(); 11967 info.putString("shortMsg", shortMsg); 11968 info.putString("longMsg", longMsg); 11969 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11970 Binder.restoreCallingIdentity(origId); 11971 return; 11972 } 11973 11974 // If we can't identify the process or it's already exceeded its crash quota, 11975 // quit right away without showing a crash dialog. 11976 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11977 Binder.restoreCallingIdentity(origId); 11978 return; 11979 } 11980 11981 Message msg = Message.obtain(); 11982 msg.what = SHOW_ERROR_MSG; 11983 HashMap data = new HashMap(); 11984 data.put("result", result); 11985 data.put("app", r); 11986 msg.obj = data; 11987 mHandler.sendMessage(msg); 11988 11989 Binder.restoreCallingIdentity(origId); 11990 } 11991 11992 int res = result.get(); 11993 11994 Intent appErrorIntent = null; 11995 synchronized (this) { 11996 if (r != null && !r.isolated) { 11997 // XXX Can't keep track of crash time for isolated processes, 11998 // since they don't have a persistent identity. 11999 mProcessCrashTimes.put(r.info.processName, r.uid, 12000 SystemClock.uptimeMillis()); 12001 } 12002 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12003 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12004 } 12005 } 12006 12007 if (appErrorIntent != null) { 12008 try { 12009 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12010 } catch (ActivityNotFoundException e) { 12011 Slog.w(TAG, "bug report receiver dissappeared", e); 12012 } 12013 } 12014 } 12015 12016 Intent createAppErrorIntentLocked(ProcessRecord r, 12017 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12018 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12019 if (report == null) { 12020 return null; 12021 } 12022 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12023 result.setComponent(r.errorReportReceiver); 12024 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12025 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12026 return result; 12027 } 12028 12029 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12030 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12031 if (r.errorReportReceiver == null) { 12032 return null; 12033 } 12034 12035 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12036 return null; 12037 } 12038 12039 ApplicationErrorReport report = new ApplicationErrorReport(); 12040 report.packageName = r.info.packageName; 12041 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12042 report.processName = r.processName; 12043 report.time = timeMillis; 12044 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12045 12046 if (r.crashing || r.forceCrashReport) { 12047 report.type = ApplicationErrorReport.TYPE_CRASH; 12048 report.crashInfo = crashInfo; 12049 } else if (r.notResponding) { 12050 report.type = ApplicationErrorReport.TYPE_ANR; 12051 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12052 12053 report.anrInfo.activity = r.notRespondingReport.tag; 12054 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12055 report.anrInfo.info = r.notRespondingReport.longMsg; 12056 } 12057 12058 return report; 12059 } 12060 12061 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12062 enforceNotIsolatedCaller("getProcessesInErrorState"); 12063 // assume our apps are happy - lazy create the list 12064 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12065 12066 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12067 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12068 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12069 12070 synchronized (this) { 12071 12072 // iterate across all processes 12073 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12074 ProcessRecord app = mLruProcesses.get(i); 12075 if (!allUsers && app.userId != userId) { 12076 continue; 12077 } 12078 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12079 // This one's in trouble, so we'll generate a report for it 12080 // crashes are higher priority (in case there's a crash *and* an anr) 12081 ActivityManager.ProcessErrorStateInfo report = null; 12082 if (app.crashing) { 12083 report = app.crashingReport; 12084 } else if (app.notResponding) { 12085 report = app.notRespondingReport; 12086 } 12087 12088 if (report != null) { 12089 if (errList == null) { 12090 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12091 } 12092 errList.add(report); 12093 } else { 12094 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12095 " crashing = " + app.crashing + 12096 " notResponding = " + app.notResponding); 12097 } 12098 } 12099 } 12100 } 12101 12102 return errList; 12103 } 12104 12105 static int procStateToImportance(int procState, int memAdj, 12106 ActivityManager.RunningAppProcessInfo currApp) { 12107 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12108 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12109 currApp.lru = memAdj; 12110 } else { 12111 currApp.lru = 0; 12112 } 12113 return imp; 12114 } 12115 12116 private void fillInProcMemInfo(ProcessRecord app, 12117 ActivityManager.RunningAppProcessInfo outInfo) { 12118 outInfo.pid = app.pid; 12119 outInfo.uid = app.info.uid; 12120 if (mHeavyWeightProcess == app) { 12121 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12122 } 12123 if (app.persistent) { 12124 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12125 } 12126 if (app.activities.size() > 0) { 12127 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12128 } 12129 outInfo.lastTrimLevel = app.trimMemoryLevel; 12130 int adj = app.curAdj; 12131 int procState = app.curProcState; 12132 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12133 outInfo.importanceReasonCode = app.adjTypeCode; 12134 outInfo.processState = app.curProcState; 12135 } 12136 12137 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12138 enforceNotIsolatedCaller("getRunningAppProcesses"); 12139 // Lazy instantiation of list 12140 List<ActivityManager.RunningAppProcessInfo> runList = null; 12141 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12142 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12143 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12144 synchronized (this) { 12145 // Iterate across all processes 12146 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12147 ProcessRecord app = mLruProcesses.get(i); 12148 if (!allUsers && app.userId != userId) { 12149 continue; 12150 } 12151 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12152 // Generate process state info for running application 12153 ActivityManager.RunningAppProcessInfo currApp = 12154 new ActivityManager.RunningAppProcessInfo(app.processName, 12155 app.pid, app.getPackageList()); 12156 fillInProcMemInfo(app, currApp); 12157 if (app.adjSource instanceof ProcessRecord) { 12158 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12159 currApp.importanceReasonImportance = 12160 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12161 app.adjSourceProcState); 12162 } else if (app.adjSource instanceof ActivityRecord) { 12163 ActivityRecord r = (ActivityRecord)app.adjSource; 12164 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12165 } 12166 if (app.adjTarget instanceof ComponentName) { 12167 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12168 } 12169 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12170 // + " lru=" + currApp.lru); 12171 if (runList == null) { 12172 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12173 } 12174 runList.add(currApp); 12175 } 12176 } 12177 } 12178 return runList; 12179 } 12180 12181 public List<ApplicationInfo> getRunningExternalApplications() { 12182 enforceNotIsolatedCaller("getRunningExternalApplications"); 12183 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12184 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12185 if (runningApps != null && runningApps.size() > 0) { 12186 Set<String> extList = new HashSet<String>(); 12187 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12188 if (app.pkgList != null) { 12189 for (String pkg : app.pkgList) { 12190 extList.add(pkg); 12191 } 12192 } 12193 } 12194 IPackageManager pm = AppGlobals.getPackageManager(); 12195 for (String pkg : extList) { 12196 try { 12197 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12198 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12199 retList.add(info); 12200 } 12201 } catch (RemoteException e) { 12202 } 12203 } 12204 } 12205 return retList; 12206 } 12207 12208 @Override 12209 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12210 enforceNotIsolatedCaller("getMyMemoryState"); 12211 synchronized (this) { 12212 ProcessRecord proc; 12213 synchronized (mPidsSelfLocked) { 12214 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12215 } 12216 fillInProcMemInfo(proc, outInfo); 12217 } 12218 } 12219 12220 @Override 12221 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12222 if (checkCallingPermission(android.Manifest.permission.DUMP) 12223 != PackageManager.PERMISSION_GRANTED) { 12224 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12225 + Binder.getCallingPid() 12226 + ", uid=" + Binder.getCallingUid() 12227 + " without permission " 12228 + android.Manifest.permission.DUMP); 12229 return; 12230 } 12231 12232 boolean dumpAll = false; 12233 boolean dumpClient = false; 12234 String dumpPackage = null; 12235 12236 int opti = 0; 12237 while (opti < args.length) { 12238 String opt = args[opti]; 12239 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12240 break; 12241 } 12242 opti++; 12243 if ("-a".equals(opt)) { 12244 dumpAll = true; 12245 } else if ("-c".equals(opt)) { 12246 dumpClient = true; 12247 } else if ("-h".equals(opt)) { 12248 pw.println("Activity manager dump options:"); 12249 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12250 pw.println(" cmd may be one of:"); 12251 pw.println(" a[ctivities]: activity stack state"); 12252 pw.println(" r[recents]: recent activities state"); 12253 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12254 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12255 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12256 pw.println(" o[om]: out of memory management"); 12257 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12258 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12259 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12260 pw.println(" service [COMP_SPEC]: service client-side state"); 12261 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12262 pw.println(" all: dump all activities"); 12263 pw.println(" top: dump the top activity"); 12264 pw.println(" write: write all pending state to storage"); 12265 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12266 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12267 pw.println(" a partial substring in a component name, a"); 12268 pw.println(" hex object identifier."); 12269 pw.println(" -a: include all available server state."); 12270 pw.println(" -c: include client state."); 12271 return; 12272 } else { 12273 pw.println("Unknown argument: " + opt + "; use -h for help"); 12274 } 12275 } 12276 12277 long origId = Binder.clearCallingIdentity(); 12278 boolean more = false; 12279 // Is the caller requesting to dump a particular piece of data? 12280 if (opti < args.length) { 12281 String cmd = args[opti]; 12282 opti++; 12283 if ("activities".equals(cmd) || "a".equals(cmd)) { 12284 synchronized (this) { 12285 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12286 } 12287 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12288 synchronized (this) { 12289 dumpRecentsLocked(fd, pw, args, opti, true, null); 12290 } 12291 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12292 String[] newArgs; 12293 String name; 12294 if (opti >= args.length) { 12295 name = null; 12296 newArgs = EMPTY_STRING_ARRAY; 12297 } else { 12298 name = args[opti]; 12299 opti++; 12300 newArgs = new String[args.length - opti]; 12301 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12302 args.length - opti); 12303 } 12304 synchronized (this) { 12305 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12306 } 12307 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12308 String[] newArgs; 12309 String name; 12310 if (opti >= args.length) { 12311 name = null; 12312 newArgs = EMPTY_STRING_ARRAY; 12313 } else { 12314 name = args[opti]; 12315 opti++; 12316 newArgs = new String[args.length - opti]; 12317 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12318 args.length - opti); 12319 } 12320 synchronized (this) { 12321 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12322 } 12323 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12324 String[] newArgs; 12325 String name; 12326 if (opti >= args.length) { 12327 name = null; 12328 newArgs = EMPTY_STRING_ARRAY; 12329 } else { 12330 name = args[opti]; 12331 opti++; 12332 newArgs = new String[args.length - opti]; 12333 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12334 args.length - opti); 12335 } 12336 synchronized (this) { 12337 dumpProcessesLocked(fd, pw, args, opti, true, name); 12338 } 12339 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12340 synchronized (this) { 12341 dumpOomLocked(fd, pw, args, opti, true); 12342 } 12343 } else if ("provider".equals(cmd)) { 12344 String[] newArgs; 12345 String name; 12346 if (opti >= args.length) { 12347 name = null; 12348 newArgs = EMPTY_STRING_ARRAY; 12349 } else { 12350 name = args[opti]; 12351 opti++; 12352 newArgs = new String[args.length - opti]; 12353 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12354 } 12355 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12356 pw.println("No providers match: " + name); 12357 pw.println("Use -h for help."); 12358 } 12359 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12360 synchronized (this) { 12361 dumpProvidersLocked(fd, pw, args, opti, true, null); 12362 } 12363 } else if ("service".equals(cmd)) { 12364 String[] newArgs; 12365 String name; 12366 if (opti >= args.length) { 12367 name = null; 12368 newArgs = EMPTY_STRING_ARRAY; 12369 } else { 12370 name = args[opti]; 12371 opti++; 12372 newArgs = new String[args.length - opti]; 12373 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12374 args.length - opti); 12375 } 12376 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12377 pw.println("No services match: " + name); 12378 pw.println("Use -h for help."); 12379 } 12380 } else if ("package".equals(cmd)) { 12381 String[] newArgs; 12382 if (opti >= args.length) { 12383 pw.println("package: no package name specified"); 12384 pw.println("Use -h for help."); 12385 } else { 12386 dumpPackage = args[opti]; 12387 opti++; 12388 newArgs = new String[args.length - opti]; 12389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12390 args.length - opti); 12391 args = newArgs; 12392 opti = 0; 12393 more = true; 12394 } 12395 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12396 synchronized (this) { 12397 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12398 } 12399 } else if ("write".equals(cmd)) { 12400 mTaskPersister.flush(); 12401 pw.println("All tasks persisted."); 12402 return; 12403 } else { 12404 // Dumping a single activity? 12405 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12406 pw.println("Bad activity command, or no activities match: " + cmd); 12407 pw.println("Use -h for help."); 12408 } 12409 } 12410 if (!more) { 12411 Binder.restoreCallingIdentity(origId); 12412 return; 12413 } 12414 } 12415 12416 // No piece of data specified, dump everything. 12417 synchronized (this) { 12418 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12419 pw.println(); 12420 if (dumpAll) { 12421 pw.println("-------------------------------------------------------------------------------"); 12422 } 12423 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12424 pw.println(); 12425 if (dumpAll) { 12426 pw.println("-------------------------------------------------------------------------------"); 12427 } 12428 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12429 pw.println(); 12430 if (dumpAll) { 12431 pw.println("-------------------------------------------------------------------------------"); 12432 } 12433 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12434 pw.println(); 12435 if (dumpAll) { 12436 pw.println("-------------------------------------------------------------------------------"); 12437 } 12438 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12439 pw.println(); 12440 if (dumpAll) { 12441 pw.println("-------------------------------------------------------------------------------"); 12442 } 12443 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12444 pw.println(); 12445 if (dumpAll) { 12446 pw.println("-------------------------------------------------------------------------------"); 12447 } 12448 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12449 } 12450 Binder.restoreCallingIdentity(origId); 12451 } 12452 12453 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12454 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12455 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12456 12457 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12458 dumpPackage); 12459 boolean needSep = printedAnything; 12460 12461 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12462 dumpPackage, needSep, " mFocusedActivity: "); 12463 if (printed) { 12464 printedAnything = true; 12465 needSep = false; 12466 } 12467 12468 if (dumpPackage == null) { 12469 if (needSep) { 12470 pw.println(); 12471 } 12472 needSep = true; 12473 printedAnything = true; 12474 mStackSupervisor.dump(pw, " "); 12475 } 12476 12477 if (!printedAnything) { 12478 pw.println(" (nothing)"); 12479 } 12480 } 12481 12482 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12483 int opti, boolean dumpAll, String dumpPackage) { 12484 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12485 12486 boolean printedAnything = false; 12487 12488 if (mRecentTasks.size() > 0) { 12489 boolean printedHeader = false; 12490 12491 final int N = mRecentTasks.size(); 12492 for (int i=0; i<N; i++) { 12493 TaskRecord tr = mRecentTasks.get(i); 12494 if (dumpPackage != null) { 12495 if (tr.realActivity == null || 12496 !dumpPackage.equals(tr.realActivity)) { 12497 continue; 12498 } 12499 } 12500 if (!printedHeader) { 12501 pw.println(" Recent tasks:"); 12502 printedHeader = true; 12503 printedAnything = true; 12504 } 12505 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12506 pw.println(tr); 12507 if (dumpAll) { 12508 mRecentTasks.get(i).dump(pw, " "); 12509 } 12510 } 12511 } 12512 12513 if (!printedAnything) { 12514 pw.println(" (nothing)"); 12515 } 12516 } 12517 12518 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12519 int opti, boolean dumpAll, String dumpPackage) { 12520 boolean needSep = false; 12521 boolean printedAnything = false; 12522 int numPers = 0; 12523 12524 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12525 12526 if (dumpAll) { 12527 final int NP = mProcessNames.getMap().size(); 12528 for (int ip=0; ip<NP; ip++) { 12529 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12530 final int NA = procs.size(); 12531 for (int ia=0; ia<NA; ia++) { 12532 ProcessRecord r = procs.valueAt(ia); 12533 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12534 continue; 12535 } 12536 if (!needSep) { 12537 pw.println(" All known processes:"); 12538 needSep = true; 12539 printedAnything = true; 12540 } 12541 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12542 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12543 pw.print(" "); pw.println(r); 12544 r.dump(pw, " "); 12545 if (r.persistent) { 12546 numPers++; 12547 } 12548 } 12549 } 12550 } 12551 12552 if (mIsolatedProcesses.size() > 0) { 12553 boolean printed = false; 12554 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12555 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12556 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12557 continue; 12558 } 12559 if (!printed) { 12560 if (needSep) { 12561 pw.println(); 12562 } 12563 pw.println(" Isolated process list (sorted by uid):"); 12564 printedAnything = true; 12565 printed = true; 12566 needSep = true; 12567 } 12568 pw.println(String.format("%sIsolated #%2d: %s", 12569 " ", i, r.toString())); 12570 } 12571 } 12572 12573 if (mLruProcesses.size() > 0) { 12574 if (needSep) { 12575 pw.println(); 12576 } 12577 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12578 pw.print(" total, non-act at "); 12579 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12580 pw.print(", non-svc at "); 12581 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12582 pw.println("):"); 12583 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12584 needSep = true; 12585 printedAnything = true; 12586 } 12587 12588 if (dumpAll || dumpPackage != null) { 12589 synchronized (mPidsSelfLocked) { 12590 boolean printed = false; 12591 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12592 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12593 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12594 continue; 12595 } 12596 if (!printed) { 12597 if (needSep) pw.println(); 12598 needSep = true; 12599 pw.println(" PID mappings:"); 12600 printed = true; 12601 printedAnything = true; 12602 } 12603 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12604 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12605 } 12606 } 12607 } 12608 12609 if (mForegroundProcesses.size() > 0) { 12610 synchronized (mPidsSelfLocked) { 12611 boolean printed = false; 12612 for (int i=0; i<mForegroundProcesses.size(); i++) { 12613 ProcessRecord r = mPidsSelfLocked.get( 12614 mForegroundProcesses.valueAt(i).pid); 12615 if (dumpPackage != null && (r == null 12616 || !r.pkgList.containsKey(dumpPackage))) { 12617 continue; 12618 } 12619 if (!printed) { 12620 if (needSep) pw.println(); 12621 needSep = true; 12622 pw.println(" Foreground Processes:"); 12623 printed = true; 12624 printedAnything = true; 12625 } 12626 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12627 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12628 } 12629 } 12630 } 12631 12632 if (mPersistentStartingProcesses.size() > 0) { 12633 if (needSep) pw.println(); 12634 needSep = true; 12635 printedAnything = true; 12636 pw.println(" Persisent processes that are starting:"); 12637 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12638 "Starting Norm", "Restarting PERS", dumpPackage); 12639 } 12640 12641 if (mRemovedProcesses.size() > 0) { 12642 if (needSep) pw.println(); 12643 needSep = true; 12644 printedAnything = true; 12645 pw.println(" Processes that are being removed:"); 12646 dumpProcessList(pw, this, mRemovedProcesses, " ", 12647 "Removed Norm", "Removed PERS", dumpPackage); 12648 } 12649 12650 if (mProcessesOnHold.size() > 0) { 12651 if (needSep) pw.println(); 12652 needSep = true; 12653 printedAnything = true; 12654 pw.println(" Processes that are on old until the system is ready:"); 12655 dumpProcessList(pw, this, mProcessesOnHold, " ", 12656 "OnHold Norm", "OnHold PERS", dumpPackage); 12657 } 12658 12659 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12660 12661 if (mProcessCrashTimes.getMap().size() > 0) { 12662 boolean printed = false; 12663 long now = SystemClock.uptimeMillis(); 12664 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12665 final int NP = pmap.size(); 12666 for (int ip=0; ip<NP; ip++) { 12667 String pname = pmap.keyAt(ip); 12668 SparseArray<Long> uids = pmap.valueAt(ip); 12669 final int N = uids.size(); 12670 for (int i=0; i<N; i++) { 12671 int puid = uids.keyAt(i); 12672 ProcessRecord r = mProcessNames.get(pname, puid); 12673 if (dumpPackage != null && (r == null 12674 || !r.pkgList.containsKey(dumpPackage))) { 12675 continue; 12676 } 12677 if (!printed) { 12678 if (needSep) pw.println(); 12679 needSep = true; 12680 pw.println(" Time since processes crashed:"); 12681 printed = true; 12682 printedAnything = true; 12683 } 12684 pw.print(" Process "); pw.print(pname); 12685 pw.print(" uid "); pw.print(puid); 12686 pw.print(": last crashed "); 12687 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12688 pw.println(" ago"); 12689 } 12690 } 12691 } 12692 12693 if (mBadProcesses.getMap().size() > 0) { 12694 boolean printed = false; 12695 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12696 final int NP = pmap.size(); 12697 for (int ip=0; ip<NP; ip++) { 12698 String pname = pmap.keyAt(ip); 12699 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12700 final int N = uids.size(); 12701 for (int i=0; i<N; i++) { 12702 int puid = uids.keyAt(i); 12703 ProcessRecord r = mProcessNames.get(pname, puid); 12704 if (dumpPackage != null && (r == null 12705 || !r.pkgList.containsKey(dumpPackage))) { 12706 continue; 12707 } 12708 if (!printed) { 12709 if (needSep) pw.println(); 12710 needSep = true; 12711 pw.println(" Bad processes:"); 12712 printedAnything = true; 12713 } 12714 BadProcessInfo info = uids.valueAt(i); 12715 pw.print(" Bad process "); pw.print(pname); 12716 pw.print(" uid "); pw.print(puid); 12717 pw.print(": crashed at time "); pw.println(info.time); 12718 if (info.shortMsg != null) { 12719 pw.print(" Short msg: "); pw.println(info.shortMsg); 12720 } 12721 if (info.longMsg != null) { 12722 pw.print(" Long msg: "); pw.println(info.longMsg); 12723 } 12724 if (info.stack != null) { 12725 pw.println(" Stack:"); 12726 int lastPos = 0; 12727 for (int pos=0; pos<info.stack.length(); pos++) { 12728 if (info.stack.charAt(pos) == '\n') { 12729 pw.print(" "); 12730 pw.write(info.stack, lastPos, pos-lastPos); 12731 pw.println(); 12732 lastPos = pos+1; 12733 } 12734 } 12735 if (lastPos < info.stack.length()) { 12736 pw.print(" "); 12737 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12738 pw.println(); 12739 } 12740 } 12741 } 12742 } 12743 } 12744 12745 if (dumpPackage == null) { 12746 pw.println(); 12747 needSep = false; 12748 pw.println(" mStartedUsers:"); 12749 for (int i=0; i<mStartedUsers.size(); i++) { 12750 UserStartedState uss = mStartedUsers.valueAt(i); 12751 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12752 pw.print(": "); uss.dump("", pw); 12753 } 12754 pw.print(" mStartedUserArray: ["); 12755 for (int i=0; i<mStartedUserArray.length; i++) { 12756 if (i > 0) pw.print(", "); 12757 pw.print(mStartedUserArray[i]); 12758 } 12759 pw.println("]"); 12760 pw.print(" mUserLru: ["); 12761 for (int i=0; i<mUserLru.size(); i++) { 12762 if (i > 0) pw.print(", "); 12763 pw.print(mUserLru.get(i)); 12764 } 12765 pw.println("]"); 12766 if (dumpAll) { 12767 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12768 } 12769 synchronized (mUserProfileGroupIdsSelfLocked) { 12770 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12771 pw.println(" mUserProfileGroupIds:"); 12772 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12773 pw.print(" User #"); 12774 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12775 pw.print(" -> profile #"); 12776 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12777 } 12778 } 12779 } 12780 } 12781 if (mHomeProcess != null && (dumpPackage == null 12782 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12783 if (needSep) { 12784 pw.println(); 12785 needSep = false; 12786 } 12787 pw.println(" mHomeProcess: " + mHomeProcess); 12788 } 12789 if (mPreviousProcess != null && (dumpPackage == null 12790 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12791 if (needSep) { 12792 pw.println(); 12793 needSep = false; 12794 } 12795 pw.println(" mPreviousProcess: " + mPreviousProcess); 12796 } 12797 if (dumpAll) { 12798 StringBuilder sb = new StringBuilder(128); 12799 sb.append(" mPreviousProcessVisibleTime: "); 12800 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12801 pw.println(sb); 12802 } 12803 if (mHeavyWeightProcess != null && (dumpPackage == null 12804 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12805 if (needSep) { 12806 pw.println(); 12807 needSep = false; 12808 } 12809 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12810 } 12811 if (dumpPackage == null) { 12812 pw.println(" mConfiguration: " + mConfiguration); 12813 } 12814 if (dumpAll) { 12815 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12816 if (mCompatModePackages.getPackages().size() > 0) { 12817 boolean printed = false; 12818 for (Map.Entry<String, Integer> entry 12819 : mCompatModePackages.getPackages().entrySet()) { 12820 String pkg = entry.getKey(); 12821 int mode = entry.getValue(); 12822 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12823 continue; 12824 } 12825 if (!printed) { 12826 pw.println(" mScreenCompatPackages:"); 12827 printed = true; 12828 } 12829 pw.print(" "); pw.print(pkg); pw.print(": "); 12830 pw.print(mode); pw.println(); 12831 } 12832 } 12833 } 12834 if (dumpPackage == null) { 12835 if (mSleeping || mWentToSleep || mLockScreenShown) { 12836 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12837 + " mLockScreenShown " + mLockScreenShown); 12838 } 12839 if (mShuttingDown || mRunningVoice) { 12840 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12841 } 12842 } 12843 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12844 || mOrigWaitForDebugger) { 12845 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12846 || dumpPackage.equals(mOrigDebugApp)) { 12847 if (needSep) { 12848 pw.println(); 12849 needSep = false; 12850 } 12851 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12852 + " mDebugTransient=" + mDebugTransient 12853 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12854 } 12855 } 12856 if (mOpenGlTraceApp != null) { 12857 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12858 if (needSep) { 12859 pw.println(); 12860 needSep = false; 12861 } 12862 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12863 } 12864 } 12865 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12866 || mProfileFd != null) { 12867 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12868 if (needSep) { 12869 pw.println(); 12870 needSep = false; 12871 } 12872 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12873 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12874 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12875 + mAutoStopProfiler); 12876 pw.println(" mProfileType=" + mProfileType); 12877 } 12878 } 12879 if (dumpPackage == null) { 12880 if (mAlwaysFinishActivities || mController != null) { 12881 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12882 + " mController=" + mController); 12883 } 12884 if (dumpAll) { 12885 pw.println(" Total persistent processes: " + numPers); 12886 pw.println(" mProcessesReady=" + mProcessesReady 12887 + " mSystemReady=" + mSystemReady); 12888 pw.println(" mBooting=" + mBooting 12889 + " mBooted=" + mBooted 12890 + " mFactoryTest=" + mFactoryTest); 12891 pw.print(" mLastPowerCheckRealtime="); 12892 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12893 pw.println(""); 12894 pw.print(" mLastPowerCheckUptime="); 12895 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12896 pw.println(""); 12897 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12898 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12899 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12900 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12901 + " (" + mLruProcesses.size() + " total)" 12902 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12903 + " mNumServiceProcs=" + mNumServiceProcs 12904 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12905 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12906 + " mLastMemoryLevel" + mLastMemoryLevel 12907 + " mLastNumProcesses" + mLastNumProcesses); 12908 long now = SystemClock.uptimeMillis(); 12909 pw.print(" mLastIdleTime="); 12910 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12911 pw.print(" mLowRamSinceLastIdle="); 12912 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12913 pw.println(); 12914 } 12915 } 12916 12917 if (!printedAnything) { 12918 pw.println(" (nothing)"); 12919 } 12920 } 12921 12922 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12923 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12924 if (mProcessesToGc.size() > 0) { 12925 boolean printed = false; 12926 long now = SystemClock.uptimeMillis(); 12927 for (int i=0; i<mProcessesToGc.size(); i++) { 12928 ProcessRecord proc = mProcessesToGc.get(i); 12929 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12930 continue; 12931 } 12932 if (!printed) { 12933 if (needSep) pw.println(); 12934 needSep = true; 12935 pw.println(" Processes that are waiting to GC:"); 12936 printed = true; 12937 } 12938 pw.print(" Process "); pw.println(proc); 12939 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12940 pw.print(", last gced="); 12941 pw.print(now-proc.lastRequestedGc); 12942 pw.print(" ms ago, last lowMem="); 12943 pw.print(now-proc.lastLowMemory); 12944 pw.println(" ms ago"); 12945 12946 } 12947 } 12948 return needSep; 12949 } 12950 12951 void printOomLevel(PrintWriter pw, String name, int adj) { 12952 pw.print(" "); 12953 if (adj >= 0) { 12954 pw.print(' '); 12955 if (adj < 10) pw.print(' '); 12956 } else { 12957 if (adj > -10) pw.print(' '); 12958 } 12959 pw.print(adj); 12960 pw.print(": "); 12961 pw.print(name); 12962 pw.print(" ("); 12963 pw.print(mProcessList.getMemLevel(adj)/1024); 12964 pw.println(" kB)"); 12965 } 12966 12967 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12968 int opti, boolean dumpAll) { 12969 boolean needSep = false; 12970 12971 if (mLruProcesses.size() > 0) { 12972 if (needSep) pw.println(); 12973 needSep = true; 12974 pw.println(" OOM levels:"); 12975 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12976 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12977 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12978 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12979 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12980 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12981 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12982 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12983 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12984 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12985 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12986 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12987 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12988 12989 if (needSep) pw.println(); 12990 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12991 pw.print(" total, non-act at "); 12992 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12993 pw.print(", non-svc at "); 12994 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12995 pw.println("):"); 12996 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12997 needSep = true; 12998 } 12999 13000 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13001 13002 pw.println(); 13003 pw.println(" mHomeProcess: " + mHomeProcess); 13004 pw.println(" mPreviousProcess: " + mPreviousProcess); 13005 if (mHeavyWeightProcess != null) { 13006 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13007 } 13008 13009 return true; 13010 } 13011 13012 /** 13013 * There are three ways to call this: 13014 * - no provider specified: dump all the providers 13015 * - a flattened component name that matched an existing provider was specified as the 13016 * first arg: dump that one provider 13017 * - the first arg isn't the flattened component name of an existing provider: 13018 * dump all providers whose component contains the first arg as a substring 13019 */ 13020 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13021 int opti, boolean dumpAll) { 13022 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13023 } 13024 13025 static class ItemMatcher { 13026 ArrayList<ComponentName> components; 13027 ArrayList<String> strings; 13028 ArrayList<Integer> objects; 13029 boolean all; 13030 13031 ItemMatcher() { 13032 all = true; 13033 } 13034 13035 void build(String name) { 13036 ComponentName componentName = ComponentName.unflattenFromString(name); 13037 if (componentName != null) { 13038 if (components == null) { 13039 components = new ArrayList<ComponentName>(); 13040 } 13041 components.add(componentName); 13042 all = false; 13043 } else { 13044 int objectId = 0; 13045 // Not a '/' separated full component name; maybe an object ID? 13046 try { 13047 objectId = Integer.parseInt(name, 16); 13048 if (objects == null) { 13049 objects = new ArrayList<Integer>(); 13050 } 13051 objects.add(objectId); 13052 all = false; 13053 } catch (RuntimeException e) { 13054 // Not an integer; just do string match. 13055 if (strings == null) { 13056 strings = new ArrayList<String>(); 13057 } 13058 strings.add(name); 13059 all = false; 13060 } 13061 } 13062 } 13063 13064 int build(String[] args, int opti) { 13065 for (; opti<args.length; opti++) { 13066 String name = args[opti]; 13067 if ("--".equals(name)) { 13068 return opti+1; 13069 } 13070 build(name); 13071 } 13072 return opti; 13073 } 13074 13075 boolean match(Object object, ComponentName comp) { 13076 if (all) { 13077 return true; 13078 } 13079 if (components != null) { 13080 for (int i=0; i<components.size(); i++) { 13081 if (components.get(i).equals(comp)) { 13082 return true; 13083 } 13084 } 13085 } 13086 if (objects != null) { 13087 for (int i=0; i<objects.size(); i++) { 13088 if (System.identityHashCode(object) == objects.get(i)) { 13089 return true; 13090 } 13091 } 13092 } 13093 if (strings != null) { 13094 String flat = comp.flattenToString(); 13095 for (int i=0; i<strings.size(); i++) { 13096 if (flat.contains(strings.get(i))) { 13097 return true; 13098 } 13099 } 13100 } 13101 return false; 13102 } 13103 } 13104 13105 /** 13106 * There are three things that cmd can be: 13107 * - a flattened component name that matches an existing activity 13108 * - the cmd arg isn't the flattened component name of an existing activity: 13109 * dump all activity whose component contains the cmd as a substring 13110 * - A hex number of the ActivityRecord object instance. 13111 */ 13112 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13113 int opti, boolean dumpAll) { 13114 ArrayList<ActivityRecord> activities; 13115 13116 synchronized (this) { 13117 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13118 } 13119 13120 if (activities.size() <= 0) { 13121 return false; 13122 } 13123 13124 String[] newArgs = new String[args.length - opti]; 13125 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13126 13127 TaskRecord lastTask = null; 13128 boolean needSep = false; 13129 for (int i=activities.size()-1; i>=0; i--) { 13130 ActivityRecord r = activities.get(i); 13131 if (needSep) { 13132 pw.println(); 13133 } 13134 needSep = true; 13135 synchronized (this) { 13136 if (lastTask != r.task) { 13137 lastTask = r.task; 13138 pw.print("TASK "); pw.print(lastTask.affinity); 13139 pw.print(" id="); pw.println(lastTask.taskId); 13140 if (dumpAll) { 13141 lastTask.dump(pw, " "); 13142 } 13143 } 13144 } 13145 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13146 } 13147 return true; 13148 } 13149 13150 /** 13151 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13152 * there is a thread associated with the activity. 13153 */ 13154 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13155 final ActivityRecord r, String[] args, boolean dumpAll) { 13156 String innerPrefix = prefix + " "; 13157 synchronized (this) { 13158 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13159 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13160 pw.print(" pid="); 13161 if (r.app != null) pw.println(r.app.pid); 13162 else pw.println("(not running)"); 13163 if (dumpAll) { 13164 r.dump(pw, innerPrefix); 13165 } 13166 } 13167 if (r.app != null && r.app.thread != null) { 13168 // flush anything that is already in the PrintWriter since the thread is going 13169 // to write to the file descriptor directly 13170 pw.flush(); 13171 try { 13172 TransferPipe tp = new TransferPipe(); 13173 try { 13174 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13175 r.appToken, innerPrefix, args); 13176 tp.go(fd); 13177 } finally { 13178 tp.kill(); 13179 } 13180 } catch (IOException e) { 13181 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13182 } catch (RemoteException e) { 13183 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13184 } 13185 } 13186 } 13187 13188 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13189 int opti, boolean dumpAll, String dumpPackage) { 13190 boolean needSep = false; 13191 boolean onlyHistory = false; 13192 boolean printedAnything = false; 13193 13194 if ("history".equals(dumpPackage)) { 13195 if (opti < args.length && "-s".equals(args[opti])) { 13196 dumpAll = false; 13197 } 13198 onlyHistory = true; 13199 dumpPackage = null; 13200 } 13201 13202 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13203 if (!onlyHistory && dumpAll) { 13204 if (mRegisteredReceivers.size() > 0) { 13205 boolean printed = false; 13206 Iterator it = mRegisteredReceivers.values().iterator(); 13207 while (it.hasNext()) { 13208 ReceiverList r = (ReceiverList)it.next(); 13209 if (dumpPackage != null && (r.app == null || 13210 !dumpPackage.equals(r.app.info.packageName))) { 13211 continue; 13212 } 13213 if (!printed) { 13214 pw.println(" Registered Receivers:"); 13215 needSep = true; 13216 printed = true; 13217 printedAnything = true; 13218 } 13219 pw.print(" * "); pw.println(r); 13220 r.dump(pw, " "); 13221 } 13222 } 13223 13224 if (mReceiverResolver.dump(pw, needSep ? 13225 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13226 " ", dumpPackage, false)) { 13227 needSep = true; 13228 printedAnything = true; 13229 } 13230 } 13231 13232 for (BroadcastQueue q : mBroadcastQueues) { 13233 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13234 printedAnything |= needSep; 13235 } 13236 13237 needSep = true; 13238 13239 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13240 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13241 if (needSep) { 13242 pw.println(); 13243 } 13244 needSep = true; 13245 printedAnything = true; 13246 pw.print(" Sticky broadcasts for user "); 13247 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13248 StringBuilder sb = new StringBuilder(128); 13249 for (Map.Entry<String, ArrayList<Intent>> ent 13250 : mStickyBroadcasts.valueAt(user).entrySet()) { 13251 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13252 if (dumpAll) { 13253 pw.println(":"); 13254 ArrayList<Intent> intents = ent.getValue(); 13255 final int N = intents.size(); 13256 for (int i=0; i<N; i++) { 13257 sb.setLength(0); 13258 sb.append(" Intent: "); 13259 intents.get(i).toShortString(sb, false, true, false, false); 13260 pw.println(sb.toString()); 13261 Bundle bundle = intents.get(i).getExtras(); 13262 if (bundle != null) { 13263 pw.print(" "); 13264 pw.println(bundle.toString()); 13265 } 13266 } 13267 } else { 13268 pw.println(""); 13269 } 13270 } 13271 } 13272 } 13273 13274 if (!onlyHistory && dumpAll) { 13275 pw.println(); 13276 for (BroadcastQueue queue : mBroadcastQueues) { 13277 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13278 + queue.mBroadcastsScheduled); 13279 } 13280 pw.println(" mHandler:"); 13281 mHandler.dump(new PrintWriterPrinter(pw), " "); 13282 needSep = true; 13283 printedAnything = true; 13284 } 13285 13286 if (!printedAnything) { 13287 pw.println(" (nothing)"); 13288 } 13289 } 13290 13291 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13292 int opti, boolean dumpAll, String dumpPackage) { 13293 boolean needSep; 13294 boolean printedAnything = false; 13295 13296 ItemMatcher matcher = new ItemMatcher(); 13297 matcher.build(args, opti); 13298 13299 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13300 13301 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13302 printedAnything |= needSep; 13303 13304 if (mLaunchingProviders.size() > 0) { 13305 boolean printed = false; 13306 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13307 ContentProviderRecord r = mLaunchingProviders.get(i); 13308 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13309 continue; 13310 } 13311 if (!printed) { 13312 if (needSep) pw.println(); 13313 needSep = true; 13314 pw.println(" Launching content providers:"); 13315 printed = true; 13316 printedAnything = true; 13317 } 13318 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13319 pw.println(r); 13320 } 13321 } 13322 13323 if (mGrantedUriPermissions.size() > 0) { 13324 boolean printed = false; 13325 int dumpUid = -2; 13326 if (dumpPackage != null) { 13327 try { 13328 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13329 } catch (NameNotFoundException e) { 13330 dumpUid = -1; 13331 } 13332 } 13333 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13334 int uid = mGrantedUriPermissions.keyAt(i); 13335 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13336 continue; 13337 } 13338 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13339 if (!printed) { 13340 if (needSep) pw.println(); 13341 needSep = true; 13342 pw.println(" Granted Uri Permissions:"); 13343 printed = true; 13344 printedAnything = true; 13345 } 13346 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13347 for (UriPermission perm : perms.values()) { 13348 pw.print(" "); pw.println(perm); 13349 if (dumpAll) { 13350 perm.dump(pw, " "); 13351 } 13352 } 13353 } 13354 } 13355 13356 if (!printedAnything) { 13357 pw.println(" (nothing)"); 13358 } 13359 } 13360 13361 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13362 int opti, boolean dumpAll, String dumpPackage) { 13363 boolean printed = false; 13364 13365 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13366 13367 if (mIntentSenderRecords.size() > 0) { 13368 Iterator<WeakReference<PendingIntentRecord>> it 13369 = mIntentSenderRecords.values().iterator(); 13370 while (it.hasNext()) { 13371 WeakReference<PendingIntentRecord> ref = it.next(); 13372 PendingIntentRecord rec = ref != null ? ref.get(): null; 13373 if (dumpPackage != null && (rec == null 13374 || !dumpPackage.equals(rec.key.packageName))) { 13375 continue; 13376 } 13377 printed = true; 13378 if (rec != null) { 13379 pw.print(" * "); pw.println(rec); 13380 if (dumpAll) { 13381 rec.dump(pw, " "); 13382 } 13383 } else { 13384 pw.print(" * "); pw.println(ref); 13385 } 13386 } 13387 } 13388 13389 if (!printed) { 13390 pw.println(" (nothing)"); 13391 } 13392 } 13393 13394 private static final int dumpProcessList(PrintWriter pw, 13395 ActivityManagerService service, List list, 13396 String prefix, String normalLabel, String persistentLabel, 13397 String dumpPackage) { 13398 int numPers = 0; 13399 final int N = list.size()-1; 13400 for (int i=N; i>=0; i--) { 13401 ProcessRecord r = (ProcessRecord)list.get(i); 13402 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13403 continue; 13404 } 13405 pw.println(String.format("%s%s #%2d: %s", 13406 prefix, (r.persistent ? persistentLabel : normalLabel), 13407 i, r.toString())); 13408 if (r.persistent) { 13409 numPers++; 13410 } 13411 } 13412 return numPers; 13413 } 13414 13415 private static final boolean dumpProcessOomList(PrintWriter pw, 13416 ActivityManagerService service, List<ProcessRecord> origList, 13417 String prefix, String normalLabel, String persistentLabel, 13418 boolean inclDetails, String dumpPackage) { 13419 13420 ArrayList<Pair<ProcessRecord, Integer>> list 13421 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13422 for (int i=0; i<origList.size(); i++) { 13423 ProcessRecord r = origList.get(i); 13424 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13425 continue; 13426 } 13427 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13428 } 13429 13430 if (list.size() <= 0) { 13431 return false; 13432 } 13433 13434 Comparator<Pair<ProcessRecord, Integer>> comparator 13435 = new Comparator<Pair<ProcessRecord, Integer>>() { 13436 @Override 13437 public int compare(Pair<ProcessRecord, Integer> object1, 13438 Pair<ProcessRecord, Integer> object2) { 13439 if (object1.first.setAdj != object2.first.setAdj) { 13440 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13441 } 13442 if (object1.second.intValue() != object2.second.intValue()) { 13443 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13444 } 13445 return 0; 13446 } 13447 }; 13448 13449 Collections.sort(list, comparator); 13450 13451 final long curRealtime = SystemClock.elapsedRealtime(); 13452 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13453 final long curUptime = SystemClock.uptimeMillis(); 13454 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13455 13456 for (int i=list.size()-1; i>=0; i--) { 13457 ProcessRecord r = list.get(i).first; 13458 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13459 char schedGroup; 13460 switch (r.setSchedGroup) { 13461 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13462 schedGroup = 'B'; 13463 break; 13464 case Process.THREAD_GROUP_DEFAULT: 13465 schedGroup = 'F'; 13466 break; 13467 default: 13468 schedGroup = '?'; 13469 break; 13470 } 13471 char foreground; 13472 if (r.foregroundActivities) { 13473 foreground = 'A'; 13474 } else if (r.foregroundServices) { 13475 foreground = 'S'; 13476 } else { 13477 foreground = ' '; 13478 } 13479 String procState = ProcessList.makeProcStateString(r.curProcState); 13480 pw.print(prefix); 13481 pw.print(r.persistent ? persistentLabel : normalLabel); 13482 pw.print(" #"); 13483 int num = (origList.size()-1)-list.get(i).second; 13484 if (num < 10) pw.print(' '); 13485 pw.print(num); 13486 pw.print(": "); 13487 pw.print(oomAdj); 13488 pw.print(' '); 13489 pw.print(schedGroup); 13490 pw.print('/'); 13491 pw.print(foreground); 13492 pw.print('/'); 13493 pw.print(procState); 13494 pw.print(" trm:"); 13495 if (r.trimMemoryLevel < 10) pw.print(' '); 13496 pw.print(r.trimMemoryLevel); 13497 pw.print(' '); 13498 pw.print(r.toShortString()); 13499 pw.print(" ("); 13500 pw.print(r.adjType); 13501 pw.println(')'); 13502 if (r.adjSource != null || r.adjTarget != null) { 13503 pw.print(prefix); 13504 pw.print(" "); 13505 if (r.adjTarget instanceof ComponentName) { 13506 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13507 } else if (r.adjTarget != null) { 13508 pw.print(r.adjTarget.toString()); 13509 } else { 13510 pw.print("{null}"); 13511 } 13512 pw.print("<="); 13513 if (r.adjSource instanceof ProcessRecord) { 13514 pw.print("Proc{"); 13515 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13516 pw.println("}"); 13517 } else if (r.adjSource != null) { 13518 pw.println(r.adjSource.toString()); 13519 } else { 13520 pw.println("{null}"); 13521 } 13522 } 13523 if (inclDetails) { 13524 pw.print(prefix); 13525 pw.print(" "); 13526 pw.print("oom: max="); pw.print(r.maxAdj); 13527 pw.print(" curRaw="); pw.print(r.curRawAdj); 13528 pw.print(" setRaw="); pw.print(r.setRawAdj); 13529 pw.print(" cur="); pw.print(r.curAdj); 13530 pw.print(" set="); pw.println(r.setAdj); 13531 pw.print(prefix); 13532 pw.print(" "); 13533 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13534 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13535 pw.print(" lastPss="); pw.print(r.lastPss); 13536 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13537 pw.print(prefix); 13538 pw.print(" "); 13539 pw.print("cached="); pw.print(r.cached); 13540 pw.print(" empty="); pw.print(r.empty); 13541 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13542 13543 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13544 if (r.lastWakeTime != 0) { 13545 long wtime; 13546 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13547 synchronized (stats) { 13548 wtime = stats.getProcessWakeTime(r.info.uid, 13549 r.pid, curRealtime); 13550 } 13551 long timeUsed = wtime - r.lastWakeTime; 13552 pw.print(prefix); 13553 pw.print(" "); 13554 pw.print("keep awake over "); 13555 TimeUtils.formatDuration(realtimeSince, pw); 13556 pw.print(" used "); 13557 TimeUtils.formatDuration(timeUsed, pw); 13558 pw.print(" ("); 13559 pw.print((timeUsed*100)/realtimeSince); 13560 pw.println("%)"); 13561 } 13562 if (r.lastCpuTime != 0) { 13563 long timeUsed = r.curCpuTime - r.lastCpuTime; 13564 pw.print(prefix); 13565 pw.print(" "); 13566 pw.print("run cpu over "); 13567 TimeUtils.formatDuration(uptimeSince, pw); 13568 pw.print(" used "); 13569 TimeUtils.formatDuration(timeUsed, pw); 13570 pw.print(" ("); 13571 pw.print((timeUsed*100)/uptimeSince); 13572 pw.println("%)"); 13573 } 13574 } 13575 } 13576 } 13577 return true; 13578 } 13579 13580 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13581 ArrayList<ProcessRecord> procs; 13582 synchronized (this) { 13583 if (args != null && args.length > start 13584 && args[start].charAt(0) != '-') { 13585 procs = new ArrayList<ProcessRecord>(); 13586 int pid = -1; 13587 try { 13588 pid = Integer.parseInt(args[start]); 13589 } catch (NumberFormatException e) { 13590 } 13591 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13592 ProcessRecord proc = mLruProcesses.get(i); 13593 if (proc.pid == pid) { 13594 procs.add(proc); 13595 } else if (proc.processName.equals(args[start])) { 13596 procs.add(proc); 13597 } 13598 } 13599 if (procs.size() <= 0) { 13600 return null; 13601 } 13602 } else { 13603 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13604 } 13605 } 13606 return procs; 13607 } 13608 13609 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13610 PrintWriter pw, String[] args) { 13611 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13612 if (procs == null) { 13613 pw.println("No process found for: " + args[0]); 13614 return; 13615 } 13616 13617 long uptime = SystemClock.uptimeMillis(); 13618 long realtime = SystemClock.elapsedRealtime(); 13619 pw.println("Applications Graphics Acceleration Info:"); 13620 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13621 13622 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13623 ProcessRecord r = procs.get(i); 13624 if (r.thread != null) { 13625 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13626 pw.flush(); 13627 try { 13628 TransferPipe tp = new TransferPipe(); 13629 try { 13630 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13631 tp.go(fd); 13632 } finally { 13633 tp.kill(); 13634 } 13635 } catch (IOException e) { 13636 pw.println("Failure while dumping the app: " + r); 13637 pw.flush(); 13638 } catch (RemoteException e) { 13639 pw.println("Got a RemoteException while dumping the app " + r); 13640 pw.flush(); 13641 } 13642 } 13643 } 13644 } 13645 13646 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13647 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13648 if (procs == null) { 13649 pw.println("No process found for: " + args[0]); 13650 return; 13651 } 13652 13653 pw.println("Applications Database Info:"); 13654 13655 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13656 ProcessRecord r = procs.get(i); 13657 if (r.thread != null) { 13658 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13659 pw.flush(); 13660 try { 13661 TransferPipe tp = new TransferPipe(); 13662 try { 13663 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13664 tp.go(fd); 13665 } finally { 13666 tp.kill(); 13667 } 13668 } catch (IOException e) { 13669 pw.println("Failure while dumping the app: " + r); 13670 pw.flush(); 13671 } catch (RemoteException e) { 13672 pw.println("Got a RemoteException while dumping the app " + r); 13673 pw.flush(); 13674 } 13675 } 13676 } 13677 } 13678 13679 final static class MemItem { 13680 final boolean isProc; 13681 final String label; 13682 final String shortLabel; 13683 final long pss; 13684 final int id; 13685 final boolean hasActivities; 13686 ArrayList<MemItem> subitems; 13687 13688 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13689 boolean _hasActivities) { 13690 isProc = true; 13691 label = _label; 13692 shortLabel = _shortLabel; 13693 pss = _pss; 13694 id = _id; 13695 hasActivities = _hasActivities; 13696 } 13697 13698 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13699 isProc = false; 13700 label = _label; 13701 shortLabel = _shortLabel; 13702 pss = _pss; 13703 id = _id; 13704 hasActivities = false; 13705 } 13706 } 13707 13708 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13709 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13710 if (sort && !isCompact) { 13711 Collections.sort(items, new Comparator<MemItem>() { 13712 @Override 13713 public int compare(MemItem lhs, MemItem rhs) { 13714 if (lhs.pss < rhs.pss) { 13715 return 1; 13716 } else if (lhs.pss > rhs.pss) { 13717 return -1; 13718 } 13719 return 0; 13720 } 13721 }); 13722 } 13723 13724 for (int i=0; i<items.size(); i++) { 13725 MemItem mi = items.get(i); 13726 if (!isCompact) { 13727 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13728 } else if (mi.isProc) { 13729 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13730 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13731 pw.println(mi.hasActivities ? ",a" : ",e"); 13732 } else { 13733 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13734 pw.println(mi.pss); 13735 } 13736 if (mi.subitems != null) { 13737 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13738 true, isCompact); 13739 } 13740 } 13741 } 13742 13743 // These are in KB. 13744 static final long[] DUMP_MEM_BUCKETS = new long[] { 13745 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13746 120*1024, 160*1024, 200*1024, 13747 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13748 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13749 }; 13750 13751 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13752 boolean stackLike) { 13753 int start = label.lastIndexOf('.'); 13754 if (start >= 0) start++; 13755 else start = 0; 13756 int end = label.length(); 13757 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13758 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13759 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13760 out.append(bucket); 13761 out.append(stackLike ? "MB." : "MB "); 13762 out.append(label, start, end); 13763 return; 13764 } 13765 } 13766 out.append(memKB/1024); 13767 out.append(stackLike ? "MB." : "MB "); 13768 out.append(label, start, end); 13769 } 13770 13771 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13772 ProcessList.NATIVE_ADJ, 13773 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13774 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13775 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13776 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13777 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13778 }; 13779 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13780 "Native", 13781 "System", "Persistent", "Foreground", 13782 "Visible", "Perceptible", 13783 "Heavy Weight", "Backup", 13784 "A Services", "Home", 13785 "Previous", "B Services", "Cached" 13786 }; 13787 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13788 "native", 13789 "sys", "pers", "fore", 13790 "vis", "percept", 13791 "heavy", "backup", 13792 "servicea", "home", 13793 "prev", "serviceb", "cached" 13794 }; 13795 13796 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13797 long realtime, boolean isCheckinRequest, boolean isCompact) { 13798 if (isCheckinRequest || isCompact) { 13799 // short checkin version 13800 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13801 } else { 13802 pw.println("Applications Memory Usage (kB):"); 13803 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13804 } 13805 } 13806 13807 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13808 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13809 boolean dumpDetails = false; 13810 boolean dumpFullDetails = false; 13811 boolean dumpDalvik = false; 13812 boolean oomOnly = false; 13813 boolean isCompact = false; 13814 boolean localOnly = false; 13815 13816 int opti = 0; 13817 while (opti < args.length) { 13818 String opt = args[opti]; 13819 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13820 break; 13821 } 13822 opti++; 13823 if ("-a".equals(opt)) { 13824 dumpDetails = true; 13825 dumpFullDetails = true; 13826 dumpDalvik = true; 13827 } else if ("-d".equals(opt)) { 13828 dumpDalvik = true; 13829 } else if ("-c".equals(opt)) { 13830 isCompact = true; 13831 } else if ("--oom".equals(opt)) { 13832 oomOnly = true; 13833 } else if ("--local".equals(opt)) { 13834 localOnly = true; 13835 } else if ("-h".equals(opt)) { 13836 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13837 pw.println(" -a: include all available information for each process."); 13838 pw.println(" -d: include dalvik details when dumping process details."); 13839 pw.println(" -c: dump in a compact machine-parseable representation."); 13840 pw.println(" --oom: only show processes organized by oom adj."); 13841 pw.println(" --local: only collect details locally, don't call process."); 13842 pw.println("If [process] is specified it can be the name or "); 13843 pw.println("pid of a specific process to dump."); 13844 return; 13845 } else { 13846 pw.println("Unknown argument: " + opt + "; use -h for help"); 13847 } 13848 } 13849 13850 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13851 long uptime = SystemClock.uptimeMillis(); 13852 long realtime = SystemClock.elapsedRealtime(); 13853 final long[] tmpLong = new long[1]; 13854 13855 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13856 if (procs == null) { 13857 // No Java processes. Maybe they want to print a native process. 13858 if (args != null && args.length > opti 13859 && args[opti].charAt(0) != '-') { 13860 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13861 = new ArrayList<ProcessCpuTracker.Stats>(); 13862 updateCpuStatsNow(); 13863 int findPid = -1; 13864 try { 13865 findPid = Integer.parseInt(args[opti]); 13866 } catch (NumberFormatException e) { 13867 } 13868 synchronized (mProcessCpuTracker) { 13869 final int N = mProcessCpuTracker.countStats(); 13870 for (int i=0; i<N; i++) { 13871 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13872 if (st.pid == findPid || (st.baseName != null 13873 && st.baseName.equals(args[opti]))) { 13874 nativeProcs.add(st); 13875 } 13876 } 13877 } 13878 if (nativeProcs.size() > 0) { 13879 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13880 isCompact); 13881 Debug.MemoryInfo mi = null; 13882 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13883 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13884 final int pid = r.pid; 13885 if (!isCheckinRequest && dumpDetails) { 13886 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13887 } 13888 if (mi == null) { 13889 mi = new Debug.MemoryInfo(); 13890 } 13891 if (dumpDetails || (!brief && !oomOnly)) { 13892 Debug.getMemoryInfo(pid, mi); 13893 } else { 13894 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13895 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13896 } 13897 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13898 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13899 if (isCheckinRequest) { 13900 pw.println(); 13901 } 13902 } 13903 return; 13904 } 13905 } 13906 pw.println("No process found for: " + args[opti]); 13907 return; 13908 } 13909 13910 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13911 dumpDetails = true; 13912 } 13913 13914 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13915 13916 String[] innerArgs = new String[args.length-opti]; 13917 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13918 13919 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13920 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13921 long nativePss=0, dalvikPss=0, otherPss=0; 13922 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13923 13924 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13925 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13926 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13927 13928 long totalPss = 0; 13929 long cachedPss = 0; 13930 13931 Debug.MemoryInfo mi = null; 13932 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13933 final ProcessRecord r = procs.get(i); 13934 final IApplicationThread thread; 13935 final int pid; 13936 final int oomAdj; 13937 final boolean hasActivities; 13938 synchronized (this) { 13939 thread = r.thread; 13940 pid = r.pid; 13941 oomAdj = r.getSetAdjWithServices(); 13942 hasActivities = r.activities.size() > 0; 13943 } 13944 if (thread != null) { 13945 if (!isCheckinRequest && dumpDetails) { 13946 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13947 } 13948 if (mi == null) { 13949 mi = new Debug.MemoryInfo(); 13950 } 13951 if (dumpDetails || (!brief && !oomOnly)) { 13952 Debug.getMemoryInfo(pid, mi); 13953 } else { 13954 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13955 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13956 } 13957 if (dumpDetails) { 13958 if (localOnly) { 13959 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13960 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13961 if (isCheckinRequest) { 13962 pw.println(); 13963 } 13964 } else { 13965 try { 13966 pw.flush(); 13967 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13968 dumpDalvik, innerArgs); 13969 } catch (RemoteException e) { 13970 if (!isCheckinRequest) { 13971 pw.println("Got RemoteException!"); 13972 pw.flush(); 13973 } 13974 } 13975 } 13976 } 13977 13978 final long myTotalPss = mi.getTotalPss(); 13979 final long myTotalUss = mi.getTotalUss(); 13980 13981 synchronized (this) { 13982 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13983 // Record this for posterity if the process has been stable. 13984 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13985 } 13986 } 13987 13988 if (!isCheckinRequest && mi != null) { 13989 totalPss += myTotalPss; 13990 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13991 (hasActivities ? " / activities)" : ")"), 13992 r.processName, myTotalPss, pid, hasActivities); 13993 procMems.add(pssItem); 13994 procMemsMap.put(pid, pssItem); 13995 13996 nativePss += mi.nativePss; 13997 dalvikPss += mi.dalvikPss; 13998 otherPss += mi.otherPss; 13999 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14000 long mem = mi.getOtherPss(j); 14001 miscPss[j] += mem; 14002 otherPss -= mem; 14003 } 14004 14005 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14006 cachedPss += myTotalPss; 14007 } 14008 14009 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14010 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14011 || oomIndex == (oomPss.length-1)) { 14012 oomPss[oomIndex] += myTotalPss; 14013 if (oomProcs[oomIndex] == null) { 14014 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14015 } 14016 oomProcs[oomIndex].add(pssItem); 14017 break; 14018 } 14019 } 14020 } 14021 } 14022 } 14023 14024 long nativeProcTotalPss = 0; 14025 14026 if (!isCheckinRequest && procs.size() > 1) { 14027 // If we are showing aggregations, also look for native processes to 14028 // include so that our aggregations are more accurate. 14029 updateCpuStatsNow(); 14030 synchronized (mProcessCpuTracker) { 14031 final int N = mProcessCpuTracker.countStats(); 14032 for (int i=0; i<N; i++) { 14033 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14034 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14035 if (mi == null) { 14036 mi = new Debug.MemoryInfo(); 14037 } 14038 if (!brief && !oomOnly) { 14039 Debug.getMemoryInfo(st.pid, mi); 14040 } else { 14041 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14042 mi.nativePrivateDirty = (int)tmpLong[0]; 14043 } 14044 14045 final long myTotalPss = mi.getTotalPss(); 14046 totalPss += myTotalPss; 14047 nativeProcTotalPss += myTotalPss; 14048 14049 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14050 st.name, myTotalPss, st.pid, false); 14051 procMems.add(pssItem); 14052 14053 nativePss += mi.nativePss; 14054 dalvikPss += mi.dalvikPss; 14055 otherPss += mi.otherPss; 14056 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14057 long mem = mi.getOtherPss(j); 14058 miscPss[j] += mem; 14059 otherPss -= mem; 14060 } 14061 oomPss[0] += myTotalPss; 14062 if (oomProcs[0] == null) { 14063 oomProcs[0] = new ArrayList<MemItem>(); 14064 } 14065 oomProcs[0].add(pssItem); 14066 } 14067 } 14068 } 14069 14070 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14071 14072 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14073 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14074 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14075 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14076 String label = Debug.MemoryInfo.getOtherLabel(j); 14077 catMems.add(new MemItem(label, label, miscPss[j], j)); 14078 } 14079 14080 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14081 for (int j=0; j<oomPss.length; j++) { 14082 if (oomPss[j] != 0) { 14083 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14084 : DUMP_MEM_OOM_LABEL[j]; 14085 MemItem item = new MemItem(label, label, oomPss[j], 14086 DUMP_MEM_OOM_ADJ[j]); 14087 item.subitems = oomProcs[j]; 14088 oomMems.add(item); 14089 } 14090 } 14091 14092 if (!brief && !oomOnly && !isCompact) { 14093 pw.println(); 14094 pw.println("Total PSS by process:"); 14095 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14096 pw.println(); 14097 } 14098 if (!isCompact) { 14099 pw.println("Total PSS by OOM adjustment:"); 14100 } 14101 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14102 if (!brief && !oomOnly) { 14103 PrintWriter out = categoryPw != null ? categoryPw : pw; 14104 if (!isCompact) { 14105 out.println(); 14106 out.println("Total PSS by category:"); 14107 } 14108 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14109 } 14110 if (!isCompact) { 14111 pw.println(); 14112 } 14113 MemInfoReader memInfo = new MemInfoReader(); 14114 memInfo.readMemInfo(); 14115 if (nativeProcTotalPss > 0) { 14116 synchronized (this) { 14117 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14118 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14119 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14120 nativeProcTotalPss); 14121 } 14122 } 14123 if (!brief) { 14124 if (!isCompact) { 14125 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14126 pw.print(" kB (status "); 14127 switch (mLastMemoryLevel) { 14128 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14129 pw.println("normal)"); 14130 break; 14131 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14132 pw.println("moderate)"); 14133 break; 14134 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14135 pw.println("low)"); 14136 break; 14137 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14138 pw.println("critical)"); 14139 break; 14140 default: 14141 pw.print(mLastMemoryLevel); 14142 pw.println(")"); 14143 break; 14144 } 14145 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14146 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14147 pw.print(cachedPss); pw.print(" cached pss + "); 14148 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14149 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14150 } else { 14151 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14152 pw.print(cachedPss + memInfo.getCachedSizeKb() 14153 + memInfo.getFreeSizeKb()); pw.print(","); 14154 pw.println(totalPss - cachedPss); 14155 } 14156 } 14157 if (!isCompact) { 14158 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14159 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14160 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14161 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14162 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14163 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14164 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14165 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14166 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14167 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14168 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14169 } 14170 if (!brief) { 14171 if (memInfo.getZramTotalSizeKb() != 0) { 14172 if (!isCompact) { 14173 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14174 pw.print(" kB physical used for "); 14175 pw.print(memInfo.getSwapTotalSizeKb() 14176 - memInfo.getSwapFreeSizeKb()); 14177 pw.print(" kB in swap ("); 14178 pw.print(memInfo.getSwapTotalSizeKb()); 14179 pw.println(" kB total swap)"); 14180 } else { 14181 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14182 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14183 pw.println(memInfo.getSwapFreeSizeKb()); 14184 } 14185 } 14186 final int[] SINGLE_LONG_FORMAT = new int[] { 14187 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14188 }; 14189 long[] longOut = new long[1]; 14190 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14191 SINGLE_LONG_FORMAT, null, longOut, null); 14192 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14193 longOut[0] = 0; 14194 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14195 SINGLE_LONG_FORMAT, null, longOut, null); 14196 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14197 longOut[0] = 0; 14198 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14199 SINGLE_LONG_FORMAT, null, longOut, null); 14200 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14201 longOut[0] = 0; 14202 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14203 SINGLE_LONG_FORMAT, null, longOut, null); 14204 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14205 if (!isCompact) { 14206 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14207 pw.print(" KSM: "); pw.print(sharing); 14208 pw.print(" kB saved from shared "); 14209 pw.print(shared); pw.println(" kB"); 14210 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14211 pw.print(voltile); pw.println(" kB volatile"); 14212 } 14213 pw.print(" Tuning: "); 14214 pw.print(ActivityManager.staticGetMemoryClass()); 14215 pw.print(" (large "); 14216 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14217 pw.print("), oom "); 14218 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14219 pw.print(" kB"); 14220 pw.print(", restore limit "); 14221 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14222 pw.print(" kB"); 14223 if (ActivityManager.isLowRamDeviceStatic()) { 14224 pw.print(" (low-ram)"); 14225 } 14226 if (ActivityManager.isHighEndGfx()) { 14227 pw.print(" (high-end-gfx)"); 14228 } 14229 pw.println(); 14230 } else { 14231 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14232 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14233 pw.println(voltile); 14234 pw.print("tuning,"); 14235 pw.print(ActivityManager.staticGetMemoryClass()); 14236 pw.print(','); 14237 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14238 pw.print(','); 14239 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14240 if (ActivityManager.isLowRamDeviceStatic()) { 14241 pw.print(",low-ram"); 14242 } 14243 if (ActivityManager.isHighEndGfx()) { 14244 pw.print(",high-end-gfx"); 14245 } 14246 pw.println(); 14247 } 14248 } 14249 } 14250 } 14251 14252 /** 14253 * Searches array of arguments for the specified string 14254 * @param args array of argument strings 14255 * @param value value to search for 14256 * @return true if the value is contained in the array 14257 */ 14258 private static boolean scanArgs(String[] args, String value) { 14259 if (args != null) { 14260 for (String arg : args) { 14261 if (value.equals(arg)) { 14262 return true; 14263 } 14264 } 14265 } 14266 return false; 14267 } 14268 14269 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14270 ContentProviderRecord cpr, boolean always) { 14271 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14272 14273 if (!inLaunching || always) { 14274 synchronized (cpr) { 14275 cpr.launchingApp = null; 14276 cpr.notifyAll(); 14277 } 14278 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14279 String names[] = cpr.info.authority.split(";"); 14280 for (int j = 0; j < names.length; j++) { 14281 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14282 } 14283 } 14284 14285 for (int i=0; i<cpr.connections.size(); i++) { 14286 ContentProviderConnection conn = cpr.connections.get(i); 14287 if (conn.waiting) { 14288 // If this connection is waiting for the provider, then we don't 14289 // need to mess with its process unless we are always removing 14290 // or for some reason the provider is not currently launching. 14291 if (inLaunching && !always) { 14292 continue; 14293 } 14294 } 14295 ProcessRecord capp = conn.client; 14296 conn.dead = true; 14297 if (conn.stableCount > 0) { 14298 if (!capp.persistent && capp.thread != null 14299 && capp.pid != 0 14300 && capp.pid != MY_PID) { 14301 capp.kill("depends on provider " 14302 + cpr.name.flattenToShortString() 14303 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14304 } 14305 } else if (capp.thread != null && conn.provider.provider != null) { 14306 try { 14307 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14308 } catch (RemoteException e) { 14309 } 14310 // In the protocol here, we don't expect the client to correctly 14311 // clean up this connection, we'll just remove it. 14312 cpr.connections.remove(i); 14313 conn.client.conProviders.remove(conn); 14314 } 14315 } 14316 14317 if (inLaunching && always) { 14318 mLaunchingProviders.remove(cpr); 14319 } 14320 return inLaunching; 14321 } 14322 14323 /** 14324 * Main code for cleaning up a process when it has gone away. This is 14325 * called both as a result of the process dying, or directly when stopping 14326 * a process when running in single process mode. 14327 * 14328 * @return Returns true if the given process has been restarted, so the 14329 * app that was passed in must remain on the process lists. 14330 */ 14331 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14332 boolean restarting, boolean allowRestart, int index) { 14333 if (index >= 0) { 14334 removeLruProcessLocked(app); 14335 ProcessList.remove(app.pid); 14336 } 14337 14338 mProcessesToGc.remove(app); 14339 mPendingPssProcesses.remove(app); 14340 14341 // Dismiss any open dialogs. 14342 if (app.crashDialog != null && !app.forceCrashReport) { 14343 app.crashDialog.dismiss(); 14344 app.crashDialog = null; 14345 } 14346 if (app.anrDialog != null) { 14347 app.anrDialog.dismiss(); 14348 app.anrDialog = null; 14349 } 14350 if (app.waitDialog != null) { 14351 app.waitDialog.dismiss(); 14352 app.waitDialog = null; 14353 } 14354 14355 app.crashing = false; 14356 app.notResponding = false; 14357 14358 app.resetPackageList(mProcessStats); 14359 app.unlinkDeathRecipient(); 14360 app.makeInactive(mProcessStats); 14361 app.waitingToKill = null; 14362 app.forcingToForeground = null; 14363 updateProcessForegroundLocked(app, false, false); 14364 app.foregroundActivities = false; 14365 app.hasShownUi = false; 14366 app.treatLikeActivity = false; 14367 app.hasAboveClient = false; 14368 app.hasClientActivities = false; 14369 14370 mServices.killServicesLocked(app, allowRestart); 14371 14372 boolean restart = false; 14373 14374 // Remove published content providers. 14375 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14376 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14377 final boolean always = app.bad || !allowRestart; 14378 if (removeDyingProviderLocked(app, cpr, always) || always) { 14379 // We left the provider in the launching list, need to 14380 // restart it. 14381 restart = true; 14382 } 14383 14384 cpr.provider = null; 14385 cpr.proc = null; 14386 } 14387 app.pubProviders.clear(); 14388 14389 // Take care of any launching providers waiting for this process. 14390 if (checkAppInLaunchingProvidersLocked(app, false)) { 14391 restart = true; 14392 } 14393 14394 // Unregister from connected content providers. 14395 if (!app.conProviders.isEmpty()) { 14396 for (int i=0; i<app.conProviders.size(); i++) { 14397 ContentProviderConnection conn = app.conProviders.get(i); 14398 conn.provider.connections.remove(conn); 14399 } 14400 app.conProviders.clear(); 14401 } 14402 14403 // At this point there may be remaining entries in mLaunchingProviders 14404 // where we were the only one waiting, so they are no longer of use. 14405 // Look for these and clean up if found. 14406 // XXX Commented out for now. Trying to figure out a way to reproduce 14407 // the actual situation to identify what is actually going on. 14408 if (false) { 14409 for (int i=0; i<mLaunchingProviders.size(); i++) { 14410 ContentProviderRecord cpr = (ContentProviderRecord) 14411 mLaunchingProviders.get(i); 14412 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14413 synchronized (cpr) { 14414 cpr.launchingApp = null; 14415 cpr.notifyAll(); 14416 } 14417 } 14418 } 14419 } 14420 14421 skipCurrentReceiverLocked(app); 14422 14423 // Unregister any receivers. 14424 for (int i=app.receivers.size()-1; i>=0; i--) { 14425 removeReceiverLocked(app.receivers.valueAt(i)); 14426 } 14427 app.receivers.clear(); 14428 14429 // If the app is undergoing backup, tell the backup manager about it 14430 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14431 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14432 + mBackupTarget.appInfo + " died during backup"); 14433 try { 14434 IBackupManager bm = IBackupManager.Stub.asInterface( 14435 ServiceManager.getService(Context.BACKUP_SERVICE)); 14436 bm.agentDisconnected(app.info.packageName); 14437 } catch (RemoteException e) { 14438 // can't happen; backup manager is local 14439 } 14440 } 14441 14442 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14443 ProcessChangeItem item = mPendingProcessChanges.get(i); 14444 if (item.pid == app.pid) { 14445 mPendingProcessChanges.remove(i); 14446 mAvailProcessChanges.add(item); 14447 } 14448 } 14449 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14450 14451 // If the caller is restarting this app, then leave it in its 14452 // current lists and let the caller take care of it. 14453 if (restarting) { 14454 return false; 14455 } 14456 14457 if (!app.persistent || app.isolated) { 14458 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14459 "Removing non-persistent process during cleanup: " + app); 14460 mProcessNames.remove(app.processName, app.uid); 14461 mIsolatedProcesses.remove(app.uid); 14462 if (mHeavyWeightProcess == app) { 14463 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14464 mHeavyWeightProcess.userId, 0)); 14465 mHeavyWeightProcess = null; 14466 } 14467 } else if (!app.removed) { 14468 // This app is persistent, so we need to keep its record around. 14469 // If it is not already on the pending app list, add it there 14470 // and start a new process for it. 14471 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14472 mPersistentStartingProcesses.add(app); 14473 restart = true; 14474 } 14475 } 14476 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14477 "Clean-up removing on hold: " + app); 14478 mProcessesOnHold.remove(app); 14479 14480 if (app == mHomeProcess) { 14481 mHomeProcess = null; 14482 } 14483 if (app == mPreviousProcess) { 14484 mPreviousProcess = null; 14485 } 14486 14487 if (restart && !app.isolated) { 14488 // We have components that still need to be running in the 14489 // process, so re-launch it. 14490 if (index < 0) { 14491 ProcessList.remove(app.pid); 14492 } 14493 mProcessNames.put(app.processName, app.uid, app); 14494 startProcessLocked(app, "restart", app.processName); 14495 return true; 14496 } else if (app.pid > 0 && app.pid != MY_PID) { 14497 // Goodbye! 14498 boolean removed; 14499 synchronized (mPidsSelfLocked) { 14500 mPidsSelfLocked.remove(app.pid); 14501 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14502 } 14503 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14504 if (app.isolated) { 14505 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14506 } 14507 app.setPid(0); 14508 } 14509 return false; 14510 } 14511 14512 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14513 // Look through the content providers we are waiting to have launched, 14514 // and if any run in this process then either schedule a restart of 14515 // the process or kill the client waiting for it if this process has 14516 // gone bad. 14517 int NL = mLaunchingProviders.size(); 14518 boolean restart = false; 14519 for (int i=0; i<NL; i++) { 14520 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14521 if (cpr.launchingApp == app) { 14522 if (!alwaysBad && !app.bad) { 14523 restart = true; 14524 } else { 14525 removeDyingProviderLocked(app, cpr, true); 14526 // cpr should have been removed from mLaunchingProviders 14527 NL = mLaunchingProviders.size(); 14528 i--; 14529 } 14530 } 14531 } 14532 return restart; 14533 } 14534 14535 // ========================================================= 14536 // SERVICES 14537 // ========================================================= 14538 14539 @Override 14540 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14541 int flags) { 14542 enforceNotIsolatedCaller("getServices"); 14543 synchronized (this) { 14544 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14545 } 14546 } 14547 14548 @Override 14549 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14550 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14551 synchronized (this) { 14552 return mServices.getRunningServiceControlPanelLocked(name); 14553 } 14554 } 14555 14556 @Override 14557 public ComponentName startService(IApplicationThread caller, Intent service, 14558 String resolvedType, int userId) { 14559 enforceNotIsolatedCaller("startService"); 14560 // Refuse possible leaked file descriptors 14561 if (service != null && service.hasFileDescriptors() == true) { 14562 throw new IllegalArgumentException("File descriptors passed in Intent"); 14563 } 14564 14565 if (DEBUG_SERVICE) 14566 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14567 synchronized(this) { 14568 final int callingPid = Binder.getCallingPid(); 14569 final int callingUid = Binder.getCallingUid(); 14570 final long origId = Binder.clearCallingIdentity(); 14571 ComponentName res = mServices.startServiceLocked(caller, service, 14572 resolvedType, callingPid, callingUid, userId); 14573 Binder.restoreCallingIdentity(origId); 14574 return res; 14575 } 14576 } 14577 14578 ComponentName startServiceInPackage(int uid, 14579 Intent service, String resolvedType, int userId) { 14580 synchronized(this) { 14581 if (DEBUG_SERVICE) 14582 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14583 final long origId = Binder.clearCallingIdentity(); 14584 ComponentName res = mServices.startServiceLocked(null, service, 14585 resolvedType, -1, uid, userId); 14586 Binder.restoreCallingIdentity(origId); 14587 return res; 14588 } 14589 } 14590 14591 @Override 14592 public int stopService(IApplicationThread caller, Intent service, 14593 String resolvedType, int userId) { 14594 enforceNotIsolatedCaller("stopService"); 14595 // Refuse possible leaked file descriptors 14596 if (service != null && service.hasFileDescriptors() == true) { 14597 throw new IllegalArgumentException("File descriptors passed in Intent"); 14598 } 14599 14600 synchronized(this) { 14601 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14602 } 14603 } 14604 14605 @Override 14606 public IBinder peekService(Intent service, String resolvedType) { 14607 enforceNotIsolatedCaller("peekService"); 14608 // Refuse possible leaked file descriptors 14609 if (service != null && service.hasFileDescriptors() == true) { 14610 throw new IllegalArgumentException("File descriptors passed in Intent"); 14611 } 14612 synchronized(this) { 14613 return mServices.peekServiceLocked(service, resolvedType); 14614 } 14615 } 14616 14617 @Override 14618 public boolean stopServiceToken(ComponentName className, IBinder token, 14619 int startId) { 14620 synchronized(this) { 14621 return mServices.stopServiceTokenLocked(className, token, startId); 14622 } 14623 } 14624 14625 @Override 14626 public void setServiceForeground(ComponentName className, IBinder token, 14627 int id, Notification notification, boolean removeNotification) { 14628 synchronized(this) { 14629 mServices.setServiceForegroundLocked(className, token, id, notification, 14630 removeNotification); 14631 } 14632 } 14633 14634 @Override 14635 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14636 boolean requireFull, String name, String callerPackage) { 14637 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14638 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14639 } 14640 14641 int unsafeConvertIncomingUser(int userId) { 14642 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14643 ? mCurrentUserId : userId; 14644 } 14645 14646 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14647 int allowMode, String name, String callerPackage) { 14648 final int callingUserId = UserHandle.getUserId(callingUid); 14649 if (callingUserId == userId) { 14650 return userId; 14651 } 14652 14653 // Note that we may be accessing mCurrentUserId outside of a lock... 14654 // shouldn't be a big deal, if this is being called outside 14655 // of a locked context there is intrinsically a race with 14656 // the value the caller will receive and someone else changing it. 14657 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14658 // we will switch to the calling user if access to the current user fails. 14659 int targetUserId = unsafeConvertIncomingUser(userId); 14660 14661 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14662 final boolean allow; 14663 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14664 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14665 // If the caller has this permission, they always pass go. And collect $200. 14666 allow = true; 14667 } else if (allowMode == ALLOW_FULL_ONLY) { 14668 // We require full access, sucks to be you. 14669 allow = false; 14670 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14671 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14672 // If the caller does not have either permission, they are always doomed. 14673 allow = false; 14674 } else if (allowMode == ALLOW_NON_FULL) { 14675 // We are blanket allowing non-full access, you lucky caller! 14676 allow = true; 14677 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14678 // We may or may not allow this depending on whether the two users are 14679 // in the same profile. 14680 synchronized (mUserProfileGroupIdsSelfLocked) { 14681 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14682 UserInfo.NO_PROFILE_GROUP_ID); 14683 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14684 UserInfo.NO_PROFILE_GROUP_ID); 14685 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14686 && callingProfile == targetProfile; 14687 } 14688 } else { 14689 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14690 } 14691 if (!allow) { 14692 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14693 // In this case, they would like to just execute as their 14694 // owner user instead of failing. 14695 targetUserId = callingUserId; 14696 } else { 14697 StringBuilder builder = new StringBuilder(128); 14698 builder.append("Permission Denial: "); 14699 builder.append(name); 14700 if (callerPackage != null) { 14701 builder.append(" from "); 14702 builder.append(callerPackage); 14703 } 14704 builder.append(" asks to run as user "); 14705 builder.append(userId); 14706 builder.append(" but is calling from user "); 14707 builder.append(UserHandle.getUserId(callingUid)); 14708 builder.append("; this requires "); 14709 builder.append(INTERACT_ACROSS_USERS_FULL); 14710 if (allowMode != ALLOW_FULL_ONLY) { 14711 builder.append(" or "); 14712 builder.append(INTERACT_ACROSS_USERS); 14713 } 14714 String msg = builder.toString(); 14715 Slog.w(TAG, msg); 14716 throw new SecurityException(msg); 14717 } 14718 } 14719 } 14720 if (!allowAll && targetUserId < 0) { 14721 throw new IllegalArgumentException( 14722 "Call does not support special user #" + targetUserId); 14723 } 14724 // Check shell permission 14725 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14726 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14727 targetUserId)) { 14728 throw new SecurityException("Shell does not have permission to access user " 14729 + targetUserId + "\n " + Debug.getCallers(3)); 14730 } 14731 } 14732 return targetUserId; 14733 } 14734 14735 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14736 String className, int flags) { 14737 boolean result = false; 14738 // For apps that don't have pre-defined UIDs, check for permission 14739 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14740 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14741 if (ActivityManager.checkUidPermission( 14742 INTERACT_ACROSS_USERS, 14743 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14744 ComponentName comp = new ComponentName(aInfo.packageName, className); 14745 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14746 + " requests FLAG_SINGLE_USER, but app does not hold " 14747 + INTERACT_ACROSS_USERS; 14748 Slog.w(TAG, msg); 14749 throw new SecurityException(msg); 14750 } 14751 // Permission passed 14752 result = true; 14753 } 14754 } else if ("system".equals(componentProcessName)) { 14755 result = true; 14756 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14757 // Phone app and persistent apps are allowed to export singleuser providers. 14758 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14759 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14760 } 14761 if (DEBUG_MU) { 14762 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14763 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14764 } 14765 return result; 14766 } 14767 14768 /** 14769 * Checks to see if the caller is in the same app as the singleton 14770 * component, or the component is in a special app. It allows special apps 14771 * to export singleton components but prevents exporting singleton 14772 * components for regular apps. 14773 */ 14774 boolean isValidSingletonCall(int callingUid, int componentUid) { 14775 int componentAppId = UserHandle.getAppId(componentUid); 14776 return UserHandle.isSameApp(callingUid, componentUid) 14777 || componentAppId == Process.SYSTEM_UID 14778 || componentAppId == Process.PHONE_UID 14779 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14780 == PackageManager.PERMISSION_GRANTED; 14781 } 14782 14783 public int bindService(IApplicationThread caller, IBinder token, 14784 Intent service, String resolvedType, 14785 IServiceConnection connection, int flags, int userId) { 14786 enforceNotIsolatedCaller("bindService"); 14787 14788 // Refuse possible leaked file descriptors 14789 if (service != null && service.hasFileDescriptors() == true) { 14790 throw new IllegalArgumentException("File descriptors passed in Intent"); 14791 } 14792 14793 synchronized(this) { 14794 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14795 connection, flags, userId); 14796 } 14797 } 14798 14799 public boolean unbindService(IServiceConnection connection) { 14800 synchronized (this) { 14801 return mServices.unbindServiceLocked(connection); 14802 } 14803 } 14804 14805 public void publishService(IBinder token, Intent intent, IBinder service) { 14806 // Refuse possible leaked file descriptors 14807 if (intent != null && intent.hasFileDescriptors() == true) { 14808 throw new IllegalArgumentException("File descriptors passed in Intent"); 14809 } 14810 14811 synchronized(this) { 14812 if (!(token instanceof ServiceRecord)) { 14813 throw new IllegalArgumentException("Invalid service token"); 14814 } 14815 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14816 } 14817 } 14818 14819 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14820 // Refuse possible leaked file descriptors 14821 if (intent != null && intent.hasFileDescriptors() == true) { 14822 throw new IllegalArgumentException("File descriptors passed in Intent"); 14823 } 14824 14825 synchronized(this) { 14826 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14827 } 14828 } 14829 14830 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14831 synchronized(this) { 14832 if (!(token instanceof ServiceRecord)) { 14833 throw new IllegalArgumentException("Invalid service token"); 14834 } 14835 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14836 } 14837 } 14838 14839 // ========================================================= 14840 // BACKUP AND RESTORE 14841 // ========================================================= 14842 14843 // Cause the target app to be launched if necessary and its backup agent 14844 // instantiated. The backup agent will invoke backupAgentCreated() on the 14845 // activity manager to announce its creation. 14846 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14847 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14848 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14849 14850 synchronized(this) { 14851 // !!! TODO: currently no check here that we're already bound 14852 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14853 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14854 synchronized (stats) { 14855 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14856 } 14857 14858 // Backup agent is now in use, its package can't be stopped. 14859 try { 14860 AppGlobals.getPackageManager().setPackageStoppedState( 14861 app.packageName, false, UserHandle.getUserId(app.uid)); 14862 } catch (RemoteException e) { 14863 } catch (IllegalArgumentException e) { 14864 Slog.w(TAG, "Failed trying to unstop package " 14865 + app.packageName + ": " + e); 14866 } 14867 14868 BackupRecord r = new BackupRecord(ss, app, backupMode); 14869 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14870 ? new ComponentName(app.packageName, app.backupAgentName) 14871 : new ComponentName("android", "FullBackupAgent"); 14872 // startProcessLocked() returns existing proc's record if it's already running 14873 ProcessRecord proc = startProcessLocked(app.processName, app, 14874 false, 0, "backup", hostingName, false, false, false); 14875 if (proc == null) { 14876 Slog.e(TAG, "Unable to start backup agent process " + r); 14877 return false; 14878 } 14879 14880 r.app = proc; 14881 mBackupTarget = r; 14882 mBackupAppName = app.packageName; 14883 14884 // Try not to kill the process during backup 14885 updateOomAdjLocked(proc); 14886 14887 // If the process is already attached, schedule the creation of the backup agent now. 14888 // If it is not yet live, this will be done when it attaches to the framework. 14889 if (proc.thread != null) { 14890 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14891 try { 14892 proc.thread.scheduleCreateBackupAgent(app, 14893 compatibilityInfoForPackageLocked(app), backupMode); 14894 } catch (RemoteException e) { 14895 // Will time out on the backup manager side 14896 } 14897 } else { 14898 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14899 } 14900 // Invariants: at this point, the target app process exists and the application 14901 // is either already running or in the process of coming up. mBackupTarget and 14902 // mBackupAppName describe the app, so that when it binds back to the AM we 14903 // know that it's scheduled for a backup-agent operation. 14904 } 14905 14906 return true; 14907 } 14908 14909 @Override 14910 public void clearPendingBackup() { 14911 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14912 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14913 14914 synchronized (this) { 14915 mBackupTarget = null; 14916 mBackupAppName = null; 14917 } 14918 } 14919 14920 // A backup agent has just come up 14921 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14922 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14923 + " = " + agent); 14924 14925 synchronized(this) { 14926 if (!agentPackageName.equals(mBackupAppName)) { 14927 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14928 return; 14929 } 14930 } 14931 14932 long oldIdent = Binder.clearCallingIdentity(); 14933 try { 14934 IBackupManager bm = IBackupManager.Stub.asInterface( 14935 ServiceManager.getService(Context.BACKUP_SERVICE)); 14936 bm.agentConnected(agentPackageName, agent); 14937 } catch (RemoteException e) { 14938 // can't happen; the backup manager service is local 14939 } catch (Exception e) { 14940 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14941 e.printStackTrace(); 14942 } finally { 14943 Binder.restoreCallingIdentity(oldIdent); 14944 } 14945 } 14946 14947 // done with this agent 14948 public void unbindBackupAgent(ApplicationInfo appInfo) { 14949 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14950 if (appInfo == null) { 14951 Slog.w(TAG, "unbind backup agent for null app"); 14952 return; 14953 } 14954 14955 synchronized(this) { 14956 try { 14957 if (mBackupAppName == null) { 14958 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14959 return; 14960 } 14961 14962 if (!mBackupAppName.equals(appInfo.packageName)) { 14963 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14964 return; 14965 } 14966 14967 // Not backing this app up any more; reset its OOM adjustment 14968 final ProcessRecord proc = mBackupTarget.app; 14969 updateOomAdjLocked(proc); 14970 14971 // If the app crashed during backup, 'thread' will be null here 14972 if (proc.thread != null) { 14973 try { 14974 proc.thread.scheduleDestroyBackupAgent(appInfo, 14975 compatibilityInfoForPackageLocked(appInfo)); 14976 } catch (Exception e) { 14977 Slog.e(TAG, "Exception when unbinding backup agent:"); 14978 e.printStackTrace(); 14979 } 14980 } 14981 } finally { 14982 mBackupTarget = null; 14983 mBackupAppName = null; 14984 } 14985 } 14986 } 14987 // ========================================================= 14988 // BROADCASTS 14989 // ========================================================= 14990 14991 private final List getStickiesLocked(String action, IntentFilter filter, 14992 List cur, int userId) { 14993 final ContentResolver resolver = mContext.getContentResolver(); 14994 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14995 if (stickies == null) { 14996 return cur; 14997 } 14998 final ArrayList<Intent> list = stickies.get(action); 14999 if (list == null) { 15000 return cur; 15001 } 15002 int N = list.size(); 15003 for (int i=0; i<N; i++) { 15004 Intent intent = list.get(i); 15005 if (filter.match(resolver, intent, true, TAG) >= 0) { 15006 if (cur == null) { 15007 cur = new ArrayList<Intent>(); 15008 } 15009 cur.add(intent); 15010 } 15011 } 15012 return cur; 15013 } 15014 15015 boolean isPendingBroadcastProcessLocked(int pid) { 15016 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15017 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15018 } 15019 15020 void skipPendingBroadcastLocked(int pid) { 15021 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15022 for (BroadcastQueue queue : mBroadcastQueues) { 15023 queue.skipPendingBroadcastLocked(pid); 15024 } 15025 } 15026 15027 // The app just attached; send any pending broadcasts that it should receive 15028 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15029 boolean didSomething = false; 15030 for (BroadcastQueue queue : mBroadcastQueues) { 15031 didSomething |= queue.sendPendingBroadcastsLocked(app); 15032 } 15033 return didSomething; 15034 } 15035 15036 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15037 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15038 enforceNotIsolatedCaller("registerReceiver"); 15039 int callingUid; 15040 int callingPid; 15041 synchronized(this) { 15042 ProcessRecord callerApp = null; 15043 if (caller != null) { 15044 callerApp = getRecordForAppLocked(caller); 15045 if (callerApp == null) { 15046 throw new SecurityException( 15047 "Unable to find app for caller " + caller 15048 + " (pid=" + Binder.getCallingPid() 15049 + ") when registering receiver " + receiver); 15050 } 15051 if (callerApp.info.uid != Process.SYSTEM_UID && 15052 !callerApp.pkgList.containsKey(callerPackage) && 15053 !"android".equals(callerPackage)) { 15054 throw new SecurityException("Given caller package " + callerPackage 15055 + " is not running in process " + callerApp); 15056 } 15057 callingUid = callerApp.info.uid; 15058 callingPid = callerApp.pid; 15059 } else { 15060 callerPackage = null; 15061 callingUid = Binder.getCallingUid(); 15062 callingPid = Binder.getCallingPid(); 15063 } 15064 15065 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15066 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15067 15068 List allSticky = null; 15069 15070 // Look for any matching sticky broadcasts... 15071 Iterator actions = filter.actionsIterator(); 15072 if (actions != null) { 15073 while (actions.hasNext()) { 15074 String action = (String)actions.next(); 15075 allSticky = getStickiesLocked(action, filter, allSticky, 15076 UserHandle.USER_ALL); 15077 allSticky = getStickiesLocked(action, filter, allSticky, 15078 UserHandle.getUserId(callingUid)); 15079 } 15080 } else { 15081 allSticky = getStickiesLocked(null, filter, allSticky, 15082 UserHandle.USER_ALL); 15083 allSticky = getStickiesLocked(null, filter, allSticky, 15084 UserHandle.getUserId(callingUid)); 15085 } 15086 15087 // The first sticky in the list is returned directly back to 15088 // the client. 15089 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15090 15091 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15092 + ": " + sticky); 15093 15094 if (receiver == null) { 15095 return sticky; 15096 } 15097 15098 ReceiverList rl 15099 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15100 if (rl == null) { 15101 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15102 userId, receiver); 15103 if (rl.app != null) { 15104 rl.app.receivers.add(rl); 15105 } else { 15106 try { 15107 receiver.asBinder().linkToDeath(rl, 0); 15108 } catch (RemoteException e) { 15109 return sticky; 15110 } 15111 rl.linkedToDeath = true; 15112 } 15113 mRegisteredReceivers.put(receiver.asBinder(), rl); 15114 } else if (rl.uid != callingUid) { 15115 throw new IllegalArgumentException( 15116 "Receiver requested to register for uid " + callingUid 15117 + " was previously registered for uid " + rl.uid); 15118 } else if (rl.pid != callingPid) { 15119 throw new IllegalArgumentException( 15120 "Receiver requested to register for pid " + callingPid 15121 + " was previously registered for pid " + rl.pid); 15122 } else if (rl.userId != userId) { 15123 throw new IllegalArgumentException( 15124 "Receiver requested to register for user " + userId 15125 + " was previously registered for user " + rl.userId); 15126 } 15127 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15128 permission, callingUid, userId); 15129 rl.add(bf); 15130 if (!bf.debugCheck()) { 15131 Slog.w(TAG, "==> For Dynamic broadast"); 15132 } 15133 mReceiverResolver.addFilter(bf); 15134 15135 // Enqueue broadcasts for all existing stickies that match 15136 // this filter. 15137 if (allSticky != null) { 15138 ArrayList receivers = new ArrayList(); 15139 receivers.add(bf); 15140 15141 int N = allSticky.size(); 15142 for (int i=0; i<N; i++) { 15143 Intent intent = (Intent)allSticky.get(i); 15144 BroadcastQueue queue = broadcastQueueForIntent(intent); 15145 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15146 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15147 null, null, false, true, true, -1); 15148 queue.enqueueParallelBroadcastLocked(r); 15149 queue.scheduleBroadcastsLocked(); 15150 } 15151 } 15152 15153 return sticky; 15154 } 15155 } 15156 15157 public void unregisterReceiver(IIntentReceiver receiver) { 15158 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15159 15160 final long origId = Binder.clearCallingIdentity(); 15161 try { 15162 boolean doTrim = false; 15163 15164 synchronized(this) { 15165 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15166 if (rl != null) { 15167 if (rl.curBroadcast != null) { 15168 BroadcastRecord r = rl.curBroadcast; 15169 final boolean doNext = finishReceiverLocked( 15170 receiver.asBinder(), r.resultCode, r.resultData, 15171 r.resultExtras, r.resultAbort); 15172 if (doNext) { 15173 doTrim = true; 15174 r.queue.processNextBroadcast(false); 15175 } 15176 } 15177 15178 if (rl.app != null) { 15179 rl.app.receivers.remove(rl); 15180 } 15181 removeReceiverLocked(rl); 15182 if (rl.linkedToDeath) { 15183 rl.linkedToDeath = false; 15184 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15185 } 15186 } 15187 } 15188 15189 // If we actually concluded any broadcasts, we might now be able 15190 // to trim the recipients' apps from our working set 15191 if (doTrim) { 15192 trimApplications(); 15193 return; 15194 } 15195 15196 } finally { 15197 Binder.restoreCallingIdentity(origId); 15198 } 15199 } 15200 15201 void removeReceiverLocked(ReceiverList rl) { 15202 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15203 int N = rl.size(); 15204 for (int i=0; i<N; i++) { 15205 mReceiverResolver.removeFilter(rl.get(i)); 15206 } 15207 } 15208 15209 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15210 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15211 ProcessRecord r = mLruProcesses.get(i); 15212 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15213 try { 15214 r.thread.dispatchPackageBroadcast(cmd, packages); 15215 } catch (RemoteException ex) { 15216 } 15217 } 15218 } 15219 } 15220 15221 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15222 int callingUid, int[] users) { 15223 List<ResolveInfo> receivers = null; 15224 try { 15225 HashSet<ComponentName> singleUserReceivers = null; 15226 boolean scannedFirstReceivers = false; 15227 for (int user : users) { 15228 // Skip users that have Shell restrictions 15229 if (callingUid == Process.SHELL_UID 15230 && getUserManagerLocked().hasUserRestriction( 15231 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15232 continue; 15233 } 15234 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15235 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15236 if (user != 0 && newReceivers != null) { 15237 // If this is not the primary user, we need to check for 15238 // any receivers that should be filtered out. 15239 for (int i=0; i<newReceivers.size(); i++) { 15240 ResolveInfo ri = newReceivers.get(i); 15241 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15242 newReceivers.remove(i); 15243 i--; 15244 } 15245 } 15246 } 15247 if (newReceivers != null && newReceivers.size() == 0) { 15248 newReceivers = null; 15249 } 15250 if (receivers == null) { 15251 receivers = newReceivers; 15252 } else if (newReceivers != null) { 15253 // We need to concatenate the additional receivers 15254 // found with what we have do far. This would be easy, 15255 // but we also need to de-dup any receivers that are 15256 // singleUser. 15257 if (!scannedFirstReceivers) { 15258 // Collect any single user receivers we had already retrieved. 15259 scannedFirstReceivers = true; 15260 for (int i=0; i<receivers.size(); i++) { 15261 ResolveInfo ri = receivers.get(i); 15262 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15263 ComponentName cn = new ComponentName( 15264 ri.activityInfo.packageName, ri.activityInfo.name); 15265 if (singleUserReceivers == null) { 15266 singleUserReceivers = new HashSet<ComponentName>(); 15267 } 15268 singleUserReceivers.add(cn); 15269 } 15270 } 15271 } 15272 // Add the new results to the existing results, tracking 15273 // and de-dupping single user receivers. 15274 for (int i=0; i<newReceivers.size(); i++) { 15275 ResolveInfo ri = newReceivers.get(i); 15276 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15277 ComponentName cn = new ComponentName( 15278 ri.activityInfo.packageName, ri.activityInfo.name); 15279 if (singleUserReceivers == null) { 15280 singleUserReceivers = new HashSet<ComponentName>(); 15281 } 15282 if (!singleUserReceivers.contains(cn)) { 15283 singleUserReceivers.add(cn); 15284 receivers.add(ri); 15285 } 15286 } else { 15287 receivers.add(ri); 15288 } 15289 } 15290 } 15291 } 15292 } catch (RemoteException ex) { 15293 // pm is in same process, this will never happen. 15294 } 15295 return receivers; 15296 } 15297 15298 private final int broadcastIntentLocked(ProcessRecord callerApp, 15299 String callerPackage, Intent intent, String resolvedType, 15300 IIntentReceiver resultTo, int resultCode, String resultData, 15301 Bundle map, String requiredPermission, int appOp, 15302 boolean ordered, boolean sticky, int callingPid, int callingUid, 15303 int userId) { 15304 intent = new Intent(intent); 15305 15306 // By default broadcasts do not go to stopped apps. 15307 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15308 15309 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15310 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15311 + " ordered=" + ordered + " userid=" + userId); 15312 if ((resultTo != null) && !ordered) { 15313 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15314 } 15315 15316 userId = handleIncomingUser(callingPid, callingUid, userId, 15317 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15318 15319 // Make sure that the user who is receiving this broadcast is started. 15320 // If not, we will just skip it. 15321 15322 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15323 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15324 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15325 Slog.w(TAG, "Skipping broadcast of " + intent 15326 + ": user " + userId + " is stopped"); 15327 return ActivityManager.BROADCAST_SUCCESS; 15328 } 15329 } 15330 15331 /* 15332 * Prevent non-system code (defined here to be non-persistent 15333 * processes) from sending protected broadcasts. 15334 */ 15335 int callingAppId = UserHandle.getAppId(callingUid); 15336 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15337 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15338 || callingAppId == Process.NFC_UID || callingUid == 0) { 15339 // Always okay. 15340 } else if (callerApp == null || !callerApp.persistent) { 15341 try { 15342 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15343 intent.getAction())) { 15344 String msg = "Permission Denial: not allowed to send broadcast " 15345 + intent.getAction() + " from pid=" 15346 + callingPid + ", uid=" + callingUid; 15347 Slog.w(TAG, msg); 15348 throw new SecurityException(msg); 15349 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15350 // Special case for compatibility: we don't want apps to send this, 15351 // but historically it has not been protected and apps may be using it 15352 // to poke their own app widget. So, instead of making it protected, 15353 // just limit it to the caller. 15354 if (callerApp == null) { 15355 String msg = "Permission Denial: not allowed to send broadcast " 15356 + intent.getAction() + " from unknown caller."; 15357 Slog.w(TAG, msg); 15358 throw new SecurityException(msg); 15359 } else if (intent.getComponent() != null) { 15360 // They are good enough to send to an explicit component... verify 15361 // it is being sent to the calling app. 15362 if (!intent.getComponent().getPackageName().equals( 15363 callerApp.info.packageName)) { 15364 String msg = "Permission Denial: not allowed to send broadcast " 15365 + intent.getAction() + " to " 15366 + intent.getComponent().getPackageName() + " from " 15367 + callerApp.info.packageName; 15368 Slog.w(TAG, msg); 15369 throw new SecurityException(msg); 15370 } 15371 } else { 15372 // Limit broadcast to their own package. 15373 intent.setPackage(callerApp.info.packageName); 15374 } 15375 } 15376 } catch (RemoteException e) { 15377 Slog.w(TAG, "Remote exception", e); 15378 return ActivityManager.BROADCAST_SUCCESS; 15379 } 15380 } 15381 15382 // Handle special intents: if this broadcast is from the package 15383 // manager about a package being removed, we need to remove all of 15384 // its activities from the history stack. 15385 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15386 intent.getAction()); 15387 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15388 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15389 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15390 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15391 || uidRemoved) { 15392 if (checkComponentPermission( 15393 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15394 callingPid, callingUid, -1, true) 15395 == PackageManager.PERMISSION_GRANTED) { 15396 if (uidRemoved) { 15397 final Bundle intentExtras = intent.getExtras(); 15398 final int uid = intentExtras != null 15399 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15400 if (uid >= 0) { 15401 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15402 synchronized (bs) { 15403 bs.removeUidStatsLocked(uid); 15404 } 15405 mAppOpsService.uidRemoved(uid); 15406 } 15407 } else { 15408 // If resources are unavailable just force stop all 15409 // those packages and flush the attribute cache as well. 15410 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15411 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15412 if (list != null && (list.length > 0)) { 15413 for (String pkg : list) { 15414 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15415 "storage unmount"); 15416 } 15417 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15418 sendPackageBroadcastLocked( 15419 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15420 } 15421 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15422 intent.getAction())) { 15423 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15424 } else { 15425 Uri data = intent.getData(); 15426 String ssp; 15427 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15428 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15429 intent.getAction()); 15430 boolean fullUninstall = removed && 15431 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15432 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15433 forceStopPackageLocked(ssp, UserHandle.getAppId( 15434 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15435 false, fullUninstall, userId, 15436 removed ? "pkg removed" : "pkg changed"); 15437 } 15438 if (removed) { 15439 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15440 new String[] {ssp}, userId); 15441 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15442 mAppOpsService.packageRemoved( 15443 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15444 15445 // Remove all permissions granted from/to this package 15446 removeUriPermissionsForPackageLocked(ssp, userId, true); 15447 } 15448 } 15449 } 15450 } 15451 } 15452 } else { 15453 String msg = "Permission Denial: " + intent.getAction() 15454 + " broadcast from " + callerPackage + " (pid=" + callingPid 15455 + ", uid=" + callingUid + ")" 15456 + " requires " 15457 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15458 Slog.w(TAG, msg); 15459 throw new SecurityException(msg); 15460 } 15461 15462 // Special case for adding a package: by default turn on compatibility 15463 // mode. 15464 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15465 Uri data = intent.getData(); 15466 String ssp; 15467 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15468 mCompatModePackages.handlePackageAddedLocked(ssp, 15469 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15470 } 15471 } 15472 15473 /* 15474 * If this is the time zone changed action, queue up a message that will reset the timezone 15475 * of all currently running processes. This message will get queued up before the broadcast 15476 * happens. 15477 */ 15478 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15479 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15480 } 15481 15482 /* 15483 * If the user set the time, let all running processes know. 15484 */ 15485 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15486 final int is24Hour = intent.getBooleanExtra( 15487 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15488 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15489 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15490 synchronized (stats) { 15491 stats.noteCurrentTimeChangedLocked(); 15492 } 15493 } 15494 15495 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15496 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15497 } 15498 15499 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15500 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15501 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15502 } 15503 15504 // Add to the sticky list if requested. 15505 if (sticky) { 15506 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15507 callingPid, callingUid) 15508 != PackageManager.PERMISSION_GRANTED) { 15509 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15510 + callingPid + ", uid=" + callingUid 15511 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15512 Slog.w(TAG, msg); 15513 throw new SecurityException(msg); 15514 } 15515 if (requiredPermission != null) { 15516 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15517 + " and enforce permission " + requiredPermission); 15518 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15519 } 15520 if (intent.getComponent() != null) { 15521 throw new SecurityException( 15522 "Sticky broadcasts can't target a specific component"); 15523 } 15524 // We use userId directly here, since the "all" target is maintained 15525 // as a separate set of sticky broadcasts. 15526 if (userId != UserHandle.USER_ALL) { 15527 // But first, if this is not a broadcast to all users, then 15528 // make sure it doesn't conflict with an existing broadcast to 15529 // all users. 15530 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15531 UserHandle.USER_ALL); 15532 if (stickies != null) { 15533 ArrayList<Intent> list = stickies.get(intent.getAction()); 15534 if (list != null) { 15535 int N = list.size(); 15536 int i; 15537 for (i=0; i<N; i++) { 15538 if (intent.filterEquals(list.get(i))) { 15539 throw new IllegalArgumentException( 15540 "Sticky broadcast " + intent + " for user " 15541 + userId + " conflicts with existing global broadcast"); 15542 } 15543 } 15544 } 15545 } 15546 } 15547 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15548 if (stickies == null) { 15549 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15550 mStickyBroadcasts.put(userId, stickies); 15551 } 15552 ArrayList<Intent> list = stickies.get(intent.getAction()); 15553 if (list == null) { 15554 list = new ArrayList<Intent>(); 15555 stickies.put(intent.getAction(), list); 15556 } 15557 int N = list.size(); 15558 int i; 15559 for (i=0; i<N; i++) { 15560 if (intent.filterEquals(list.get(i))) { 15561 // This sticky already exists, replace it. 15562 list.set(i, new Intent(intent)); 15563 break; 15564 } 15565 } 15566 if (i >= N) { 15567 list.add(new Intent(intent)); 15568 } 15569 } 15570 15571 int[] users; 15572 if (userId == UserHandle.USER_ALL) { 15573 // Caller wants broadcast to go to all started users. 15574 users = mStartedUserArray; 15575 } else { 15576 // Caller wants broadcast to go to one specific user. 15577 users = new int[] {userId}; 15578 } 15579 15580 // Figure out who all will receive this broadcast. 15581 List receivers = null; 15582 List<BroadcastFilter> registeredReceivers = null; 15583 // Need to resolve the intent to interested receivers... 15584 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15585 == 0) { 15586 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15587 } 15588 if (intent.getComponent() == null) { 15589 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15590 // Query one target user at a time, excluding shell-restricted users 15591 UserManagerService ums = getUserManagerLocked(); 15592 for (int i = 0; i < users.length; i++) { 15593 if (ums.hasUserRestriction( 15594 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15595 continue; 15596 } 15597 List<BroadcastFilter> registeredReceiversForUser = 15598 mReceiverResolver.queryIntent(intent, 15599 resolvedType, false, users[i]); 15600 if (registeredReceivers == null) { 15601 registeredReceivers = registeredReceiversForUser; 15602 } else if (registeredReceiversForUser != null) { 15603 registeredReceivers.addAll(registeredReceiversForUser); 15604 } 15605 } 15606 } else { 15607 registeredReceivers = mReceiverResolver.queryIntent(intent, 15608 resolvedType, false, userId); 15609 } 15610 } 15611 15612 final boolean replacePending = 15613 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15614 15615 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15616 + " replacePending=" + replacePending); 15617 15618 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15619 if (!ordered && NR > 0) { 15620 // If we are not serializing this broadcast, then send the 15621 // registered receivers separately so they don't wait for the 15622 // components to be launched. 15623 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15624 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15625 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15626 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15627 ordered, sticky, false, userId); 15628 if (DEBUG_BROADCAST) Slog.v( 15629 TAG, "Enqueueing parallel broadcast " + r); 15630 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15631 if (!replaced) { 15632 queue.enqueueParallelBroadcastLocked(r); 15633 queue.scheduleBroadcastsLocked(); 15634 } 15635 registeredReceivers = null; 15636 NR = 0; 15637 } 15638 15639 // Merge into one list. 15640 int ir = 0; 15641 if (receivers != null) { 15642 // A special case for PACKAGE_ADDED: do not allow the package 15643 // being added to see this broadcast. This prevents them from 15644 // using this as a back door to get run as soon as they are 15645 // installed. Maybe in the future we want to have a special install 15646 // broadcast or such for apps, but we'd like to deliberately make 15647 // this decision. 15648 String skipPackages[] = null; 15649 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15650 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15651 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15652 Uri data = intent.getData(); 15653 if (data != null) { 15654 String pkgName = data.getSchemeSpecificPart(); 15655 if (pkgName != null) { 15656 skipPackages = new String[] { pkgName }; 15657 } 15658 } 15659 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15660 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15661 } 15662 if (skipPackages != null && (skipPackages.length > 0)) { 15663 for (String skipPackage : skipPackages) { 15664 if (skipPackage != null) { 15665 int NT = receivers.size(); 15666 for (int it=0; it<NT; it++) { 15667 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15668 if (curt.activityInfo.packageName.equals(skipPackage)) { 15669 receivers.remove(it); 15670 it--; 15671 NT--; 15672 } 15673 } 15674 } 15675 } 15676 } 15677 15678 int NT = receivers != null ? receivers.size() : 0; 15679 int it = 0; 15680 ResolveInfo curt = null; 15681 BroadcastFilter curr = null; 15682 while (it < NT && ir < NR) { 15683 if (curt == null) { 15684 curt = (ResolveInfo)receivers.get(it); 15685 } 15686 if (curr == null) { 15687 curr = registeredReceivers.get(ir); 15688 } 15689 if (curr.getPriority() >= curt.priority) { 15690 // Insert this broadcast record into the final list. 15691 receivers.add(it, curr); 15692 ir++; 15693 curr = null; 15694 it++; 15695 NT++; 15696 } else { 15697 // Skip to the next ResolveInfo in the final list. 15698 it++; 15699 curt = null; 15700 } 15701 } 15702 } 15703 while (ir < NR) { 15704 if (receivers == null) { 15705 receivers = new ArrayList(); 15706 } 15707 receivers.add(registeredReceivers.get(ir)); 15708 ir++; 15709 } 15710 15711 if ((receivers != null && receivers.size() > 0) 15712 || resultTo != null) { 15713 BroadcastQueue queue = broadcastQueueForIntent(intent); 15714 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15715 callerPackage, callingPid, callingUid, resolvedType, 15716 requiredPermission, appOp, receivers, resultTo, resultCode, 15717 resultData, map, ordered, sticky, false, userId); 15718 if (DEBUG_BROADCAST) Slog.v( 15719 TAG, "Enqueueing ordered broadcast " + r 15720 + ": prev had " + queue.mOrderedBroadcasts.size()); 15721 if (DEBUG_BROADCAST) { 15722 int seq = r.intent.getIntExtra("seq", -1); 15723 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15724 } 15725 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15726 if (!replaced) { 15727 queue.enqueueOrderedBroadcastLocked(r); 15728 queue.scheduleBroadcastsLocked(); 15729 } 15730 } 15731 15732 return ActivityManager.BROADCAST_SUCCESS; 15733 } 15734 15735 final Intent verifyBroadcastLocked(Intent intent) { 15736 // Refuse possible leaked file descriptors 15737 if (intent != null && intent.hasFileDescriptors() == true) { 15738 throw new IllegalArgumentException("File descriptors passed in Intent"); 15739 } 15740 15741 int flags = intent.getFlags(); 15742 15743 if (!mProcessesReady) { 15744 // if the caller really truly claims to know what they're doing, go 15745 // ahead and allow the broadcast without launching any receivers 15746 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15747 intent = new Intent(intent); 15748 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15749 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15750 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15751 + " before boot completion"); 15752 throw new IllegalStateException("Cannot broadcast before boot completed"); 15753 } 15754 } 15755 15756 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15757 throw new IllegalArgumentException( 15758 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15759 } 15760 15761 return intent; 15762 } 15763 15764 public final int broadcastIntent(IApplicationThread caller, 15765 Intent intent, String resolvedType, IIntentReceiver resultTo, 15766 int resultCode, String resultData, Bundle map, 15767 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15768 enforceNotIsolatedCaller("broadcastIntent"); 15769 synchronized(this) { 15770 intent = verifyBroadcastLocked(intent); 15771 15772 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15773 final int callingPid = Binder.getCallingPid(); 15774 final int callingUid = Binder.getCallingUid(); 15775 final long origId = Binder.clearCallingIdentity(); 15776 int res = broadcastIntentLocked(callerApp, 15777 callerApp != null ? callerApp.info.packageName : null, 15778 intent, resolvedType, resultTo, 15779 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15780 callingPid, callingUid, userId); 15781 Binder.restoreCallingIdentity(origId); 15782 return res; 15783 } 15784 } 15785 15786 int broadcastIntentInPackage(String packageName, int uid, 15787 Intent intent, String resolvedType, IIntentReceiver resultTo, 15788 int resultCode, String resultData, Bundle map, 15789 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15790 synchronized(this) { 15791 intent = verifyBroadcastLocked(intent); 15792 15793 final long origId = Binder.clearCallingIdentity(); 15794 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15795 resultTo, resultCode, resultData, map, requiredPermission, 15796 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15797 Binder.restoreCallingIdentity(origId); 15798 return res; 15799 } 15800 } 15801 15802 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15803 // Refuse possible leaked file descriptors 15804 if (intent != null && intent.hasFileDescriptors() == true) { 15805 throw new IllegalArgumentException("File descriptors passed in Intent"); 15806 } 15807 15808 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15809 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15810 15811 synchronized(this) { 15812 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15813 != PackageManager.PERMISSION_GRANTED) { 15814 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15815 + Binder.getCallingPid() 15816 + ", uid=" + Binder.getCallingUid() 15817 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15818 Slog.w(TAG, msg); 15819 throw new SecurityException(msg); 15820 } 15821 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15822 if (stickies != null) { 15823 ArrayList<Intent> list = stickies.get(intent.getAction()); 15824 if (list != null) { 15825 int N = list.size(); 15826 int i; 15827 for (i=0; i<N; i++) { 15828 if (intent.filterEquals(list.get(i))) { 15829 list.remove(i); 15830 break; 15831 } 15832 } 15833 if (list.size() <= 0) { 15834 stickies.remove(intent.getAction()); 15835 } 15836 } 15837 if (stickies.size() <= 0) { 15838 mStickyBroadcasts.remove(userId); 15839 } 15840 } 15841 } 15842 } 15843 15844 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15845 String resultData, Bundle resultExtras, boolean resultAbort) { 15846 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15847 if (r == null) { 15848 Slog.w(TAG, "finishReceiver called but not found on queue"); 15849 return false; 15850 } 15851 15852 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15853 } 15854 15855 void backgroundServicesFinishedLocked(int userId) { 15856 for (BroadcastQueue queue : mBroadcastQueues) { 15857 queue.backgroundServicesFinishedLocked(userId); 15858 } 15859 } 15860 15861 public void finishReceiver(IBinder who, int resultCode, String resultData, 15862 Bundle resultExtras, boolean resultAbort) { 15863 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15864 15865 // Refuse possible leaked file descriptors 15866 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15867 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15868 } 15869 15870 final long origId = Binder.clearCallingIdentity(); 15871 try { 15872 boolean doNext = false; 15873 BroadcastRecord r; 15874 15875 synchronized(this) { 15876 r = broadcastRecordForReceiverLocked(who); 15877 if (r != null) { 15878 doNext = r.queue.finishReceiverLocked(r, resultCode, 15879 resultData, resultExtras, resultAbort, true); 15880 } 15881 } 15882 15883 if (doNext) { 15884 r.queue.processNextBroadcast(false); 15885 } 15886 trimApplications(); 15887 } finally { 15888 Binder.restoreCallingIdentity(origId); 15889 } 15890 } 15891 15892 // ========================================================= 15893 // INSTRUMENTATION 15894 // ========================================================= 15895 15896 public boolean startInstrumentation(ComponentName className, 15897 String profileFile, int flags, Bundle arguments, 15898 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15899 int userId, String abiOverride) { 15900 enforceNotIsolatedCaller("startInstrumentation"); 15901 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15902 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15903 // Refuse possible leaked file descriptors 15904 if (arguments != null && arguments.hasFileDescriptors()) { 15905 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15906 } 15907 15908 synchronized(this) { 15909 InstrumentationInfo ii = null; 15910 ApplicationInfo ai = null; 15911 try { 15912 ii = mContext.getPackageManager().getInstrumentationInfo( 15913 className, STOCK_PM_FLAGS); 15914 ai = AppGlobals.getPackageManager().getApplicationInfo( 15915 ii.targetPackage, STOCK_PM_FLAGS, userId); 15916 } catch (PackageManager.NameNotFoundException e) { 15917 } catch (RemoteException e) { 15918 } 15919 if (ii == null) { 15920 reportStartInstrumentationFailure(watcher, className, 15921 "Unable to find instrumentation info for: " + className); 15922 return false; 15923 } 15924 if (ai == null) { 15925 reportStartInstrumentationFailure(watcher, className, 15926 "Unable to find instrumentation target package: " + ii.targetPackage); 15927 return false; 15928 } 15929 15930 int match = mContext.getPackageManager().checkSignatures( 15931 ii.targetPackage, ii.packageName); 15932 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15933 String msg = "Permission Denial: starting instrumentation " 15934 + className + " from pid=" 15935 + Binder.getCallingPid() 15936 + ", uid=" + Binder.getCallingPid() 15937 + " not allowed because package " + ii.packageName 15938 + " does not have a signature matching the target " 15939 + ii.targetPackage; 15940 reportStartInstrumentationFailure(watcher, className, msg); 15941 throw new SecurityException(msg); 15942 } 15943 15944 final long origId = Binder.clearCallingIdentity(); 15945 // Instrumentation can kill and relaunch even persistent processes 15946 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15947 "start instr"); 15948 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15949 app.instrumentationClass = className; 15950 app.instrumentationInfo = ai; 15951 app.instrumentationProfileFile = profileFile; 15952 app.instrumentationArguments = arguments; 15953 app.instrumentationWatcher = watcher; 15954 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15955 app.instrumentationResultClass = className; 15956 Binder.restoreCallingIdentity(origId); 15957 } 15958 15959 return true; 15960 } 15961 15962 /** 15963 * Report errors that occur while attempting to start Instrumentation. Always writes the 15964 * error to the logs, but if somebody is watching, send the report there too. This enables 15965 * the "am" command to report errors with more information. 15966 * 15967 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15968 * @param cn The component name of the instrumentation. 15969 * @param report The error report. 15970 */ 15971 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15972 ComponentName cn, String report) { 15973 Slog.w(TAG, report); 15974 try { 15975 if (watcher != null) { 15976 Bundle results = new Bundle(); 15977 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15978 results.putString("Error", report); 15979 watcher.instrumentationStatus(cn, -1, results); 15980 } 15981 } catch (RemoteException e) { 15982 Slog.w(TAG, e); 15983 } 15984 } 15985 15986 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15987 if (app.instrumentationWatcher != null) { 15988 try { 15989 // NOTE: IInstrumentationWatcher *must* be oneway here 15990 app.instrumentationWatcher.instrumentationFinished( 15991 app.instrumentationClass, 15992 resultCode, 15993 results); 15994 } catch (RemoteException e) { 15995 } 15996 } 15997 if (app.instrumentationUiAutomationConnection != null) { 15998 try { 15999 app.instrumentationUiAutomationConnection.shutdown(); 16000 } catch (RemoteException re) { 16001 /* ignore */ 16002 } 16003 // Only a UiAutomation can set this flag and now that 16004 // it is finished we make sure it is reset to its default. 16005 mUserIsMonkey = false; 16006 } 16007 app.instrumentationWatcher = null; 16008 app.instrumentationUiAutomationConnection = null; 16009 app.instrumentationClass = null; 16010 app.instrumentationInfo = null; 16011 app.instrumentationProfileFile = null; 16012 app.instrumentationArguments = null; 16013 16014 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16015 "finished inst"); 16016 } 16017 16018 public void finishInstrumentation(IApplicationThread target, 16019 int resultCode, Bundle results) { 16020 int userId = UserHandle.getCallingUserId(); 16021 // Refuse possible leaked file descriptors 16022 if (results != null && results.hasFileDescriptors()) { 16023 throw new IllegalArgumentException("File descriptors passed in Intent"); 16024 } 16025 16026 synchronized(this) { 16027 ProcessRecord app = getRecordForAppLocked(target); 16028 if (app == null) { 16029 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16030 return; 16031 } 16032 final long origId = Binder.clearCallingIdentity(); 16033 finishInstrumentationLocked(app, resultCode, results); 16034 Binder.restoreCallingIdentity(origId); 16035 } 16036 } 16037 16038 // ========================================================= 16039 // CONFIGURATION 16040 // ========================================================= 16041 16042 public ConfigurationInfo getDeviceConfigurationInfo() { 16043 ConfigurationInfo config = new ConfigurationInfo(); 16044 synchronized (this) { 16045 config.reqTouchScreen = mConfiguration.touchscreen; 16046 config.reqKeyboardType = mConfiguration.keyboard; 16047 config.reqNavigation = mConfiguration.navigation; 16048 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16049 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16050 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16051 } 16052 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16053 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16054 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16055 } 16056 config.reqGlEsVersion = GL_ES_VERSION; 16057 } 16058 return config; 16059 } 16060 16061 ActivityStack getFocusedStack() { 16062 return mStackSupervisor.getFocusedStack(); 16063 } 16064 16065 public Configuration getConfiguration() { 16066 Configuration ci; 16067 synchronized(this) { 16068 ci = new Configuration(mConfiguration); 16069 } 16070 return ci; 16071 } 16072 16073 public void updatePersistentConfiguration(Configuration values) { 16074 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16075 "updateConfiguration()"); 16076 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16077 "updateConfiguration()"); 16078 if (values == null) { 16079 throw new NullPointerException("Configuration must not be null"); 16080 } 16081 16082 synchronized(this) { 16083 final long origId = Binder.clearCallingIdentity(); 16084 updateConfigurationLocked(values, null, true, false); 16085 Binder.restoreCallingIdentity(origId); 16086 } 16087 } 16088 16089 public void updateConfiguration(Configuration values) { 16090 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16091 "updateConfiguration()"); 16092 16093 synchronized(this) { 16094 if (values == null && mWindowManager != null) { 16095 // sentinel: fetch the current configuration from the window manager 16096 values = mWindowManager.computeNewConfiguration(); 16097 } 16098 16099 if (mWindowManager != null) { 16100 mProcessList.applyDisplaySize(mWindowManager); 16101 } 16102 16103 final long origId = Binder.clearCallingIdentity(); 16104 if (values != null) { 16105 Settings.System.clearConfiguration(values); 16106 } 16107 updateConfigurationLocked(values, null, false, false); 16108 Binder.restoreCallingIdentity(origId); 16109 } 16110 } 16111 16112 /** 16113 * Do either or both things: (1) change the current configuration, and (2) 16114 * make sure the given activity is running with the (now) current 16115 * configuration. Returns true if the activity has been left running, or 16116 * false if <var>starting</var> is being destroyed to match the new 16117 * configuration. 16118 * @param persistent TODO 16119 */ 16120 boolean updateConfigurationLocked(Configuration values, 16121 ActivityRecord starting, boolean persistent, boolean initLocale) { 16122 int changes = 0; 16123 16124 if (values != null) { 16125 Configuration newConfig = new Configuration(mConfiguration); 16126 changes = newConfig.updateFrom(values); 16127 if (changes != 0) { 16128 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16129 Slog.i(TAG, "Updating configuration to: " + values); 16130 } 16131 16132 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16133 16134 if (values.locale != null && !initLocale) { 16135 saveLocaleLocked(values.locale, 16136 !values.locale.equals(mConfiguration.locale), 16137 values.userSetLocale); 16138 } 16139 16140 mConfigurationSeq++; 16141 if (mConfigurationSeq <= 0) { 16142 mConfigurationSeq = 1; 16143 } 16144 newConfig.seq = mConfigurationSeq; 16145 mConfiguration = newConfig; 16146 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16147 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16148 //mUsageStatsService.noteStartConfig(newConfig); 16149 16150 final Configuration configCopy = new Configuration(mConfiguration); 16151 16152 // TODO: If our config changes, should we auto dismiss any currently 16153 // showing dialogs? 16154 mShowDialogs = shouldShowDialogs(newConfig); 16155 16156 AttributeCache ac = AttributeCache.instance(); 16157 if (ac != null) { 16158 ac.updateConfiguration(configCopy); 16159 } 16160 16161 // Make sure all resources in our process are updated 16162 // right now, so that anyone who is going to retrieve 16163 // resource values after we return will be sure to get 16164 // the new ones. This is especially important during 16165 // boot, where the first config change needs to guarantee 16166 // all resources have that config before following boot 16167 // code is executed. 16168 mSystemThread.applyConfigurationToResources(configCopy); 16169 16170 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16171 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16172 msg.obj = new Configuration(configCopy); 16173 mHandler.sendMessage(msg); 16174 } 16175 16176 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16177 ProcessRecord app = mLruProcesses.get(i); 16178 try { 16179 if (app.thread != null) { 16180 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16181 + app.processName + " new config " + mConfiguration); 16182 app.thread.scheduleConfigurationChanged(configCopy); 16183 } 16184 } catch (Exception e) { 16185 } 16186 } 16187 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16188 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16189 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16190 | Intent.FLAG_RECEIVER_FOREGROUND); 16191 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16192 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16193 Process.SYSTEM_UID, UserHandle.USER_ALL); 16194 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16195 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16196 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16197 broadcastIntentLocked(null, null, intent, 16198 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16199 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16200 } 16201 } 16202 } 16203 16204 boolean kept = true; 16205 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16206 // mainStack is null during startup. 16207 if (mainStack != null) { 16208 if (changes != 0 && starting == null) { 16209 // If the configuration changed, and the caller is not already 16210 // in the process of starting an activity, then find the top 16211 // activity to check if its configuration needs to change. 16212 starting = mainStack.topRunningActivityLocked(null); 16213 } 16214 16215 if (starting != null) { 16216 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16217 // And we need to make sure at this point that all other activities 16218 // are made visible with the correct configuration. 16219 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16220 } 16221 } 16222 16223 if (values != null && mWindowManager != null) { 16224 mWindowManager.setNewConfiguration(mConfiguration); 16225 } 16226 16227 return kept; 16228 } 16229 16230 /** 16231 * Decide based on the configuration whether we should shouw the ANR, 16232 * crash, etc dialogs. The idea is that if there is no affordnace to 16233 * press the on-screen buttons, we shouldn't show the dialog. 16234 * 16235 * A thought: SystemUI might also want to get told about this, the Power 16236 * dialog / global actions also might want different behaviors. 16237 */ 16238 private static final boolean shouldShowDialogs(Configuration config) { 16239 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16240 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16241 } 16242 16243 /** 16244 * Save the locale. You must be inside a synchronized (this) block. 16245 */ 16246 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16247 if(isDiff) { 16248 SystemProperties.set("user.language", l.getLanguage()); 16249 SystemProperties.set("user.region", l.getCountry()); 16250 } 16251 16252 if(isPersist) { 16253 SystemProperties.set("persist.sys.language", l.getLanguage()); 16254 SystemProperties.set("persist.sys.country", l.getCountry()); 16255 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16256 } 16257 } 16258 16259 @Override 16260 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16261 synchronized (this) { 16262 ActivityRecord srec = ActivityRecord.forToken(token); 16263 if (srec.task != null && srec.task.stack != null) { 16264 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16265 } 16266 } 16267 return false; 16268 } 16269 16270 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16271 Intent resultData) { 16272 16273 synchronized (this) { 16274 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16275 if (stack != null) { 16276 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16277 } 16278 return false; 16279 } 16280 } 16281 16282 public int getLaunchedFromUid(IBinder activityToken) { 16283 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16284 if (srec == null) { 16285 return -1; 16286 } 16287 return srec.launchedFromUid; 16288 } 16289 16290 public String getLaunchedFromPackage(IBinder activityToken) { 16291 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16292 if (srec == null) { 16293 return null; 16294 } 16295 return srec.launchedFromPackage; 16296 } 16297 16298 // ========================================================= 16299 // LIFETIME MANAGEMENT 16300 // ========================================================= 16301 16302 // Returns which broadcast queue the app is the current [or imminent] receiver 16303 // on, or 'null' if the app is not an active broadcast recipient. 16304 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16305 BroadcastRecord r = app.curReceiver; 16306 if (r != null) { 16307 return r.queue; 16308 } 16309 16310 // It's not the current receiver, but it might be starting up to become one 16311 synchronized (this) { 16312 for (BroadcastQueue queue : mBroadcastQueues) { 16313 r = queue.mPendingBroadcast; 16314 if (r != null && r.curApp == app) { 16315 // found it; report which queue it's in 16316 return queue; 16317 } 16318 } 16319 } 16320 16321 return null; 16322 } 16323 16324 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16325 boolean doingAll, long now) { 16326 if (mAdjSeq == app.adjSeq) { 16327 // This adjustment has already been computed. 16328 return app.curRawAdj; 16329 } 16330 16331 if (app.thread == null) { 16332 app.adjSeq = mAdjSeq; 16333 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16334 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16335 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16336 } 16337 16338 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16339 app.adjSource = null; 16340 app.adjTarget = null; 16341 app.empty = false; 16342 app.cached = false; 16343 16344 final int activitiesSize = app.activities.size(); 16345 16346 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16347 // The max adjustment doesn't allow this app to be anything 16348 // below foreground, so it is not worth doing work for it. 16349 app.adjType = "fixed"; 16350 app.adjSeq = mAdjSeq; 16351 app.curRawAdj = app.maxAdj; 16352 app.foregroundActivities = false; 16353 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16354 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16355 // System processes can do UI, and when they do we want to have 16356 // them trim their memory after the user leaves the UI. To 16357 // facilitate this, here we need to determine whether or not it 16358 // is currently showing UI. 16359 app.systemNoUi = true; 16360 if (app == TOP_APP) { 16361 app.systemNoUi = false; 16362 } else if (activitiesSize > 0) { 16363 for (int j = 0; j < activitiesSize; j++) { 16364 final ActivityRecord r = app.activities.get(j); 16365 if (r.visible) { 16366 app.systemNoUi = false; 16367 } 16368 } 16369 } 16370 if (!app.systemNoUi) { 16371 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16372 } 16373 return (app.curAdj=app.maxAdj); 16374 } 16375 16376 app.systemNoUi = false; 16377 16378 // Determine the importance of the process, starting with most 16379 // important to least, and assign an appropriate OOM adjustment. 16380 int adj; 16381 int schedGroup; 16382 int procState; 16383 boolean foregroundActivities = false; 16384 BroadcastQueue queue; 16385 if (app == TOP_APP) { 16386 // The last app on the list is the foreground app. 16387 adj = ProcessList.FOREGROUND_APP_ADJ; 16388 schedGroup = Process.THREAD_GROUP_DEFAULT; 16389 app.adjType = "top-activity"; 16390 foregroundActivities = true; 16391 procState = ActivityManager.PROCESS_STATE_TOP; 16392 } else if (app.instrumentationClass != null) { 16393 // Don't want to kill running instrumentation. 16394 adj = ProcessList.FOREGROUND_APP_ADJ; 16395 schedGroup = Process.THREAD_GROUP_DEFAULT; 16396 app.adjType = "instrumentation"; 16397 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16398 } else if ((queue = isReceivingBroadcast(app)) != null) { 16399 // An app that is currently receiving a broadcast also 16400 // counts as being in the foreground for OOM killer purposes. 16401 // It's placed in a sched group based on the nature of the 16402 // broadcast as reflected by which queue it's active in. 16403 adj = ProcessList.FOREGROUND_APP_ADJ; 16404 schedGroup = (queue == mFgBroadcastQueue) 16405 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16406 app.adjType = "broadcast"; 16407 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16408 } else if (app.executingServices.size() > 0) { 16409 // An app that is currently executing a service callback also 16410 // counts as being in the foreground. 16411 adj = ProcessList.FOREGROUND_APP_ADJ; 16412 schedGroup = app.execServicesFg ? 16413 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16414 app.adjType = "exec-service"; 16415 procState = ActivityManager.PROCESS_STATE_SERVICE; 16416 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16417 } else { 16418 // As far as we know the process is empty. We may change our mind later. 16419 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16420 // At this point we don't actually know the adjustment. Use the cached adj 16421 // value that the caller wants us to. 16422 adj = cachedAdj; 16423 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16424 app.cached = true; 16425 app.empty = true; 16426 app.adjType = "cch-empty"; 16427 } 16428 16429 // Examine all activities if not already foreground. 16430 if (!foregroundActivities && activitiesSize > 0) { 16431 for (int j = 0; j < activitiesSize; j++) { 16432 final ActivityRecord r = app.activities.get(j); 16433 if (r.app != app) { 16434 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16435 + app + "?!?"); 16436 continue; 16437 } 16438 if (r.visible) { 16439 // App has a visible activity; only upgrade adjustment. 16440 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16441 adj = ProcessList.VISIBLE_APP_ADJ; 16442 app.adjType = "visible"; 16443 } 16444 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16445 procState = ActivityManager.PROCESS_STATE_TOP; 16446 } 16447 schedGroup = Process.THREAD_GROUP_DEFAULT; 16448 app.cached = false; 16449 app.empty = false; 16450 foregroundActivities = true; 16451 break; 16452 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16453 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16454 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16455 app.adjType = "pausing"; 16456 } 16457 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16458 procState = ActivityManager.PROCESS_STATE_TOP; 16459 } 16460 schedGroup = Process.THREAD_GROUP_DEFAULT; 16461 app.cached = false; 16462 app.empty = false; 16463 foregroundActivities = true; 16464 } else if (r.state == ActivityState.STOPPING) { 16465 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16466 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16467 app.adjType = "stopping"; 16468 } 16469 // For the process state, we will at this point consider the 16470 // process to be cached. It will be cached either as an activity 16471 // or empty depending on whether the activity is finishing. We do 16472 // this so that we can treat the process as cached for purposes of 16473 // memory trimming (determing current memory level, trim command to 16474 // send to process) since there can be an arbitrary number of stopping 16475 // processes and they should soon all go into the cached state. 16476 if (!r.finishing) { 16477 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16478 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16479 } 16480 } 16481 app.cached = false; 16482 app.empty = false; 16483 foregroundActivities = true; 16484 } else { 16485 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16486 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16487 app.adjType = "cch-act"; 16488 } 16489 } 16490 } 16491 } 16492 16493 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16494 if (app.foregroundServices) { 16495 // The user is aware of this app, so make it visible. 16496 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16497 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16498 app.cached = false; 16499 app.adjType = "fg-service"; 16500 schedGroup = Process.THREAD_GROUP_DEFAULT; 16501 } else if (app.forcingToForeground != null) { 16502 // The user is aware of this app, so make it visible. 16503 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16504 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16505 app.cached = false; 16506 app.adjType = "force-fg"; 16507 app.adjSource = app.forcingToForeground; 16508 schedGroup = Process.THREAD_GROUP_DEFAULT; 16509 } 16510 } 16511 16512 if (app == mHeavyWeightProcess) { 16513 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16514 // We don't want to kill the current heavy-weight process. 16515 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16516 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16517 app.cached = false; 16518 app.adjType = "heavy"; 16519 } 16520 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16521 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16522 } 16523 } 16524 16525 if (app == mHomeProcess) { 16526 if (adj > ProcessList.HOME_APP_ADJ) { 16527 // This process is hosting what we currently consider to be the 16528 // home app, so we don't want to let it go into the background. 16529 adj = ProcessList.HOME_APP_ADJ; 16530 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16531 app.cached = false; 16532 app.adjType = "home"; 16533 } 16534 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16535 procState = ActivityManager.PROCESS_STATE_HOME; 16536 } 16537 } 16538 16539 if (app == mPreviousProcess && app.activities.size() > 0) { 16540 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16541 // This was the previous process that showed UI to the user. 16542 // We want to try to keep it around more aggressively, to give 16543 // a good experience around switching between two apps. 16544 adj = ProcessList.PREVIOUS_APP_ADJ; 16545 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16546 app.cached = false; 16547 app.adjType = "previous"; 16548 } 16549 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16550 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16551 } 16552 } 16553 16554 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16555 + " reason=" + app.adjType); 16556 16557 // By default, we use the computed adjustment. It may be changed if 16558 // there are applications dependent on our services or providers, but 16559 // this gives us a baseline and makes sure we don't get into an 16560 // infinite recursion. 16561 app.adjSeq = mAdjSeq; 16562 app.curRawAdj = adj; 16563 app.hasStartedServices = false; 16564 16565 if (mBackupTarget != null && app == mBackupTarget.app) { 16566 // If possible we want to avoid killing apps while they're being backed up 16567 if (adj > ProcessList.BACKUP_APP_ADJ) { 16568 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16569 adj = ProcessList.BACKUP_APP_ADJ; 16570 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16571 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16572 } 16573 app.adjType = "backup"; 16574 app.cached = false; 16575 } 16576 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16577 procState = ActivityManager.PROCESS_STATE_BACKUP; 16578 } 16579 } 16580 16581 boolean mayBeTop = false; 16582 16583 for (int is = app.services.size()-1; 16584 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16585 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16586 || procState > ActivityManager.PROCESS_STATE_TOP); 16587 is--) { 16588 ServiceRecord s = app.services.valueAt(is); 16589 if (s.startRequested) { 16590 app.hasStartedServices = true; 16591 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16592 procState = ActivityManager.PROCESS_STATE_SERVICE; 16593 } 16594 if (app.hasShownUi && app != mHomeProcess) { 16595 // If this process has shown some UI, let it immediately 16596 // go to the LRU list because it may be pretty heavy with 16597 // UI stuff. We'll tag it with a label just to help 16598 // debug and understand what is going on. 16599 if (adj > ProcessList.SERVICE_ADJ) { 16600 app.adjType = "cch-started-ui-services"; 16601 } 16602 } else { 16603 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16604 // This service has seen some activity within 16605 // recent memory, so we will keep its process ahead 16606 // of the background processes. 16607 if (adj > ProcessList.SERVICE_ADJ) { 16608 adj = ProcessList.SERVICE_ADJ; 16609 app.adjType = "started-services"; 16610 app.cached = false; 16611 } 16612 } 16613 // If we have let the service slide into the background 16614 // state, still have some text describing what it is doing 16615 // even though the service no longer has an impact. 16616 if (adj > ProcessList.SERVICE_ADJ) { 16617 app.adjType = "cch-started-services"; 16618 } 16619 } 16620 } 16621 for (int conni = s.connections.size()-1; 16622 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16623 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16624 || procState > ActivityManager.PROCESS_STATE_TOP); 16625 conni--) { 16626 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16627 for (int i = 0; 16628 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16629 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16630 || procState > ActivityManager.PROCESS_STATE_TOP); 16631 i++) { 16632 // XXX should compute this based on the max of 16633 // all connected clients. 16634 ConnectionRecord cr = clist.get(i); 16635 if (cr.binding.client == app) { 16636 // Binding to ourself is not interesting. 16637 continue; 16638 } 16639 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16640 ProcessRecord client = cr.binding.client; 16641 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16642 TOP_APP, doingAll, now); 16643 int clientProcState = client.curProcState; 16644 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16645 // If the other app is cached for any reason, for purposes here 16646 // we are going to consider it empty. The specific cached state 16647 // doesn't propagate except under certain conditions. 16648 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16649 } 16650 String adjType = null; 16651 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16652 // Not doing bind OOM management, so treat 16653 // this guy more like a started service. 16654 if (app.hasShownUi && app != mHomeProcess) { 16655 // If this process has shown some UI, let it immediately 16656 // go to the LRU list because it may be pretty heavy with 16657 // UI stuff. We'll tag it with a label just to help 16658 // debug and understand what is going on. 16659 if (adj > clientAdj) { 16660 adjType = "cch-bound-ui-services"; 16661 } 16662 app.cached = false; 16663 clientAdj = adj; 16664 clientProcState = procState; 16665 } else { 16666 if (now >= (s.lastActivity 16667 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16668 // This service has not seen activity within 16669 // recent memory, so allow it to drop to the 16670 // LRU list if there is no other reason to keep 16671 // it around. We'll also tag it with a label just 16672 // to help debug and undertand what is going on. 16673 if (adj > clientAdj) { 16674 adjType = "cch-bound-services"; 16675 } 16676 clientAdj = adj; 16677 } 16678 } 16679 } 16680 if (adj > clientAdj) { 16681 // If this process has recently shown UI, and 16682 // the process that is binding to it is less 16683 // important than being visible, then we don't 16684 // care about the binding as much as we care 16685 // about letting this process get into the LRU 16686 // list to be killed and restarted if needed for 16687 // memory. 16688 if (app.hasShownUi && app != mHomeProcess 16689 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16690 adjType = "cch-bound-ui-services"; 16691 } else { 16692 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16693 |Context.BIND_IMPORTANT)) != 0) { 16694 adj = clientAdj; 16695 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16696 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16697 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16698 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16699 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16700 adj = clientAdj; 16701 } else { 16702 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16703 adj = ProcessList.VISIBLE_APP_ADJ; 16704 } 16705 } 16706 if (!client.cached) { 16707 app.cached = false; 16708 } 16709 adjType = "service"; 16710 } 16711 } 16712 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16713 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16714 schedGroup = Process.THREAD_GROUP_DEFAULT; 16715 } 16716 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16717 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16718 // Special handling of clients who are in the top state. 16719 // We *may* want to consider this process to be in the 16720 // top state as well, but only if there is not another 16721 // reason for it to be running. Being on the top is a 16722 // special state, meaning you are specifically running 16723 // for the current top app. If the process is already 16724 // running in the background for some other reason, it 16725 // is more important to continue considering it to be 16726 // in the background state. 16727 mayBeTop = true; 16728 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16729 } else { 16730 // Special handling for above-top states (persistent 16731 // processes). These should not bring the current process 16732 // into the top state, since they are not on top. Instead 16733 // give them the best state after that. 16734 clientProcState = 16735 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16736 } 16737 } 16738 } else { 16739 if (clientProcState < 16740 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16741 clientProcState = 16742 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16743 } 16744 } 16745 if (procState > clientProcState) { 16746 procState = clientProcState; 16747 } 16748 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16749 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16750 app.pendingUiClean = true; 16751 } 16752 if (adjType != null) { 16753 app.adjType = adjType; 16754 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16755 .REASON_SERVICE_IN_USE; 16756 app.adjSource = cr.binding.client; 16757 app.adjSourceProcState = clientProcState; 16758 app.adjTarget = s.name; 16759 } 16760 } 16761 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16762 app.treatLikeActivity = true; 16763 } 16764 final ActivityRecord a = cr.activity; 16765 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16766 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16767 (a.visible || a.state == ActivityState.RESUMED 16768 || a.state == ActivityState.PAUSING)) { 16769 adj = ProcessList.FOREGROUND_APP_ADJ; 16770 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16771 schedGroup = Process.THREAD_GROUP_DEFAULT; 16772 } 16773 app.cached = false; 16774 app.adjType = "service"; 16775 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16776 .REASON_SERVICE_IN_USE; 16777 app.adjSource = a; 16778 app.adjSourceProcState = procState; 16779 app.adjTarget = s.name; 16780 } 16781 } 16782 } 16783 } 16784 } 16785 16786 for (int provi = app.pubProviders.size()-1; 16787 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16788 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16789 || procState > ActivityManager.PROCESS_STATE_TOP); 16790 provi--) { 16791 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16792 for (int i = cpr.connections.size()-1; 16793 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16794 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16795 || procState > ActivityManager.PROCESS_STATE_TOP); 16796 i--) { 16797 ContentProviderConnection conn = cpr.connections.get(i); 16798 ProcessRecord client = conn.client; 16799 if (client == app) { 16800 // Being our own client is not interesting. 16801 continue; 16802 } 16803 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16804 int clientProcState = client.curProcState; 16805 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16806 // If the other app is cached for any reason, for purposes here 16807 // we are going to consider it empty. 16808 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16809 } 16810 if (adj > clientAdj) { 16811 if (app.hasShownUi && app != mHomeProcess 16812 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16813 app.adjType = "cch-ui-provider"; 16814 } else { 16815 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16816 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16817 app.adjType = "provider"; 16818 } 16819 app.cached &= client.cached; 16820 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16821 .REASON_PROVIDER_IN_USE; 16822 app.adjSource = client; 16823 app.adjSourceProcState = clientProcState; 16824 app.adjTarget = cpr.name; 16825 } 16826 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16827 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16828 // Special handling of clients who are in the top state. 16829 // We *may* want to consider this process to be in the 16830 // top state as well, but only if there is not another 16831 // reason for it to be running. Being on the top is a 16832 // special state, meaning you are specifically running 16833 // for the current top app. If the process is already 16834 // running in the background for some other reason, it 16835 // is more important to continue considering it to be 16836 // in the background state. 16837 mayBeTop = true; 16838 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16839 } else { 16840 // Special handling for above-top states (persistent 16841 // processes). These should not bring the current process 16842 // into the top state, since they are not on top. Instead 16843 // give them the best state after that. 16844 clientProcState = 16845 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16846 } 16847 } 16848 if (procState > clientProcState) { 16849 procState = clientProcState; 16850 } 16851 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16852 schedGroup = Process.THREAD_GROUP_DEFAULT; 16853 } 16854 } 16855 // If the provider has external (non-framework) process 16856 // dependencies, ensure that its adjustment is at least 16857 // FOREGROUND_APP_ADJ. 16858 if (cpr.hasExternalProcessHandles()) { 16859 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16860 adj = ProcessList.FOREGROUND_APP_ADJ; 16861 schedGroup = Process.THREAD_GROUP_DEFAULT; 16862 app.cached = false; 16863 app.adjType = "provider"; 16864 app.adjTarget = cpr.name; 16865 } 16866 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16867 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16868 } 16869 } 16870 } 16871 16872 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16873 // A client of one of our services or providers is in the top state. We 16874 // *may* want to be in the top state, but not if we are already running in 16875 // the background for some other reason. For the decision here, we are going 16876 // to pick out a few specific states that we want to remain in when a client 16877 // is top (states that tend to be longer-term) and otherwise allow it to go 16878 // to the top state. 16879 switch (procState) { 16880 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16881 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16882 case ActivityManager.PROCESS_STATE_SERVICE: 16883 // These all are longer-term states, so pull them up to the top 16884 // of the background states, but not all the way to the top state. 16885 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16886 break; 16887 default: 16888 // Otherwise, top is a better choice, so take it. 16889 procState = ActivityManager.PROCESS_STATE_TOP; 16890 break; 16891 } 16892 } 16893 16894 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16895 if (app.hasClientActivities) { 16896 // This is a cached process, but with client activities. Mark it so. 16897 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16898 app.adjType = "cch-client-act"; 16899 } else if (app.treatLikeActivity) { 16900 // This is a cached process, but somebody wants us to treat it like it has 16901 // an activity, okay! 16902 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16903 app.adjType = "cch-as-act"; 16904 } 16905 } 16906 16907 if (adj == ProcessList.SERVICE_ADJ) { 16908 if (doingAll) { 16909 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16910 mNewNumServiceProcs++; 16911 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16912 if (!app.serviceb) { 16913 // This service isn't far enough down on the LRU list to 16914 // normally be a B service, but if we are low on RAM and it 16915 // is large we want to force it down since we would prefer to 16916 // keep launcher over it. 16917 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16918 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16919 app.serviceHighRam = true; 16920 app.serviceb = true; 16921 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16922 } else { 16923 mNewNumAServiceProcs++; 16924 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16925 } 16926 } else { 16927 app.serviceHighRam = false; 16928 } 16929 } 16930 if (app.serviceb) { 16931 adj = ProcessList.SERVICE_B_ADJ; 16932 } 16933 } 16934 16935 app.curRawAdj = adj; 16936 16937 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16938 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16939 if (adj > app.maxAdj) { 16940 adj = app.maxAdj; 16941 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16942 schedGroup = Process.THREAD_GROUP_DEFAULT; 16943 } 16944 } 16945 16946 // Do final modification to adj. Everything we do between here and applying 16947 // the final setAdj must be done in this function, because we will also use 16948 // it when computing the final cached adj later. Note that we don't need to 16949 // worry about this for max adj above, since max adj will always be used to 16950 // keep it out of the cached vaues. 16951 app.curAdj = app.modifyRawOomAdj(adj); 16952 app.curSchedGroup = schedGroup; 16953 app.curProcState = procState; 16954 app.foregroundActivities = foregroundActivities; 16955 16956 return app.curRawAdj; 16957 } 16958 16959 /** 16960 * Schedule PSS collection of a process. 16961 */ 16962 void requestPssLocked(ProcessRecord proc, int procState) { 16963 if (mPendingPssProcesses.contains(proc)) { 16964 return; 16965 } 16966 if (mPendingPssProcesses.size() == 0) { 16967 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16968 } 16969 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16970 proc.pssProcState = procState; 16971 mPendingPssProcesses.add(proc); 16972 } 16973 16974 /** 16975 * Schedule PSS collection of all processes. 16976 */ 16977 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16978 if (!always) { 16979 if (now < (mLastFullPssTime + 16980 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16981 return; 16982 } 16983 } 16984 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16985 mLastFullPssTime = now; 16986 mFullPssPending = true; 16987 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16988 mPendingPssProcesses.clear(); 16989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16990 ProcessRecord app = mLruProcesses.get(i); 16991 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16992 app.pssProcState = app.setProcState; 16993 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16994 isSleeping(), now); 16995 mPendingPssProcesses.add(app); 16996 } 16997 } 16998 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16999 } 17000 17001 /** 17002 * Ask a given process to GC right now. 17003 */ 17004 final void performAppGcLocked(ProcessRecord app) { 17005 try { 17006 app.lastRequestedGc = SystemClock.uptimeMillis(); 17007 if (app.thread != null) { 17008 if (app.reportLowMemory) { 17009 app.reportLowMemory = false; 17010 app.thread.scheduleLowMemory(); 17011 } else { 17012 app.thread.processInBackground(); 17013 } 17014 } 17015 } catch (Exception e) { 17016 // whatever. 17017 } 17018 } 17019 17020 /** 17021 * Returns true if things are idle enough to perform GCs. 17022 */ 17023 private final boolean canGcNowLocked() { 17024 boolean processingBroadcasts = false; 17025 for (BroadcastQueue q : mBroadcastQueues) { 17026 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17027 processingBroadcasts = true; 17028 } 17029 } 17030 return !processingBroadcasts 17031 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17032 } 17033 17034 /** 17035 * Perform GCs on all processes that are waiting for it, but only 17036 * if things are idle. 17037 */ 17038 final void performAppGcsLocked() { 17039 final int N = mProcessesToGc.size(); 17040 if (N <= 0) { 17041 return; 17042 } 17043 if (canGcNowLocked()) { 17044 while (mProcessesToGc.size() > 0) { 17045 ProcessRecord proc = mProcessesToGc.remove(0); 17046 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17047 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17048 <= SystemClock.uptimeMillis()) { 17049 // To avoid spamming the system, we will GC processes one 17050 // at a time, waiting a few seconds between each. 17051 performAppGcLocked(proc); 17052 scheduleAppGcsLocked(); 17053 return; 17054 } else { 17055 // It hasn't been long enough since we last GCed this 17056 // process... put it in the list to wait for its time. 17057 addProcessToGcListLocked(proc); 17058 break; 17059 } 17060 } 17061 } 17062 17063 scheduleAppGcsLocked(); 17064 } 17065 } 17066 17067 /** 17068 * If all looks good, perform GCs on all processes waiting for them. 17069 */ 17070 final void performAppGcsIfAppropriateLocked() { 17071 if (canGcNowLocked()) { 17072 performAppGcsLocked(); 17073 return; 17074 } 17075 // Still not idle, wait some more. 17076 scheduleAppGcsLocked(); 17077 } 17078 17079 /** 17080 * Schedule the execution of all pending app GCs. 17081 */ 17082 final void scheduleAppGcsLocked() { 17083 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17084 17085 if (mProcessesToGc.size() > 0) { 17086 // Schedule a GC for the time to the next process. 17087 ProcessRecord proc = mProcessesToGc.get(0); 17088 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17089 17090 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17091 long now = SystemClock.uptimeMillis(); 17092 if (when < (now+GC_TIMEOUT)) { 17093 when = now + GC_TIMEOUT; 17094 } 17095 mHandler.sendMessageAtTime(msg, when); 17096 } 17097 } 17098 17099 /** 17100 * Add a process to the array of processes waiting to be GCed. Keeps the 17101 * list in sorted order by the last GC time. The process can't already be 17102 * on the list. 17103 */ 17104 final void addProcessToGcListLocked(ProcessRecord proc) { 17105 boolean added = false; 17106 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17107 if (mProcessesToGc.get(i).lastRequestedGc < 17108 proc.lastRequestedGc) { 17109 added = true; 17110 mProcessesToGc.add(i+1, proc); 17111 break; 17112 } 17113 } 17114 if (!added) { 17115 mProcessesToGc.add(0, proc); 17116 } 17117 } 17118 17119 /** 17120 * Set up to ask a process to GC itself. This will either do it 17121 * immediately, or put it on the list of processes to gc the next 17122 * time things are idle. 17123 */ 17124 final void scheduleAppGcLocked(ProcessRecord app) { 17125 long now = SystemClock.uptimeMillis(); 17126 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17127 return; 17128 } 17129 if (!mProcessesToGc.contains(app)) { 17130 addProcessToGcListLocked(app); 17131 scheduleAppGcsLocked(); 17132 } 17133 } 17134 17135 final void checkExcessivePowerUsageLocked(boolean doKills) { 17136 updateCpuStatsNow(); 17137 17138 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17139 boolean doWakeKills = doKills; 17140 boolean doCpuKills = doKills; 17141 if (mLastPowerCheckRealtime == 0) { 17142 doWakeKills = false; 17143 } 17144 if (mLastPowerCheckUptime == 0) { 17145 doCpuKills = false; 17146 } 17147 if (stats.isScreenOn()) { 17148 doWakeKills = false; 17149 } 17150 final long curRealtime = SystemClock.elapsedRealtime(); 17151 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17152 final long curUptime = SystemClock.uptimeMillis(); 17153 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17154 mLastPowerCheckRealtime = curRealtime; 17155 mLastPowerCheckUptime = curUptime; 17156 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17157 doWakeKills = false; 17158 } 17159 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17160 doCpuKills = false; 17161 } 17162 int i = mLruProcesses.size(); 17163 while (i > 0) { 17164 i--; 17165 ProcessRecord app = mLruProcesses.get(i); 17166 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17167 long wtime; 17168 synchronized (stats) { 17169 wtime = stats.getProcessWakeTime(app.info.uid, 17170 app.pid, curRealtime); 17171 } 17172 long wtimeUsed = wtime - app.lastWakeTime; 17173 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17174 if (DEBUG_POWER) { 17175 StringBuilder sb = new StringBuilder(128); 17176 sb.append("Wake for "); 17177 app.toShortString(sb); 17178 sb.append(": over "); 17179 TimeUtils.formatDuration(realtimeSince, sb); 17180 sb.append(" used "); 17181 TimeUtils.formatDuration(wtimeUsed, sb); 17182 sb.append(" ("); 17183 sb.append((wtimeUsed*100)/realtimeSince); 17184 sb.append("%)"); 17185 Slog.i(TAG, sb.toString()); 17186 sb.setLength(0); 17187 sb.append("CPU for "); 17188 app.toShortString(sb); 17189 sb.append(": over "); 17190 TimeUtils.formatDuration(uptimeSince, sb); 17191 sb.append(" used "); 17192 TimeUtils.formatDuration(cputimeUsed, sb); 17193 sb.append(" ("); 17194 sb.append((cputimeUsed*100)/uptimeSince); 17195 sb.append("%)"); 17196 Slog.i(TAG, sb.toString()); 17197 } 17198 // If a process has held a wake lock for more 17199 // than 50% of the time during this period, 17200 // that sounds bad. Kill! 17201 if (doWakeKills && realtimeSince > 0 17202 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17203 synchronized (stats) { 17204 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17205 realtimeSince, wtimeUsed); 17206 } 17207 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17208 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17209 } else if (doCpuKills && uptimeSince > 0 17210 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17211 synchronized (stats) { 17212 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17213 uptimeSince, cputimeUsed); 17214 } 17215 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17216 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17217 } else { 17218 app.lastWakeTime = wtime; 17219 app.lastCpuTime = app.curCpuTime; 17220 } 17221 } 17222 } 17223 } 17224 17225 private final boolean applyOomAdjLocked(ProcessRecord app, 17226 ProcessRecord TOP_APP, boolean doingAll, long now) { 17227 boolean success = true; 17228 17229 if (app.curRawAdj != app.setRawAdj) { 17230 app.setRawAdj = app.curRawAdj; 17231 } 17232 17233 int changes = 0; 17234 17235 if (app.curAdj != app.setAdj) { 17236 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17237 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17238 TAG, "Set " + app.pid + " " + app.processName + 17239 " adj " + app.curAdj + ": " + app.adjType); 17240 app.setAdj = app.curAdj; 17241 } 17242 17243 if (app.setSchedGroup != app.curSchedGroup) { 17244 app.setSchedGroup = app.curSchedGroup; 17245 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17246 "Setting process group of " + app.processName 17247 + " to " + app.curSchedGroup); 17248 if (app.waitingToKill != null && 17249 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17250 app.kill(app.waitingToKill, true); 17251 success = false; 17252 } else { 17253 if (true) { 17254 long oldId = Binder.clearCallingIdentity(); 17255 try { 17256 Process.setProcessGroup(app.pid, app.curSchedGroup); 17257 } catch (Exception e) { 17258 Slog.w(TAG, "Failed setting process group of " + app.pid 17259 + " to " + app.curSchedGroup); 17260 e.printStackTrace(); 17261 } finally { 17262 Binder.restoreCallingIdentity(oldId); 17263 } 17264 } else { 17265 if (app.thread != null) { 17266 try { 17267 app.thread.setSchedulingGroup(app.curSchedGroup); 17268 } catch (RemoteException e) { 17269 } 17270 } 17271 } 17272 Process.setSwappiness(app.pid, 17273 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17274 } 17275 } 17276 if (app.repForegroundActivities != app.foregroundActivities) { 17277 app.repForegroundActivities = app.foregroundActivities; 17278 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17279 } 17280 if (app.repProcState != app.curProcState) { 17281 app.repProcState = app.curProcState; 17282 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17283 if (app.thread != null) { 17284 try { 17285 if (false) { 17286 //RuntimeException h = new RuntimeException("here"); 17287 Slog.i(TAG, "Sending new process state " + app.repProcState 17288 + " to " + app /*, h*/); 17289 } 17290 app.thread.setProcessState(app.repProcState); 17291 } catch (RemoteException e) { 17292 } 17293 } 17294 } 17295 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17296 app.setProcState)) { 17297 app.lastStateTime = now; 17298 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17299 isSleeping(), now); 17300 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17301 + ProcessList.makeProcStateString(app.setProcState) + " to " 17302 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17303 + (app.nextPssTime-now) + ": " + app); 17304 } else { 17305 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17306 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17307 requestPssLocked(app, app.setProcState); 17308 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17309 isSleeping(), now); 17310 } else if (false && DEBUG_PSS) { 17311 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17312 } 17313 } 17314 if (app.setProcState != app.curProcState) { 17315 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17316 "Proc state change of " + app.processName 17317 + " to " + app.curProcState); 17318 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17319 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17320 if (setImportant && !curImportant) { 17321 // This app is no longer something we consider important enough to allow to 17322 // use arbitrary amounts of battery power. Note 17323 // its current wake lock time to later know to kill it if 17324 // it is not behaving well. 17325 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17326 synchronized (stats) { 17327 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17328 app.pid, SystemClock.elapsedRealtime()); 17329 } 17330 app.lastCpuTime = app.curCpuTime; 17331 17332 } 17333 app.setProcState = app.curProcState; 17334 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17335 app.notCachedSinceIdle = false; 17336 } 17337 if (!doingAll) { 17338 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17339 } else { 17340 app.procStateChanged = true; 17341 } 17342 } 17343 17344 if (changes != 0) { 17345 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17346 int i = mPendingProcessChanges.size()-1; 17347 ProcessChangeItem item = null; 17348 while (i >= 0) { 17349 item = mPendingProcessChanges.get(i); 17350 if (item.pid == app.pid) { 17351 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17352 break; 17353 } 17354 i--; 17355 } 17356 if (i < 0) { 17357 // No existing item in pending changes; need a new one. 17358 final int NA = mAvailProcessChanges.size(); 17359 if (NA > 0) { 17360 item = mAvailProcessChanges.remove(NA-1); 17361 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17362 } else { 17363 item = new ProcessChangeItem(); 17364 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17365 } 17366 item.changes = 0; 17367 item.pid = app.pid; 17368 item.uid = app.info.uid; 17369 if (mPendingProcessChanges.size() == 0) { 17370 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17371 "*** Enqueueing dispatch processes changed!"); 17372 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17373 } 17374 mPendingProcessChanges.add(item); 17375 } 17376 item.changes |= changes; 17377 item.processState = app.repProcState; 17378 item.foregroundActivities = app.repForegroundActivities; 17379 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17380 + Integer.toHexString(System.identityHashCode(item)) 17381 + " " + app.toShortString() + ": changes=" + item.changes 17382 + " procState=" + item.processState 17383 + " foreground=" + item.foregroundActivities 17384 + " type=" + app.adjType + " source=" + app.adjSource 17385 + " target=" + app.adjTarget); 17386 } 17387 17388 return success; 17389 } 17390 17391 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17392 if (proc.thread != null) { 17393 if (proc.baseProcessTracker != null) { 17394 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17395 } 17396 if (proc.repProcState >= 0) { 17397 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17398 proc.repProcState); 17399 } 17400 } 17401 } 17402 17403 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17404 ProcessRecord TOP_APP, boolean doingAll, long now) { 17405 if (app.thread == null) { 17406 return false; 17407 } 17408 17409 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17410 17411 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17412 } 17413 17414 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17415 boolean oomAdj) { 17416 if (isForeground != proc.foregroundServices) { 17417 proc.foregroundServices = isForeground; 17418 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17419 proc.info.uid); 17420 if (isForeground) { 17421 if (curProcs == null) { 17422 curProcs = new ArrayList<ProcessRecord>(); 17423 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17424 } 17425 if (!curProcs.contains(proc)) { 17426 curProcs.add(proc); 17427 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17428 proc.info.packageName, proc.info.uid); 17429 } 17430 } else { 17431 if (curProcs != null) { 17432 if (curProcs.remove(proc)) { 17433 mBatteryStatsService.noteEvent( 17434 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17435 proc.info.packageName, proc.info.uid); 17436 if (curProcs.size() <= 0) { 17437 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17438 } 17439 } 17440 } 17441 } 17442 if (oomAdj) { 17443 updateOomAdjLocked(); 17444 } 17445 } 17446 } 17447 17448 private final ActivityRecord resumedAppLocked() { 17449 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17450 String pkg; 17451 int uid; 17452 if (act != null) { 17453 pkg = act.packageName; 17454 uid = act.info.applicationInfo.uid; 17455 } else { 17456 pkg = null; 17457 uid = -1; 17458 } 17459 // Has the UID or resumed package name changed? 17460 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17461 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17462 if (mCurResumedPackage != null) { 17463 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17464 mCurResumedPackage, mCurResumedUid); 17465 } 17466 mCurResumedPackage = pkg; 17467 mCurResumedUid = uid; 17468 if (mCurResumedPackage != null) { 17469 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17470 mCurResumedPackage, mCurResumedUid); 17471 } 17472 } 17473 return act; 17474 } 17475 17476 final boolean updateOomAdjLocked(ProcessRecord app) { 17477 final ActivityRecord TOP_ACT = resumedAppLocked(); 17478 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17479 final boolean wasCached = app.cached; 17480 17481 mAdjSeq++; 17482 17483 // This is the desired cached adjusment we want to tell it to use. 17484 // If our app is currently cached, we know it, and that is it. Otherwise, 17485 // we don't know it yet, and it needs to now be cached we will then 17486 // need to do a complete oom adj. 17487 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17488 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17489 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17490 SystemClock.uptimeMillis()); 17491 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17492 // Changed to/from cached state, so apps after it in the LRU 17493 // list may also be changed. 17494 updateOomAdjLocked(); 17495 } 17496 return success; 17497 } 17498 17499 final void updateOomAdjLocked() { 17500 final ActivityRecord TOP_ACT = resumedAppLocked(); 17501 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17502 final long now = SystemClock.uptimeMillis(); 17503 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17504 final int N = mLruProcesses.size(); 17505 17506 if (false) { 17507 RuntimeException e = new RuntimeException(); 17508 e.fillInStackTrace(); 17509 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17510 } 17511 17512 mAdjSeq++; 17513 mNewNumServiceProcs = 0; 17514 mNewNumAServiceProcs = 0; 17515 17516 final int emptyProcessLimit; 17517 final int cachedProcessLimit; 17518 if (mProcessLimit <= 0) { 17519 emptyProcessLimit = cachedProcessLimit = 0; 17520 } else if (mProcessLimit == 1) { 17521 emptyProcessLimit = 1; 17522 cachedProcessLimit = 0; 17523 } else { 17524 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17525 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17526 } 17527 17528 // Let's determine how many processes we have running vs. 17529 // how many slots we have for background processes; we may want 17530 // to put multiple processes in a slot of there are enough of 17531 // them. 17532 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17533 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17534 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17535 if (numEmptyProcs > cachedProcessLimit) { 17536 // If there are more empty processes than our limit on cached 17537 // processes, then use the cached process limit for the factor. 17538 // This ensures that the really old empty processes get pushed 17539 // down to the bottom, so if we are running low on memory we will 17540 // have a better chance at keeping around more cached processes 17541 // instead of a gazillion empty processes. 17542 numEmptyProcs = cachedProcessLimit; 17543 } 17544 int emptyFactor = numEmptyProcs/numSlots; 17545 if (emptyFactor < 1) emptyFactor = 1; 17546 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17547 if (cachedFactor < 1) cachedFactor = 1; 17548 int stepCached = 0; 17549 int stepEmpty = 0; 17550 int numCached = 0; 17551 int numEmpty = 0; 17552 int numTrimming = 0; 17553 17554 mNumNonCachedProcs = 0; 17555 mNumCachedHiddenProcs = 0; 17556 17557 // First update the OOM adjustment for each of the 17558 // application processes based on their current state. 17559 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17560 int nextCachedAdj = curCachedAdj+1; 17561 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17562 int nextEmptyAdj = curEmptyAdj+2; 17563 for (int i=N-1; i>=0; i--) { 17564 ProcessRecord app = mLruProcesses.get(i); 17565 if (!app.killedByAm && app.thread != null) { 17566 app.procStateChanged = false; 17567 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17568 17569 // If we haven't yet assigned the final cached adj 17570 // to the process, do that now. 17571 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17572 switch (app.curProcState) { 17573 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17574 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17575 // This process is a cached process holding activities... 17576 // assign it the next cached value for that type, and then 17577 // step that cached level. 17578 app.curRawAdj = curCachedAdj; 17579 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17580 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17581 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17582 + ")"); 17583 if (curCachedAdj != nextCachedAdj) { 17584 stepCached++; 17585 if (stepCached >= cachedFactor) { 17586 stepCached = 0; 17587 curCachedAdj = nextCachedAdj; 17588 nextCachedAdj += 2; 17589 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17590 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17591 } 17592 } 17593 } 17594 break; 17595 default: 17596 // For everything else, assign next empty cached process 17597 // level and bump that up. Note that this means that 17598 // long-running services that have dropped down to the 17599 // cached level will be treated as empty (since their process 17600 // state is still as a service), which is what we want. 17601 app.curRawAdj = curEmptyAdj; 17602 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17603 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17604 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17605 + ")"); 17606 if (curEmptyAdj != nextEmptyAdj) { 17607 stepEmpty++; 17608 if (stepEmpty >= emptyFactor) { 17609 stepEmpty = 0; 17610 curEmptyAdj = nextEmptyAdj; 17611 nextEmptyAdj += 2; 17612 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17613 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17614 } 17615 } 17616 } 17617 break; 17618 } 17619 } 17620 17621 applyOomAdjLocked(app, TOP_APP, true, now); 17622 17623 // Count the number of process types. 17624 switch (app.curProcState) { 17625 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17626 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17627 mNumCachedHiddenProcs++; 17628 numCached++; 17629 if (numCached > cachedProcessLimit) { 17630 app.kill("cached #" + numCached, true); 17631 } 17632 break; 17633 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17634 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17635 && app.lastActivityTime < oldTime) { 17636 app.kill("empty for " 17637 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17638 / 1000) + "s", true); 17639 } else { 17640 numEmpty++; 17641 if (numEmpty > emptyProcessLimit) { 17642 app.kill("empty #" + numEmpty, true); 17643 } 17644 } 17645 break; 17646 default: 17647 mNumNonCachedProcs++; 17648 break; 17649 } 17650 17651 if (app.isolated && app.services.size() <= 0) { 17652 // If this is an isolated process, and there are no 17653 // services running in it, then the process is no longer 17654 // needed. We agressively kill these because we can by 17655 // definition not re-use the same process again, and it is 17656 // good to avoid having whatever code was running in them 17657 // left sitting around after no longer needed. 17658 app.kill("isolated not needed", true); 17659 } 17660 17661 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17662 && !app.killedByAm) { 17663 numTrimming++; 17664 } 17665 } 17666 } 17667 17668 mNumServiceProcs = mNewNumServiceProcs; 17669 17670 // Now determine the memory trimming level of background processes. 17671 // Unfortunately we need to start at the back of the list to do this 17672 // properly. We only do this if the number of background apps we 17673 // are managing to keep around is less than half the maximum we desire; 17674 // if we are keeping a good number around, we'll let them use whatever 17675 // memory they want. 17676 final int numCachedAndEmpty = numCached + numEmpty; 17677 int memFactor; 17678 if (numCached <= ProcessList.TRIM_CACHED_APPS 17679 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17680 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17681 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17682 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17683 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17684 } else { 17685 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17686 } 17687 } else { 17688 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17689 } 17690 // We always allow the memory level to go up (better). We only allow it to go 17691 // down if we are in a state where that is allowed, *and* the total number of processes 17692 // has gone down since last time. 17693 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17694 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17695 + " last=" + mLastNumProcesses); 17696 if (memFactor > mLastMemoryLevel) { 17697 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17698 memFactor = mLastMemoryLevel; 17699 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17700 } 17701 } 17702 mLastMemoryLevel = memFactor; 17703 mLastNumProcesses = mLruProcesses.size(); 17704 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17705 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17706 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17707 if (mLowRamStartTime == 0) { 17708 mLowRamStartTime = now; 17709 } 17710 int step = 0; 17711 int fgTrimLevel; 17712 switch (memFactor) { 17713 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17714 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17715 break; 17716 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17717 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17718 break; 17719 default: 17720 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17721 break; 17722 } 17723 int factor = numTrimming/3; 17724 int minFactor = 2; 17725 if (mHomeProcess != null) minFactor++; 17726 if (mPreviousProcess != null) minFactor++; 17727 if (factor < minFactor) factor = minFactor; 17728 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17729 for (int i=N-1; i>=0; i--) { 17730 ProcessRecord app = mLruProcesses.get(i); 17731 if (allChanged || app.procStateChanged) { 17732 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17733 app.procStateChanged = false; 17734 } 17735 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17736 && !app.killedByAm) { 17737 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17738 try { 17739 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17740 "Trimming memory of " + app.processName 17741 + " to " + curLevel); 17742 app.thread.scheduleTrimMemory(curLevel); 17743 } catch (RemoteException e) { 17744 } 17745 if (false) { 17746 // For now we won't do this; our memory trimming seems 17747 // to be good enough at this point that destroying 17748 // activities causes more harm than good. 17749 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17750 && app != mHomeProcess && app != mPreviousProcess) { 17751 // Need to do this on its own message because the stack may not 17752 // be in a consistent state at this point. 17753 // For these apps we will also finish their activities 17754 // to help them free memory. 17755 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17756 } 17757 } 17758 } 17759 app.trimMemoryLevel = curLevel; 17760 step++; 17761 if (step >= factor) { 17762 step = 0; 17763 switch (curLevel) { 17764 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17765 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17766 break; 17767 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17768 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17769 break; 17770 } 17771 } 17772 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17773 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17774 && app.thread != null) { 17775 try { 17776 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17777 "Trimming memory of heavy-weight " + app.processName 17778 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17779 app.thread.scheduleTrimMemory( 17780 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17781 } catch (RemoteException e) { 17782 } 17783 } 17784 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17785 } else { 17786 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17787 || app.systemNoUi) && app.pendingUiClean) { 17788 // If this application is now in the background and it 17789 // had done UI, then give it the special trim level to 17790 // have it free UI resources. 17791 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17792 if (app.trimMemoryLevel < level && app.thread != null) { 17793 try { 17794 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17795 "Trimming memory of bg-ui " + app.processName 17796 + " to " + level); 17797 app.thread.scheduleTrimMemory(level); 17798 } catch (RemoteException e) { 17799 } 17800 } 17801 app.pendingUiClean = false; 17802 } 17803 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17804 try { 17805 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17806 "Trimming memory of fg " + app.processName 17807 + " to " + fgTrimLevel); 17808 app.thread.scheduleTrimMemory(fgTrimLevel); 17809 } catch (RemoteException e) { 17810 } 17811 } 17812 app.trimMemoryLevel = fgTrimLevel; 17813 } 17814 } 17815 } else { 17816 if (mLowRamStartTime != 0) { 17817 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17818 mLowRamStartTime = 0; 17819 } 17820 for (int i=N-1; i>=0; i--) { 17821 ProcessRecord app = mLruProcesses.get(i); 17822 if (allChanged || app.procStateChanged) { 17823 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17824 app.procStateChanged = false; 17825 } 17826 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17827 || app.systemNoUi) && app.pendingUiClean) { 17828 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17829 && app.thread != null) { 17830 try { 17831 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17832 "Trimming memory of ui hidden " + app.processName 17833 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17834 app.thread.scheduleTrimMemory( 17835 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17836 } catch (RemoteException e) { 17837 } 17838 } 17839 app.pendingUiClean = false; 17840 } 17841 app.trimMemoryLevel = 0; 17842 } 17843 } 17844 17845 if (mAlwaysFinishActivities) { 17846 // Need to do this on its own message because the stack may not 17847 // be in a consistent state at this point. 17848 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17849 } 17850 17851 if (allChanged) { 17852 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17853 } 17854 17855 if (mProcessStats.shouldWriteNowLocked(now)) { 17856 mHandler.post(new Runnable() { 17857 @Override public void run() { 17858 synchronized (ActivityManagerService.this) { 17859 mProcessStats.writeStateAsyncLocked(); 17860 } 17861 } 17862 }); 17863 } 17864 17865 if (DEBUG_OOM_ADJ) { 17866 if (false) { 17867 RuntimeException here = new RuntimeException("here"); 17868 here.fillInStackTrace(); 17869 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17870 } else { 17871 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17872 } 17873 } 17874 } 17875 17876 final void trimApplications() { 17877 synchronized (this) { 17878 int i; 17879 17880 // First remove any unused application processes whose package 17881 // has been removed. 17882 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17883 final ProcessRecord app = mRemovedProcesses.get(i); 17884 if (app.activities.size() == 0 17885 && app.curReceiver == null && app.services.size() == 0) { 17886 Slog.i( 17887 TAG, "Exiting empty application process " 17888 + app.processName + " (" 17889 + (app.thread != null ? app.thread.asBinder() : null) 17890 + ")\n"); 17891 if (app.pid > 0 && app.pid != MY_PID) { 17892 app.kill("empty", false); 17893 } else { 17894 try { 17895 app.thread.scheduleExit(); 17896 } catch (Exception e) { 17897 // Ignore exceptions. 17898 } 17899 } 17900 cleanUpApplicationRecordLocked(app, false, true, -1); 17901 mRemovedProcesses.remove(i); 17902 17903 if (app.persistent) { 17904 addAppLocked(app.info, false, null /* ABI override */); 17905 } 17906 } 17907 } 17908 17909 // Now update the oom adj for all processes. 17910 updateOomAdjLocked(); 17911 } 17912 } 17913 17914 /** This method sends the specified signal to each of the persistent apps */ 17915 public void signalPersistentProcesses(int sig) throws RemoteException { 17916 if (sig != Process.SIGNAL_USR1) { 17917 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17918 } 17919 17920 synchronized (this) { 17921 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17922 != PackageManager.PERMISSION_GRANTED) { 17923 throw new SecurityException("Requires permission " 17924 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17925 } 17926 17927 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17928 ProcessRecord r = mLruProcesses.get(i); 17929 if (r.thread != null && r.persistent) { 17930 Process.sendSignal(r.pid, sig); 17931 } 17932 } 17933 } 17934 } 17935 17936 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17937 if (proc == null || proc == mProfileProc) { 17938 proc = mProfileProc; 17939 profileType = mProfileType; 17940 clearProfilerLocked(); 17941 } 17942 if (proc == null) { 17943 return; 17944 } 17945 try { 17946 proc.thread.profilerControl(false, null, profileType); 17947 } catch (RemoteException e) { 17948 throw new IllegalStateException("Process disappeared"); 17949 } 17950 } 17951 17952 private void clearProfilerLocked() { 17953 if (mProfileFd != null) { 17954 try { 17955 mProfileFd.close(); 17956 } catch (IOException e) { 17957 } 17958 } 17959 mProfileApp = null; 17960 mProfileProc = null; 17961 mProfileFile = null; 17962 mProfileType = 0; 17963 mAutoStopProfiler = false; 17964 mSamplingInterval = 0; 17965 } 17966 17967 public boolean profileControl(String process, int userId, boolean start, 17968 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17969 17970 try { 17971 synchronized (this) { 17972 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17973 // its own permission. 17974 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17975 != PackageManager.PERMISSION_GRANTED) { 17976 throw new SecurityException("Requires permission " 17977 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17978 } 17979 17980 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17981 throw new IllegalArgumentException("null profile info or fd"); 17982 } 17983 17984 ProcessRecord proc = null; 17985 if (process != null) { 17986 proc = findProcessLocked(process, userId, "profileControl"); 17987 } 17988 17989 if (start && (proc == null || proc.thread == null)) { 17990 throw new IllegalArgumentException("Unknown process: " + process); 17991 } 17992 17993 if (start) { 17994 stopProfilerLocked(null, 0); 17995 setProfileApp(proc.info, proc.processName, profilerInfo); 17996 mProfileProc = proc; 17997 mProfileType = profileType; 17998 ParcelFileDescriptor fd = profilerInfo.profileFd; 17999 try { 18000 fd = fd.dup(); 18001 } catch (IOException e) { 18002 fd = null; 18003 } 18004 profilerInfo.profileFd = fd; 18005 proc.thread.profilerControl(start, profilerInfo, profileType); 18006 fd = null; 18007 mProfileFd = null; 18008 } else { 18009 stopProfilerLocked(proc, profileType); 18010 if (profilerInfo != null && profilerInfo.profileFd != null) { 18011 try { 18012 profilerInfo.profileFd.close(); 18013 } catch (IOException e) { 18014 } 18015 } 18016 } 18017 18018 return true; 18019 } 18020 } catch (RemoteException e) { 18021 throw new IllegalStateException("Process disappeared"); 18022 } finally { 18023 if (profilerInfo != null && profilerInfo.profileFd != null) { 18024 try { 18025 profilerInfo.profileFd.close(); 18026 } catch (IOException e) { 18027 } 18028 } 18029 } 18030 } 18031 18032 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18033 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18034 userId, true, ALLOW_FULL_ONLY, callName, null); 18035 ProcessRecord proc = null; 18036 try { 18037 int pid = Integer.parseInt(process); 18038 synchronized (mPidsSelfLocked) { 18039 proc = mPidsSelfLocked.get(pid); 18040 } 18041 } catch (NumberFormatException e) { 18042 } 18043 18044 if (proc == null) { 18045 ArrayMap<String, SparseArray<ProcessRecord>> all 18046 = mProcessNames.getMap(); 18047 SparseArray<ProcessRecord> procs = all.get(process); 18048 if (procs != null && procs.size() > 0) { 18049 proc = procs.valueAt(0); 18050 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18051 for (int i=1; i<procs.size(); i++) { 18052 ProcessRecord thisProc = procs.valueAt(i); 18053 if (thisProc.userId == userId) { 18054 proc = thisProc; 18055 break; 18056 } 18057 } 18058 } 18059 } 18060 } 18061 18062 return proc; 18063 } 18064 18065 public boolean dumpHeap(String process, int userId, boolean managed, 18066 String path, ParcelFileDescriptor fd) throws RemoteException { 18067 18068 try { 18069 synchronized (this) { 18070 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18071 // its own permission (same as profileControl). 18072 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18073 != PackageManager.PERMISSION_GRANTED) { 18074 throw new SecurityException("Requires permission " 18075 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18076 } 18077 18078 if (fd == null) { 18079 throw new IllegalArgumentException("null fd"); 18080 } 18081 18082 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18083 if (proc == null || proc.thread == null) { 18084 throw new IllegalArgumentException("Unknown process: " + process); 18085 } 18086 18087 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18088 if (!isDebuggable) { 18089 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18090 throw new SecurityException("Process not debuggable: " + proc); 18091 } 18092 } 18093 18094 proc.thread.dumpHeap(managed, path, fd); 18095 fd = null; 18096 return true; 18097 } 18098 } catch (RemoteException e) { 18099 throw new IllegalStateException("Process disappeared"); 18100 } finally { 18101 if (fd != null) { 18102 try { 18103 fd.close(); 18104 } catch (IOException e) { 18105 } 18106 } 18107 } 18108 } 18109 18110 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18111 public void monitor() { 18112 synchronized (this) { } 18113 } 18114 18115 void onCoreSettingsChange(Bundle settings) { 18116 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18117 ProcessRecord processRecord = mLruProcesses.get(i); 18118 try { 18119 if (processRecord.thread != null) { 18120 processRecord.thread.setCoreSettings(settings); 18121 } 18122 } catch (RemoteException re) { 18123 /* ignore */ 18124 } 18125 } 18126 } 18127 18128 // Multi-user methods 18129 18130 /** 18131 * Start user, if its not already running, but don't bring it to foreground. 18132 */ 18133 @Override 18134 public boolean startUserInBackground(final int userId) { 18135 return startUser(userId, /* foreground */ false); 18136 } 18137 18138 /** 18139 * Start user, if its not already running, and bring it to foreground. 18140 */ 18141 boolean startUserInForeground(final int userId, Dialog dlg) { 18142 boolean result = startUser(userId, /* foreground */ true); 18143 dlg.dismiss(); 18144 return result; 18145 } 18146 18147 /** 18148 * Refreshes the list of users related to the current user when either a 18149 * user switch happens or when a new related user is started in the 18150 * background. 18151 */ 18152 private void updateCurrentProfileIdsLocked() { 18153 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18154 mCurrentUserId, false /* enabledOnly */); 18155 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18156 for (int i = 0; i < currentProfileIds.length; i++) { 18157 currentProfileIds[i] = profiles.get(i).id; 18158 } 18159 mCurrentProfileIds = currentProfileIds; 18160 18161 synchronized (mUserProfileGroupIdsSelfLocked) { 18162 mUserProfileGroupIdsSelfLocked.clear(); 18163 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18164 for (int i = 0; i < users.size(); i++) { 18165 UserInfo user = users.get(i); 18166 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18167 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18168 } 18169 } 18170 } 18171 } 18172 18173 private Set getProfileIdsLocked(int userId) { 18174 Set userIds = new HashSet<Integer>(); 18175 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18176 userId, false /* enabledOnly */); 18177 for (UserInfo user : profiles) { 18178 userIds.add(Integer.valueOf(user.id)); 18179 } 18180 return userIds; 18181 } 18182 18183 @Override 18184 public boolean switchUser(final int userId) { 18185 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18186 String userName; 18187 synchronized (this) { 18188 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18189 if (userInfo == null) { 18190 Slog.w(TAG, "No user info for user #" + userId); 18191 return false; 18192 } 18193 if (userInfo.isManagedProfile()) { 18194 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18195 return false; 18196 } 18197 userName = userInfo.name; 18198 mTargetUserId = userId; 18199 } 18200 mHandler.removeMessages(START_USER_SWITCH_MSG); 18201 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18202 return true; 18203 } 18204 18205 private void showUserSwitchDialog(int userId, String userName) { 18206 // The dialog will show and then initiate the user switch by calling startUserInForeground 18207 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18208 true /* above system */); 18209 d.show(); 18210 } 18211 18212 private boolean startUser(final int userId, final boolean foreground) { 18213 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18214 != PackageManager.PERMISSION_GRANTED) { 18215 String msg = "Permission Denial: switchUser() from pid=" 18216 + Binder.getCallingPid() 18217 + ", uid=" + Binder.getCallingUid() 18218 + " requires " + INTERACT_ACROSS_USERS_FULL; 18219 Slog.w(TAG, msg); 18220 throw new SecurityException(msg); 18221 } 18222 18223 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18224 18225 final long ident = Binder.clearCallingIdentity(); 18226 try { 18227 synchronized (this) { 18228 final int oldUserId = mCurrentUserId; 18229 if (oldUserId == userId) { 18230 return true; 18231 } 18232 18233 mStackSupervisor.setLockTaskModeLocked(null, false); 18234 18235 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18236 if (userInfo == null) { 18237 Slog.w(TAG, "No user info for user #" + userId); 18238 return false; 18239 } 18240 if (foreground && userInfo.isManagedProfile()) { 18241 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18242 return false; 18243 } 18244 18245 if (foreground) { 18246 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18247 R.anim.screen_user_enter); 18248 } 18249 18250 boolean needStart = false; 18251 18252 // If the user we are switching to is not currently started, then 18253 // we need to start it now. 18254 if (mStartedUsers.get(userId) == null) { 18255 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18256 updateStartedUserArrayLocked(); 18257 needStart = true; 18258 } 18259 18260 final Integer userIdInt = Integer.valueOf(userId); 18261 mUserLru.remove(userIdInt); 18262 mUserLru.add(userIdInt); 18263 18264 if (foreground) { 18265 mCurrentUserId = userId; 18266 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18267 updateCurrentProfileIdsLocked(); 18268 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18269 // Once the internal notion of the active user has switched, we lock the device 18270 // with the option to show the user switcher on the keyguard. 18271 mWindowManager.lockNow(null); 18272 } else { 18273 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18274 updateCurrentProfileIdsLocked(); 18275 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18276 mUserLru.remove(currentUserIdInt); 18277 mUserLru.add(currentUserIdInt); 18278 } 18279 18280 final UserStartedState uss = mStartedUsers.get(userId); 18281 18282 // Make sure user is in the started state. If it is currently 18283 // stopping, we need to knock that off. 18284 if (uss.mState == UserStartedState.STATE_STOPPING) { 18285 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18286 // so we can just fairly silently bring the user back from 18287 // the almost-dead. 18288 uss.mState = UserStartedState.STATE_RUNNING; 18289 updateStartedUserArrayLocked(); 18290 needStart = true; 18291 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18292 // This means ACTION_SHUTDOWN has been sent, so we will 18293 // need to treat this as a new boot of the user. 18294 uss.mState = UserStartedState.STATE_BOOTING; 18295 updateStartedUserArrayLocked(); 18296 needStart = true; 18297 } 18298 18299 if (uss.mState == UserStartedState.STATE_BOOTING) { 18300 // Booting up a new user, need to tell system services about it. 18301 // Note that this is on the same handler as scheduling of broadcasts, 18302 // which is important because it needs to go first. 18303 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18304 } 18305 18306 if (foreground) { 18307 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18308 oldUserId)); 18309 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18310 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18311 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18312 oldUserId, userId, uss)); 18313 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18314 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18315 } 18316 18317 if (needStart) { 18318 // Send USER_STARTED broadcast 18319 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18320 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18321 | Intent.FLAG_RECEIVER_FOREGROUND); 18322 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18323 broadcastIntentLocked(null, null, intent, 18324 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18325 false, false, MY_PID, Process.SYSTEM_UID, userId); 18326 } 18327 18328 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18329 if (userId != UserHandle.USER_OWNER) { 18330 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18331 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18332 broadcastIntentLocked(null, null, intent, null, 18333 new IIntentReceiver.Stub() { 18334 public void performReceive(Intent intent, int resultCode, 18335 String data, Bundle extras, boolean ordered, 18336 boolean sticky, int sendingUser) { 18337 onUserInitialized(uss, foreground, oldUserId, userId); 18338 } 18339 }, 0, null, null, null, AppOpsManager.OP_NONE, 18340 true, false, MY_PID, Process.SYSTEM_UID, 18341 userId); 18342 uss.initializing = true; 18343 } else { 18344 getUserManagerLocked().makeInitialized(userInfo.id); 18345 } 18346 } 18347 18348 if (foreground) { 18349 if (!uss.initializing) { 18350 moveUserToForeground(uss, oldUserId, userId); 18351 } 18352 } else { 18353 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18354 } 18355 18356 if (needStart) { 18357 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18358 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18359 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18360 broadcastIntentLocked(null, null, intent, 18361 null, new IIntentReceiver.Stub() { 18362 @Override 18363 public void performReceive(Intent intent, int resultCode, String data, 18364 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18365 throws RemoteException { 18366 } 18367 }, 0, null, null, 18368 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18369 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18370 } 18371 } 18372 } finally { 18373 Binder.restoreCallingIdentity(ident); 18374 } 18375 18376 return true; 18377 } 18378 18379 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18380 long ident = Binder.clearCallingIdentity(); 18381 try { 18382 Intent intent; 18383 if (oldUserId >= 0) { 18384 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18385 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18386 int count = profiles.size(); 18387 for (int i = 0; i < count; i++) { 18388 int profileUserId = profiles.get(i).id; 18389 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18391 | Intent.FLAG_RECEIVER_FOREGROUND); 18392 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18393 broadcastIntentLocked(null, null, intent, 18394 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18395 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18396 } 18397 } 18398 if (newUserId >= 0) { 18399 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18400 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18401 int count = profiles.size(); 18402 for (int i = 0; i < count; i++) { 18403 int profileUserId = profiles.get(i).id; 18404 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18406 | Intent.FLAG_RECEIVER_FOREGROUND); 18407 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18408 broadcastIntentLocked(null, null, intent, 18409 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18410 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18411 } 18412 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18414 | Intent.FLAG_RECEIVER_FOREGROUND); 18415 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18416 broadcastIntentLocked(null, null, intent, 18417 null, null, 0, null, null, 18418 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18419 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18420 } 18421 } finally { 18422 Binder.restoreCallingIdentity(ident); 18423 } 18424 } 18425 18426 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18427 final int newUserId) { 18428 final int N = mUserSwitchObservers.beginBroadcast(); 18429 if (N > 0) { 18430 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18431 int mCount = 0; 18432 @Override 18433 public void sendResult(Bundle data) throws RemoteException { 18434 synchronized (ActivityManagerService.this) { 18435 if (mCurUserSwitchCallback == this) { 18436 mCount++; 18437 if (mCount == N) { 18438 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18439 } 18440 } 18441 } 18442 } 18443 }; 18444 synchronized (this) { 18445 uss.switching = true; 18446 mCurUserSwitchCallback = callback; 18447 } 18448 for (int i=0; i<N; i++) { 18449 try { 18450 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18451 newUserId, callback); 18452 } catch (RemoteException e) { 18453 } 18454 } 18455 } else { 18456 synchronized (this) { 18457 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18458 } 18459 } 18460 mUserSwitchObservers.finishBroadcast(); 18461 } 18462 18463 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18464 synchronized (this) { 18465 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18466 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18467 } 18468 } 18469 18470 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18471 mCurUserSwitchCallback = null; 18472 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18473 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18474 oldUserId, newUserId, uss)); 18475 } 18476 18477 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18478 synchronized (this) { 18479 if (foreground) { 18480 moveUserToForeground(uss, oldUserId, newUserId); 18481 } 18482 } 18483 18484 completeSwitchAndInitalize(uss, newUserId, true, false); 18485 } 18486 18487 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18488 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18489 if (homeInFront) { 18490 startHomeActivityLocked(newUserId); 18491 } else { 18492 mStackSupervisor.resumeTopActivitiesLocked(); 18493 } 18494 EventLogTags.writeAmSwitchUser(newUserId); 18495 getUserManagerLocked().userForeground(newUserId); 18496 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18497 } 18498 18499 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18500 completeSwitchAndInitalize(uss, newUserId, false, true); 18501 } 18502 18503 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18504 boolean clearInitializing, boolean clearSwitching) { 18505 boolean unfrozen = false; 18506 synchronized (this) { 18507 if (clearInitializing) { 18508 uss.initializing = false; 18509 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18510 } 18511 if (clearSwitching) { 18512 uss.switching = false; 18513 } 18514 if (!uss.switching && !uss.initializing) { 18515 mWindowManager.stopFreezingScreen(); 18516 unfrozen = true; 18517 } 18518 } 18519 if (unfrozen) { 18520 final int N = mUserSwitchObservers.beginBroadcast(); 18521 for (int i=0; i<N; i++) { 18522 try { 18523 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18524 } catch (RemoteException e) { 18525 } 18526 } 18527 mUserSwitchObservers.finishBroadcast(); 18528 } 18529 } 18530 18531 void scheduleStartProfilesLocked() { 18532 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18533 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18534 DateUtils.SECOND_IN_MILLIS); 18535 } 18536 } 18537 18538 void startProfilesLocked() { 18539 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18540 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18541 mCurrentUserId, false /* enabledOnly */); 18542 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18543 for (UserInfo user : profiles) { 18544 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18545 && user.id != mCurrentUserId) { 18546 toStart.add(user); 18547 } 18548 } 18549 final int n = toStart.size(); 18550 int i = 0; 18551 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18552 startUserInBackground(toStart.get(i).id); 18553 } 18554 if (i < n) { 18555 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18556 } 18557 } 18558 18559 void finishUserBoot(UserStartedState uss) { 18560 synchronized (this) { 18561 if (uss.mState == UserStartedState.STATE_BOOTING 18562 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18563 uss.mState = UserStartedState.STATE_RUNNING; 18564 final int userId = uss.mHandle.getIdentifier(); 18565 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18566 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18567 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18568 broadcastIntentLocked(null, null, intent, 18569 null, null, 0, null, null, 18570 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18571 true, false, MY_PID, Process.SYSTEM_UID, userId); 18572 } 18573 } 18574 } 18575 18576 void finishUserSwitch(UserStartedState uss) { 18577 synchronized (this) { 18578 finishUserBoot(uss); 18579 18580 startProfilesLocked(); 18581 18582 int num = mUserLru.size(); 18583 int i = 0; 18584 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18585 Integer oldUserId = mUserLru.get(i); 18586 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18587 if (oldUss == null) { 18588 // Shouldn't happen, but be sane if it does. 18589 mUserLru.remove(i); 18590 num--; 18591 continue; 18592 } 18593 if (oldUss.mState == UserStartedState.STATE_STOPPING 18594 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18595 // This user is already stopping, doesn't count. 18596 num--; 18597 i++; 18598 continue; 18599 } 18600 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18601 // Owner and current can't be stopped, but count as running. 18602 i++; 18603 continue; 18604 } 18605 // This is a user to be stopped. 18606 stopUserLocked(oldUserId, null); 18607 num--; 18608 i++; 18609 } 18610 } 18611 } 18612 18613 @Override 18614 public int stopUser(final int userId, final IStopUserCallback callback) { 18615 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18616 != PackageManager.PERMISSION_GRANTED) { 18617 String msg = "Permission Denial: switchUser() from pid=" 18618 + Binder.getCallingPid() 18619 + ", uid=" + Binder.getCallingUid() 18620 + " requires " + INTERACT_ACROSS_USERS_FULL; 18621 Slog.w(TAG, msg); 18622 throw new SecurityException(msg); 18623 } 18624 if (userId <= 0) { 18625 throw new IllegalArgumentException("Can't stop primary user " + userId); 18626 } 18627 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18628 synchronized (this) { 18629 return stopUserLocked(userId, callback); 18630 } 18631 } 18632 18633 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18634 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18635 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18636 return ActivityManager.USER_OP_IS_CURRENT; 18637 } 18638 18639 final UserStartedState uss = mStartedUsers.get(userId); 18640 if (uss == null) { 18641 // User is not started, nothing to do... but we do need to 18642 // callback if requested. 18643 if (callback != null) { 18644 mHandler.post(new Runnable() { 18645 @Override 18646 public void run() { 18647 try { 18648 callback.userStopped(userId); 18649 } catch (RemoteException e) { 18650 } 18651 } 18652 }); 18653 } 18654 return ActivityManager.USER_OP_SUCCESS; 18655 } 18656 18657 if (callback != null) { 18658 uss.mStopCallbacks.add(callback); 18659 } 18660 18661 if (uss.mState != UserStartedState.STATE_STOPPING 18662 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18663 uss.mState = UserStartedState.STATE_STOPPING; 18664 updateStartedUserArrayLocked(); 18665 18666 long ident = Binder.clearCallingIdentity(); 18667 try { 18668 // We are going to broadcast ACTION_USER_STOPPING and then 18669 // once that is done send a final ACTION_SHUTDOWN and then 18670 // stop the user. 18671 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18672 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18673 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18674 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18675 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18676 // This is the result receiver for the final shutdown broadcast. 18677 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18678 @Override 18679 public void performReceive(Intent intent, int resultCode, String data, 18680 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18681 finishUserStop(uss); 18682 } 18683 }; 18684 // This is the result receiver for the initial stopping broadcast. 18685 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18686 @Override 18687 public void performReceive(Intent intent, int resultCode, String data, 18688 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18689 // On to the next. 18690 synchronized (ActivityManagerService.this) { 18691 if (uss.mState != UserStartedState.STATE_STOPPING) { 18692 // Whoops, we are being started back up. Abort, abort! 18693 return; 18694 } 18695 uss.mState = UserStartedState.STATE_SHUTDOWN; 18696 } 18697 mBatteryStatsService.noteEvent( 18698 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18699 Integer.toString(userId), userId); 18700 mSystemServiceManager.stopUser(userId); 18701 broadcastIntentLocked(null, null, shutdownIntent, 18702 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18703 true, false, MY_PID, Process.SYSTEM_UID, userId); 18704 } 18705 }; 18706 // Kick things off. 18707 broadcastIntentLocked(null, null, stoppingIntent, 18708 null, stoppingReceiver, 0, null, null, 18709 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18710 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18711 } finally { 18712 Binder.restoreCallingIdentity(ident); 18713 } 18714 } 18715 18716 return ActivityManager.USER_OP_SUCCESS; 18717 } 18718 18719 void finishUserStop(UserStartedState uss) { 18720 final int userId = uss.mHandle.getIdentifier(); 18721 boolean stopped; 18722 ArrayList<IStopUserCallback> callbacks; 18723 synchronized (this) { 18724 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18725 if (mStartedUsers.get(userId) != uss) { 18726 stopped = false; 18727 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18728 stopped = false; 18729 } else { 18730 stopped = true; 18731 // User can no longer run. 18732 mStartedUsers.remove(userId); 18733 mUserLru.remove(Integer.valueOf(userId)); 18734 updateStartedUserArrayLocked(); 18735 18736 // Clean up all state and processes associated with the user. 18737 // Kill all the processes for the user. 18738 forceStopUserLocked(userId, "finish user"); 18739 } 18740 18741 // Explicitly remove the old information in mRecentTasks. 18742 removeRecentTasksForUserLocked(userId); 18743 } 18744 18745 for (int i=0; i<callbacks.size(); i++) { 18746 try { 18747 if (stopped) callbacks.get(i).userStopped(userId); 18748 else callbacks.get(i).userStopAborted(userId); 18749 } catch (RemoteException e) { 18750 } 18751 } 18752 18753 if (stopped) { 18754 mSystemServiceManager.cleanupUser(userId); 18755 synchronized (this) { 18756 mStackSupervisor.removeUserLocked(userId); 18757 } 18758 } 18759 } 18760 18761 @Override 18762 public UserInfo getCurrentUser() { 18763 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18764 != PackageManager.PERMISSION_GRANTED) && ( 18765 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18766 != PackageManager.PERMISSION_GRANTED)) { 18767 String msg = "Permission Denial: getCurrentUser() from pid=" 18768 + Binder.getCallingPid() 18769 + ", uid=" + Binder.getCallingUid() 18770 + " requires " + INTERACT_ACROSS_USERS; 18771 Slog.w(TAG, msg); 18772 throw new SecurityException(msg); 18773 } 18774 synchronized (this) { 18775 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18776 return getUserManagerLocked().getUserInfo(userId); 18777 } 18778 } 18779 18780 int getCurrentUserIdLocked() { 18781 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18782 } 18783 18784 @Override 18785 public boolean isUserRunning(int userId, boolean orStopped) { 18786 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18787 != PackageManager.PERMISSION_GRANTED) { 18788 String msg = "Permission Denial: isUserRunning() from pid=" 18789 + Binder.getCallingPid() 18790 + ", uid=" + Binder.getCallingUid() 18791 + " requires " + INTERACT_ACROSS_USERS; 18792 Slog.w(TAG, msg); 18793 throw new SecurityException(msg); 18794 } 18795 synchronized (this) { 18796 return isUserRunningLocked(userId, orStopped); 18797 } 18798 } 18799 18800 boolean isUserRunningLocked(int userId, boolean orStopped) { 18801 UserStartedState state = mStartedUsers.get(userId); 18802 if (state == null) { 18803 return false; 18804 } 18805 if (orStopped) { 18806 return true; 18807 } 18808 return state.mState != UserStartedState.STATE_STOPPING 18809 && state.mState != UserStartedState.STATE_SHUTDOWN; 18810 } 18811 18812 @Override 18813 public int[] getRunningUserIds() { 18814 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18815 != PackageManager.PERMISSION_GRANTED) { 18816 String msg = "Permission Denial: isUserRunning() from pid=" 18817 + Binder.getCallingPid() 18818 + ", uid=" + Binder.getCallingUid() 18819 + " requires " + INTERACT_ACROSS_USERS; 18820 Slog.w(TAG, msg); 18821 throw new SecurityException(msg); 18822 } 18823 synchronized (this) { 18824 return mStartedUserArray; 18825 } 18826 } 18827 18828 private void updateStartedUserArrayLocked() { 18829 int num = 0; 18830 for (int i=0; i<mStartedUsers.size(); i++) { 18831 UserStartedState uss = mStartedUsers.valueAt(i); 18832 // This list does not include stopping users. 18833 if (uss.mState != UserStartedState.STATE_STOPPING 18834 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18835 num++; 18836 } 18837 } 18838 mStartedUserArray = new int[num]; 18839 num = 0; 18840 for (int i=0; i<mStartedUsers.size(); i++) { 18841 UserStartedState uss = mStartedUsers.valueAt(i); 18842 if (uss.mState != UserStartedState.STATE_STOPPING 18843 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18844 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18845 num++; 18846 } 18847 } 18848 } 18849 18850 @Override 18851 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18852 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18853 != PackageManager.PERMISSION_GRANTED) { 18854 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18855 + Binder.getCallingPid() 18856 + ", uid=" + Binder.getCallingUid() 18857 + " requires " + INTERACT_ACROSS_USERS_FULL; 18858 Slog.w(TAG, msg); 18859 throw new SecurityException(msg); 18860 } 18861 18862 mUserSwitchObservers.register(observer); 18863 } 18864 18865 @Override 18866 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18867 mUserSwitchObservers.unregister(observer); 18868 } 18869 18870 private boolean userExists(int userId) { 18871 if (userId == 0) { 18872 return true; 18873 } 18874 UserManagerService ums = getUserManagerLocked(); 18875 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18876 } 18877 18878 int[] getUsersLocked() { 18879 UserManagerService ums = getUserManagerLocked(); 18880 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18881 } 18882 18883 UserManagerService getUserManagerLocked() { 18884 if (mUserManager == null) { 18885 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18886 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18887 } 18888 return mUserManager; 18889 } 18890 18891 private int applyUserId(int uid, int userId) { 18892 return UserHandle.getUid(userId, uid); 18893 } 18894 18895 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18896 if (info == null) return null; 18897 ApplicationInfo newInfo = new ApplicationInfo(info); 18898 newInfo.uid = applyUserId(info.uid, userId); 18899 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18900 + info.packageName; 18901 return newInfo; 18902 } 18903 18904 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18905 if (aInfo == null 18906 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18907 return aInfo; 18908 } 18909 18910 ActivityInfo info = new ActivityInfo(aInfo); 18911 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18912 return info; 18913 } 18914 18915 private final class LocalService extends ActivityManagerInternal { 18916 @Override 18917 public void goingToSleep() { 18918 ActivityManagerService.this.goingToSleep(); 18919 } 18920 18921 @Override 18922 public void wakingUp() { 18923 ActivityManagerService.this.wakingUp(); 18924 } 18925 18926 @Override 18927 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18928 String processName, String abiOverride, int uid, Runnable crashHandler) { 18929 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18930 processName, abiOverride, uid, crashHandler); 18931 } 18932 } 18933 18934 /** 18935 * An implementation of IAppTask, that allows an app to manage its own tasks via 18936 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18937 * only the process that calls getAppTasks() can call the AppTask methods. 18938 */ 18939 class AppTaskImpl extends IAppTask.Stub { 18940 private int mTaskId; 18941 private int mCallingUid; 18942 18943 public AppTaskImpl(int taskId, int callingUid) { 18944 mTaskId = taskId; 18945 mCallingUid = callingUid; 18946 } 18947 18948 private void checkCaller() { 18949 if (mCallingUid != Binder.getCallingUid()) { 18950 throw new SecurityException("Caller " + mCallingUid 18951 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18952 } 18953 } 18954 18955 @Override 18956 public void finishAndRemoveTask() { 18957 checkCaller(); 18958 18959 synchronized (ActivityManagerService.this) { 18960 long origId = Binder.clearCallingIdentity(); 18961 try { 18962 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18963 if (tr == null) { 18964 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18965 } 18966 // Only kill the process if we are not a new document 18967 int flags = tr.getBaseIntent().getFlags(); 18968 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18969 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18970 removeTaskByIdLocked(mTaskId, 18971 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18972 } finally { 18973 Binder.restoreCallingIdentity(origId); 18974 } 18975 } 18976 } 18977 18978 @Override 18979 public ActivityManager.RecentTaskInfo getTaskInfo() { 18980 checkCaller(); 18981 18982 synchronized (ActivityManagerService.this) { 18983 long origId = Binder.clearCallingIdentity(); 18984 try { 18985 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18986 if (tr == null) { 18987 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18988 } 18989 return createRecentTaskInfoFromTaskRecord(tr); 18990 } finally { 18991 Binder.restoreCallingIdentity(origId); 18992 } 18993 } 18994 } 18995 18996 @Override 18997 public void moveToFront() { 18998 checkCaller(); 18999 19000 final TaskRecord tr; 19001 synchronized (ActivityManagerService.this) { 19002 tr = recentTaskForIdLocked(mTaskId); 19003 if (tr == null) { 19004 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19005 } 19006 if (tr.getRootActivity() != null) { 19007 moveTaskToFrontLocked(tr.taskId, 0, null); 19008 return; 19009 } 19010 } 19011 19012 startActivityFromRecentsInner(tr.taskId, null); 19013 } 19014 19015 @Override 19016 public int startActivity(IBinder whoThread, String callingPackage, 19017 Intent intent, String resolvedType, Bundle options) { 19018 checkCaller(); 19019 19020 int callingUser = UserHandle.getCallingUserId(); 19021 TaskRecord tr; 19022 IApplicationThread appThread; 19023 synchronized (ActivityManagerService.this) { 19024 tr = recentTaskForIdLocked(mTaskId); 19025 if (tr == null) { 19026 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19027 } 19028 appThread = ApplicationThreadNative.asInterface(whoThread); 19029 if (appThread == null) { 19030 throw new IllegalArgumentException("Bad app thread " + appThread); 19031 } 19032 } 19033 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19034 resolvedType, null, null, null, null, 0, 0, null, null, 19035 null, options, callingUser, null, tr); 19036 } 19037 19038 @Override 19039 public void setExcludeFromRecents(boolean exclude) { 19040 checkCaller(); 19041 19042 synchronized (ActivityManagerService.this) { 19043 long origId = Binder.clearCallingIdentity(); 19044 try { 19045 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19046 if (tr == null) { 19047 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19048 } 19049 Intent intent = tr.getBaseIntent(); 19050 if (exclude) { 19051 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19052 } else { 19053 intent.setFlags(intent.getFlags() 19054 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19055 } 19056 } finally { 19057 Binder.restoreCallingIdentity(origId); 19058 } 19059 } 19060 } 19061 } 19062} 19063