ActivityManagerService.java revision 95cce9f382693ad13039d1a1fb15529017a20929
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 6320 // And trigger dev.bootcomplete if we are not showing encryption progress 6321 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6322 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6323 SystemProperties.set("dev.bootcomplete", "1"); 6324 } 6325 for (int i=0; i<mStartedUsers.size(); i++) { 6326 UserStartedState uss = mStartedUsers.valueAt(i); 6327 if (uss.mState == UserStartedState.STATE_BOOTING) { 6328 uss.mState = UserStartedState.STATE_RUNNING; 6329 final int userId = mStartedUsers.keyAt(i); 6330 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6331 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6332 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6333 broadcastIntentLocked(null, null, intent, null, 6334 new IIntentReceiver.Stub() { 6335 @Override 6336 public void performReceive(Intent intent, int resultCode, 6337 String data, Bundle extras, boolean ordered, 6338 boolean sticky, int sendingUser) { 6339 synchronized (ActivityManagerService.this) { 6340 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6341 true, false); 6342 } 6343 } 6344 }, 6345 0, null, null, 6346 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6347 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6348 userId); 6349 } 6350 } 6351 scheduleStartProfilesLocked(); 6352 } 6353 } 6354 } 6355 6356 @Override 6357 public void bootAnimationComplete() { 6358 final boolean callFinishBooting; 6359 synchronized (this) { 6360 callFinishBooting = mCallFinishBooting; 6361 mBootAnimationComplete = true; 6362 } 6363 if (callFinishBooting) { 6364 finishBooting(); 6365 } 6366 } 6367 6368 final void ensureBootCompleted() { 6369 boolean booting; 6370 boolean enableScreen; 6371 synchronized (this) { 6372 booting = mBooting; 6373 mBooting = false; 6374 enableScreen = !mBooted; 6375 mBooted = true; 6376 } 6377 6378 if (booting) { 6379 finishBooting(); 6380 } 6381 6382 if (enableScreen) { 6383 enableScreenAfterBoot(); 6384 } 6385 } 6386 6387 @Override 6388 public final void activityResumed(IBinder token) { 6389 final long origId = Binder.clearCallingIdentity(); 6390 synchronized(this) { 6391 ActivityStack stack = ActivityRecord.getStackLocked(token); 6392 if (stack != null) { 6393 ActivityRecord.activityResumedLocked(token); 6394 } 6395 } 6396 Binder.restoreCallingIdentity(origId); 6397 } 6398 6399 @Override 6400 public final void activityPaused(IBinder token) { 6401 final long origId = Binder.clearCallingIdentity(); 6402 synchronized(this) { 6403 ActivityStack stack = ActivityRecord.getStackLocked(token); 6404 if (stack != null) { 6405 stack.activityPausedLocked(token, false); 6406 } 6407 } 6408 Binder.restoreCallingIdentity(origId); 6409 } 6410 6411 @Override 6412 public final void activityStopped(IBinder token, Bundle icicle, 6413 PersistableBundle persistentState, CharSequence description) { 6414 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6415 6416 // Refuse possible leaked file descriptors 6417 if (icicle != null && icicle.hasFileDescriptors()) { 6418 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6419 } 6420 6421 final long origId = Binder.clearCallingIdentity(); 6422 6423 synchronized (this) { 6424 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6425 if (r != null) { 6426 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6427 } 6428 } 6429 6430 trimApplications(); 6431 6432 Binder.restoreCallingIdentity(origId); 6433 } 6434 6435 @Override 6436 public final void activityDestroyed(IBinder token) { 6437 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6438 synchronized (this) { 6439 ActivityStack stack = ActivityRecord.getStackLocked(token); 6440 if (stack != null) { 6441 stack.activityDestroyedLocked(token); 6442 } 6443 } 6444 } 6445 6446 @Override 6447 public final void backgroundResourcesReleased(IBinder token) { 6448 final long origId = Binder.clearCallingIdentity(); 6449 try { 6450 synchronized (this) { 6451 ActivityStack stack = ActivityRecord.getStackLocked(token); 6452 if (stack != null) { 6453 stack.backgroundResourcesReleased(token); 6454 } 6455 } 6456 } finally { 6457 Binder.restoreCallingIdentity(origId); 6458 } 6459 } 6460 6461 @Override 6462 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6463 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6464 } 6465 6466 @Override 6467 public final void notifyEnterAnimationComplete(IBinder token) { 6468 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6469 } 6470 6471 @Override 6472 public String getCallingPackage(IBinder token) { 6473 synchronized (this) { 6474 ActivityRecord r = getCallingRecordLocked(token); 6475 return r != null ? r.info.packageName : null; 6476 } 6477 } 6478 6479 @Override 6480 public ComponentName getCallingActivity(IBinder token) { 6481 synchronized (this) { 6482 ActivityRecord r = getCallingRecordLocked(token); 6483 return r != null ? r.intent.getComponent() : null; 6484 } 6485 } 6486 6487 private ActivityRecord getCallingRecordLocked(IBinder token) { 6488 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6489 if (r == null) { 6490 return null; 6491 } 6492 return r.resultTo; 6493 } 6494 6495 @Override 6496 public ComponentName getActivityClassForToken(IBinder token) { 6497 synchronized(this) { 6498 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6499 if (r == null) { 6500 return null; 6501 } 6502 return r.intent.getComponent(); 6503 } 6504 } 6505 6506 @Override 6507 public String getPackageForToken(IBinder token) { 6508 synchronized(this) { 6509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6510 if (r == null) { 6511 return null; 6512 } 6513 return r.packageName; 6514 } 6515 } 6516 6517 @Override 6518 public IIntentSender getIntentSender(int type, 6519 String packageName, IBinder token, String resultWho, 6520 int requestCode, Intent[] intents, String[] resolvedTypes, 6521 int flags, Bundle options, int userId) { 6522 enforceNotIsolatedCaller("getIntentSender"); 6523 // Refuse possible leaked file descriptors 6524 if (intents != null) { 6525 if (intents.length < 1) { 6526 throw new IllegalArgumentException("Intents array length must be >= 1"); 6527 } 6528 for (int i=0; i<intents.length; i++) { 6529 Intent intent = intents[i]; 6530 if (intent != null) { 6531 if (intent.hasFileDescriptors()) { 6532 throw new IllegalArgumentException("File descriptors passed in Intent"); 6533 } 6534 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6535 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6536 throw new IllegalArgumentException( 6537 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6538 } 6539 intents[i] = new Intent(intent); 6540 } 6541 } 6542 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6543 throw new IllegalArgumentException( 6544 "Intent array length does not match resolvedTypes length"); 6545 } 6546 } 6547 if (options != null) { 6548 if (options.hasFileDescriptors()) { 6549 throw new IllegalArgumentException("File descriptors passed in options"); 6550 } 6551 } 6552 6553 synchronized(this) { 6554 int callingUid = Binder.getCallingUid(); 6555 int origUserId = userId; 6556 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6557 type == ActivityManager.INTENT_SENDER_BROADCAST, 6558 ALLOW_NON_FULL, "getIntentSender", null); 6559 if (origUserId == UserHandle.USER_CURRENT) { 6560 // We don't want to evaluate this until the pending intent is 6561 // actually executed. However, we do want to always do the 6562 // security checking for it above. 6563 userId = UserHandle.USER_CURRENT; 6564 } 6565 try { 6566 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6567 int uid = AppGlobals.getPackageManager() 6568 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6569 if (!UserHandle.isSameApp(callingUid, uid)) { 6570 String msg = "Permission Denial: getIntentSender() from pid=" 6571 + Binder.getCallingPid() 6572 + ", uid=" + Binder.getCallingUid() 6573 + ", (need uid=" + uid + ")" 6574 + " is not allowed to send as package " + packageName; 6575 Slog.w(TAG, msg); 6576 throw new SecurityException(msg); 6577 } 6578 } 6579 6580 return getIntentSenderLocked(type, packageName, callingUid, userId, 6581 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6582 6583 } catch (RemoteException e) { 6584 throw new SecurityException(e); 6585 } 6586 } 6587 } 6588 6589 IIntentSender getIntentSenderLocked(int type, String packageName, 6590 int callingUid, int userId, IBinder token, String resultWho, 6591 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6592 Bundle options) { 6593 if (DEBUG_MU) 6594 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6595 ActivityRecord activity = null; 6596 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6597 activity = ActivityRecord.isInStackLocked(token); 6598 if (activity == null) { 6599 return null; 6600 } 6601 if (activity.finishing) { 6602 return null; 6603 } 6604 } 6605 6606 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6607 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6608 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6609 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6610 |PendingIntent.FLAG_UPDATE_CURRENT); 6611 6612 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6613 type, packageName, activity, resultWho, 6614 requestCode, intents, resolvedTypes, flags, options, userId); 6615 WeakReference<PendingIntentRecord> ref; 6616 ref = mIntentSenderRecords.get(key); 6617 PendingIntentRecord rec = ref != null ? ref.get() : null; 6618 if (rec != null) { 6619 if (!cancelCurrent) { 6620 if (updateCurrent) { 6621 if (rec.key.requestIntent != null) { 6622 rec.key.requestIntent.replaceExtras(intents != null ? 6623 intents[intents.length - 1] : null); 6624 } 6625 if (intents != null) { 6626 intents[intents.length-1] = rec.key.requestIntent; 6627 rec.key.allIntents = intents; 6628 rec.key.allResolvedTypes = resolvedTypes; 6629 } else { 6630 rec.key.allIntents = null; 6631 rec.key.allResolvedTypes = null; 6632 } 6633 } 6634 return rec; 6635 } 6636 rec.canceled = true; 6637 mIntentSenderRecords.remove(key); 6638 } 6639 if (noCreate) { 6640 return rec; 6641 } 6642 rec = new PendingIntentRecord(this, key, callingUid); 6643 mIntentSenderRecords.put(key, rec.ref); 6644 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6645 if (activity.pendingResults == null) { 6646 activity.pendingResults 6647 = new HashSet<WeakReference<PendingIntentRecord>>(); 6648 } 6649 activity.pendingResults.add(rec.ref); 6650 } 6651 return rec; 6652 } 6653 6654 @Override 6655 public void cancelIntentSender(IIntentSender sender) { 6656 if (!(sender instanceof PendingIntentRecord)) { 6657 return; 6658 } 6659 synchronized(this) { 6660 PendingIntentRecord rec = (PendingIntentRecord)sender; 6661 try { 6662 int uid = AppGlobals.getPackageManager() 6663 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6664 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6665 String msg = "Permission Denial: cancelIntentSender() from pid=" 6666 + Binder.getCallingPid() 6667 + ", uid=" + Binder.getCallingUid() 6668 + " is not allowed to cancel packges " 6669 + rec.key.packageName; 6670 Slog.w(TAG, msg); 6671 throw new SecurityException(msg); 6672 } 6673 } catch (RemoteException e) { 6674 throw new SecurityException(e); 6675 } 6676 cancelIntentSenderLocked(rec, true); 6677 } 6678 } 6679 6680 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6681 rec.canceled = true; 6682 mIntentSenderRecords.remove(rec.key); 6683 if (cleanActivity && rec.key.activity != null) { 6684 rec.key.activity.pendingResults.remove(rec.ref); 6685 } 6686 } 6687 6688 @Override 6689 public String getPackageForIntentSender(IIntentSender pendingResult) { 6690 if (!(pendingResult instanceof PendingIntentRecord)) { 6691 return null; 6692 } 6693 try { 6694 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6695 return res.key.packageName; 6696 } catch (ClassCastException e) { 6697 } 6698 return null; 6699 } 6700 6701 @Override 6702 public int getUidForIntentSender(IIntentSender sender) { 6703 if (sender instanceof PendingIntentRecord) { 6704 try { 6705 PendingIntentRecord res = (PendingIntentRecord)sender; 6706 return res.uid; 6707 } catch (ClassCastException e) { 6708 } 6709 } 6710 return -1; 6711 } 6712 6713 @Override 6714 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6715 if (!(pendingResult instanceof PendingIntentRecord)) { 6716 return false; 6717 } 6718 try { 6719 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6720 if (res.key.allIntents == null) { 6721 return false; 6722 } 6723 for (int i=0; i<res.key.allIntents.length; i++) { 6724 Intent intent = res.key.allIntents[i]; 6725 if (intent.getPackage() != null && intent.getComponent() != null) { 6726 return false; 6727 } 6728 } 6729 return true; 6730 } catch (ClassCastException e) { 6731 } 6732 return false; 6733 } 6734 6735 @Override 6736 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6737 if (!(pendingResult instanceof PendingIntentRecord)) { 6738 return false; 6739 } 6740 try { 6741 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6742 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6743 return true; 6744 } 6745 return false; 6746 } catch (ClassCastException e) { 6747 } 6748 return false; 6749 } 6750 6751 @Override 6752 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6753 if (!(pendingResult instanceof PendingIntentRecord)) { 6754 return null; 6755 } 6756 try { 6757 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6758 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6759 } catch (ClassCastException e) { 6760 } 6761 return null; 6762 } 6763 6764 @Override 6765 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6766 if (!(pendingResult instanceof PendingIntentRecord)) { 6767 return null; 6768 } 6769 try { 6770 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6771 Intent intent = res.key.requestIntent; 6772 if (intent != null) { 6773 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6774 || res.lastTagPrefix.equals(prefix))) { 6775 return res.lastTag; 6776 } 6777 res.lastTagPrefix = prefix; 6778 StringBuilder sb = new StringBuilder(128); 6779 if (prefix != null) { 6780 sb.append(prefix); 6781 } 6782 if (intent.getAction() != null) { 6783 sb.append(intent.getAction()); 6784 } else if (intent.getComponent() != null) { 6785 intent.getComponent().appendShortString(sb); 6786 } else { 6787 sb.append("?"); 6788 } 6789 return res.lastTag = sb.toString(); 6790 } 6791 } catch (ClassCastException e) { 6792 } 6793 return null; 6794 } 6795 6796 @Override 6797 public void setProcessLimit(int max) { 6798 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6799 "setProcessLimit()"); 6800 synchronized (this) { 6801 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6802 mProcessLimitOverride = max; 6803 } 6804 trimApplications(); 6805 } 6806 6807 @Override 6808 public int getProcessLimit() { 6809 synchronized (this) { 6810 return mProcessLimitOverride; 6811 } 6812 } 6813 6814 void foregroundTokenDied(ForegroundToken token) { 6815 synchronized (ActivityManagerService.this) { 6816 synchronized (mPidsSelfLocked) { 6817 ForegroundToken cur 6818 = mForegroundProcesses.get(token.pid); 6819 if (cur != token) { 6820 return; 6821 } 6822 mForegroundProcesses.remove(token.pid); 6823 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6824 if (pr == null) { 6825 return; 6826 } 6827 pr.forcingToForeground = null; 6828 updateProcessForegroundLocked(pr, false, false); 6829 } 6830 updateOomAdjLocked(); 6831 } 6832 } 6833 6834 @Override 6835 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6836 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6837 "setProcessForeground()"); 6838 synchronized(this) { 6839 boolean changed = false; 6840 6841 synchronized (mPidsSelfLocked) { 6842 ProcessRecord pr = mPidsSelfLocked.get(pid); 6843 if (pr == null && isForeground) { 6844 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6845 return; 6846 } 6847 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6848 if (oldToken != null) { 6849 oldToken.token.unlinkToDeath(oldToken, 0); 6850 mForegroundProcesses.remove(pid); 6851 if (pr != null) { 6852 pr.forcingToForeground = null; 6853 } 6854 changed = true; 6855 } 6856 if (isForeground && token != null) { 6857 ForegroundToken newToken = new ForegroundToken() { 6858 @Override 6859 public void binderDied() { 6860 foregroundTokenDied(this); 6861 } 6862 }; 6863 newToken.pid = pid; 6864 newToken.token = token; 6865 try { 6866 token.linkToDeath(newToken, 0); 6867 mForegroundProcesses.put(pid, newToken); 6868 pr.forcingToForeground = token; 6869 changed = true; 6870 } catch (RemoteException e) { 6871 // If the process died while doing this, we will later 6872 // do the cleanup with the process death link. 6873 } 6874 } 6875 } 6876 6877 if (changed) { 6878 updateOomAdjLocked(); 6879 } 6880 } 6881 } 6882 6883 // ========================================================= 6884 // PERMISSIONS 6885 // ========================================================= 6886 6887 static class PermissionController extends IPermissionController.Stub { 6888 ActivityManagerService mActivityManagerService; 6889 PermissionController(ActivityManagerService activityManagerService) { 6890 mActivityManagerService = activityManagerService; 6891 } 6892 6893 @Override 6894 public boolean checkPermission(String permission, int pid, int uid) { 6895 return mActivityManagerService.checkPermission(permission, pid, 6896 uid) == PackageManager.PERMISSION_GRANTED; 6897 } 6898 } 6899 6900 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6901 @Override 6902 public int checkComponentPermission(String permission, int pid, int uid, 6903 int owningUid, boolean exported) { 6904 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6905 owningUid, exported); 6906 } 6907 6908 @Override 6909 public Object getAMSLock() { 6910 return ActivityManagerService.this; 6911 } 6912 } 6913 6914 /** 6915 * This can be called with or without the global lock held. 6916 */ 6917 int checkComponentPermission(String permission, int pid, int uid, 6918 int owningUid, boolean exported) { 6919 // We might be performing an operation on behalf of an indirect binder 6920 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6921 // client identity accordingly before proceeding. 6922 Identity tlsIdentity = sCallerIdentity.get(); 6923 if (tlsIdentity != null) { 6924 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6925 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6926 uid = tlsIdentity.uid; 6927 pid = tlsIdentity.pid; 6928 } 6929 6930 if (pid == MY_PID) { 6931 return PackageManager.PERMISSION_GRANTED; 6932 } 6933 6934 return ActivityManager.checkComponentPermission(permission, uid, 6935 owningUid, exported); 6936 } 6937 6938 /** 6939 * As the only public entry point for permissions checking, this method 6940 * can enforce the semantic that requesting a check on a null global 6941 * permission is automatically denied. (Internally a null permission 6942 * string is used when calling {@link #checkComponentPermission} in cases 6943 * when only uid-based security is needed.) 6944 * 6945 * This can be called with or without the global lock held. 6946 */ 6947 @Override 6948 public int checkPermission(String permission, int pid, int uid) { 6949 if (permission == null) { 6950 return PackageManager.PERMISSION_DENIED; 6951 } 6952 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6953 } 6954 6955 /** 6956 * Binder IPC calls go through the public entry point. 6957 * This can be called with or without the global lock held. 6958 */ 6959 int checkCallingPermission(String permission) { 6960 return checkPermission(permission, 6961 Binder.getCallingPid(), 6962 UserHandle.getAppId(Binder.getCallingUid())); 6963 } 6964 6965 /** 6966 * This can be called with or without the global lock held. 6967 */ 6968 void enforceCallingPermission(String permission, String func) { 6969 if (checkCallingPermission(permission) 6970 == PackageManager.PERMISSION_GRANTED) { 6971 return; 6972 } 6973 6974 String msg = "Permission Denial: " + func + " from pid=" 6975 + Binder.getCallingPid() 6976 + ", uid=" + Binder.getCallingUid() 6977 + " requires " + permission; 6978 Slog.w(TAG, msg); 6979 throw new SecurityException(msg); 6980 } 6981 6982 /** 6983 * Determine if UID is holding permissions required to access {@link Uri} in 6984 * the given {@link ProviderInfo}. Final permission checking is always done 6985 * in {@link ContentProvider}. 6986 */ 6987 private final boolean checkHoldingPermissionsLocked( 6988 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6989 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6990 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6991 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6992 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6993 != PERMISSION_GRANTED) { 6994 return false; 6995 } 6996 } 6997 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6998 } 6999 7000 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7001 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7002 if (pi.applicationInfo.uid == uid) { 7003 return true; 7004 } else if (!pi.exported) { 7005 return false; 7006 } 7007 7008 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7009 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7010 try { 7011 // check if target holds top-level <provider> permissions 7012 if (!readMet && pi.readPermission != null && considerUidPermissions 7013 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7014 readMet = true; 7015 } 7016 if (!writeMet && pi.writePermission != null && considerUidPermissions 7017 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7018 writeMet = true; 7019 } 7020 7021 // track if unprotected read/write is allowed; any denied 7022 // <path-permission> below removes this ability 7023 boolean allowDefaultRead = pi.readPermission == null; 7024 boolean allowDefaultWrite = pi.writePermission == null; 7025 7026 // check if target holds any <path-permission> that match uri 7027 final PathPermission[] pps = pi.pathPermissions; 7028 if (pps != null) { 7029 final String path = grantUri.uri.getPath(); 7030 int i = pps.length; 7031 while (i > 0 && (!readMet || !writeMet)) { 7032 i--; 7033 PathPermission pp = pps[i]; 7034 if (pp.match(path)) { 7035 if (!readMet) { 7036 final String pprperm = pp.getReadPermission(); 7037 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7038 + pprperm + " for " + pp.getPath() 7039 + ": match=" + pp.match(path) 7040 + " check=" + pm.checkUidPermission(pprperm, uid)); 7041 if (pprperm != null) { 7042 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7043 == PERMISSION_GRANTED) { 7044 readMet = true; 7045 } else { 7046 allowDefaultRead = false; 7047 } 7048 } 7049 } 7050 if (!writeMet) { 7051 final String ppwperm = pp.getWritePermission(); 7052 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7053 + ppwperm + " for " + pp.getPath() 7054 + ": match=" + pp.match(path) 7055 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7056 if (ppwperm != null) { 7057 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7058 == PERMISSION_GRANTED) { 7059 writeMet = true; 7060 } else { 7061 allowDefaultWrite = false; 7062 } 7063 } 7064 } 7065 } 7066 } 7067 } 7068 7069 // grant unprotected <provider> read/write, if not blocked by 7070 // <path-permission> above 7071 if (allowDefaultRead) readMet = true; 7072 if (allowDefaultWrite) writeMet = true; 7073 7074 } catch (RemoteException e) { 7075 return false; 7076 } 7077 7078 return readMet && writeMet; 7079 } 7080 7081 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7082 ProviderInfo pi = null; 7083 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7084 if (cpr != null) { 7085 pi = cpr.info; 7086 } else { 7087 try { 7088 pi = AppGlobals.getPackageManager().resolveContentProvider( 7089 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7090 } catch (RemoteException ex) { 7091 } 7092 } 7093 return pi; 7094 } 7095 7096 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7097 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7098 if (targetUris != null) { 7099 return targetUris.get(grantUri); 7100 } 7101 return null; 7102 } 7103 7104 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7105 String targetPkg, int targetUid, GrantUri grantUri) { 7106 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7107 if (targetUris == null) { 7108 targetUris = Maps.newArrayMap(); 7109 mGrantedUriPermissions.put(targetUid, targetUris); 7110 } 7111 7112 UriPermission perm = targetUris.get(grantUri); 7113 if (perm == null) { 7114 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7115 targetUris.put(grantUri, perm); 7116 } 7117 7118 return perm; 7119 } 7120 7121 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7122 final int modeFlags) { 7123 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7124 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7125 : UriPermission.STRENGTH_OWNED; 7126 7127 // Root gets to do everything. 7128 if (uid == 0) { 7129 return true; 7130 } 7131 7132 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7133 if (perms == null) return false; 7134 7135 // First look for exact match 7136 final UriPermission exactPerm = perms.get(grantUri); 7137 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7138 return true; 7139 } 7140 7141 // No exact match, look for prefixes 7142 final int N = perms.size(); 7143 for (int i = 0; i < N; i++) { 7144 final UriPermission perm = perms.valueAt(i); 7145 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7146 && perm.getStrength(modeFlags) >= minStrength) { 7147 return true; 7148 } 7149 } 7150 7151 return false; 7152 } 7153 7154 /** 7155 * @param uri This uri must NOT contain an embedded userId. 7156 * @param userId The userId in which the uri is to be resolved. 7157 */ 7158 @Override 7159 public int checkUriPermission(Uri uri, int pid, int uid, 7160 final int modeFlags, int userId) { 7161 enforceNotIsolatedCaller("checkUriPermission"); 7162 7163 // Another redirected-binder-call permissions check as in 7164 // {@link checkComponentPermission}. 7165 Identity tlsIdentity = sCallerIdentity.get(); 7166 if (tlsIdentity != null) { 7167 uid = tlsIdentity.uid; 7168 pid = tlsIdentity.pid; 7169 } 7170 7171 // Our own process gets to do everything. 7172 if (pid == MY_PID) { 7173 return PackageManager.PERMISSION_GRANTED; 7174 } 7175 synchronized (this) { 7176 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7177 ? PackageManager.PERMISSION_GRANTED 7178 : PackageManager.PERMISSION_DENIED; 7179 } 7180 } 7181 7182 /** 7183 * Check if the targetPkg can be granted permission to access uri by 7184 * the callingUid using the given modeFlags. Throws a security exception 7185 * if callingUid is not allowed to do this. Returns the uid of the target 7186 * if the URI permission grant should be performed; returns -1 if it is not 7187 * needed (for example targetPkg already has permission to access the URI). 7188 * If you already know the uid of the target, you can supply it in 7189 * lastTargetUid else set that to -1. 7190 */ 7191 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7192 final int modeFlags, int lastTargetUid) { 7193 if (!Intent.isAccessUriMode(modeFlags)) { 7194 return -1; 7195 } 7196 7197 if (targetPkg != null) { 7198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7199 "Checking grant " + targetPkg + " permission to " + grantUri); 7200 } 7201 7202 final IPackageManager pm = AppGlobals.getPackageManager(); 7203 7204 // If this is not a content: uri, we can't do anything with it. 7205 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7207 "Can't grant URI permission for non-content URI: " + grantUri); 7208 return -1; 7209 } 7210 7211 final String authority = grantUri.uri.getAuthority(); 7212 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7213 if (pi == null) { 7214 Slog.w(TAG, "No content provider found for permission check: " + 7215 grantUri.uri.toSafeString()); 7216 return -1; 7217 } 7218 7219 int targetUid = lastTargetUid; 7220 if (targetUid < 0 && targetPkg != null) { 7221 try { 7222 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7223 if (targetUid < 0) { 7224 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7225 "Can't grant URI permission no uid for: " + targetPkg); 7226 return -1; 7227 } 7228 } catch (RemoteException ex) { 7229 return -1; 7230 } 7231 } 7232 7233 if (targetUid >= 0) { 7234 // First... does the target actually need this permission? 7235 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7236 // No need to grant the target this permission. 7237 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7238 "Target " + targetPkg + " already has full permission to " + grantUri); 7239 return -1; 7240 } 7241 } else { 7242 // First... there is no target package, so can anyone access it? 7243 boolean allowed = pi.exported; 7244 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7245 if (pi.readPermission != null) { 7246 allowed = false; 7247 } 7248 } 7249 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7250 if (pi.writePermission != null) { 7251 allowed = false; 7252 } 7253 } 7254 if (allowed) { 7255 return -1; 7256 } 7257 } 7258 7259 /* There is a special cross user grant if: 7260 * - The target is on another user. 7261 * - Apps on the current user can access the uri without any uid permissions. 7262 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7263 * grant uri permissions. 7264 */ 7265 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7266 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7267 modeFlags, false /*without considering the uid permissions*/); 7268 7269 // Second... is the provider allowing granting of URI permissions? 7270 if (!specialCrossUserGrant) { 7271 if (!pi.grantUriPermissions) { 7272 throw new SecurityException("Provider " + pi.packageName 7273 + "/" + pi.name 7274 + " does not allow granting of Uri permissions (uri " 7275 + grantUri + ")"); 7276 } 7277 if (pi.uriPermissionPatterns != null) { 7278 final int N = pi.uriPermissionPatterns.length; 7279 boolean allowed = false; 7280 for (int i=0; i<N; i++) { 7281 if (pi.uriPermissionPatterns[i] != null 7282 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7283 allowed = true; 7284 break; 7285 } 7286 } 7287 if (!allowed) { 7288 throw new SecurityException("Provider " + pi.packageName 7289 + "/" + pi.name 7290 + " does not allow granting of permission to path of Uri " 7291 + grantUri); 7292 } 7293 } 7294 } 7295 7296 // Third... does the caller itself have permission to access 7297 // this uri? 7298 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7299 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7300 // Require they hold a strong enough Uri permission 7301 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7302 throw new SecurityException("Uid " + callingUid 7303 + " does not have permission to uri " + grantUri); 7304 } 7305 } 7306 } 7307 return targetUid; 7308 } 7309 7310 /** 7311 * @param uri This uri must NOT contain an embedded userId. 7312 * @param userId The userId in which the uri is to be resolved. 7313 */ 7314 @Override 7315 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7316 final int modeFlags, int userId) { 7317 enforceNotIsolatedCaller("checkGrantUriPermission"); 7318 synchronized(this) { 7319 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7320 new GrantUri(userId, uri, false), modeFlags, -1); 7321 } 7322 } 7323 7324 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7325 final int modeFlags, UriPermissionOwner owner) { 7326 if (!Intent.isAccessUriMode(modeFlags)) { 7327 return; 7328 } 7329 7330 // So here we are: the caller has the assumed permission 7331 // to the uri, and the target doesn't. Let's now give this to 7332 // the target. 7333 7334 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7335 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7336 7337 final String authority = grantUri.uri.getAuthority(); 7338 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7339 if (pi == null) { 7340 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7341 return; 7342 } 7343 7344 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7345 grantUri.prefix = true; 7346 } 7347 final UriPermission perm = findOrCreateUriPermissionLocked( 7348 pi.packageName, targetPkg, targetUid, grantUri); 7349 perm.grantModes(modeFlags, owner); 7350 } 7351 7352 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7353 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7354 if (targetPkg == null) { 7355 throw new NullPointerException("targetPkg"); 7356 } 7357 int targetUid; 7358 final IPackageManager pm = AppGlobals.getPackageManager(); 7359 try { 7360 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7361 } catch (RemoteException ex) { 7362 return; 7363 } 7364 7365 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7366 targetUid); 7367 if (targetUid < 0) { 7368 return; 7369 } 7370 7371 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7372 owner); 7373 } 7374 7375 static class NeededUriGrants extends ArrayList<GrantUri> { 7376 final String targetPkg; 7377 final int targetUid; 7378 final int flags; 7379 7380 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7381 this.targetPkg = targetPkg; 7382 this.targetUid = targetUid; 7383 this.flags = flags; 7384 } 7385 } 7386 7387 /** 7388 * Like checkGrantUriPermissionLocked, but takes an Intent. 7389 */ 7390 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7391 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7392 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7393 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7394 + " clip=" + (intent != null ? intent.getClipData() : null) 7395 + " from " + intent + "; flags=0x" 7396 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7397 7398 if (targetPkg == null) { 7399 throw new NullPointerException("targetPkg"); 7400 } 7401 7402 if (intent == null) { 7403 return null; 7404 } 7405 Uri data = intent.getData(); 7406 ClipData clip = intent.getClipData(); 7407 if (data == null && clip == null) { 7408 return null; 7409 } 7410 // Default userId for uris in the intent (if they don't specify it themselves) 7411 int contentUserHint = intent.getContentUserHint(); 7412 if (contentUserHint == UserHandle.USER_CURRENT) { 7413 contentUserHint = UserHandle.getUserId(callingUid); 7414 } 7415 final IPackageManager pm = AppGlobals.getPackageManager(); 7416 int targetUid; 7417 if (needed != null) { 7418 targetUid = needed.targetUid; 7419 } else { 7420 try { 7421 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7422 } catch (RemoteException ex) { 7423 return null; 7424 } 7425 if (targetUid < 0) { 7426 if (DEBUG_URI_PERMISSION) { 7427 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7428 + " on user " + targetUserId); 7429 } 7430 return null; 7431 } 7432 } 7433 if (data != null) { 7434 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7435 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7436 targetUid); 7437 if (targetUid > 0) { 7438 if (needed == null) { 7439 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7440 } 7441 needed.add(grantUri); 7442 } 7443 } 7444 if (clip != null) { 7445 for (int i=0; i<clip.getItemCount(); i++) { 7446 Uri uri = clip.getItemAt(i).getUri(); 7447 if (uri != null) { 7448 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7449 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7450 targetUid); 7451 if (targetUid > 0) { 7452 if (needed == null) { 7453 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7454 } 7455 needed.add(grantUri); 7456 } 7457 } else { 7458 Intent clipIntent = clip.getItemAt(i).getIntent(); 7459 if (clipIntent != null) { 7460 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7461 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7462 if (newNeeded != null) { 7463 needed = newNeeded; 7464 } 7465 } 7466 } 7467 } 7468 } 7469 7470 return needed; 7471 } 7472 7473 /** 7474 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7475 */ 7476 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7477 UriPermissionOwner owner) { 7478 if (needed != null) { 7479 for (int i=0; i<needed.size(); i++) { 7480 GrantUri grantUri = needed.get(i); 7481 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7482 grantUri, needed.flags, owner); 7483 } 7484 } 7485 } 7486 7487 void grantUriPermissionFromIntentLocked(int callingUid, 7488 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7489 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7490 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7491 if (needed == null) { 7492 return; 7493 } 7494 7495 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7496 } 7497 7498 /** 7499 * @param uri This uri must NOT contain an embedded userId. 7500 * @param userId The userId in which the uri is to be resolved. 7501 */ 7502 @Override 7503 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7504 final int modeFlags, int userId) { 7505 enforceNotIsolatedCaller("grantUriPermission"); 7506 GrantUri grantUri = new GrantUri(userId, uri, false); 7507 synchronized(this) { 7508 final ProcessRecord r = getRecordForAppLocked(caller); 7509 if (r == null) { 7510 throw new SecurityException("Unable to find app for caller " 7511 + caller 7512 + " when granting permission to uri " + grantUri); 7513 } 7514 if (targetPkg == null) { 7515 throw new IllegalArgumentException("null target"); 7516 } 7517 if (grantUri == null) { 7518 throw new IllegalArgumentException("null uri"); 7519 } 7520 7521 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7522 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7523 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7524 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7525 7526 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7527 UserHandle.getUserId(r.uid)); 7528 } 7529 } 7530 7531 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7532 if (perm.modeFlags == 0) { 7533 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7534 perm.targetUid); 7535 if (perms != null) { 7536 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7537 "Removing " + perm.targetUid + " permission to " + perm.uri); 7538 7539 perms.remove(perm.uri); 7540 if (perms.isEmpty()) { 7541 mGrantedUriPermissions.remove(perm.targetUid); 7542 } 7543 } 7544 } 7545 } 7546 7547 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7548 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7549 7550 final IPackageManager pm = AppGlobals.getPackageManager(); 7551 final String authority = grantUri.uri.getAuthority(); 7552 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7553 if (pi == null) { 7554 Slog.w(TAG, "No content provider found for permission revoke: " 7555 + grantUri.toSafeString()); 7556 return; 7557 } 7558 7559 // Does the caller have this permission on the URI? 7560 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7561 // If they don't have direct access to the URI, then revoke any 7562 // ownerless URI permissions that have been granted to them. 7563 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7564 if (perms != null) { 7565 boolean persistChanged = false; 7566 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7567 final UriPermission perm = it.next(); 7568 if (perm.uri.sourceUserId == grantUri.sourceUserId 7569 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7570 if (DEBUG_URI_PERMISSION) 7571 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7572 " permission to " + perm.uri); 7573 persistChanged |= perm.revokeModes( 7574 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7575 if (perm.modeFlags == 0) { 7576 it.remove(); 7577 } 7578 } 7579 } 7580 if (perms.isEmpty()) { 7581 mGrantedUriPermissions.remove(callingUid); 7582 } 7583 if (persistChanged) { 7584 schedulePersistUriGrants(); 7585 } 7586 } 7587 return; 7588 } 7589 7590 boolean persistChanged = false; 7591 7592 // Go through all of the permissions and remove any that match. 7593 int N = mGrantedUriPermissions.size(); 7594 for (int i = 0; i < N; i++) { 7595 final int targetUid = mGrantedUriPermissions.keyAt(i); 7596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7597 7598 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7599 final UriPermission perm = it.next(); 7600 if (perm.uri.sourceUserId == grantUri.sourceUserId 7601 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7602 if (DEBUG_URI_PERMISSION) 7603 Slog.v(TAG, 7604 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7605 persistChanged |= perm.revokeModes( 7606 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7607 if (perm.modeFlags == 0) { 7608 it.remove(); 7609 } 7610 } 7611 } 7612 7613 if (perms.isEmpty()) { 7614 mGrantedUriPermissions.remove(targetUid); 7615 N--; 7616 i--; 7617 } 7618 } 7619 7620 if (persistChanged) { 7621 schedulePersistUriGrants(); 7622 } 7623 } 7624 7625 /** 7626 * @param uri This uri must NOT contain an embedded userId. 7627 * @param userId The userId in which the uri is to be resolved. 7628 */ 7629 @Override 7630 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7631 int userId) { 7632 enforceNotIsolatedCaller("revokeUriPermission"); 7633 synchronized(this) { 7634 final ProcessRecord r = getRecordForAppLocked(caller); 7635 if (r == null) { 7636 throw new SecurityException("Unable to find app for caller " 7637 + caller 7638 + " when revoking permission to uri " + uri); 7639 } 7640 if (uri == null) { 7641 Slog.w(TAG, "revokeUriPermission: null uri"); 7642 return; 7643 } 7644 7645 if (!Intent.isAccessUriMode(modeFlags)) { 7646 return; 7647 } 7648 7649 final IPackageManager pm = AppGlobals.getPackageManager(); 7650 final String authority = uri.getAuthority(); 7651 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7652 if (pi == null) { 7653 Slog.w(TAG, "No content provider found for permission revoke: " 7654 + uri.toSafeString()); 7655 return; 7656 } 7657 7658 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7659 } 7660 } 7661 7662 /** 7663 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7664 * given package. 7665 * 7666 * @param packageName Package name to match, or {@code null} to apply to all 7667 * packages. 7668 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7669 * to all users. 7670 * @param persistable If persistable grants should be removed. 7671 */ 7672 private void removeUriPermissionsForPackageLocked( 7673 String packageName, int userHandle, boolean persistable) { 7674 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7675 throw new IllegalArgumentException("Must narrow by either package or user"); 7676 } 7677 7678 boolean persistChanged = false; 7679 7680 int N = mGrantedUriPermissions.size(); 7681 for (int i = 0; i < N; i++) { 7682 final int targetUid = mGrantedUriPermissions.keyAt(i); 7683 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7684 7685 // Only inspect grants matching user 7686 if (userHandle == UserHandle.USER_ALL 7687 || userHandle == UserHandle.getUserId(targetUid)) { 7688 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7689 final UriPermission perm = it.next(); 7690 7691 // Only inspect grants matching package 7692 if (packageName == null || perm.sourcePkg.equals(packageName) 7693 || perm.targetPkg.equals(packageName)) { 7694 persistChanged |= perm.revokeModes(persistable 7695 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7696 7697 // Only remove when no modes remain; any persisted grants 7698 // will keep this alive. 7699 if (perm.modeFlags == 0) { 7700 it.remove(); 7701 } 7702 } 7703 } 7704 7705 if (perms.isEmpty()) { 7706 mGrantedUriPermissions.remove(targetUid); 7707 N--; 7708 i--; 7709 } 7710 } 7711 } 7712 7713 if (persistChanged) { 7714 schedulePersistUriGrants(); 7715 } 7716 } 7717 7718 @Override 7719 public IBinder newUriPermissionOwner(String name) { 7720 enforceNotIsolatedCaller("newUriPermissionOwner"); 7721 synchronized(this) { 7722 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7723 return owner.getExternalTokenLocked(); 7724 } 7725 } 7726 7727 /** 7728 * @param uri This uri must NOT contain an embedded userId. 7729 * @param sourceUserId The userId in which the uri is to be resolved. 7730 * @param targetUserId The userId of the app that receives the grant. 7731 */ 7732 @Override 7733 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7734 final int modeFlags, int sourceUserId, int targetUserId) { 7735 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7736 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7737 synchronized(this) { 7738 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7739 if (owner == null) { 7740 throw new IllegalArgumentException("Unknown owner: " + token); 7741 } 7742 if (fromUid != Binder.getCallingUid()) { 7743 if (Binder.getCallingUid() != Process.myUid()) { 7744 // Only system code can grant URI permissions on behalf 7745 // of other users. 7746 throw new SecurityException("nice try"); 7747 } 7748 } 7749 if (targetPkg == null) { 7750 throw new IllegalArgumentException("null target"); 7751 } 7752 if (uri == null) { 7753 throw new IllegalArgumentException("null uri"); 7754 } 7755 7756 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7757 modeFlags, owner, targetUserId); 7758 } 7759 } 7760 7761 /** 7762 * @param uri This uri must NOT contain an embedded userId. 7763 * @param userId The userId in which the uri is to be resolved. 7764 */ 7765 @Override 7766 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7767 synchronized(this) { 7768 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7769 if (owner == null) { 7770 throw new IllegalArgumentException("Unknown owner: " + token); 7771 } 7772 7773 if (uri == null) { 7774 owner.removeUriPermissionsLocked(mode); 7775 } else { 7776 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7777 } 7778 } 7779 } 7780 7781 private void schedulePersistUriGrants() { 7782 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7783 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7784 10 * DateUtils.SECOND_IN_MILLIS); 7785 } 7786 } 7787 7788 private void writeGrantedUriPermissions() { 7789 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7790 7791 // Snapshot permissions so we can persist without lock 7792 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7793 synchronized (this) { 7794 final int size = mGrantedUriPermissions.size(); 7795 for (int i = 0; i < size; i++) { 7796 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7797 for (UriPermission perm : perms.values()) { 7798 if (perm.persistedModeFlags != 0) { 7799 persist.add(perm.snapshot()); 7800 } 7801 } 7802 } 7803 } 7804 7805 FileOutputStream fos = null; 7806 try { 7807 fos = mGrantFile.startWrite(); 7808 7809 XmlSerializer out = new FastXmlSerializer(); 7810 out.setOutput(fos, "utf-8"); 7811 out.startDocument(null, true); 7812 out.startTag(null, TAG_URI_GRANTS); 7813 for (UriPermission.Snapshot perm : persist) { 7814 out.startTag(null, TAG_URI_GRANT); 7815 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7816 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7817 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7818 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7819 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7820 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7821 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7822 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7823 out.endTag(null, TAG_URI_GRANT); 7824 } 7825 out.endTag(null, TAG_URI_GRANTS); 7826 out.endDocument(); 7827 7828 mGrantFile.finishWrite(fos); 7829 } catch (IOException e) { 7830 if (fos != null) { 7831 mGrantFile.failWrite(fos); 7832 } 7833 } 7834 } 7835 7836 private void readGrantedUriPermissionsLocked() { 7837 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7838 7839 final long now = System.currentTimeMillis(); 7840 7841 FileInputStream fis = null; 7842 try { 7843 fis = mGrantFile.openRead(); 7844 final XmlPullParser in = Xml.newPullParser(); 7845 in.setInput(fis, null); 7846 7847 int type; 7848 while ((type = in.next()) != END_DOCUMENT) { 7849 final String tag = in.getName(); 7850 if (type == START_TAG) { 7851 if (TAG_URI_GRANT.equals(tag)) { 7852 final int sourceUserId; 7853 final int targetUserId; 7854 final int userHandle = readIntAttribute(in, 7855 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7856 if (userHandle != UserHandle.USER_NULL) { 7857 // For backwards compatibility. 7858 sourceUserId = userHandle; 7859 targetUserId = userHandle; 7860 } else { 7861 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7862 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7863 } 7864 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7865 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7866 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7867 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7868 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7869 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7870 7871 // Sanity check that provider still belongs to source package 7872 final ProviderInfo pi = getProviderInfoLocked( 7873 uri.getAuthority(), sourceUserId); 7874 if (pi != null && sourcePkg.equals(pi.packageName)) { 7875 int targetUid = -1; 7876 try { 7877 targetUid = AppGlobals.getPackageManager() 7878 .getPackageUid(targetPkg, targetUserId); 7879 } catch (RemoteException e) { 7880 } 7881 if (targetUid != -1) { 7882 final UriPermission perm = findOrCreateUriPermissionLocked( 7883 sourcePkg, targetPkg, targetUid, 7884 new GrantUri(sourceUserId, uri, prefix)); 7885 perm.initPersistedModes(modeFlags, createdTime); 7886 } 7887 } else { 7888 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7889 + " but instead found " + pi); 7890 } 7891 } 7892 } 7893 } 7894 } catch (FileNotFoundException e) { 7895 // Missing grants is okay 7896 } catch (IOException e) { 7897 Log.wtf(TAG, "Failed reading Uri grants", e); 7898 } catch (XmlPullParserException e) { 7899 Log.wtf(TAG, "Failed reading Uri grants", e); 7900 } finally { 7901 IoUtils.closeQuietly(fis); 7902 } 7903 } 7904 7905 /** 7906 * @param uri This uri must NOT contain an embedded userId. 7907 * @param userId The userId in which the uri is to be resolved. 7908 */ 7909 @Override 7910 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7911 enforceNotIsolatedCaller("takePersistableUriPermission"); 7912 7913 Preconditions.checkFlagsArgument(modeFlags, 7914 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7915 7916 synchronized (this) { 7917 final int callingUid = Binder.getCallingUid(); 7918 boolean persistChanged = false; 7919 GrantUri grantUri = new GrantUri(userId, uri, false); 7920 7921 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7922 new GrantUri(userId, uri, false)); 7923 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7924 new GrantUri(userId, uri, true)); 7925 7926 final boolean exactValid = (exactPerm != null) 7927 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7928 final boolean prefixValid = (prefixPerm != null) 7929 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7930 7931 if (!(exactValid || prefixValid)) { 7932 throw new SecurityException("No persistable permission grants found for UID " 7933 + callingUid + " and Uri " + grantUri.toSafeString()); 7934 } 7935 7936 if (exactValid) { 7937 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7938 } 7939 if (prefixValid) { 7940 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7941 } 7942 7943 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7944 7945 if (persistChanged) { 7946 schedulePersistUriGrants(); 7947 } 7948 } 7949 } 7950 7951 /** 7952 * @param uri This uri must NOT contain an embedded userId. 7953 * @param userId The userId in which the uri is to be resolved. 7954 */ 7955 @Override 7956 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7957 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7958 7959 Preconditions.checkFlagsArgument(modeFlags, 7960 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7961 7962 synchronized (this) { 7963 final int callingUid = Binder.getCallingUid(); 7964 boolean persistChanged = false; 7965 7966 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7967 new GrantUri(userId, uri, false)); 7968 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7969 new GrantUri(userId, uri, true)); 7970 if (exactPerm == null && prefixPerm == null) { 7971 throw new SecurityException("No permission grants found for UID " + callingUid 7972 + " and Uri " + uri.toSafeString()); 7973 } 7974 7975 if (exactPerm != null) { 7976 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7977 removeUriPermissionIfNeededLocked(exactPerm); 7978 } 7979 if (prefixPerm != null) { 7980 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7981 removeUriPermissionIfNeededLocked(prefixPerm); 7982 } 7983 7984 if (persistChanged) { 7985 schedulePersistUriGrants(); 7986 } 7987 } 7988 } 7989 7990 /** 7991 * Prune any older {@link UriPermission} for the given UID until outstanding 7992 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7993 * 7994 * @return if any mutations occured that require persisting. 7995 */ 7996 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7997 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7998 if (perms == null) return false; 7999 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8000 8001 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8002 for (UriPermission perm : perms.values()) { 8003 if (perm.persistedModeFlags != 0) { 8004 persisted.add(perm); 8005 } 8006 } 8007 8008 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8009 if (trimCount <= 0) return false; 8010 8011 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8012 for (int i = 0; i < trimCount; i++) { 8013 final UriPermission perm = persisted.get(i); 8014 8015 if (DEBUG_URI_PERMISSION) { 8016 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8017 } 8018 8019 perm.releasePersistableModes(~0); 8020 removeUriPermissionIfNeededLocked(perm); 8021 } 8022 8023 return true; 8024 } 8025 8026 @Override 8027 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8028 String packageName, boolean incoming) { 8029 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8030 Preconditions.checkNotNull(packageName, "packageName"); 8031 8032 final int callingUid = Binder.getCallingUid(); 8033 final IPackageManager pm = AppGlobals.getPackageManager(); 8034 try { 8035 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8036 if (packageUid != callingUid) { 8037 throw new SecurityException( 8038 "Package " + packageName + " does not belong to calling UID " + callingUid); 8039 } 8040 } catch (RemoteException e) { 8041 throw new SecurityException("Failed to verify package name ownership"); 8042 } 8043 8044 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8045 synchronized (this) { 8046 if (incoming) { 8047 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8048 callingUid); 8049 if (perms == null) { 8050 Slog.w(TAG, "No permission grants found for " + packageName); 8051 } else { 8052 for (UriPermission perm : perms.values()) { 8053 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8054 result.add(perm.buildPersistedPublicApiObject()); 8055 } 8056 } 8057 } 8058 } else { 8059 final int size = mGrantedUriPermissions.size(); 8060 for (int i = 0; i < size; i++) { 8061 final ArrayMap<GrantUri, UriPermission> perms = 8062 mGrantedUriPermissions.valueAt(i); 8063 for (UriPermission perm : perms.values()) { 8064 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8065 result.add(perm.buildPersistedPublicApiObject()); 8066 } 8067 } 8068 } 8069 } 8070 } 8071 return new ParceledListSlice<android.content.UriPermission>(result); 8072 } 8073 8074 @Override 8075 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8076 synchronized (this) { 8077 ProcessRecord app = 8078 who != null ? getRecordForAppLocked(who) : null; 8079 if (app == null) return; 8080 8081 Message msg = Message.obtain(); 8082 msg.what = WAIT_FOR_DEBUGGER_MSG; 8083 msg.obj = app; 8084 msg.arg1 = waiting ? 1 : 0; 8085 mHandler.sendMessage(msg); 8086 } 8087 } 8088 8089 @Override 8090 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8091 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8092 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8093 outInfo.availMem = Process.getFreeMemory(); 8094 outInfo.totalMem = Process.getTotalMemory(); 8095 outInfo.threshold = homeAppMem; 8096 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8097 outInfo.hiddenAppThreshold = cachedAppMem; 8098 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8099 ProcessList.SERVICE_ADJ); 8100 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8101 ProcessList.VISIBLE_APP_ADJ); 8102 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8103 ProcessList.FOREGROUND_APP_ADJ); 8104 } 8105 8106 // ========================================================= 8107 // TASK MANAGEMENT 8108 // ========================================================= 8109 8110 @Override 8111 public List<IAppTask> getAppTasks(String callingPackage) { 8112 int callingUid = Binder.getCallingUid(); 8113 long ident = Binder.clearCallingIdentity(); 8114 8115 synchronized(this) { 8116 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8117 try { 8118 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8119 8120 final int N = mRecentTasks.size(); 8121 for (int i = 0; i < N; i++) { 8122 TaskRecord tr = mRecentTasks.get(i); 8123 // Skip tasks that do not match the caller. We don't need to verify 8124 // callingPackage, because we are also limiting to callingUid and know 8125 // that will limit to the correct security sandbox. 8126 if (tr.effectiveUid != callingUid) { 8127 continue; 8128 } 8129 Intent intent = tr.getBaseIntent(); 8130 if (intent == null || 8131 !callingPackage.equals(intent.getComponent().getPackageName())) { 8132 continue; 8133 } 8134 ActivityManager.RecentTaskInfo taskInfo = 8135 createRecentTaskInfoFromTaskRecord(tr); 8136 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8137 list.add(taskImpl); 8138 } 8139 } finally { 8140 Binder.restoreCallingIdentity(ident); 8141 } 8142 return list; 8143 } 8144 } 8145 8146 @Override 8147 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8148 final int callingUid = Binder.getCallingUid(); 8149 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8150 8151 synchronized(this) { 8152 if (localLOGV) Slog.v( 8153 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8154 8155 final boolean allowed = checkCallingPermission( 8156 android.Manifest.permission.GET_TASKS) 8157 == PackageManager.PERMISSION_GRANTED; 8158 if (!allowed) { 8159 Slog.w(TAG, "getTasks: caller " + callingUid 8160 + " does not hold GET_TASKS; limiting output"); 8161 } 8162 8163 // TODO: Improve with MRU list from all ActivityStacks. 8164 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8165 } 8166 8167 return list; 8168 } 8169 8170 TaskRecord getMostRecentTask() { 8171 return mRecentTasks.get(0); 8172 } 8173 8174 /** 8175 * Creates a new RecentTaskInfo from a TaskRecord. 8176 */ 8177 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8178 // Update the task description to reflect any changes in the task stack 8179 tr.updateTaskDescription(); 8180 8181 // Compose the recent task info 8182 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8183 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8184 rti.persistentId = tr.taskId; 8185 rti.baseIntent = new Intent(tr.getBaseIntent()); 8186 rti.origActivity = tr.origActivity; 8187 rti.description = tr.lastDescription; 8188 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8189 rti.userId = tr.userId; 8190 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8191 rti.firstActiveTime = tr.firstActiveTime; 8192 rti.lastActiveTime = tr.lastActiveTime; 8193 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8194 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8195 return rti; 8196 } 8197 8198 @Override 8199 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8200 final int callingUid = Binder.getCallingUid(); 8201 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8202 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8203 8204 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8205 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8206 synchronized (this) { 8207 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8208 == PackageManager.PERMISSION_GRANTED; 8209 if (!allowed) { 8210 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8211 + " does not hold GET_TASKS; limiting output"); 8212 } 8213 final boolean detailed = checkCallingPermission( 8214 android.Manifest.permission.GET_DETAILED_TASKS) 8215 == PackageManager.PERMISSION_GRANTED; 8216 8217 final int N = mRecentTasks.size(); 8218 ArrayList<ActivityManager.RecentTaskInfo> res 8219 = new ArrayList<ActivityManager.RecentTaskInfo>( 8220 maxNum < N ? maxNum : N); 8221 8222 final Set<Integer> includedUsers; 8223 if (includeProfiles) { 8224 includedUsers = getProfileIdsLocked(userId); 8225 } else { 8226 includedUsers = new HashSet<Integer>(); 8227 } 8228 includedUsers.add(Integer.valueOf(userId)); 8229 8230 for (int i=0; i<N && maxNum > 0; i++) { 8231 TaskRecord tr = mRecentTasks.get(i); 8232 // Only add calling user or related users recent tasks 8233 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8234 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8235 continue; 8236 } 8237 8238 // Return the entry if desired by the caller. We always return 8239 // the first entry, because callers always expect this to be the 8240 // foreground app. We may filter others if the caller has 8241 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8242 // we should exclude the entry. 8243 8244 if (i == 0 8245 || withExcluded 8246 || (tr.intent == null) 8247 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8248 == 0)) { 8249 if (!allowed) { 8250 // If the caller doesn't have the GET_TASKS permission, then only 8251 // allow them to see a small subset of tasks -- their own and home. 8252 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8253 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8254 continue; 8255 } 8256 } 8257 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8258 if (tr.stack != null && tr.stack.isHomeStack()) { 8259 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8260 continue; 8261 } 8262 } 8263 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8264 // Don't include auto remove tasks that are finished or finishing. 8265 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8266 + tr); 8267 continue; 8268 } 8269 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8270 && !tr.isAvailable) { 8271 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8272 continue; 8273 } 8274 8275 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8276 if (!detailed) { 8277 rti.baseIntent.replaceExtras((Bundle)null); 8278 } 8279 8280 res.add(rti); 8281 maxNum--; 8282 } 8283 } 8284 return res; 8285 } 8286 } 8287 8288 private TaskRecord recentTaskForIdLocked(int id) { 8289 final int N = mRecentTasks.size(); 8290 for (int i=0; i<N; i++) { 8291 TaskRecord tr = mRecentTasks.get(i); 8292 if (tr.taskId == id) { 8293 return tr; 8294 } 8295 } 8296 return null; 8297 } 8298 8299 @Override 8300 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8301 synchronized (this) { 8302 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8303 "getTaskThumbnail()"); 8304 TaskRecord tr = recentTaskForIdLocked(id); 8305 if (tr != null) { 8306 return tr.getTaskThumbnailLocked(); 8307 } 8308 } 8309 return null; 8310 } 8311 8312 @Override 8313 public int addAppTask(IBinder activityToken, Intent intent, 8314 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8315 final int callingUid = Binder.getCallingUid(); 8316 final long callingIdent = Binder.clearCallingIdentity(); 8317 8318 try { 8319 synchronized (this) { 8320 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8321 if (r == null) { 8322 throw new IllegalArgumentException("Activity does not exist; token=" 8323 + activityToken); 8324 } 8325 ComponentName comp = intent.getComponent(); 8326 if (comp == null) { 8327 throw new IllegalArgumentException("Intent " + intent 8328 + " must specify explicit component"); 8329 } 8330 if (thumbnail.getWidth() != mThumbnailWidth 8331 || thumbnail.getHeight() != mThumbnailHeight) { 8332 throw new IllegalArgumentException("Bad thumbnail size: got " 8333 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8334 + mThumbnailWidth + "x" + mThumbnailHeight); 8335 } 8336 if (intent.getSelector() != null) { 8337 intent.setSelector(null); 8338 } 8339 if (intent.getSourceBounds() != null) { 8340 intent.setSourceBounds(null); 8341 } 8342 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8343 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8344 // The caller has added this as an auto-remove task... that makes no 8345 // sense, so turn off auto-remove. 8346 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8347 } 8348 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8349 // Must be a new task. 8350 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8351 } 8352 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8353 mLastAddedTaskActivity = null; 8354 } 8355 ActivityInfo ainfo = mLastAddedTaskActivity; 8356 if (ainfo == null) { 8357 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8358 comp, 0, UserHandle.getUserId(callingUid)); 8359 if (ainfo.applicationInfo.uid != callingUid) { 8360 throw new SecurityException( 8361 "Can't add task for another application: target uid=" 8362 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8363 } 8364 } 8365 8366 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8367 intent, description); 8368 8369 int trimIdx = trimRecentsForTask(task, false); 8370 if (trimIdx >= 0) { 8371 // If this would have caused a trim, then we'll abort because that 8372 // means it would be added at the end of the list but then just removed. 8373 return -1; 8374 } 8375 8376 final int N = mRecentTasks.size(); 8377 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8378 final TaskRecord tr = mRecentTasks.remove(N - 1); 8379 tr.removedFromRecents(mTaskPersister); 8380 } 8381 8382 task.inRecents = true; 8383 mRecentTasks.add(task); 8384 r.task.stack.addTask(task, false, false); 8385 8386 task.setLastThumbnail(thumbnail); 8387 task.freeLastThumbnail(); 8388 8389 return task.taskId; 8390 } 8391 } finally { 8392 Binder.restoreCallingIdentity(callingIdent); 8393 } 8394 } 8395 8396 @Override 8397 public Point getAppTaskThumbnailSize() { 8398 synchronized (this) { 8399 return new Point(mThumbnailWidth, mThumbnailHeight); 8400 } 8401 } 8402 8403 @Override 8404 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8405 synchronized (this) { 8406 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8407 if (r != null) { 8408 r.setTaskDescription(td); 8409 r.task.updateTaskDescription(); 8410 } 8411 } 8412 } 8413 8414 @Override 8415 public Bitmap getTaskDescriptionIcon(String filename) { 8416 if (!FileUtils.isValidExtFilename(filename) 8417 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8418 throw new IllegalArgumentException("Bad filename: " + filename); 8419 } 8420 return mTaskPersister.getTaskDescriptionIcon(filename); 8421 } 8422 8423 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8424 mRecentTasks.remove(tr); 8425 tr.removedFromRecents(mTaskPersister); 8426 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8427 Intent baseIntent = new Intent( 8428 tr.intent != null ? tr.intent : tr.affinityIntent); 8429 ComponentName component = baseIntent.getComponent(); 8430 if (component == null) { 8431 Slog.w(TAG, "Now component for base intent of task: " + tr); 8432 return; 8433 } 8434 8435 // Find any running services associated with this app. 8436 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8437 8438 if (killProcesses) { 8439 // Find any running processes associated with this app. 8440 final String pkg = component.getPackageName(); 8441 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8442 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8443 for (int i=0; i<pmap.size(); i++) { 8444 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8445 for (int j=0; j<uids.size(); j++) { 8446 ProcessRecord proc = uids.valueAt(j); 8447 if (proc.userId != tr.userId) { 8448 continue; 8449 } 8450 if (!proc.pkgList.containsKey(pkg)) { 8451 continue; 8452 } 8453 procs.add(proc); 8454 } 8455 } 8456 8457 // Kill the running processes. 8458 for (int i=0; i<procs.size(); i++) { 8459 ProcessRecord pr = procs.get(i); 8460 if (pr == mHomeProcess) { 8461 // Don't kill the home process along with tasks from the same package. 8462 continue; 8463 } 8464 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8465 pr.kill("remove task", true); 8466 } else { 8467 pr.waitingToKill = "remove task"; 8468 } 8469 } 8470 } 8471 } 8472 8473 /** 8474 * Removes the task with the specified task id. 8475 * 8476 * @param taskId Identifier of the task to be removed. 8477 * @param flags Additional operational flags. May be 0 or 8478 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8479 * @return Returns true if the given task was found and removed. 8480 */ 8481 private boolean removeTaskByIdLocked(int taskId, int flags) { 8482 TaskRecord tr = recentTaskForIdLocked(taskId); 8483 if (tr != null) { 8484 tr.removeTaskActivitiesLocked(); 8485 cleanUpRemovedTaskLocked(tr, flags); 8486 if (tr.isPersistable) { 8487 notifyTaskPersisterLocked(null, true); 8488 } 8489 return true; 8490 } 8491 return false; 8492 } 8493 8494 @Override 8495 public boolean removeTask(int taskId, int flags) { 8496 synchronized (this) { 8497 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8498 "removeTask()"); 8499 long ident = Binder.clearCallingIdentity(); 8500 try { 8501 return removeTaskByIdLocked(taskId, flags); 8502 } finally { 8503 Binder.restoreCallingIdentity(ident); 8504 } 8505 } 8506 } 8507 8508 /** 8509 * TODO: Add mController hook 8510 */ 8511 @Override 8512 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8513 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8514 "moveTaskToFront()"); 8515 8516 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8517 synchronized(this) { 8518 moveTaskToFrontLocked(taskId, flags, options); 8519 } 8520 } 8521 8522 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8523 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8524 Binder.getCallingUid(), -1, -1, "Task to front")) { 8525 ActivityOptions.abort(options); 8526 return; 8527 } 8528 final long origId = Binder.clearCallingIdentity(); 8529 try { 8530 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8531 if (task == null) { 8532 return; 8533 } 8534 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8535 mStackSupervisor.showLockTaskToast(); 8536 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8537 return; 8538 } 8539 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8540 if (prev != null && prev.isRecentsActivity()) { 8541 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8542 } 8543 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8544 } finally { 8545 Binder.restoreCallingIdentity(origId); 8546 } 8547 ActivityOptions.abort(options); 8548 } 8549 8550 @Override 8551 public void moveTaskToBack(int taskId) { 8552 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8553 "moveTaskToBack()"); 8554 8555 synchronized(this) { 8556 TaskRecord tr = recentTaskForIdLocked(taskId); 8557 if (tr != null) { 8558 if (tr == mStackSupervisor.mLockTaskModeTask) { 8559 mStackSupervisor.showLockTaskToast(); 8560 return; 8561 } 8562 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8563 ActivityStack stack = tr.stack; 8564 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8565 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8566 Binder.getCallingUid(), -1, -1, "Task to back")) { 8567 return; 8568 } 8569 } 8570 final long origId = Binder.clearCallingIdentity(); 8571 try { 8572 stack.moveTaskToBackLocked(taskId, null); 8573 } finally { 8574 Binder.restoreCallingIdentity(origId); 8575 } 8576 } 8577 } 8578 } 8579 8580 /** 8581 * Moves an activity, and all of the other activities within the same task, to the bottom 8582 * of the history stack. The activity's order within the task is unchanged. 8583 * 8584 * @param token A reference to the activity we wish to move 8585 * @param nonRoot If false then this only works if the activity is the root 8586 * of a task; if true it will work for any activity in a task. 8587 * @return Returns true if the move completed, false if not. 8588 */ 8589 @Override 8590 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8591 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8592 synchronized(this) { 8593 final long origId = Binder.clearCallingIdentity(); 8594 try { 8595 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8596 if (taskId >= 0) { 8597 if ((mStackSupervisor.mLockTaskModeTask != null) 8598 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8599 mStackSupervisor.showLockTaskToast(); 8600 return false; 8601 } 8602 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8603 } 8604 } finally { 8605 Binder.restoreCallingIdentity(origId); 8606 } 8607 } 8608 return false; 8609 } 8610 8611 @Override 8612 public void moveTaskBackwards(int task) { 8613 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8614 "moveTaskBackwards()"); 8615 8616 synchronized(this) { 8617 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8618 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8619 return; 8620 } 8621 final long origId = Binder.clearCallingIdentity(); 8622 moveTaskBackwardsLocked(task); 8623 Binder.restoreCallingIdentity(origId); 8624 } 8625 } 8626 8627 private final void moveTaskBackwardsLocked(int task) { 8628 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8629 } 8630 8631 @Override 8632 public IBinder getHomeActivityToken() throws RemoteException { 8633 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8634 "getHomeActivityToken()"); 8635 synchronized (this) { 8636 return mStackSupervisor.getHomeActivityToken(); 8637 } 8638 } 8639 8640 @Override 8641 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8642 IActivityContainerCallback callback) throws RemoteException { 8643 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8644 "createActivityContainer()"); 8645 synchronized (this) { 8646 if (parentActivityToken == null) { 8647 throw new IllegalArgumentException("parent token must not be null"); 8648 } 8649 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8650 if (r == null) { 8651 return null; 8652 } 8653 if (callback == null) { 8654 throw new IllegalArgumentException("callback must not be null"); 8655 } 8656 return mStackSupervisor.createActivityContainer(r, callback); 8657 } 8658 } 8659 8660 @Override 8661 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8662 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8663 "deleteActivityContainer()"); 8664 synchronized (this) { 8665 mStackSupervisor.deleteActivityContainer(container); 8666 } 8667 } 8668 8669 @Override 8670 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8671 throws RemoteException { 8672 synchronized (this) { 8673 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8674 if (stack != null) { 8675 return stack.mActivityContainer; 8676 } 8677 return null; 8678 } 8679 } 8680 8681 @Override 8682 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8683 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8684 "moveTaskToStack()"); 8685 if (stackId == HOME_STACK_ID) { 8686 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8687 new RuntimeException("here").fillInStackTrace()); 8688 } 8689 synchronized (this) { 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8693 + stackId + " toTop=" + toTop); 8694 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 } 8700 8701 @Override 8702 public void resizeStack(int stackBoxId, Rect bounds) { 8703 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8704 "resizeStackBox()"); 8705 long ident = Binder.clearCallingIdentity(); 8706 try { 8707 mWindowManager.resizeStack(stackBoxId, bounds); 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public List<StackInfo> getAllStackInfos() { 8715 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8716 "getAllStackInfos()"); 8717 long ident = Binder.clearCallingIdentity(); 8718 try { 8719 synchronized (this) { 8720 return mStackSupervisor.getAllStackInfosLocked(); 8721 } 8722 } finally { 8723 Binder.restoreCallingIdentity(ident); 8724 } 8725 } 8726 8727 @Override 8728 public StackInfo getStackInfo(int stackId) { 8729 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8730 "getStackInfo()"); 8731 long ident = Binder.clearCallingIdentity(); 8732 try { 8733 synchronized (this) { 8734 return mStackSupervisor.getStackInfoLocked(stackId); 8735 } 8736 } finally { 8737 Binder.restoreCallingIdentity(ident); 8738 } 8739 } 8740 8741 @Override 8742 public boolean isInHomeStack(int taskId) { 8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8744 "getStackInfo()"); 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 synchronized (this) { 8748 TaskRecord tr = recentTaskForIdLocked(taskId); 8749 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8750 } 8751 } finally { 8752 Binder.restoreCallingIdentity(ident); 8753 } 8754 } 8755 8756 @Override 8757 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8758 synchronized(this) { 8759 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8760 } 8761 } 8762 8763 private boolean isLockTaskAuthorized(String pkg) { 8764 final DevicePolicyManager dpm = (DevicePolicyManager) 8765 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8766 try { 8767 int uid = mContext.getPackageManager().getPackageUid(pkg, 8768 Binder.getCallingUserHandle().getIdentifier()); 8769 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8770 } catch (NameNotFoundException e) { 8771 return false; 8772 } 8773 } 8774 8775 void startLockTaskMode(TaskRecord task) { 8776 final String pkg; 8777 synchronized (this) { 8778 pkg = task.intent.getComponent().getPackageName(); 8779 } 8780 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8781 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8782 final TaskRecord taskRecord = task; 8783 mHandler.post(new Runnable() { 8784 @Override 8785 public void run() { 8786 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8787 } 8788 }); 8789 return; 8790 } 8791 long ident = Binder.clearCallingIdentity(); 8792 try { 8793 synchronized (this) { 8794 // Since we lost lock on task, make sure it is still there. 8795 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8796 if (task != null) { 8797 if (!isSystemInitiated 8798 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8799 throw new IllegalArgumentException("Invalid task, not in foreground"); 8800 } 8801 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8802 } 8803 } 8804 } finally { 8805 Binder.restoreCallingIdentity(ident); 8806 } 8807 } 8808 8809 @Override 8810 public void startLockTaskMode(int taskId) { 8811 final TaskRecord task; 8812 long ident = Binder.clearCallingIdentity(); 8813 try { 8814 synchronized (this) { 8815 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8816 } 8817 } finally { 8818 Binder.restoreCallingIdentity(ident); 8819 } 8820 if (task != null) { 8821 startLockTaskMode(task); 8822 } 8823 } 8824 8825 @Override 8826 public void startLockTaskMode(IBinder token) { 8827 final TaskRecord task; 8828 long ident = Binder.clearCallingIdentity(); 8829 try { 8830 synchronized (this) { 8831 final ActivityRecord r = ActivityRecord.forToken(token); 8832 if (r == null) { 8833 return; 8834 } 8835 task = r.task; 8836 } 8837 } finally { 8838 Binder.restoreCallingIdentity(ident); 8839 } 8840 if (task != null) { 8841 startLockTaskMode(task); 8842 } 8843 } 8844 8845 @Override 8846 public void startLockTaskModeOnCurrent() throws RemoteException { 8847 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8848 "startLockTaskModeOnCurrent"); 8849 ActivityRecord r = null; 8850 synchronized (this) { 8851 r = mStackSupervisor.topRunningActivityLocked(); 8852 } 8853 startLockTaskMode(r.task); 8854 } 8855 8856 @Override 8857 public void stopLockTaskMode() { 8858 // Verify that the user matches the package of the intent for the TaskRecord 8859 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8860 // and stopLockTaskMode. 8861 final int callingUid = Binder.getCallingUid(); 8862 if (callingUid != Process.SYSTEM_UID) { 8863 try { 8864 String pkg = 8865 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8866 int uid = mContext.getPackageManager().getPackageUid(pkg, 8867 Binder.getCallingUserHandle().getIdentifier()); 8868 if (uid != callingUid) { 8869 throw new SecurityException("Invalid uid, expected " + uid); 8870 } 8871 } catch (NameNotFoundException e) { 8872 Log.d(TAG, "stopLockTaskMode " + e); 8873 return; 8874 } 8875 } 8876 long ident = Binder.clearCallingIdentity(); 8877 try { 8878 Log.d(TAG, "stopLockTaskMode"); 8879 // Stop lock task 8880 synchronized (this) { 8881 mStackSupervisor.setLockTaskModeLocked(null, false); 8882 } 8883 } finally { 8884 Binder.restoreCallingIdentity(ident); 8885 } 8886 } 8887 8888 @Override 8889 public void stopLockTaskModeOnCurrent() throws RemoteException { 8890 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8891 "stopLockTaskModeOnCurrent"); 8892 long ident = Binder.clearCallingIdentity(); 8893 try { 8894 stopLockTaskMode(); 8895 } finally { 8896 Binder.restoreCallingIdentity(ident); 8897 } 8898 } 8899 8900 @Override 8901 public boolean isInLockTaskMode() { 8902 synchronized (this) { 8903 return mStackSupervisor.isInLockTaskMode(); 8904 } 8905 } 8906 8907 // ========================================================= 8908 // CONTENT PROVIDERS 8909 // ========================================================= 8910 8911 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8912 List<ProviderInfo> providers = null; 8913 try { 8914 providers = AppGlobals.getPackageManager(). 8915 queryContentProviders(app.processName, app.uid, 8916 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8917 } catch (RemoteException ex) { 8918 } 8919 if (DEBUG_MU) 8920 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8921 int userId = app.userId; 8922 if (providers != null) { 8923 int N = providers.size(); 8924 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8925 for (int i=0; i<N; i++) { 8926 ProviderInfo cpi = 8927 (ProviderInfo)providers.get(i); 8928 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8929 cpi.name, cpi.flags); 8930 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8931 // This is a singleton provider, but a user besides the 8932 // default user is asking to initialize a process it runs 8933 // in... well, no, it doesn't actually run in this process, 8934 // it runs in the process of the default user. Get rid of it. 8935 providers.remove(i); 8936 N--; 8937 i--; 8938 continue; 8939 } 8940 8941 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8942 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8943 if (cpr == null) { 8944 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8945 mProviderMap.putProviderByClass(comp, cpr); 8946 } 8947 if (DEBUG_MU) 8948 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8949 app.pubProviders.put(cpi.name, cpr); 8950 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8951 // Don't add this if it is a platform component that is marked 8952 // to run in multiple processes, because this is actually 8953 // part of the framework so doesn't make sense to track as a 8954 // separate apk in the process. 8955 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8956 mProcessStats); 8957 } 8958 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8959 } 8960 } 8961 return providers; 8962 } 8963 8964 /** 8965 * Check if {@link ProcessRecord} has a possible chance at accessing the 8966 * given {@link ProviderInfo}. Final permission checking is always done 8967 * in {@link ContentProvider}. 8968 */ 8969 private final String checkContentProviderPermissionLocked( 8970 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8971 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8972 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8973 boolean checkedGrants = false; 8974 if (checkUser) { 8975 // Looking for cross-user grants before enforcing the typical cross-users permissions 8976 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8977 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8978 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8979 return null; 8980 } 8981 checkedGrants = true; 8982 } 8983 userId = handleIncomingUser(callingPid, callingUid, userId, 8984 false, ALLOW_NON_FULL, 8985 "checkContentProviderPermissionLocked " + cpi.authority, null); 8986 if (userId != tmpTargetUserId) { 8987 // When we actually went to determine the final targer user ID, this ended 8988 // up different than our initial check for the authority. This is because 8989 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8990 // SELF. So we need to re-check the grants again. 8991 checkedGrants = false; 8992 } 8993 } 8994 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8995 cpi.applicationInfo.uid, cpi.exported) 8996 == PackageManager.PERMISSION_GRANTED) { 8997 return null; 8998 } 8999 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9000 cpi.applicationInfo.uid, cpi.exported) 9001 == PackageManager.PERMISSION_GRANTED) { 9002 return null; 9003 } 9004 9005 PathPermission[] pps = cpi.pathPermissions; 9006 if (pps != null) { 9007 int i = pps.length; 9008 while (i > 0) { 9009 i--; 9010 PathPermission pp = pps[i]; 9011 String pprperm = pp.getReadPermission(); 9012 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9013 cpi.applicationInfo.uid, cpi.exported) 9014 == PackageManager.PERMISSION_GRANTED) { 9015 return null; 9016 } 9017 String ppwperm = pp.getWritePermission(); 9018 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9019 cpi.applicationInfo.uid, cpi.exported) 9020 == PackageManager.PERMISSION_GRANTED) { 9021 return null; 9022 } 9023 } 9024 } 9025 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9026 return null; 9027 } 9028 9029 String msg; 9030 if (!cpi.exported) { 9031 msg = "Permission Denial: opening provider " + cpi.name 9032 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9033 + ", uid=" + callingUid + ") that is not exported from uid " 9034 + cpi.applicationInfo.uid; 9035 } else { 9036 msg = "Permission Denial: opening provider " + cpi.name 9037 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9038 + ", uid=" + callingUid + ") requires " 9039 + cpi.readPermission + " or " + cpi.writePermission; 9040 } 9041 Slog.w(TAG, msg); 9042 return msg; 9043 } 9044 9045 /** 9046 * Returns if the ContentProvider has granted a uri to callingUid 9047 */ 9048 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9049 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9050 if (perms != null) { 9051 for (int i=perms.size()-1; i>=0; i--) { 9052 GrantUri grantUri = perms.keyAt(i); 9053 if (grantUri.sourceUserId == userId || !checkUser) { 9054 if (matchesProvider(grantUri.uri, cpi)) { 9055 return true; 9056 } 9057 } 9058 } 9059 } 9060 return false; 9061 } 9062 9063 /** 9064 * Returns true if the uri authority is one of the authorities specified in the provider. 9065 */ 9066 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9067 String uriAuth = uri.getAuthority(); 9068 String cpiAuth = cpi.authority; 9069 if (cpiAuth.indexOf(';') == -1) { 9070 return cpiAuth.equals(uriAuth); 9071 } 9072 String[] cpiAuths = cpiAuth.split(";"); 9073 int length = cpiAuths.length; 9074 for (int i = 0; i < length; i++) { 9075 if (cpiAuths[i].equals(uriAuth)) return true; 9076 } 9077 return false; 9078 } 9079 9080 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9081 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9082 if (r != null) { 9083 for (int i=0; i<r.conProviders.size(); i++) { 9084 ContentProviderConnection conn = r.conProviders.get(i); 9085 if (conn.provider == cpr) { 9086 if (DEBUG_PROVIDER) Slog.v(TAG, 9087 "Adding provider requested by " 9088 + r.processName + " from process " 9089 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9090 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9091 if (stable) { 9092 conn.stableCount++; 9093 conn.numStableIncs++; 9094 } else { 9095 conn.unstableCount++; 9096 conn.numUnstableIncs++; 9097 } 9098 return conn; 9099 } 9100 } 9101 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9102 if (stable) { 9103 conn.stableCount = 1; 9104 conn.numStableIncs = 1; 9105 } else { 9106 conn.unstableCount = 1; 9107 conn.numUnstableIncs = 1; 9108 } 9109 cpr.connections.add(conn); 9110 r.conProviders.add(conn); 9111 return conn; 9112 } 9113 cpr.addExternalProcessHandleLocked(externalProcessToken); 9114 return null; 9115 } 9116 9117 boolean decProviderCountLocked(ContentProviderConnection conn, 9118 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9119 if (conn != null) { 9120 cpr = conn.provider; 9121 if (DEBUG_PROVIDER) Slog.v(TAG, 9122 "Removing provider requested by " 9123 + conn.client.processName + " from process " 9124 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9125 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9126 if (stable) { 9127 conn.stableCount--; 9128 } else { 9129 conn.unstableCount--; 9130 } 9131 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9132 cpr.connections.remove(conn); 9133 conn.client.conProviders.remove(conn); 9134 return true; 9135 } 9136 return false; 9137 } 9138 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9139 return false; 9140 } 9141 9142 private void checkTime(long startTime, String where) { 9143 long now = SystemClock.elapsedRealtime(); 9144 if ((now-startTime) > 1000) { 9145 // If we are taking more than a second, log about it. 9146 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9147 } 9148 } 9149 9150 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9151 String name, IBinder token, boolean stable, int userId) { 9152 ContentProviderRecord cpr; 9153 ContentProviderConnection conn = null; 9154 ProviderInfo cpi = null; 9155 9156 synchronized(this) { 9157 long startTime = SystemClock.elapsedRealtime(); 9158 9159 ProcessRecord r = null; 9160 if (caller != null) { 9161 r = getRecordForAppLocked(caller); 9162 if (r == null) { 9163 throw new SecurityException( 9164 "Unable to find app for caller " + caller 9165 + " (pid=" + Binder.getCallingPid() 9166 + ") when getting content provider " + name); 9167 } 9168 } 9169 9170 boolean checkCrossUser = true; 9171 9172 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9173 9174 // First check if this content provider has been published... 9175 cpr = mProviderMap.getProviderByName(name, userId); 9176 // If that didn't work, check if it exists for user 0 and then 9177 // verify that it's a singleton provider before using it. 9178 if (cpr == null && userId != UserHandle.USER_OWNER) { 9179 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9180 if (cpr != null) { 9181 cpi = cpr.info; 9182 if (isSingleton(cpi.processName, cpi.applicationInfo, 9183 cpi.name, cpi.flags) 9184 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9185 userId = UserHandle.USER_OWNER; 9186 checkCrossUser = false; 9187 } else { 9188 cpr = null; 9189 cpi = null; 9190 } 9191 } 9192 } 9193 9194 boolean providerRunning = cpr != null; 9195 if (providerRunning) { 9196 cpi = cpr.info; 9197 String msg; 9198 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9199 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9200 != null) { 9201 throw new SecurityException(msg); 9202 } 9203 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9204 9205 if (r != null && cpr.canRunHere(r)) { 9206 // This provider has been published or is in the process 9207 // of being published... but it is also allowed to run 9208 // in the caller's process, so don't make a connection 9209 // and just let the caller instantiate its own instance. 9210 ContentProviderHolder holder = cpr.newHolder(null); 9211 // don't give caller the provider object, it needs 9212 // to make its own. 9213 holder.provider = null; 9214 return holder; 9215 } 9216 9217 final long origId = Binder.clearCallingIdentity(); 9218 9219 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9220 9221 // In this case the provider instance already exists, so we can 9222 // return it right away. 9223 conn = incProviderCountLocked(r, cpr, token, stable); 9224 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9225 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9226 // If this is a perceptible app accessing the provider, 9227 // make sure to count it as being accessed and thus 9228 // back up on the LRU list. This is good because 9229 // content providers are often expensive to start. 9230 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9231 updateLruProcessLocked(cpr.proc, false, null); 9232 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9233 } 9234 } 9235 9236 if (cpr.proc != null) { 9237 if (false) { 9238 if (cpr.name.flattenToShortString().equals( 9239 "com.android.providers.calendar/.CalendarProvider2")) { 9240 Slog.v(TAG, "****************** KILLING " 9241 + cpr.name.flattenToShortString()); 9242 Process.killProcess(cpr.proc.pid); 9243 } 9244 } 9245 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9246 boolean success = updateOomAdjLocked(cpr.proc); 9247 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9248 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9249 // NOTE: there is still a race here where a signal could be 9250 // pending on the process even though we managed to update its 9251 // adj level. Not sure what to do about this, but at least 9252 // the race is now smaller. 9253 if (!success) { 9254 // Uh oh... it looks like the provider's process 9255 // has been killed on us. We need to wait for a new 9256 // process to be started, and make sure its death 9257 // doesn't kill our process. 9258 Slog.i(TAG, 9259 "Existing provider " + cpr.name.flattenToShortString() 9260 + " is crashing; detaching " + r); 9261 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9262 checkTime(startTime, "getContentProviderImpl: before appDied"); 9263 appDiedLocked(cpr.proc); 9264 checkTime(startTime, "getContentProviderImpl: after appDied"); 9265 if (!lastRef) { 9266 // This wasn't the last ref our process had on 9267 // the provider... we have now been killed, bail. 9268 return null; 9269 } 9270 providerRunning = false; 9271 conn = null; 9272 } 9273 } 9274 9275 Binder.restoreCallingIdentity(origId); 9276 } 9277 9278 boolean singleton; 9279 if (!providerRunning) { 9280 try { 9281 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9282 cpi = AppGlobals.getPackageManager(). 9283 resolveContentProvider(name, 9284 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9285 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9286 } catch (RemoteException ex) { 9287 } 9288 if (cpi == null) { 9289 return null; 9290 } 9291 // If the provider is a singleton AND 9292 // (it's a call within the same user || the provider is a 9293 // privileged app) 9294 // Then allow connecting to the singleton provider 9295 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9296 cpi.name, cpi.flags) 9297 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9298 if (singleton) { 9299 userId = UserHandle.USER_OWNER; 9300 } 9301 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9302 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9303 9304 String msg; 9305 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9306 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9307 != null) { 9308 throw new SecurityException(msg); 9309 } 9310 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9311 9312 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9313 && !cpi.processName.equals("system")) { 9314 // If this content provider does not run in the system 9315 // process, and the system is not yet ready to run other 9316 // processes, then fail fast instead of hanging. 9317 throw new IllegalArgumentException( 9318 "Attempt to launch content provider before system ready"); 9319 } 9320 9321 // Make sure that the user who owns this provider is started. If not, 9322 // we don't want to allow it to run. 9323 if (mStartedUsers.get(userId) == null) { 9324 Slog.w(TAG, "Unable to launch app " 9325 + cpi.applicationInfo.packageName + "/" 9326 + cpi.applicationInfo.uid + " for provider " 9327 + name + ": user " + userId + " is stopped"); 9328 return null; 9329 } 9330 9331 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9332 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9333 cpr = mProviderMap.getProviderByClass(comp, userId); 9334 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9335 final boolean firstClass = cpr == null; 9336 if (firstClass) { 9337 try { 9338 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9339 ApplicationInfo ai = 9340 AppGlobals.getPackageManager(). 9341 getApplicationInfo( 9342 cpi.applicationInfo.packageName, 9343 STOCK_PM_FLAGS, userId); 9344 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9345 if (ai == null) { 9346 Slog.w(TAG, "No package info for content provider " 9347 + cpi.name); 9348 return null; 9349 } 9350 ai = getAppInfoForUser(ai, userId); 9351 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9352 } catch (RemoteException ex) { 9353 // pm is in same process, this will never happen. 9354 } 9355 } 9356 9357 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9358 9359 if (r != null && cpr.canRunHere(r)) { 9360 // If this is a multiprocess provider, then just return its 9361 // info and allow the caller to instantiate it. Only do 9362 // this if the provider is the same user as the caller's 9363 // process, or can run as root (so can be in any process). 9364 return cpr.newHolder(null); 9365 } 9366 9367 if (DEBUG_PROVIDER) { 9368 RuntimeException e = new RuntimeException("here"); 9369 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9370 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9371 } 9372 9373 // This is single process, and our app is now connecting to it. 9374 // See if we are already in the process of launching this 9375 // provider. 9376 final int N = mLaunchingProviders.size(); 9377 int i; 9378 for (i=0; i<N; i++) { 9379 if (mLaunchingProviders.get(i) == cpr) { 9380 break; 9381 } 9382 } 9383 9384 // If the provider is not already being launched, then get it 9385 // started. 9386 if (i >= N) { 9387 final long origId = Binder.clearCallingIdentity(); 9388 9389 try { 9390 // Content provider is now in use, its package can't be stopped. 9391 try { 9392 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9393 AppGlobals.getPackageManager().setPackageStoppedState( 9394 cpr.appInfo.packageName, false, userId); 9395 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9396 } catch (RemoteException e) { 9397 } catch (IllegalArgumentException e) { 9398 Slog.w(TAG, "Failed trying to unstop package " 9399 + cpr.appInfo.packageName + ": " + e); 9400 } 9401 9402 // Use existing process if already started 9403 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9404 ProcessRecord proc = getProcessRecordLocked( 9405 cpi.processName, cpr.appInfo.uid, false); 9406 if (proc != null && proc.thread != null) { 9407 if (DEBUG_PROVIDER) { 9408 Slog.d(TAG, "Installing in existing process " + proc); 9409 } 9410 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9411 proc.pubProviders.put(cpi.name, cpr); 9412 try { 9413 proc.thread.scheduleInstallProvider(cpi); 9414 } catch (RemoteException e) { 9415 } 9416 } else { 9417 checkTime(startTime, "getContentProviderImpl: before start process"); 9418 proc = startProcessLocked(cpi.processName, 9419 cpr.appInfo, false, 0, "content provider", 9420 new ComponentName(cpi.applicationInfo.packageName, 9421 cpi.name), false, false, false); 9422 checkTime(startTime, "getContentProviderImpl: after start process"); 9423 if (proc == null) { 9424 Slog.w(TAG, "Unable to launch app " 9425 + cpi.applicationInfo.packageName + "/" 9426 + cpi.applicationInfo.uid + " for provider " 9427 + name + ": process is bad"); 9428 return null; 9429 } 9430 } 9431 cpr.launchingApp = proc; 9432 mLaunchingProviders.add(cpr); 9433 } finally { 9434 Binder.restoreCallingIdentity(origId); 9435 } 9436 } 9437 9438 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9439 9440 // Make sure the provider is published (the same provider class 9441 // may be published under multiple names). 9442 if (firstClass) { 9443 mProviderMap.putProviderByClass(comp, cpr); 9444 } 9445 9446 mProviderMap.putProviderByName(name, cpr); 9447 conn = incProviderCountLocked(r, cpr, token, stable); 9448 if (conn != null) { 9449 conn.waiting = true; 9450 } 9451 } 9452 checkTime(startTime, "getContentProviderImpl: done!"); 9453 } 9454 9455 // Wait for the provider to be published... 9456 synchronized (cpr) { 9457 while (cpr.provider == null) { 9458 if (cpr.launchingApp == null) { 9459 Slog.w(TAG, "Unable to launch app " 9460 + cpi.applicationInfo.packageName + "/" 9461 + cpi.applicationInfo.uid + " for provider " 9462 + name + ": launching app became null"); 9463 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9464 UserHandle.getUserId(cpi.applicationInfo.uid), 9465 cpi.applicationInfo.packageName, 9466 cpi.applicationInfo.uid, name); 9467 return null; 9468 } 9469 try { 9470 if (DEBUG_MU) { 9471 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9472 + cpr.launchingApp); 9473 } 9474 if (conn != null) { 9475 conn.waiting = true; 9476 } 9477 cpr.wait(); 9478 } catch (InterruptedException ex) { 9479 } finally { 9480 if (conn != null) { 9481 conn.waiting = false; 9482 } 9483 } 9484 } 9485 } 9486 return cpr != null ? cpr.newHolder(conn) : null; 9487 } 9488 9489 @Override 9490 public final ContentProviderHolder getContentProvider( 9491 IApplicationThread caller, String name, int userId, boolean stable) { 9492 enforceNotIsolatedCaller("getContentProvider"); 9493 if (caller == null) { 9494 String msg = "null IApplicationThread when getting content provider " 9495 + name; 9496 Slog.w(TAG, msg); 9497 throw new SecurityException(msg); 9498 } 9499 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9500 // with cross-user grant. 9501 return getContentProviderImpl(caller, name, null, stable, userId); 9502 } 9503 9504 public ContentProviderHolder getContentProviderExternal( 9505 String name, int userId, IBinder token) { 9506 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9507 "Do not have permission in call getContentProviderExternal()"); 9508 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9509 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9510 return getContentProviderExternalUnchecked(name, token, userId); 9511 } 9512 9513 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9514 IBinder token, int userId) { 9515 return getContentProviderImpl(null, name, token, true, userId); 9516 } 9517 9518 /** 9519 * Drop a content provider from a ProcessRecord's bookkeeping 9520 */ 9521 public void removeContentProvider(IBinder connection, boolean stable) { 9522 enforceNotIsolatedCaller("removeContentProvider"); 9523 long ident = Binder.clearCallingIdentity(); 9524 try { 9525 synchronized (this) { 9526 ContentProviderConnection conn; 9527 try { 9528 conn = (ContentProviderConnection)connection; 9529 } catch (ClassCastException e) { 9530 String msg ="removeContentProvider: " + connection 9531 + " not a ContentProviderConnection"; 9532 Slog.w(TAG, msg); 9533 throw new IllegalArgumentException(msg); 9534 } 9535 if (conn == null) { 9536 throw new NullPointerException("connection is null"); 9537 } 9538 if (decProviderCountLocked(conn, null, null, stable)) { 9539 updateOomAdjLocked(); 9540 } 9541 } 9542 } finally { 9543 Binder.restoreCallingIdentity(ident); 9544 } 9545 } 9546 9547 public void removeContentProviderExternal(String name, IBinder token) { 9548 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9549 "Do not have permission in call removeContentProviderExternal()"); 9550 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9551 } 9552 9553 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9554 synchronized (this) { 9555 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9556 if(cpr == null) { 9557 //remove from mProvidersByClass 9558 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9559 return; 9560 } 9561 9562 //update content provider record entry info 9563 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9564 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9565 if (localCpr.hasExternalProcessHandles()) { 9566 if (localCpr.removeExternalProcessHandleLocked(token)) { 9567 updateOomAdjLocked(); 9568 } else { 9569 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9570 + " with no external reference for token: " 9571 + token + "."); 9572 } 9573 } else { 9574 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9575 + " with no external references."); 9576 } 9577 } 9578 } 9579 9580 public final void publishContentProviders(IApplicationThread caller, 9581 List<ContentProviderHolder> providers) { 9582 if (providers == null) { 9583 return; 9584 } 9585 9586 enforceNotIsolatedCaller("publishContentProviders"); 9587 synchronized (this) { 9588 final ProcessRecord r = getRecordForAppLocked(caller); 9589 if (DEBUG_MU) 9590 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9591 if (r == null) { 9592 throw new SecurityException( 9593 "Unable to find app for caller " + caller 9594 + " (pid=" + Binder.getCallingPid() 9595 + ") when publishing content providers"); 9596 } 9597 9598 final long origId = Binder.clearCallingIdentity(); 9599 9600 final int N = providers.size(); 9601 for (int i=0; i<N; i++) { 9602 ContentProviderHolder src = providers.get(i); 9603 if (src == null || src.info == null || src.provider == null) { 9604 continue; 9605 } 9606 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9607 if (DEBUG_MU) 9608 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9609 if (dst != null) { 9610 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9611 mProviderMap.putProviderByClass(comp, dst); 9612 String names[] = dst.info.authority.split(";"); 9613 for (int j = 0; j < names.length; j++) { 9614 mProviderMap.putProviderByName(names[j], dst); 9615 } 9616 9617 int NL = mLaunchingProviders.size(); 9618 int j; 9619 for (j=0; j<NL; j++) { 9620 if (mLaunchingProviders.get(j) == dst) { 9621 mLaunchingProviders.remove(j); 9622 j--; 9623 NL--; 9624 } 9625 } 9626 synchronized (dst) { 9627 dst.provider = src.provider; 9628 dst.proc = r; 9629 dst.notifyAll(); 9630 } 9631 updateOomAdjLocked(r); 9632 } 9633 } 9634 9635 Binder.restoreCallingIdentity(origId); 9636 } 9637 } 9638 9639 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9640 ContentProviderConnection conn; 9641 try { 9642 conn = (ContentProviderConnection)connection; 9643 } catch (ClassCastException e) { 9644 String msg ="refContentProvider: " + connection 9645 + " not a ContentProviderConnection"; 9646 Slog.w(TAG, msg); 9647 throw new IllegalArgumentException(msg); 9648 } 9649 if (conn == null) { 9650 throw new NullPointerException("connection is null"); 9651 } 9652 9653 synchronized (this) { 9654 if (stable > 0) { 9655 conn.numStableIncs += stable; 9656 } 9657 stable = conn.stableCount + stable; 9658 if (stable < 0) { 9659 throw new IllegalStateException("stableCount < 0: " + stable); 9660 } 9661 9662 if (unstable > 0) { 9663 conn.numUnstableIncs += unstable; 9664 } 9665 unstable = conn.unstableCount + unstable; 9666 if (unstable < 0) { 9667 throw new IllegalStateException("unstableCount < 0: " + unstable); 9668 } 9669 9670 if ((stable+unstable) <= 0) { 9671 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9672 + stable + " unstable=" + unstable); 9673 } 9674 conn.stableCount = stable; 9675 conn.unstableCount = unstable; 9676 return !conn.dead; 9677 } 9678 } 9679 9680 public void unstableProviderDied(IBinder connection) { 9681 ContentProviderConnection conn; 9682 try { 9683 conn = (ContentProviderConnection)connection; 9684 } catch (ClassCastException e) { 9685 String msg ="refContentProvider: " + connection 9686 + " not a ContentProviderConnection"; 9687 Slog.w(TAG, msg); 9688 throw new IllegalArgumentException(msg); 9689 } 9690 if (conn == null) { 9691 throw new NullPointerException("connection is null"); 9692 } 9693 9694 // Safely retrieve the content provider associated with the connection. 9695 IContentProvider provider; 9696 synchronized (this) { 9697 provider = conn.provider.provider; 9698 } 9699 9700 if (provider == null) { 9701 // Um, yeah, we're way ahead of you. 9702 return; 9703 } 9704 9705 // Make sure the caller is being honest with us. 9706 if (provider.asBinder().pingBinder()) { 9707 // Er, no, still looks good to us. 9708 synchronized (this) { 9709 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9710 + " says " + conn + " died, but we don't agree"); 9711 return; 9712 } 9713 } 9714 9715 // Well look at that! It's dead! 9716 synchronized (this) { 9717 if (conn.provider.provider != provider) { 9718 // But something changed... good enough. 9719 return; 9720 } 9721 9722 ProcessRecord proc = conn.provider.proc; 9723 if (proc == null || proc.thread == null) { 9724 // Seems like the process is already cleaned up. 9725 return; 9726 } 9727 9728 // As far as we're concerned, this is just like receiving a 9729 // death notification... just a bit prematurely. 9730 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9731 + ") early provider death"); 9732 final long ident = Binder.clearCallingIdentity(); 9733 try { 9734 appDiedLocked(proc); 9735 } finally { 9736 Binder.restoreCallingIdentity(ident); 9737 } 9738 } 9739 } 9740 9741 @Override 9742 public void appNotRespondingViaProvider(IBinder connection) { 9743 enforceCallingPermission( 9744 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9745 9746 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9747 if (conn == null) { 9748 Slog.w(TAG, "ContentProviderConnection is null"); 9749 return; 9750 } 9751 9752 final ProcessRecord host = conn.provider.proc; 9753 if (host == null) { 9754 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9755 return; 9756 } 9757 9758 final long token = Binder.clearCallingIdentity(); 9759 try { 9760 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9761 } finally { 9762 Binder.restoreCallingIdentity(token); 9763 } 9764 } 9765 9766 public final void installSystemProviders() { 9767 List<ProviderInfo> providers; 9768 synchronized (this) { 9769 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9770 providers = generateApplicationProvidersLocked(app); 9771 if (providers != null) { 9772 for (int i=providers.size()-1; i>=0; i--) { 9773 ProviderInfo pi = (ProviderInfo)providers.get(i); 9774 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9775 Slog.w(TAG, "Not installing system proc provider " + pi.name 9776 + ": not system .apk"); 9777 providers.remove(i); 9778 } 9779 } 9780 } 9781 } 9782 if (providers != null) { 9783 mSystemThread.installSystemProviders(providers); 9784 } 9785 9786 mCoreSettingsObserver = new CoreSettingsObserver(this); 9787 9788 //mUsageStatsService.monitorPackages(); 9789 } 9790 9791 /** 9792 * Allows apps to retrieve the MIME type of a URI. 9793 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9794 * users, then it does not need permission to access the ContentProvider. 9795 * Either, it needs cross-user uri grants. 9796 * 9797 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9798 * 9799 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9800 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9801 */ 9802 public String getProviderMimeType(Uri uri, int userId) { 9803 enforceNotIsolatedCaller("getProviderMimeType"); 9804 final String name = uri.getAuthority(); 9805 int callingUid = Binder.getCallingUid(); 9806 int callingPid = Binder.getCallingPid(); 9807 long ident = 0; 9808 boolean clearedIdentity = false; 9809 userId = unsafeConvertIncomingUser(userId); 9810 if (canClearIdentity(callingPid, callingUid, userId)) { 9811 clearedIdentity = true; 9812 ident = Binder.clearCallingIdentity(); 9813 } 9814 ContentProviderHolder holder = null; 9815 try { 9816 holder = getContentProviderExternalUnchecked(name, null, userId); 9817 if (holder != null) { 9818 return holder.provider.getType(uri); 9819 } 9820 } catch (RemoteException e) { 9821 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9822 return null; 9823 } finally { 9824 // We need to clear the identity to call removeContentProviderExternalUnchecked 9825 if (!clearedIdentity) { 9826 ident = Binder.clearCallingIdentity(); 9827 } 9828 try { 9829 if (holder != null) { 9830 removeContentProviderExternalUnchecked(name, null, userId); 9831 } 9832 } finally { 9833 Binder.restoreCallingIdentity(ident); 9834 } 9835 } 9836 9837 return null; 9838 } 9839 9840 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9841 if (UserHandle.getUserId(callingUid) == userId) { 9842 return true; 9843 } 9844 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9845 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9846 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9847 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9848 return true; 9849 } 9850 return false; 9851 } 9852 9853 // ========================================================= 9854 // GLOBAL MANAGEMENT 9855 // ========================================================= 9856 9857 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9858 boolean isolated, int isolatedUid) { 9859 String proc = customProcess != null ? customProcess : info.processName; 9860 BatteryStatsImpl.Uid.Proc ps = null; 9861 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9862 int uid = info.uid; 9863 if (isolated) { 9864 if (isolatedUid == 0) { 9865 int userId = UserHandle.getUserId(uid); 9866 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9867 while (true) { 9868 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9869 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9870 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9871 } 9872 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9873 mNextIsolatedProcessUid++; 9874 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9875 // No process for this uid, use it. 9876 break; 9877 } 9878 stepsLeft--; 9879 if (stepsLeft <= 0) { 9880 return null; 9881 } 9882 } 9883 } else { 9884 // Special case for startIsolatedProcess (internal only), where 9885 // the uid of the isolated process is specified by the caller. 9886 uid = isolatedUid; 9887 } 9888 } 9889 return new ProcessRecord(stats, info, proc, uid); 9890 } 9891 9892 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9893 String abiOverride) { 9894 ProcessRecord app; 9895 if (!isolated) { 9896 app = getProcessRecordLocked(info.processName, info.uid, true); 9897 } else { 9898 app = null; 9899 } 9900 9901 if (app == null) { 9902 app = newProcessRecordLocked(info, null, isolated, 0); 9903 mProcessNames.put(info.processName, app.uid, app); 9904 if (isolated) { 9905 mIsolatedProcesses.put(app.uid, app); 9906 } 9907 updateLruProcessLocked(app, false, null); 9908 updateOomAdjLocked(); 9909 } 9910 9911 // This package really, really can not be stopped. 9912 try { 9913 AppGlobals.getPackageManager().setPackageStoppedState( 9914 info.packageName, false, UserHandle.getUserId(app.uid)); 9915 } catch (RemoteException e) { 9916 } catch (IllegalArgumentException e) { 9917 Slog.w(TAG, "Failed trying to unstop package " 9918 + info.packageName + ": " + e); 9919 } 9920 9921 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9922 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9923 app.persistent = true; 9924 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9925 } 9926 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9927 mPersistentStartingProcesses.add(app); 9928 startProcessLocked(app, "added application", app.processName, abiOverride, 9929 null /* entryPoint */, null /* entryPointArgs */); 9930 } 9931 9932 return app; 9933 } 9934 9935 public void unhandledBack() { 9936 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9937 "unhandledBack()"); 9938 9939 synchronized(this) { 9940 final long origId = Binder.clearCallingIdentity(); 9941 try { 9942 getFocusedStack().unhandledBackLocked(); 9943 } finally { 9944 Binder.restoreCallingIdentity(origId); 9945 } 9946 } 9947 } 9948 9949 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9950 enforceNotIsolatedCaller("openContentUri"); 9951 final int userId = UserHandle.getCallingUserId(); 9952 String name = uri.getAuthority(); 9953 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9954 ParcelFileDescriptor pfd = null; 9955 if (cph != null) { 9956 // We record the binder invoker's uid in thread-local storage before 9957 // going to the content provider to open the file. Later, in the code 9958 // that handles all permissions checks, we look for this uid and use 9959 // that rather than the Activity Manager's own uid. The effect is that 9960 // we do the check against the caller's permissions even though it looks 9961 // to the content provider like the Activity Manager itself is making 9962 // the request. 9963 sCallerIdentity.set(new Identity( 9964 Binder.getCallingPid(), Binder.getCallingUid())); 9965 try { 9966 pfd = cph.provider.openFile(null, uri, "r", null); 9967 } catch (FileNotFoundException e) { 9968 // do nothing; pfd will be returned null 9969 } finally { 9970 // Ensure that whatever happens, we clean up the identity state 9971 sCallerIdentity.remove(); 9972 } 9973 9974 // We've got the fd now, so we're done with the provider. 9975 removeContentProviderExternalUnchecked(name, null, userId); 9976 } else { 9977 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9978 } 9979 return pfd; 9980 } 9981 9982 // Actually is sleeping or shutting down or whatever else in the future 9983 // is an inactive state. 9984 public boolean isSleepingOrShuttingDown() { 9985 return isSleeping() || mShuttingDown; 9986 } 9987 9988 public boolean isSleeping() { 9989 return mSleeping; 9990 } 9991 9992 void goingToSleep() { 9993 synchronized(this) { 9994 mWentToSleep = true; 9995 goToSleepIfNeededLocked(); 9996 } 9997 } 9998 9999 void finishRunningVoiceLocked() { 10000 if (mRunningVoice) { 10001 mRunningVoice = false; 10002 goToSleepIfNeededLocked(); 10003 } 10004 } 10005 10006 void goToSleepIfNeededLocked() { 10007 if (mWentToSleep && !mRunningVoice) { 10008 if (!mSleeping) { 10009 mSleeping = true; 10010 mStackSupervisor.goingToSleepLocked(); 10011 10012 // Initialize the wake times of all processes. 10013 checkExcessivePowerUsageLocked(false); 10014 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10015 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10016 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10017 } 10018 } 10019 } 10020 10021 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10022 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10023 // Never persist the home stack. 10024 return; 10025 } 10026 mTaskPersister.wakeup(task, flush); 10027 } 10028 10029 @Override 10030 public boolean shutdown(int timeout) { 10031 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10032 != PackageManager.PERMISSION_GRANTED) { 10033 throw new SecurityException("Requires permission " 10034 + android.Manifest.permission.SHUTDOWN); 10035 } 10036 10037 boolean timedout = false; 10038 10039 synchronized(this) { 10040 mShuttingDown = true; 10041 updateEventDispatchingLocked(); 10042 timedout = mStackSupervisor.shutdownLocked(timeout); 10043 } 10044 10045 mAppOpsService.shutdown(); 10046 if (mUsageStatsService != null) { 10047 mUsageStatsService.prepareShutdown(); 10048 } 10049 mBatteryStatsService.shutdown(); 10050 synchronized (this) { 10051 mProcessStats.shutdownLocked(); 10052 } 10053 notifyTaskPersisterLocked(null, true); 10054 10055 return timedout; 10056 } 10057 10058 public final void activitySlept(IBinder token) { 10059 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10060 10061 final long origId = Binder.clearCallingIdentity(); 10062 10063 synchronized (this) { 10064 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10065 if (r != null) { 10066 mStackSupervisor.activitySleptLocked(r); 10067 } 10068 } 10069 10070 Binder.restoreCallingIdentity(origId); 10071 } 10072 10073 void logLockScreen(String msg) { 10074 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10075 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10076 mWentToSleep + " mSleeping=" + mSleeping); 10077 } 10078 10079 private void comeOutOfSleepIfNeededLocked() { 10080 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10081 if (mSleeping) { 10082 mSleeping = false; 10083 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10084 } 10085 } 10086 } 10087 10088 void wakingUp() { 10089 synchronized(this) { 10090 mWentToSleep = false; 10091 comeOutOfSleepIfNeededLocked(); 10092 } 10093 } 10094 10095 void startRunningVoiceLocked() { 10096 if (!mRunningVoice) { 10097 mRunningVoice = true; 10098 comeOutOfSleepIfNeededLocked(); 10099 } 10100 } 10101 10102 private void updateEventDispatchingLocked() { 10103 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10104 } 10105 10106 public void setLockScreenShown(boolean shown) { 10107 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10108 != PackageManager.PERMISSION_GRANTED) { 10109 throw new SecurityException("Requires permission " 10110 + android.Manifest.permission.DEVICE_POWER); 10111 } 10112 10113 synchronized(this) { 10114 long ident = Binder.clearCallingIdentity(); 10115 try { 10116 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10117 mLockScreenShown = shown; 10118 comeOutOfSleepIfNeededLocked(); 10119 } finally { 10120 Binder.restoreCallingIdentity(ident); 10121 } 10122 } 10123 } 10124 10125 @Override 10126 public void stopAppSwitches() { 10127 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10128 != PackageManager.PERMISSION_GRANTED) { 10129 throw new SecurityException("Requires permission " 10130 + android.Manifest.permission.STOP_APP_SWITCHES); 10131 } 10132 10133 synchronized(this) { 10134 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10135 + APP_SWITCH_DELAY_TIME; 10136 mDidAppSwitch = false; 10137 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10138 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10139 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10140 } 10141 } 10142 10143 public void resumeAppSwitches() { 10144 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10145 != PackageManager.PERMISSION_GRANTED) { 10146 throw new SecurityException("Requires permission " 10147 + android.Manifest.permission.STOP_APP_SWITCHES); 10148 } 10149 10150 synchronized(this) { 10151 // Note that we don't execute any pending app switches... we will 10152 // let those wait until either the timeout, or the next start 10153 // activity request. 10154 mAppSwitchesAllowedTime = 0; 10155 } 10156 } 10157 10158 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10159 int callingPid, int callingUid, String name) { 10160 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10161 return true; 10162 } 10163 10164 int perm = checkComponentPermission( 10165 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10166 sourceUid, -1, true); 10167 if (perm == PackageManager.PERMISSION_GRANTED) { 10168 return true; 10169 } 10170 10171 // If the actual IPC caller is different from the logical source, then 10172 // also see if they are allowed to control app switches. 10173 if (callingUid != -1 && callingUid != sourceUid) { 10174 perm = checkComponentPermission( 10175 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10176 callingUid, -1, true); 10177 if (perm == PackageManager.PERMISSION_GRANTED) { 10178 return true; 10179 } 10180 } 10181 10182 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10183 return false; 10184 } 10185 10186 public void setDebugApp(String packageName, boolean waitForDebugger, 10187 boolean persistent) { 10188 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10189 "setDebugApp()"); 10190 10191 long ident = Binder.clearCallingIdentity(); 10192 try { 10193 // Note that this is not really thread safe if there are multiple 10194 // callers into it at the same time, but that's not a situation we 10195 // care about. 10196 if (persistent) { 10197 final ContentResolver resolver = mContext.getContentResolver(); 10198 Settings.Global.putString( 10199 resolver, Settings.Global.DEBUG_APP, 10200 packageName); 10201 Settings.Global.putInt( 10202 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10203 waitForDebugger ? 1 : 0); 10204 } 10205 10206 synchronized (this) { 10207 if (!persistent) { 10208 mOrigDebugApp = mDebugApp; 10209 mOrigWaitForDebugger = mWaitForDebugger; 10210 } 10211 mDebugApp = packageName; 10212 mWaitForDebugger = waitForDebugger; 10213 mDebugTransient = !persistent; 10214 if (packageName != null) { 10215 forceStopPackageLocked(packageName, -1, false, false, true, true, 10216 false, UserHandle.USER_ALL, "set debug app"); 10217 } 10218 } 10219 } finally { 10220 Binder.restoreCallingIdentity(ident); 10221 } 10222 } 10223 10224 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10225 synchronized (this) { 10226 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10227 if (!isDebuggable) { 10228 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10229 throw new SecurityException("Process not debuggable: " + app.packageName); 10230 } 10231 } 10232 10233 mOpenGlTraceApp = processName; 10234 } 10235 } 10236 10237 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10238 synchronized (this) { 10239 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10240 if (!isDebuggable) { 10241 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10242 throw new SecurityException("Process not debuggable: " + app.packageName); 10243 } 10244 } 10245 mProfileApp = processName; 10246 mProfileFile = profilerInfo.profileFile; 10247 if (mProfileFd != null) { 10248 try { 10249 mProfileFd.close(); 10250 } catch (IOException e) { 10251 } 10252 mProfileFd = null; 10253 } 10254 mProfileFd = profilerInfo.profileFd; 10255 mSamplingInterval = profilerInfo.samplingInterval; 10256 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10257 mProfileType = 0; 10258 } 10259 } 10260 10261 @Override 10262 public void setAlwaysFinish(boolean enabled) { 10263 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10264 "setAlwaysFinish()"); 10265 10266 Settings.Global.putInt( 10267 mContext.getContentResolver(), 10268 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10269 10270 synchronized (this) { 10271 mAlwaysFinishActivities = enabled; 10272 } 10273 } 10274 10275 @Override 10276 public void setActivityController(IActivityController controller) { 10277 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10278 "setActivityController()"); 10279 synchronized (this) { 10280 mController = controller; 10281 Watchdog.getInstance().setActivityController(controller); 10282 } 10283 } 10284 10285 @Override 10286 public void setUserIsMonkey(boolean userIsMonkey) { 10287 synchronized (this) { 10288 synchronized (mPidsSelfLocked) { 10289 final int callingPid = Binder.getCallingPid(); 10290 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10291 if (precessRecord == null) { 10292 throw new SecurityException("Unknown process: " + callingPid); 10293 } 10294 if (precessRecord.instrumentationUiAutomationConnection == null) { 10295 throw new SecurityException("Only an instrumentation process " 10296 + "with a UiAutomation can call setUserIsMonkey"); 10297 } 10298 } 10299 mUserIsMonkey = userIsMonkey; 10300 } 10301 } 10302 10303 @Override 10304 public boolean isUserAMonkey() { 10305 synchronized (this) { 10306 // If there is a controller also implies the user is a monkey. 10307 return (mUserIsMonkey || mController != null); 10308 } 10309 } 10310 10311 public void requestBugReport() { 10312 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10313 SystemProperties.set("ctl.start", "bugreport"); 10314 } 10315 10316 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10317 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10318 } 10319 10320 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10321 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10322 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10323 } 10324 return KEY_DISPATCHING_TIMEOUT; 10325 } 10326 10327 @Override 10328 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10329 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10330 != PackageManager.PERMISSION_GRANTED) { 10331 throw new SecurityException("Requires permission " 10332 + android.Manifest.permission.FILTER_EVENTS); 10333 } 10334 ProcessRecord proc; 10335 long timeout; 10336 synchronized (this) { 10337 synchronized (mPidsSelfLocked) { 10338 proc = mPidsSelfLocked.get(pid); 10339 } 10340 timeout = getInputDispatchingTimeoutLocked(proc); 10341 } 10342 10343 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10344 return -1; 10345 } 10346 10347 return timeout; 10348 } 10349 10350 /** 10351 * Handle input dispatching timeouts. 10352 * Returns whether input dispatching should be aborted or not. 10353 */ 10354 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10355 final ActivityRecord activity, final ActivityRecord parent, 10356 final boolean aboveSystem, String reason) { 10357 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10358 != PackageManager.PERMISSION_GRANTED) { 10359 throw new SecurityException("Requires permission " 10360 + android.Manifest.permission.FILTER_EVENTS); 10361 } 10362 10363 final String annotation; 10364 if (reason == null) { 10365 annotation = "Input dispatching timed out"; 10366 } else { 10367 annotation = "Input dispatching timed out (" + reason + ")"; 10368 } 10369 10370 if (proc != null) { 10371 synchronized (this) { 10372 if (proc.debugging) { 10373 return false; 10374 } 10375 10376 if (mDidDexOpt) { 10377 // Give more time since we were dexopting. 10378 mDidDexOpt = false; 10379 return false; 10380 } 10381 10382 if (proc.instrumentationClass != null) { 10383 Bundle info = new Bundle(); 10384 info.putString("shortMsg", "keyDispatchingTimedOut"); 10385 info.putString("longMsg", annotation); 10386 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10387 return true; 10388 } 10389 } 10390 mHandler.post(new Runnable() { 10391 @Override 10392 public void run() { 10393 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10394 } 10395 }); 10396 } 10397 10398 return true; 10399 } 10400 10401 public Bundle getAssistContextExtras(int requestType) { 10402 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10403 "getAssistContextExtras()"); 10404 PendingAssistExtras pae; 10405 Bundle extras = new Bundle(); 10406 synchronized (this) { 10407 ActivityRecord activity = getFocusedStack().mResumedActivity; 10408 if (activity == null) { 10409 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10410 return null; 10411 } 10412 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10413 if (activity.app == null || activity.app.thread == null) { 10414 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10415 return extras; 10416 } 10417 if (activity.app.pid == Binder.getCallingPid()) { 10418 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10419 return extras; 10420 } 10421 pae = new PendingAssistExtras(activity); 10422 try { 10423 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10424 requestType); 10425 mPendingAssistExtras.add(pae); 10426 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10427 } catch (RemoteException e) { 10428 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10429 return extras; 10430 } 10431 } 10432 synchronized (pae) { 10433 while (!pae.haveResult) { 10434 try { 10435 pae.wait(); 10436 } catch (InterruptedException e) { 10437 } 10438 } 10439 if (pae.result != null) { 10440 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10441 } 10442 } 10443 synchronized (this) { 10444 mPendingAssistExtras.remove(pae); 10445 mHandler.removeCallbacks(pae); 10446 } 10447 return extras; 10448 } 10449 10450 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10451 PendingAssistExtras pae = (PendingAssistExtras)token; 10452 synchronized (pae) { 10453 pae.result = extras; 10454 pae.haveResult = true; 10455 pae.notifyAll(); 10456 } 10457 } 10458 10459 public void registerProcessObserver(IProcessObserver observer) { 10460 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10461 "registerProcessObserver()"); 10462 synchronized (this) { 10463 mProcessObservers.register(observer); 10464 } 10465 } 10466 10467 @Override 10468 public void unregisterProcessObserver(IProcessObserver observer) { 10469 synchronized (this) { 10470 mProcessObservers.unregister(observer); 10471 } 10472 } 10473 10474 @Override 10475 public boolean convertFromTranslucent(IBinder token) { 10476 final long origId = Binder.clearCallingIdentity(); 10477 try { 10478 synchronized (this) { 10479 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10480 if (r == null) { 10481 return false; 10482 } 10483 final boolean translucentChanged = r.changeWindowTranslucency(true); 10484 if (translucentChanged) { 10485 r.task.stack.releaseBackgroundResources(); 10486 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10487 } 10488 mWindowManager.setAppFullscreen(token, true); 10489 return translucentChanged; 10490 } 10491 } finally { 10492 Binder.restoreCallingIdentity(origId); 10493 } 10494 } 10495 10496 @Override 10497 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10498 final long origId = Binder.clearCallingIdentity(); 10499 try { 10500 synchronized (this) { 10501 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10502 if (r == null) { 10503 return false; 10504 } 10505 int index = r.task.mActivities.lastIndexOf(r); 10506 if (index > 0) { 10507 ActivityRecord under = r.task.mActivities.get(index - 1); 10508 under.returningOptions = options; 10509 } 10510 final boolean translucentChanged = r.changeWindowTranslucency(false); 10511 if (translucentChanged) { 10512 r.task.stack.convertToTranslucent(r); 10513 } 10514 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10515 mWindowManager.setAppFullscreen(token, false); 10516 return translucentChanged; 10517 } 10518 } finally { 10519 Binder.restoreCallingIdentity(origId); 10520 } 10521 } 10522 10523 @Override 10524 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10525 final long origId = Binder.clearCallingIdentity(); 10526 try { 10527 synchronized (this) { 10528 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10529 if (r != null) { 10530 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10531 } 10532 } 10533 return false; 10534 } finally { 10535 Binder.restoreCallingIdentity(origId); 10536 } 10537 } 10538 10539 @Override 10540 public boolean isBackgroundVisibleBehind(IBinder token) { 10541 final long origId = Binder.clearCallingIdentity(); 10542 try { 10543 synchronized (this) { 10544 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10545 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10546 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10547 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10548 return visible; 10549 } 10550 } finally { 10551 Binder.restoreCallingIdentity(origId); 10552 } 10553 } 10554 10555 @Override 10556 public ActivityOptions getActivityOptions(IBinder token) { 10557 final long origId = Binder.clearCallingIdentity(); 10558 try { 10559 synchronized (this) { 10560 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10561 if (r != null) { 10562 final ActivityOptions activityOptions = r.pendingOptions; 10563 r.pendingOptions = null; 10564 return activityOptions; 10565 } 10566 return null; 10567 } 10568 } finally { 10569 Binder.restoreCallingIdentity(origId); 10570 } 10571 } 10572 10573 @Override 10574 public void setImmersive(IBinder token, boolean immersive) { 10575 synchronized(this) { 10576 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10577 if (r == null) { 10578 throw new IllegalArgumentException(); 10579 } 10580 r.immersive = immersive; 10581 10582 // update associated state if we're frontmost 10583 if (r == mFocusedActivity) { 10584 if (DEBUG_IMMERSIVE) { 10585 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10586 } 10587 applyUpdateLockStateLocked(r); 10588 } 10589 } 10590 } 10591 10592 @Override 10593 public boolean isImmersive(IBinder token) { 10594 synchronized (this) { 10595 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10596 if (r == null) { 10597 throw new IllegalArgumentException(); 10598 } 10599 return r.immersive; 10600 } 10601 } 10602 10603 public boolean isTopActivityImmersive() { 10604 enforceNotIsolatedCaller("startActivity"); 10605 synchronized (this) { 10606 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10607 return (r != null) ? r.immersive : false; 10608 } 10609 } 10610 10611 @Override 10612 public boolean isTopOfTask(IBinder token) { 10613 synchronized (this) { 10614 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10615 if (r == null) { 10616 throw new IllegalArgumentException(); 10617 } 10618 return r.task.getTopActivity() == r; 10619 } 10620 } 10621 10622 public final void enterSafeMode() { 10623 synchronized(this) { 10624 // It only makes sense to do this before the system is ready 10625 // and started launching other packages. 10626 if (!mSystemReady) { 10627 try { 10628 AppGlobals.getPackageManager().enterSafeMode(); 10629 } catch (RemoteException e) { 10630 } 10631 } 10632 10633 mSafeMode = true; 10634 } 10635 } 10636 10637 public final void showSafeModeOverlay() { 10638 View v = LayoutInflater.from(mContext).inflate( 10639 com.android.internal.R.layout.safe_mode, null); 10640 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10641 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10642 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10643 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10644 lp.gravity = Gravity.BOTTOM | Gravity.START; 10645 lp.format = v.getBackground().getOpacity(); 10646 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10647 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10648 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10649 ((WindowManager)mContext.getSystemService( 10650 Context.WINDOW_SERVICE)).addView(v, lp); 10651 } 10652 10653 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10654 if (!(sender instanceof PendingIntentRecord)) { 10655 return; 10656 } 10657 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10658 synchronized (stats) { 10659 if (mBatteryStatsService.isOnBattery()) { 10660 mBatteryStatsService.enforceCallingPermission(); 10661 PendingIntentRecord rec = (PendingIntentRecord)sender; 10662 int MY_UID = Binder.getCallingUid(); 10663 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10664 BatteryStatsImpl.Uid.Pkg pkg = 10665 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10666 sourcePkg != null ? sourcePkg : rec.key.packageName); 10667 pkg.incWakeupsLocked(); 10668 } 10669 } 10670 } 10671 10672 public boolean killPids(int[] pids, String pReason, boolean secure) { 10673 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10674 throw new SecurityException("killPids only available to the system"); 10675 } 10676 String reason = (pReason == null) ? "Unknown" : pReason; 10677 // XXX Note: don't acquire main activity lock here, because the window 10678 // manager calls in with its locks held. 10679 10680 boolean killed = false; 10681 synchronized (mPidsSelfLocked) { 10682 int[] types = new int[pids.length]; 10683 int worstType = 0; 10684 for (int i=0; i<pids.length; i++) { 10685 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10686 if (proc != null) { 10687 int type = proc.setAdj; 10688 types[i] = type; 10689 if (type > worstType) { 10690 worstType = type; 10691 } 10692 } 10693 } 10694 10695 // If the worst oom_adj is somewhere in the cached proc LRU range, 10696 // then constrain it so we will kill all cached procs. 10697 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10698 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10699 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10700 } 10701 10702 // If this is not a secure call, don't let it kill processes that 10703 // are important. 10704 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10705 worstType = ProcessList.SERVICE_ADJ; 10706 } 10707 10708 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10709 for (int i=0; i<pids.length; i++) { 10710 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10711 if (proc == null) { 10712 continue; 10713 } 10714 int adj = proc.setAdj; 10715 if (adj >= worstType && !proc.killedByAm) { 10716 proc.kill(reason, true); 10717 killed = true; 10718 } 10719 } 10720 } 10721 return killed; 10722 } 10723 10724 @Override 10725 public void killUid(int uid, String reason) { 10726 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10727 throw new SecurityException("killUid only available to the system"); 10728 } 10729 synchronized (this) { 10730 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10731 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10732 reason != null ? reason : "kill uid"); 10733 } 10734 } 10735 10736 @Override 10737 public boolean killProcessesBelowForeground(String reason) { 10738 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10739 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10740 } 10741 10742 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10743 } 10744 10745 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10746 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10747 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10748 } 10749 10750 boolean killed = false; 10751 synchronized (mPidsSelfLocked) { 10752 final int size = mPidsSelfLocked.size(); 10753 for (int i = 0; i < size; i++) { 10754 final int pid = mPidsSelfLocked.keyAt(i); 10755 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10756 if (proc == null) continue; 10757 10758 final int adj = proc.setAdj; 10759 if (adj > belowAdj && !proc.killedByAm) { 10760 proc.kill(reason, true); 10761 killed = true; 10762 } 10763 } 10764 } 10765 return killed; 10766 } 10767 10768 @Override 10769 public void hang(final IBinder who, boolean allowRestart) { 10770 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10771 != PackageManager.PERMISSION_GRANTED) { 10772 throw new SecurityException("Requires permission " 10773 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10774 } 10775 10776 final IBinder.DeathRecipient death = new DeathRecipient() { 10777 @Override 10778 public void binderDied() { 10779 synchronized (this) { 10780 notifyAll(); 10781 } 10782 } 10783 }; 10784 10785 try { 10786 who.linkToDeath(death, 0); 10787 } catch (RemoteException e) { 10788 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10789 return; 10790 } 10791 10792 synchronized (this) { 10793 Watchdog.getInstance().setAllowRestart(allowRestart); 10794 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10795 synchronized (death) { 10796 while (who.isBinderAlive()) { 10797 try { 10798 death.wait(); 10799 } catch (InterruptedException e) { 10800 } 10801 } 10802 } 10803 Watchdog.getInstance().setAllowRestart(true); 10804 } 10805 } 10806 10807 @Override 10808 public void restart() { 10809 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10810 != PackageManager.PERMISSION_GRANTED) { 10811 throw new SecurityException("Requires permission " 10812 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10813 } 10814 10815 Log.i(TAG, "Sending shutdown broadcast..."); 10816 10817 BroadcastReceiver br = new BroadcastReceiver() { 10818 @Override public void onReceive(Context context, Intent intent) { 10819 // Now the broadcast is done, finish up the low-level shutdown. 10820 Log.i(TAG, "Shutting down activity manager..."); 10821 shutdown(10000); 10822 Log.i(TAG, "Shutdown complete, restarting!"); 10823 Process.killProcess(Process.myPid()); 10824 System.exit(10); 10825 } 10826 }; 10827 10828 // First send the high-level shut down broadcast. 10829 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10830 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10831 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10832 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10833 mContext.sendOrderedBroadcastAsUser(intent, 10834 UserHandle.ALL, null, br, mHandler, 0, null, null); 10835 */ 10836 br.onReceive(mContext, intent); 10837 } 10838 10839 private long getLowRamTimeSinceIdle(long now) { 10840 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10841 } 10842 10843 @Override 10844 public void performIdleMaintenance() { 10845 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10846 != PackageManager.PERMISSION_GRANTED) { 10847 throw new SecurityException("Requires permission " 10848 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10849 } 10850 10851 synchronized (this) { 10852 final long now = SystemClock.uptimeMillis(); 10853 final long timeSinceLastIdle = now - mLastIdleTime; 10854 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10855 mLastIdleTime = now; 10856 mLowRamTimeSinceLastIdle = 0; 10857 if (mLowRamStartTime != 0) { 10858 mLowRamStartTime = now; 10859 } 10860 10861 StringBuilder sb = new StringBuilder(128); 10862 sb.append("Idle maintenance over "); 10863 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10864 sb.append(" low RAM for "); 10865 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10866 Slog.i(TAG, sb.toString()); 10867 10868 // If at least 1/3 of our time since the last idle period has been spent 10869 // with RAM low, then we want to kill processes. 10870 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10871 10872 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10873 ProcessRecord proc = mLruProcesses.get(i); 10874 if (proc.notCachedSinceIdle) { 10875 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10876 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10877 if (doKilling && proc.initialIdlePss != 0 10878 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10879 proc.kill("idle maint (pss " + proc.lastPss 10880 + " from " + proc.initialIdlePss + ")", true); 10881 } 10882 } 10883 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10884 proc.notCachedSinceIdle = true; 10885 proc.initialIdlePss = 0; 10886 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10887 isSleeping(), now); 10888 } 10889 } 10890 10891 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10892 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10893 } 10894 } 10895 10896 private void retrieveSettings() { 10897 final ContentResolver resolver = mContext.getContentResolver(); 10898 String debugApp = Settings.Global.getString( 10899 resolver, Settings.Global.DEBUG_APP); 10900 boolean waitForDebugger = Settings.Global.getInt( 10901 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10902 boolean alwaysFinishActivities = Settings.Global.getInt( 10903 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10904 boolean forceRtl = Settings.Global.getInt( 10905 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10906 // Transfer any global setting for forcing RTL layout, into a System Property 10907 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10908 10909 Configuration configuration = new Configuration(); 10910 Settings.System.getConfiguration(resolver, configuration); 10911 if (forceRtl) { 10912 // This will take care of setting the correct layout direction flags 10913 configuration.setLayoutDirection(configuration.locale); 10914 } 10915 10916 synchronized (this) { 10917 mDebugApp = mOrigDebugApp = debugApp; 10918 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10919 mAlwaysFinishActivities = alwaysFinishActivities; 10920 // This happens before any activities are started, so we can 10921 // change mConfiguration in-place. 10922 updateConfigurationLocked(configuration, null, false, true); 10923 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10924 } 10925 } 10926 10927 /** Loads resources after the current configuration has been set. */ 10928 private void loadResourcesOnSystemReady() { 10929 final Resources res = mContext.getResources(); 10930 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10931 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10932 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10933 } 10934 10935 public boolean testIsSystemReady() { 10936 // no need to synchronize(this) just to read & return the value 10937 return mSystemReady; 10938 } 10939 10940 private static File getCalledPreBootReceiversFile() { 10941 File dataDir = Environment.getDataDirectory(); 10942 File systemDir = new File(dataDir, "system"); 10943 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10944 return fname; 10945 } 10946 10947 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10948 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10949 File file = getCalledPreBootReceiversFile(); 10950 FileInputStream fis = null; 10951 try { 10952 fis = new FileInputStream(file); 10953 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10954 int fvers = dis.readInt(); 10955 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10956 String vers = dis.readUTF(); 10957 String codename = dis.readUTF(); 10958 String build = dis.readUTF(); 10959 if (android.os.Build.VERSION.RELEASE.equals(vers) 10960 && android.os.Build.VERSION.CODENAME.equals(codename) 10961 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10962 int num = dis.readInt(); 10963 while (num > 0) { 10964 num--; 10965 String pkg = dis.readUTF(); 10966 String cls = dis.readUTF(); 10967 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10968 } 10969 } 10970 } 10971 } catch (FileNotFoundException e) { 10972 } catch (IOException e) { 10973 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10974 } finally { 10975 if (fis != null) { 10976 try { 10977 fis.close(); 10978 } catch (IOException e) { 10979 } 10980 } 10981 } 10982 return lastDoneReceivers; 10983 } 10984 10985 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10986 File file = getCalledPreBootReceiversFile(); 10987 FileOutputStream fos = null; 10988 DataOutputStream dos = null; 10989 try { 10990 fos = new FileOutputStream(file); 10991 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10992 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10993 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10994 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10995 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10996 dos.writeInt(list.size()); 10997 for (int i=0; i<list.size(); i++) { 10998 dos.writeUTF(list.get(i).getPackageName()); 10999 dos.writeUTF(list.get(i).getClassName()); 11000 } 11001 } catch (IOException e) { 11002 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11003 file.delete(); 11004 } finally { 11005 FileUtils.sync(fos); 11006 if (dos != null) { 11007 try { 11008 dos.close(); 11009 } catch (IOException e) { 11010 // TODO Auto-generated catch block 11011 e.printStackTrace(); 11012 } 11013 } 11014 } 11015 } 11016 11017 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11018 ArrayList<ComponentName> doneReceivers, int userId) { 11019 boolean waitingUpdate = false; 11020 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11021 List<ResolveInfo> ris = null; 11022 try { 11023 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11024 intent, null, 0, userId); 11025 } catch (RemoteException e) { 11026 } 11027 if (ris != null) { 11028 for (int i=ris.size()-1; i>=0; i--) { 11029 if ((ris.get(i).activityInfo.applicationInfo.flags 11030 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11031 ris.remove(i); 11032 } 11033 } 11034 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11035 11036 // For User 0, load the version number. When delivering to a new user, deliver 11037 // to all receivers. 11038 if (userId == UserHandle.USER_OWNER) { 11039 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11040 for (int i=0; i<ris.size(); i++) { 11041 ActivityInfo ai = ris.get(i).activityInfo; 11042 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11043 if (lastDoneReceivers.contains(comp)) { 11044 // We already did the pre boot receiver for this app with the current 11045 // platform version, so don't do it again... 11046 ris.remove(i); 11047 i--; 11048 // ...however, do keep it as one that has been done, so we don't 11049 // forget about it when rewriting the file of last done receivers. 11050 doneReceivers.add(comp); 11051 } 11052 } 11053 } 11054 11055 // If primary user, send broadcast to all available users, else just to userId 11056 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11057 : new int[] { userId }; 11058 for (int i = 0; i < ris.size(); i++) { 11059 ActivityInfo ai = ris.get(i).activityInfo; 11060 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11061 doneReceivers.add(comp); 11062 intent.setComponent(comp); 11063 for (int j=0; j<users.length; j++) { 11064 IIntentReceiver finisher = null; 11065 // On last receiver and user, set up a completion callback 11066 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11067 finisher = new IIntentReceiver.Stub() { 11068 public void performReceive(Intent intent, int resultCode, 11069 String data, Bundle extras, boolean ordered, 11070 boolean sticky, int sendingUser) { 11071 // The raw IIntentReceiver interface is called 11072 // with the AM lock held, so redispatch to 11073 // execute our code without the lock. 11074 mHandler.post(onFinishCallback); 11075 } 11076 }; 11077 } 11078 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11079 + " for user " + users[j]); 11080 broadcastIntentLocked(null, null, intent, null, finisher, 11081 0, null, null, null, AppOpsManager.OP_NONE, 11082 true, false, MY_PID, Process.SYSTEM_UID, 11083 users[j]); 11084 if (finisher != null) { 11085 waitingUpdate = true; 11086 } 11087 } 11088 } 11089 } 11090 11091 return waitingUpdate; 11092 } 11093 11094 public void systemReady(final Runnable goingCallback) { 11095 synchronized(this) { 11096 if (mSystemReady) { 11097 // If we're done calling all the receivers, run the next "boot phase" passed in 11098 // by the SystemServer 11099 if (goingCallback != null) { 11100 goingCallback.run(); 11101 } 11102 return; 11103 } 11104 11105 // Make sure we have the current profile info, since it is needed for 11106 // security checks. 11107 updateCurrentProfileIdsLocked(); 11108 11109 if (mRecentTasks == null) { 11110 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11111 if (!mRecentTasks.isEmpty()) { 11112 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11113 } 11114 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11115 mTaskPersister.startPersisting(); 11116 } 11117 11118 // Check to see if there are any update receivers to run. 11119 if (!mDidUpdate) { 11120 if (mWaitingUpdate) { 11121 return; 11122 } 11123 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11124 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11125 public void run() { 11126 synchronized (ActivityManagerService.this) { 11127 mDidUpdate = true; 11128 } 11129 writeLastDonePreBootReceivers(doneReceivers); 11130 showBootMessage(mContext.getText( 11131 R.string.android_upgrading_complete), 11132 false); 11133 systemReady(goingCallback); 11134 } 11135 }, doneReceivers, UserHandle.USER_OWNER); 11136 11137 if (mWaitingUpdate) { 11138 return; 11139 } 11140 mDidUpdate = true; 11141 } 11142 11143 mAppOpsService.systemReady(); 11144 mSystemReady = true; 11145 } 11146 11147 ArrayList<ProcessRecord> procsToKill = null; 11148 synchronized(mPidsSelfLocked) { 11149 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11150 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11151 if (!isAllowedWhileBooting(proc.info)){ 11152 if (procsToKill == null) { 11153 procsToKill = new ArrayList<ProcessRecord>(); 11154 } 11155 procsToKill.add(proc); 11156 } 11157 } 11158 } 11159 11160 synchronized(this) { 11161 if (procsToKill != null) { 11162 for (int i=procsToKill.size()-1; i>=0; i--) { 11163 ProcessRecord proc = procsToKill.get(i); 11164 Slog.i(TAG, "Removing system update proc: " + proc); 11165 removeProcessLocked(proc, true, false, "system update done"); 11166 } 11167 } 11168 11169 // Now that we have cleaned up any update processes, we 11170 // are ready to start launching real processes and know that 11171 // we won't trample on them any more. 11172 mProcessesReady = true; 11173 } 11174 11175 Slog.i(TAG, "System now ready"); 11176 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11177 SystemClock.uptimeMillis()); 11178 11179 synchronized(this) { 11180 // Make sure we have no pre-ready processes sitting around. 11181 11182 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11183 ResolveInfo ri = mContext.getPackageManager() 11184 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11185 STOCK_PM_FLAGS); 11186 CharSequence errorMsg = null; 11187 if (ri != null) { 11188 ActivityInfo ai = ri.activityInfo; 11189 ApplicationInfo app = ai.applicationInfo; 11190 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11191 mTopAction = Intent.ACTION_FACTORY_TEST; 11192 mTopData = null; 11193 mTopComponent = new ComponentName(app.packageName, 11194 ai.name); 11195 } else { 11196 errorMsg = mContext.getResources().getText( 11197 com.android.internal.R.string.factorytest_not_system); 11198 } 11199 } else { 11200 errorMsg = mContext.getResources().getText( 11201 com.android.internal.R.string.factorytest_no_action); 11202 } 11203 if (errorMsg != null) { 11204 mTopAction = null; 11205 mTopData = null; 11206 mTopComponent = null; 11207 Message msg = Message.obtain(); 11208 msg.what = SHOW_FACTORY_ERROR_MSG; 11209 msg.getData().putCharSequence("msg", errorMsg); 11210 mHandler.sendMessage(msg); 11211 } 11212 } 11213 } 11214 11215 retrieveSettings(); 11216 loadResourcesOnSystemReady(); 11217 11218 synchronized (this) { 11219 readGrantedUriPermissionsLocked(); 11220 } 11221 11222 if (goingCallback != null) goingCallback.run(); 11223 11224 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11225 Integer.toString(mCurrentUserId), mCurrentUserId); 11226 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11227 Integer.toString(mCurrentUserId), mCurrentUserId); 11228 mSystemServiceManager.startUser(mCurrentUserId); 11229 11230 synchronized (this) { 11231 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11232 try { 11233 List apps = AppGlobals.getPackageManager(). 11234 getPersistentApplications(STOCK_PM_FLAGS); 11235 if (apps != null) { 11236 int N = apps.size(); 11237 int i; 11238 for (i=0; i<N; i++) { 11239 ApplicationInfo info 11240 = (ApplicationInfo)apps.get(i); 11241 if (info != null && 11242 !info.packageName.equals("android")) { 11243 addAppLocked(info, false, null /* ABI override */); 11244 } 11245 } 11246 } 11247 } catch (RemoteException ex) { 11248 // pm is in same process, this will never happen. 11249 } 11250 } 11251 11252 // Start up initial activity. 11253 mBooting = true; 11254 11255 try { 11256 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11257 Message msg = Message.obtain(); 11258 msg.what = SHOW_UID_ERROR_MSG; 11259 mHandler.sendMessage(msg); 11260 } 11261 } catch (RemoteException e) { 11262 } 11263 11264 long ident = Binder.clearCallingIdentity(); 11265 try { 11266 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11267 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11268 | Intent.FLAG_RECEIVER_FOREGROUND); 11269 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11270 broadcastIntentLocked(null, null, intent, 11271 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11272 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11273 intent = new Intent(Intent.ACTION_USER_STARTING); 11274 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11275 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11276 broadcastIntentLocked(null, null, intent, 11277 null, new IIntentReceiver.Stub() { 11278 @Override 11279 public void performReceive(Intent intent, int resultCode, String data, 11280 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11281 throws RemoteException { 11282 } 11283 }, 0, null, null, 11284 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11285 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11286 } catch (Throwable t) { 11287 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11288 } finally { 11289 Binder.restoreCallingIdentity(ident); 11290 } 11291 mStackSupervisor.resumeTopActivitiesLocked(); 11292 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11293 } 11294 } 11295 11296 private boolean makeAppCrashingLocked(ProcessRecord app, 11297 String shortMsg, String longMsg, String stackTrace) { 11298 app.crashing = true; 11299 app.crashingReport = generateProcessError(app, 11300 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11301 startAppProblemLocked(app); 11302 app.stopFreezingAllLocked(); 11303 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11304 } 11305 11306 private void makeAppNotRespondingLocked(ProcessRecord app, 11307 String activity, String shortMsg, String longMsg) { 11308 app.notResponding = true; 11309 app.notRespondingReport = generateProcessError(app, 11310 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11311 activity, shortMsg, longMsg, null); 11312 startAppProblemLocked(app); 11313 app.stopFreezingAllLocked(); 11314 } 11315 11316 /** 11317 * Generate a process error record, suitable for attachment to a ProcessRecord. 11318 * 11319 * @param app The ProcessRecord in which the error occurred. 11320 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11321 * ActivityManager.AppErrorStateInfo 11322 * @param activity The activity associated with the crash, if known. 11323 * @param shortMsg Short message describing the crash. 11324 * @param longMsg Long message describing the crash. 11325 * @param stackTrace Full crash stack trace, may be null. 11326 * 11327 * @return Returns a fully-formed AppErrorStateInfo record. 11328 */ 11329 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11330 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11331 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11332 11333 report.condition = condition; 11334 report.processName = app.processName; 11335 report.pid = app.pid; 11336 report.uid = app.info.uid; 11337 report.tag = activity; 11338 report.shortMsg = shortMsg; 11339 report.longMsg = longMsg; 11340 report.stackTrace = stackTrace; 11341 11342 return report; 11343 } 11344 11345 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11346 synchronized (this) { 11347 app.crashing = false; 11348 app.crashingReport = null; 11349 app.notResponding = false; 11350 app.notRespondingReport = null; 11351 if (app.anrDialog == fromDialog) { 11352 app.anrDialog = null; 11353 } 11354 if (app.waitDialog == fromDialog) { 11355 app.waitDialog = null; 11356 } 11357 if (app.pid > 0 && app.pid != MY_PID) { 11358 handleAppCrashLocked(app, null, null, null); 11359 app.kill("user request after error", true); 11360 } 11361 } 11362 } 11363 11364 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11365 String stackTrace) { 11366 long now = SystemClock.uptimeMillis(); 11367 11368 Long crashTime; 11369 if (!app.isolated) { 11370 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11371 } else { 11372 crashTime = null; 11373 } 11374 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11375 // This process loses! 11376 Slog.w(TAG, "Process " + app.info.processName 11377 + " has crashed too many times: killing!"); 11378 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11379 app.userId, app.info.processName, app.uid); 11380 mStackSupervisor.handleAppCrashLocked(app); 11381 if (!app.persistent) { 11382 // We don't want to start this process again until the user 11383 // explicitly does so... but for persistent process, we really 11384 // need to keep it running. If a persistent process is actually 11385 // repeatedly crashing, then badness for everyone. 11386 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11387 app.info.processName); 11388 if (!app.isolated) { 11389 // XXX We don't have a way to mark isolated processes 11390 // as bad, since they don't have a peristent identity. 11391 mBadProcesses.put(app.info.processName, app.uid, 11392 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11393 mProcessCrashTimes.remove(app.info.processName, app.uid); 11394 } 11395 app.bad = true; 11396 app.removed = true; 11397 // Don't let services in this process be restarted and potentially 11398 // annoy the user repeatedly. Unless it is persistent, since those 11399 // processes run critical code. 11400 removeProcessLocked(app, false, false, "crash"); 11401 mStackSupervisor.resumeTopActivitiesLocked(); 11402 return false; 11403 } 11404 mStackSupervisor.resumeTopActivitiesLocked(); 11405 } else { 11406 mStackSupervisor.finishTopRunningActivityLocked(app); 11407 } 11408 11409 // Bump up the crash count of any services currently running in the proc. 11410 for (int i=app.services.size()-1; i>=0; i--) { 11411 // Any services running in the application need to be placed 11412 // back in the pending list. 11413 ServiceRecord sr = app.services.valueAt(i); 11414 sr.crashCount++; 11415 } 11416 11417 // If the crashing process is what we consider to be the "home process" and it has been 11418 // replaced by a third-party app, clear the package preferred activities from packages 11419 // with a home activity running in the process to prevent a repeatedly crashing app 11420 // from blocking the user to manually clear the list. 11421 final ArrayList<ActivityRecord> activities = app.activities; 11422 if (app == mHomeProcess && activities.size() > 0 11423 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11424 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11425 final ActivityRecord r = activities.get(activityNdx); 11426 if (r.isHomeActivity()) { 11427 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11428 try { 11429 ActivityThread.getPackageManager() 11430 .clearPackagePreferredActivities(r.packageName); 11431 } catch (RemoteException c) { 11432 // pm is in same process, this will never happen. 11433 } 11434 } 11435 } 11436 } 11437 11438 if (!app.isolated) { 11439 // XXX Can't keep track of crash times for isolated processes, 11440 // because they don't have a perisistent identity. 11441 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11442 } 11443 11444 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11445 return true; 11446 } 11447 11448 void startAppProblemLocked(ProcessRecord app) { 11449 // If this app is not running under the current user, then we 11450 // can't give it a report button because that would require 11451 // launching the report UI under a different user. 11452 app.errorReportReceiver = null; 11453 11454 for (int userId : mCurrentProfileIds) { 11455 if (app.userId == userId) { 11456 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11457 mContext, app.info.packageName, app.info.flags); 11458 } 11459 } 11460 skipCurrentReceiverLocked(app); 11461 } 11462 11463 void skipCurrentReceiverLocked(ProcessRecord app) { 11464 for (BroadcastQueue queue : mBroadcastQueues) { 11465 queue.skipCurrentReceiverLocked(app); 11466 } 11467 } 11468 11469 /** 11470 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11471 * The application process will exit immediately after this call returns. 11472 * @param app object of the crashing app, null for the system server 11473 * @param crashInfo describing the exception 11474 */ 11475 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11476 ProcessRecord r = findAppProcess(app, "Crash"); 11477 final String processName = app == null ? "system_server" 11478 : (r == null ? "unknown" : r.processName); 11479 11480 handleApplicationCrashInner("crash", r, processName, crashInfo); 11481 } 11482 11483 /* Native crash reporting uses this inner version because it needs to be somewhat 11484 * decoupled from the AM-managed cleanup lifecycle 11485 */ 11486 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11487 ApplicationErrorReport.CrashInfo crashInfo) { 11488 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11489 UserHandle.getUserId(Binder.getCallingUid()), processName, 11490 r == null ? -1 : r.info.flags, 11491 crashInfo.exceptionClassName, 11492 crashInfo.exceptionMessage, 11493 crashInfo.throwFileName, 11494 crashInfo.throwLineNumber); 11495 11496 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11497 11498 crashApplication(r, crashInfo); 11499 } 11500 11501 public void handleApplicationStrictModeViolation( 11502 IBinder app, 11503 int violationMask, 11504 StrictMode.ViolationInfo info) { 11505 ProcessRecord r = findAppProcess(app, "StrictMode"); 11506 if (r == null) { 11507 return; 11508 } 11509 11510 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11511 Integer stackFingerprint = info.hashCode(); 11512 boolean logIt = true; 11513 synchronized (mAlreadyLoggedViolatedStacks) { 11514 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11515 logIt = false; 11516 // TODO: sub-sample into EventLog for these, with 11517 // the info.durationMillis? Then we'd get 11518 // the relative pain numbers, without logging all 11519 // the stack traces repeatedly. We'd want to do 11520 // likewise in the client code, which also does 11521 // dup suppression, before the Binder call. 11522 } else { 11523 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11524 mAlreadyLoggedViolatedStacks.clear(); 11525 } 11526 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11527 } 11528 } 11529 if (logIt) { 11530 logStrictModeViolationToDropBox(r, info); 11531 } 11532 } 11533 11534 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11535 AppErrorResult result = new AppErrorResult(); 11536 synchronized (this) { 11537 final long origId = Binder.clearCallingIdentity(); 11538 11539 Message msg = Message.obtain(); 11540 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11541 HashMap<String, Object> data = new HashMap<String, Object>(); 11542 data.put("result", result); 11543 data.put("app", r); 11544 data.put("violationMask", violationMask); 11545 data.put("info", info); 11546 msg.obj = data; 11547 mHandler.sendMessage(msg); 11548 11549 Binder.restoreCallingIdentity(origId); 11550 } 11551 int res = result.get(); 11552 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11553 } 11554 } 11555 11556 // Depending on the policy in effect, there could be a bunch of 11557 // these in quick succession so we try to batch these together to 11558 // minimize disk writes, number of dropbox entries, and maximize 11559 // compression, by having more fewer, larger records. 11560 private void logStrictModeViolationToDropBox( 11561 ProcessRecord process, 11562 StrictMode.ViolationInfo info) { 11563 if (info == null) { 11564 return; 11565 } 11566 final boolean isSystemApp = process == null || 11567 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11568 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11569 final String processName = process == null ? "unknown" : process.processName; 11570 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11571 final DropBoxManager dbox = (DropBoxManager) 11572 mContext.getSystemService(Context.DROPBOX_SERVICE); 11573 11574 // Exit early if the dropbox isn't configured to accept this report type. 11575 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11576 11577 boolean bufferWasEmpty; 11578 boolean needsFlush; 11579 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11580 synchronized (sb) { 11581 bufferWasEmpty = sb.length() == 0; 11582 appendDropBoxProcessHeaders(process, processName, sb); 11583 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11584 sb.append("System-App: ").append(isSystemApp).append("\n"); 11585 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11586 if (info.violationNumThisLoop != 0) { 11587 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11588 } 11589 if (info.numAnimationsRunning != 0) { 11590 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11591 } 11592 if (info.broadcastIntentAction != null) { 11593 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11594 } 11595 if (info.durationMillis != -1) { 11596 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11597 } 11598 if (info.numInstances != -1) { 11599 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11600 } 11601 if (info.tags != null) { 11602 for (String tag : info.tags) { 11603 sb.append("Span-Tag: ").append(tag).append("\n"); 11604 } 11605 } 11606 sb.append("\n"); 11607 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11608 sb.append(info.crashInfo.stackTrace); 11609 } 11610 sb.append("\n"); 11611 11612 // Only buffer up to ~64k. Various logging bits truncate 11613 // things at 128k. 11614 needsFlush = (sb.length() > 64 * 1024); 11615 } 11616 11617 // Flush immediately if the buffer's grown too large, or this 11618 // is a non-system app. Non-system apps are isolated with a 11619 // different tag & policy and not batched. 11620 // 11621 // Batching is useful during internal testing with 11622 // StrictMode settings turned up high. Without batching, 11623 // thousands of separate files could be created on boot. 11624 if (!isSystemApp || needsFlush) { 11625 new Thread("Error dump: " + dropboxTag) { 11626 @Override 11627 public void run() { 11628 String report; 11629 synchronized (sb) { 11630 report = sb.toString(); 11631 sb.delete(0, sb.length()); 11632 sb.trimToSize(); 11633 } 11634 if (report.length() != 0) { 11635 dbox.addText(dropboxTag, report); 11636 } 11637 } 11638 }.start(); 11639 return; 11640 } 11641 11642 // System app batching: 11643 if (!bufferWasEmpty) { 11644 // An existing dropbox-writing thread is outstanding, so 11645 // we don't need to start it up. The existing thread will 11646 // catch the buffer appends we just did. 11647 return; 11648 } 11649 11650 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11651 // (After this point, we shouldn't access AMS internal data structures.) 11652 new Thread("Error dump: " + dropboxTag) { 11653 @Override 11654 public void run() { 11655 // 5 second sleep to let stacks arrive and be batched together 11656 try { 11657 Thread.sleep(5000); // 5 seconds 11658 } catch (InterruptedException e) {} 11659 11660 String errorReport; 11661 synchronized (mStrictModeBuffer) { 11662 errorReport = mStrictModeBuffer.toString(); 11663 if (errorReport.length() == 0) { 11664 return; 11665 } 11666 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11667 mStrictModeBuffer.trimToSize(); 11668 } 11669 dbox.addText(dropboxTag, errorReport); 11670 } 11671 }.start(); 11672 } 11673 11674 /** 11675 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11676 * @param app object of the crashing app, null for the system server 11677 * @param tag reported by the caller 11678 * @param system whether this wtf is coming from the system 11679 * @param crashInfo describing the context of the error 11680 * @return true if the process should exit immediately (WTF is fatal) 11681 */ 11682 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11683 final ApplicationErrorReport.CrashInfo crashInfo) { 11684 final ProcessRecord r = findAppProcess(app, "WTF"); 11685 final String processName = app == null ? "system_server" 11686 : (r == null ? "unknown" : r.processName); 11687 11688 EventLog.writeEvent(EventLogTags.AM_WTF, 11689 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11690 processName, 11691 r == null ? -1 : r.info.flags, 11692 tag, crashInfo.exceptionMessage); 11693 11694 if (system) { 11695 // If this is coming from the system, we could very well have low-level 11696 // system locks held, so we want to do this all asynchronously. And we 11697 // never want this to become fatal, so there is that too. 11698 mHandler.post(new Runnable() { 11699 @Override public void run() { 11700 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11701 crashInfo); 11702 } 11703 }); 11704 return false; 11705 } 11706 11707 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11708 11709 if (r != null && r.pid != Process.myPid() && 11710 Settings.Global.getInt(mContext.getContentResolver(), 11711 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11712 crashApplication(r, crashInfo); 11713 return true; 11714 } else { 11715 return false; 11716 } 11717 } 11718 11719 /** 11720 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11721 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11722 */ 11723 private ProcessRecord findAppProcess(IBinder app, String reason) { 11724 if (app == null) { 11725 return null; 11726 } 11727 11728 synchronized (this) { 11729 final int NP = mProcessNames.getMap().size(); 11730 for (int ip=0; ip<NP; ip++) { 11731 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11732 final int NA = apps.size(); 11733 for (int ia=0; ia<NA; ia++) { 11734 ProcessRecord p = apps.valueAt(ia); 11735 if (p.thread != null && p.thread.asBinder() == app) { 11736 return p; 11737 } 11738 } 11739 } 11740 11741 Slog.w(TAG, "Can't find mystery application for " + reason 11742 + " from pid=" + Binder.getCallingPid() 11743 + " uid=" + Binder.getCallingUid() + ": " + app); 11744 return null; 11745 } 11746 } 11747 11748 /** 11749 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11750 * to append various headers to the dropbox log text. 11751 */ 11752 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11753 StringBuilder sb) { 11754 // Watchdog thread ends up invoking this function (with 11755 // a null ProcessRecord) to add the stack file to dropbox. 11756 // Do not acquire a lock on this (am) in such cases, as it 11757 // could cause a potential deadlock, if and when watchdog 11758 // is invoked due to unavailability of lock on am and it 11759 // would prevent watchdog from killing system_server. 11760 if (process == null) { 11761 sb.append("Process: ").append(processName).append("\n"); 11762 return; 11763 } 11764 // Note: ProcessRecord 'process' is guarded by the service 11765 // instance. (notably process.pkgList, which could otherwise change 11766 // concurrently during execution of this method) 11767 synchronized (this) { 11768 sb.append("Process: ").append(processName).append("\n"); 11769 int flags = process.info.flags; 11770 IPackageManager pm = AppGlobals.getPackageManager(); 11771 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11772 for (int ip=0; ip<process.pkgList.size(); ip++) { 11773 String pkg = process.pkgList.keyAt(ip); 11774 sb.append("Package: ").append(pkg); 11775 try { 11776 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11777 if (pi != null) { 11778 sb.append(" v").append(pi.versionCode); 11779 if (pi.versionName != null) { 11780 sb.append(" (").append(pi.versionName).append(")"); 11781 } 11782 } 11783 } catch (RemoteException e) { 11784 Slog.e(TAG, "Error getting package info: " + pkg, e); 11785 } 11786 sb.append("\n"); 11787 } 11788 } 11789 } 11790 11791 private static String processClass(ProcessRecord process) { 11792 if (process == null || process.pid == MY_PID) { 11793 return "system_server"; 11794 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11795 return "system_app"; 11796 } else { 11797 return "data_app"; 11798 } 11799 } 11800 11801 /** 11802 * Write a description of an error (crash, WTF, ANR) to the drop box. 11803 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11804 * @param process which caused the error, null means the system server 11805 * @param activity which triggered the error, null if unknown 11806 * @param parent activity related to the error, null if unknown 11807 * @param subject line related to the error, null if absent 11808 * @param report in long form describing the error, null if absent 11809 * @param logFile to include in the report, null if none 11810 * @param crashInfo giving an application stack trace, null if absent 11811 */ 11812 public void addErrorToDropBox(String eventType, 11813 ProcessRecord process, String processName, ActivityRecord activity, 11814 ActivityRecord parent, String subject, 11815 final String report, final File logFile, 11816 final ApplicationErrorReport.CrashInfo crashInfo) { 11817 // NOTE -- this must never acquire the ActivityManagerService lock, 11818 // otherwise the watchdog may be prevented from resetting the system. 11819 11820 final String dropboxTag = processClass(process) + "_" + eventType; 11821 final DropBoxManager dbox = (DropBoxManager) 11822 mContext.getSystemService(Context.DROPBOX_SERVICE); 11823 11824 // Exit early if the dropbox isn't configured to accept this report type. 11825 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11826 11827 final StringBuilder sb = new StringBuilder(1024); 11828 appendDropBoxProcessHeaders(process, processName, sb); 11829 if (activity != null) { 11830 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11831 } 11832 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11833 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11834 } 11835 if (parent != null && parent != activity) { 11836 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11837 } 11838 if (subject != null) { 11839 sb.append("Subject: ").append(subject).append("\n"); 11840 } 11841 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11842 if (Debug.isDebuggerConnected()) { 11843 sb.append("Debugger: Connected\n"); 11844 } 11845 sb.append("\n"); 11846 11847 // Do the rest in a worker thread to avoid blocking the caller on I/O 11848 // (After this point, we shouldn't access AMS internal data structures.) 11849 Thread worker = new Thread("Error dump: " + dropboxTag) { 11850 @Override 11851 public void run() { 11852 if (report != null) { 11853 sb.append(report); 11854 } 11855 if (logFile != null) { 11856 try { 11857 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11858 "\n\n[[TRUNCATED]]")); 11859 } catch (IOException e) { 11860 Slog.e(TAG, "Error reading " + logFile, e); 11861 } 11862 } 11863 if (crashInfo != null && crashInfo.stackTrace != null) { 11864 sb.append(crashInfo.stackTrace); 11865 } 11866 11867 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11868 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11869 if (lines > 0) { 11870 sb.append("\n"); 11871 11872 // Merge several logcat streams, and take the last N lines 11873 InputStreamReader input = null; 11874 try { 11875 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11876 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11877 "-b", "crash", 11878 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11879 11880 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11881 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11882 input = new InputStreamReader(logcat.getInputStream()); 11883 11884 int num; 11885 char[] buf = new char[8192]; 11886 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11887 } catch (IOException e) { 11888 Slog.e(TAG, "Error running logcat", e); 11889 } finally { 11890 if (input != null) try { input.close(); } catch (IOException e) {} 11891 } 11892 } 11893 11894 dbox.addText(dropboxTag, sb.toString()); 11895 } 11896 }; 11897 11898 if (process == null) { 11899 // If process is null, we are being called from some internal code 11900 // and may be about to die -- run this synchronously. 11901 worker.run(); 11902 } else { 11903 worker.start(); 11904 } 11905 } 11906 11907 /** 11908 * Bring up the "unexpected error" dialog box for a crashing app. 11909 * Deal with edge cases (intercepts from instrumented applications, 11910 * ActivityController, error intent receivers, that sort of thing). 11911 * @param r the application crashing 11912 * @param crashInfo describing the failure 11913 */ 11914 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11915 long timeMillis = System.currentTimeMillis(); 11916 String shortMsg = crashInfo.exceptionClassName; 11917 String longMsg = crashInfo.exceptionMessage; 11918 String stackTrace = crashInfo.stackTrace; 11919 if (shortMsg != null && longMsg != null) { 11920 longMsg = shortMsg + ": " + longMsg; 11921 } else if (shortMsg != null) { 11922 longMsg = shortMsg; 11923 } 11924 11925 AppErrorResult result = new AppErrorResult(); 11926 synchronized (this) { 11927 if (mController != null) { 11928 try { 11929 String name = r != null ? r.processName : null; 11930 int pid = r != null ? r.pid : Binder.getCallingPid(); 11931 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11932 if (!mController.appCrashed(name, pid, 11933 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11934 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11935 && "Native crash".equals(crashInfo.exceptionClassName)) { 11936 Slog.w(TAG, "Skip killing native crashed app " + name 11937 + "(" + pid + ") during testing"); 11938 } else { 11939 Slog.w(TAG, "Force-killing crashed app " + name 11940 + " at watcher's request"); 11941 if (r != null) { 11942 r.kill("crash", true); 11943 } else { 11944 // Huh. 11945 Process.killProcess(pid); 11946 Process.killProcessGroup(uid, pid); 11947 } 11948 } 11949 return; 11950 } 11951 } catch (RemoteException e) { 11952 mController = null; 11953 Watchdog.getInstance().setActivityController(null); 11954 } 11955 } 11956 11957 final long origId = Binder.clearCallingIdentity(); 11958 11959 // If this process is running instrumentation, finish it. 11960 if (r != null && r.instrumentationClass != null) { 11961 Slog.w(TAG, "Error in app " + r.processName 11962 + " running instrumentation " + r.instrumentationClass + ":"); 11963 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11964 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11965 Bundle info = new Bundle(); 11966 info.putString("shortMsg", shortMsg); 11967 info.putString("longMsg", longMsg); 11968 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11969 Binder.restoreCallingIdentity(origId); 11970 return; 11971 } 11972 11973 // If we can't identify the process or it's already exceeded its crash quota, 11974 // quit right away without showing a crash dialog. 11975 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11976 Binder.restoreCallingIdentity(origId); 11977 return; 11978 } 11979 11980 Message msg = Message.obtain(); 11981 msg.what = SHOW_ERROR_MSG; 11982 HashMap data = new HashMap(); 11983 data.put("result", result); 11984 data.put("app", r); 11985 msg.obj = data; 11986 mHandler.sendMessage(msg); 11987 11988 Binder.restoreCallingIdentity(origId); 11989 } 11990 11991 int res = result.get(); 11992 11993 Intent appErrorIntent = null; 11994 synchronized (this) { 11995 if (r != null && !r.isolated) { 11996 // XXX Can't keep track of crash time for isolated processes, 11997 // since they don't have a persistent identity. 11998 mProcessCrashTimes.put(r.info.processName, r.uid, 11999 SystemClock.uptimeMillis()); 12000 } 12001 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12002 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12003 } 12004 } 12005 12006 if (appErrorIntent != null) { 12007 try { 12008 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12009 } catch (ActivityNotFoundException e) { 12010 Slog.w(TAG, "bug report receiver dissappeared", e); 12011 } 12012 } 12013 } 12014 12015 Intent createAppErrorIntentLocked(ProcessRecord r, 12016 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12017 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12018 if (report == null) { 12019 return null; 12020 } 12021 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12022 result.setComponent(r.errorReportReceiver); 12023 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12024 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12025 return result; 12026 } 12027 12028 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12029 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12030 if (r.errorReportReceiver == null) { 12031 return null; 12032 } 12033 12034 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12035 return null; 12036 } 12037 12038 ApplicationErrorReport report = new ApplicationErrorReport(); 12039 report.packageName = r.info.packageName; 12040 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12041 report.processName = r.processName; 12042 report.time = timeMillis; 12043 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12044 12045 if (r.crashing || r.forceCrashReport) { 12046 report.type = ApplicationErrorReport.TYPE_CRASH; 12047 report.crashInfo = crashInfo; 12048 } else if (r.notResponding) { 12049 report.type = ApplicationErrorReport.TYPE_ANR; 12050 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12051 12052 report.anrInfo.activity = r.notRespondingReport.tag; 12053 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12054 report.anrInfo.info = r.notRespondingReport.longMsg; 12055 } 12056 12057 return report; 12058 } 12059 12060 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12061 enforceNotIsolatedCaller("getProcessesInErrorState"); 12062 // assume our apps are happy - lazy create the list 12063 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12064 12065 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12066 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12067 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12068 12069 synchronized (this) { 12070 12071 // iterate across all processes 12072 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12073 ProcessRecord app = mLruProcesses.get(i); 12074 if (!allUsers && app.userId != userId) { 12075 continue; 12076 } 12077 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12078 // This one's in trouble, so we'll generate a report for it 12079 // crashes are higher priority (in case there's a crash *and* an anr) 12080 ActivityManager.ProcessErrorStateInfo report = null; 12081 if (app.crashing) { 12082 report = app.crashingReport; 12083 } else if (app.notResponding) { 12084 report = app.notRespondingReport; 12085 } 12086 12087 if (report != null) { 12088 if (errList == null) { 12089 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12090 } 12091 errList.add(report); 12092 } else { 12093 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12094 " crashing = " + app.crashing + 12095 " notResponding = " + app.notResponding); 12096 } 12097 } 12098 } 12099 } 12100 12101 return errList; 12102 } 12103 12104 static int procStateToImportance(int procState, int memAdj, 12105 ActivityManager.RunningAppProcessInfo currApp) { 12106 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12107 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12108 currApp.lru = memAdj; 12109 } else { 12110 currApp.lru = 0; 12111 } 12112 return imp; 12113 } 12114 12115 private void fillInProcMemInfo(ProcessRecord app, 12116 ActivityManager.RunningAppProcessInfo outInfo) { 12117 outInfo.pid = app.pid; 12118 outInfo.uid = app.info.uid; 12119 if (mHeavyWeightProcess == app) { 12120 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12121 } 12122 if (app.persistent) { 12123 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12124 } 12125 if (app.activities.size() > 0) { 12126 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12127 } 12128 outInfo.lastTrimLevel = app.trimMemoryLevel; 12129 int adj = app.curAdj; 12130 int procState = app.curProcState; 12131 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12132 outInfo.importanceReasonCode = app.adjTypeCode; 12133 outInfo.processState = app.curProcState; 12134 } 12135 12136 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12137 enforceNotIsolatedCaller("getRunningAppProcesses"); 12138 // Lazy instantiation of list 12139 List<ActivityManager.RunningAppProcessInfo> runList = null; 12140 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12141 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12142 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12143 synchronized (this) { 12144 // Iterate across all processes 12145 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12146 ProcessRecord app = mLruProcesses.get(i); 12147 if (!allUsers && app.userId != userId) { 12148 continue; 12149 } 12150 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12151 // Generate process state info for running application 12152 ActivityManager.RunningAppProcessInfo currApp = 12153 new ActivityManager.RunningAppProcessInfo(app.processName, 12154 app.pid, app.getPackageList()); 12155 fillInProcMemInfo(app, currApp); 12156 if (app.adjSource instanceof ProcessRecord) { 12157 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12158 currApp.importanceReasonImportance = 12159 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12160 app.adjSourceProcState); 12161 } else if (app.adjSource instanceof ActivityRecord) { 12162 ActivityRecord r = (ActivityRecord)app.adjSource; 12163 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12164 } 12165 if (app.adjTarget instanceof ComponentName) { 12166 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12167 } 12168 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12169 // + " lru=" + currApp.lru); 12170 if (runList == null) { 12171 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12172 } 12173 runList.add(currApp); 12174 } 12175 } 12176 } 12177 return runList; 12178 } 12179 12180 public List<ApplicationInfo> getRunningExternalApplications() { 12181 enforceNotIsolatedCaller("getRunningExternalApplications"); 12182 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12183 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12184 if (runningApps != null && runningApps.size() > 0) { 12185 Set<String> extList = new HashSet<String>(); 12186 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12187 if (app.pkgList != null) { 12188 for (String pkg : app.pkgList) { 12189 extList.add(pkg); 12190 } 12191 } 12192 } 12193 IPackageManager pm = AppGlobals.getPackageManager(); 12194 for (String pkg : extList) { 12195 try { 12196 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12197 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12198 retList.add(info); 12199 } 12200 } catch (RemoteException e) { 12201 } 12202 } 12203 } 12204 return retList; 12205 } 12206 12207 @Override 12208 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12209 enforceNotIsolatedCaller("getMyMemoryState"); 12210 synchronized (this) { 12211 ProcessRecord proc; 12212 synchronized (mPidsSelfLocked) { 12213 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12214 } 12215 fillInProcMemInfo(proc, outInfo); 12216 } 12217 } 12218 12219 @Override 12220 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12221 if (checkCallingPermission(android.Manifest.permission.DUMP) 12222 != PackageManager.PERMISSION_GRANTED) { 12223 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12224 + Binder.getCallingPid() 12225 + ", uid=" + Binder.getCallingUid() 12226 + " without permission " 12227 + android.Manifest.permission.DUMP); 12228 return; 12229 } 12230 12231 boolean dumpAll = false; 12232 boolean dumpClient = false; 12233 String dumpPackage = null; 12234 12235 int opti = 0; 12236 while (opti < args.length) { 12237 String opt = args[opti]; 12238 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12239 break; 12240 } 12241 opti++; 12242 if ("-a".equals(opt)) { 12243 dumpAll = true; 12244 } else if ("-c".equals(opt)) { 12245 dumpClient = true; 12246 } else if ("-h".equals(opt)) { 12247 pw.println("Activity manager dump options:"); 12248 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12249 pw.println(" cmd may be one of:"); 12250 pw.println(" a[ctivities]: activity stack state"); 12251 pw.println(" r[recents]: recent activities state"); 12252 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12253 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12254 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12255 pw.println(" o[om]: out of memory management"); 12256 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12257 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12258 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12259 pw.println(" service [COMP_SPEC]: service client-side state"); 12260 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12261 pw.println(" all: dump all activities"); 12262 pw.println(" top: dump the top activity"); 12263 pw.println(" write: write all pending state to storage"); 12264 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12265 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12266 pw.println(" a partial substring in a component name, a"); 12267 pw.println(" hex object identifier."); 12268 pw.println(" -a: include all available server state."); 12269 pw.println(" -c: include client state."); 12270 return; 12271 } else { 12272 pw.println("Unknown argument: " + opt + "; use -h for help"); 12273 } 12274 } 12275 12276 long origId = Binder.clearCallingIdentity(); 12277 boolean more = false; 12278 // Is the caller requesting to dump a particular piece of data? 12279 if (opti < args.length) { 12280 String cmd = args[opti]; 12281 opti++; 12282 if ("activities".equals(cmd) || "a".equals(cmd)) { 12283 synchronized (this) { 12284 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12285 } 12286 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12287 synchronized (this) { 12288 dumpRecentsLocked(fd, pw, args, opti, true, null); 12289 } 12290 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12291 String[] newArgs; 12292 String name; 12293 if (opti >= args.length) { 12294 name = null; 12295 newArgs = EMPTY_STRING_ARRAY; 12296 } else { 12297 name = args[opti]; 12298 opti++; 12299 newArgs = new String[args.length - opti]; 12300 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12301 args.length - opti); 12302 } 12303 synchronized (this) { 12304 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12305 } 12306 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12307 String[] newArgs; 12308 String name; 12309 if (opti >= args.length) { 12310 name = null; 12311 newArgs = EMPTY_STRING_ARRAY; 12312 } else { 12313 name = args[opti]; 12314 opti++; 12315 newArgs = new String[args.length - opti]; 12316 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12317 args.length - opti); 12318 } 12319 synchronized (this) { 12320 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12321 } 12322 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12323 String[] newArgs; 12324 String name; 12325 if (opti >= args.length) { 12326 name = null; 12327 newArgs = EMPTY_STRING_ARRAY; 12328 } else { 12329 name = args[opti]; 12330 opti++; 12331 newArgs = new String[args.length - opti]; 12332 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12333 args.length - opti); 12334 } 12335 synchronized (this) { 12336 dumpProcessesLocked(fd, pw, args, opti, true, name); 12337 } 12338 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12339 synchronized (this) { 12340 dumpOomLocked(fd, pw, args, opti, true); 12341 } 12342 } else if ("provider".equals(cmd)) { 12343 String[] newArgs; 12344 String name; 12345 if (opti >= args.length) { 12346 name = null; 12347 newArgs = EMPTY_STRING_ARRAY; 12348 } else { 12349 name = args[opti]; 12350 opti++; 12351 newArgs = new String[args.length - opti]; 12352 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12353 } 12354 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12355 pw.println("No providers match: " + name); 12356 pw.println("Use -h for help."); 12357 } 12358 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12359 synchronized (this) { 12360 dumpProvidersLocked(fd, pw, args, opti, true, null); 12361 } 12362 } else if ("service".equals(cmd)) { 12363 String[] newArgs; 12364 String name; 12365 if (opti >= args.length) { 12366 name = null; 12367 newArgs = EMPTY_STRING_ARRAY; 12368 } else { 12369 name = args[opti]; 12370 opti++; 12371 newArgs = new String[args.length - opti]; 12372 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12373 args.length - opti); 12374 } 12375 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12376 pw.println("No services match: " + name); 12377 pw.println("Use -h for help."); 12378 } 12379 } else if ("package".equals(cmd)) { 12380 String[] newArgs; 12381 if (opti >= args.length) { 12382 pw.println("package: no package name specified"); 12383 pw.println("Use -h for help."); 12384 } else { 12385 dumpPackage = args[opti]; 12386 opti++; 12387 newArgs = new String[args.length - opti]; 12388 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12389 args.length - opti); 12390 args = newArgs; 12391 opti = 0; 12392 more = true; 12393 } 12394 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12395 synchronized (this) { 12396 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12397 } 12398 } else if ("write".equals(cmd)) { 12399 mTaskPersister.flush(); 12400 pw.println("All tasks persisted."); 12401 return; 12402 } else { 12403 // Dumping a single activity? 12404 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12405 pw.println("Bad activity command, or no activities match: " + cmd); 12406 pw.println("Use -h for help."); 12407 } 12408 } 12409 if (!more) { 12410 Binder.restoreCallingIdentity(origId); 12411 return; 12412 } 12413 } 12414 12415 // No piece of data specified, dump everything. 12416 synchronized (this) { 12417 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12418 pw.println(); 12419 if (dumpAll) { 12420 pw.println("-------------------------------------------------------------------------------"); 12421 } 12422 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12423 pw.println(); 12424 if (dumpAll) { 12425 pw.println("-------------------------------------------------------------------------------"); 12426 } 12427 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12428 pw.println(); 12429 if (dumpAll) { 12430 pw.println("-------------------------------------------------------------------------------"); 12431 } 12432 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12433 pw.println(); 12434 if (dumpAll) { 12435 pw.println("-------------------------------------------------------------------------------"); 12436 } 12437 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12438 pw.println(); 12439 if (dumpAll) { 12440 pw.println("-------------------------------------------------------------------------------"); 12441 } 12442 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12443 pw.println(); 12444 if (dumpAll) { 12445 pw.println("-------------------------------------------------------------------------------"); 12446 } 12447 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12448 } 12449 Binder.restoreCallingIdentity(origId); 12450 } 12451 12452 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12453 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12454 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12455 12456 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12457 dumpPackage); 12458 boolean needSep = printedAnything; 12459 12460 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12461 dumpPackage, needSep, " mFocusedActivity: "); 12462 if (printed) { 12463 printedAnything = true; 12464 needSep = false; 12465 } 12466 12467 if (dumpPackage == null) { 12468 if (needSep) { 12469 pw.println(); 12470 } 12471 needSep = true; 12472 printedAnything = true; 12473 mStackSupervisor.dump(pw, " "); 12474 } 12475 12476 if (!printedAnything) { 12477 pw.println(" (nothing)"); 12478 } 12479 } 12480 12481 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12482 int opti, boolean dumpAll, String dumpPackage) { 12483 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12484 12485 boolean printedAnything = false; 12486 12487 if (mRecentTasks.size() > 0) { 12488 boolean printedHeader = false; 12489 12490 final int N = mRecentTasks.size(); 12491 for (int i=0; i<N; i++) { 12492 TaskRecord tr = mRecentTasks.get(i); 12493 if (dumpPackage != null) { 12494 if (tr.realActivity == null || 12495 !dumpPackage.equals(tr.realActivity)) { 12496 continue; 12497 } 12498 } 12499 if (!printedHeader) { 12500 pw.println(" Recent tasks:"); 12501 printedHeader = true; 12502 printedAnything = true; 12503 } 12504 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12505 pw.println(tr); 12506 if (dumpAll) { 12507 mRecentTasks.get(i).dump(pw, " "); 12508 } 12509 } 12510 } 12511 12512 if (!printedAnything) { 12513 pw.println(" (nothing)"); 12514 } 12515 } 12516 12517 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12518 int opti, boolean dumpAll, String dumpPackage) { 12519 boolean needSep = false; 12520 boolean printedAnything = false; 12521 int numPers = 0; 12522 12523 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12524 12525 if (dumpAll) { 12526 final int NP = mProcessNames.getMap().size(); 12527 for (int ip=0; ip<NP; ip++) { 12528 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12529 final int NA = procs.size(); 12530 for (int ia=0; ia<NA; ia++) { 12531 ProcessRecord r = procs.valueAt(ia); 12532 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12533 continue; 12534 } 12535 if (!needSep) { 12536 pw.println(" All known processes:"); 12537 needSep = true; 12538 printedAnything = true; 12539 } 12540 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12541 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12542 pw.print(" "); pw.println(r); 12543 r.dump(pw, " "); 12544 if (r.persistent) { 12545 numPers++; 12546 } 12547 } 12548 } 12549 } 12550 12551 if (mIsolatedProcesses.size() > 0) { 12552 boolean printed = false; 12553 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12554 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12555 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12556 continue; 12557 } 12558 if (!printed) { 12559 if (needSep) { 12560 pw.println(); 12561 } 12562 pw.println(" Isolated process list (sorted by uid):"); 12563 printedAnything = true; 12564 printed = true; 12565 needSep = true; 12566 } 12567 pw.println(String.format("%sIsolated #%2d: %s", 12568 " ", i, r.toString())); 12569 } 12570 } 12571 12572 if (mLruProcesses.size() > 0) { 12573 if (needSep) { 12574 pw.println(); 12575 } 12576 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12577 pw.print(" total, non-act at "); 12578 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12579 pw.print(", non-svc at "); 12580 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12581 pw.println("):"); 12582 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12583 needSep = true; 12584 printedAnything = true; 12585 } 12586 12587 if (dumpAll || dumpPackage != null) { 12588 synchronized (mPidsSelfLocked) { 12589 boolean printed = false; 12590 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12591 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12592 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12593 continue; 12594 } 12595 if (!printed) { 12596 if (needSep) pw.println(); 12597 needSep = true; 12598 pw.println(" PID mappings:"); 12599 printed = true; 12600 printedAnything = true; 12601 } 12602 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12603 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12604 } 12605 } 12606 } 12607 12608 if (mForegroundProcesses.size() > 0) { 12609 synchronized (mPidsSelfLocked) { 12610 boolean printed = false; 12611 for (int i=0; i<mForegroundProcesses.size(); i++) { 12612 ProcessRecord r = mPidsSelfLocked.get( 12613 mForegroundProcesses.valueAt(i).pid); 12614 if (dumpPackage != null && (r == null 12615 || !r.pkgList.containsKey(dumpPackage))) { 12616 continue; 12617 } 12618 if (!printed) { 12619 if (needSep) pw.println(); 12620 needSep = true; 12621 pw.println(" Foreground Processes:"); 12622 printed = true; 12623 printedAnything = true; 12624 } 12625 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12626 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12627 } 12628 } 12629 } 12630 12631 if (mPersistentStartingProcesses.size() > 0) { 12632 if (needSep) pw.println(); 12633 needSep = true; 12634 printedAnything = true; 12635 pw.println(" Persisent processes that are starting:"); 12636 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12637 "Starting Norm", "Restarting PERS", dumpPackage); 12638 } 12639 12640 if (mRemovedProcesses.size() > 0) { 12641 if (needSep) pw.println(); 12642 needSep = true; 12643 printedAnything = true; 12644 pw.println(" Processes that are being removed:"); 12645 dumpProcessList(pw, this, mRemovedProcesses, " ", 12646 "Removed Norm", "Removed PERS", dumpPackage); 12647 } 12648 12649 if (mProcessesOnHold.size() > 0) { 12650 if (needSep) pw.println(); 12651 needSep = true; 12652 printedAnything = true; 12653 pw.println(" Processes that are on old until the system is ready:"); 12654 dumpProcessList(pw, this, mProcessesOnHold, " ", 12655 "OnHold Norm", "OnHold PERS", dumpPackage); 12656 } 12657 12658 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12659 12660 if (mProcessCrashTimes.getMap().size() > 0) { 12661 boolean printed = false; 12662 long now = SystemClock.uptimeMillis(); 12663 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12664 final int NP = pmap.size(); 12665 for (int ip=0; ip<NP; ip++) { 12666 String pname = pmap.keyAt(ip); 12667 SparseArray<Long> uids = pmap.valueAt(ip); 12668 final int N = uids.size(); 12669 for (int i=0; i<N; i++) { 12670 int puid = uids.keyAt(i); 12671 ProcessRecord r = mProcessNames.get(pname, puid); 12672 if (dumpPackage != null && (r == null 12673 || !r.pkgList.containsKey(dumpPackage))) { 12674 continue; 12675 } 12676 if (!printed) { 12677 if (needSep) pw.println(); 12678 needSep = true; 12679 pw.println(" Time since processes crashed:"); 12680 printed = true; 12681 printedAnything = true; 12682 } 12683 pw.print(" Process "); pw.print(pname); 12684 pw.print(" uid "); pw.print(puid); 12685 pw.print(": last crashed "); 12686 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12687 pw.println(" ago"); 12688 } 12689 } 12690 } 12691 12692 if (mBadProcesses.getMap().size() > 0) { 12693 boolean printed = false; 12694 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12695 final int NP = pmap.size(); 12696 for (int ip=0; ip<NP; ip++) { 12697 String pname = pmap.keyAt(ip); 12698 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12699 final int N = uids.size(); 12700 for (int i=0; i<N; i++) { 12701 int puid = uids.keyAt(i); 12702 ProcessRecord r = mProcessNames.get(pname, puid); 12703 if (dumpPackage != null && (r == null 12704 || !r.pkgList.containsKey(dumpPackage))) { 12705 continue; 12706 } 12707 if (!printed) { 12708 if (needSep) pw.println(); 12709 needSep = true; 12710 pw.println(" Bad processes:"); 12711 printedAnything = true; 12712 } 12713 BadProcessInfo info = uids.valueAt(i); 12714 pw.print(" Bad process "); pw.print(pname); 12715 pw.print(" uid "); pw.print(puid); 12716 pw.print(": crashed at time "); pw.println(info.time); 12717 if (info.shortMsg != null) { 12718 pw.print(" Short msg: "); pw.println(info.shortMsg); 12719 } 12720 if (info.longMsg != null) { 12721 pw.print(" Long msg: "); pw.println(info.longMsg); 12722 } 12723 if (info.stack != null) { 12724 pw.println(" Stack:"); 12725 int lastPos = 0; 12726 for (int pos=0; pos<info.stack.length(); pos++) { 12727 if (info.stack.charAt(pos) == '\n') { 12728 pw.print(" "); 12729 pw.write(info.stack, lastPos, pos-lastPos); 12730 pw.println(); 12731 lastPos = pos+1; 12732 } 12733 } 12734 if (lastPos < info.stack.length()) { 12735 pw.print(" "); 12736 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12737 pw.println(); 12738 } 12739 } 12740 } 12741 } 12742 } 12743 12744 if (dumpPackage == null) { 12745 pw.println(); 12746 needSep = false; 12747 pw.println(" mStartedUsers:"); 12748 for (int i=0; i<mStartedUsers.size(); i++) { 12749 UserStartedState uss = mStartedUsers.valueAt(i); 12750 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12751 pw.print(": "); uss.dump("", pw); 12752 } 12753 pw.print(" mStartedUserArray: ["); 12754 for (int i=0; i<mStartedUserArray.length; i++) { 12755 if (i > 0) pw.print(", "); 12756 pw.print(mStartedUserArray[i]); 12757 } 12758 pw.println("]"); 12759 pw.print(" mUserLru: ["); 12760 for (int i=0; i<mUserLru.size(); i++) { 12761 if (i > 0) pw.print(", "); 12762 pw.print(mUserLru.get(i)); 12763 } 12764 pw.println("]"); 12765 if (dumpAll) { 12766 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12767 } 12768 synchronized (mUserProfileGroupIdsSelfLocked) { 12769 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12770 pw.println(" mUserProfileGroupIds:"); 12771 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12772 pw.print(" User #"); 12773 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12774 pw.print(" -> profile #"); 12775 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12776 } 12777 } 12778 } 12779 } 12780 if (mHomeProcess != null && (dumpPackage == null 12781 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12782 if (needSep) { 12783 pw.println(); 12784 needSep = false; 12785 } 12786 pw.println(" mHomeProcess: " + mHomeProcess); 12787 } 12788 if (mPreviousProcess != null && (dumpPackage == null 12789 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12790 if (needSep) { 12791 pw.println(); 12792 needSep = false; 12793 } 12794 pw.println(" mPreviousProcess: " + mPreviousProcess); 12795 } 12796 if (dumpAll) { 12797 StringBuilder sb = new StringBuilder(128); 12798 sb.append(" mPreviousProcessVisibleTime: "); 12799 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12800 pw.println(sb); 12801 } 12802 if (mHeavyWeightProcess != null && (dumpPackage == null 12803 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12804 if (needSep) { 12805 pw.println(); 12806 needSep = false; 12807 } 12808 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12809 } 12810 if (dumpPackage == null) { 12811 pw.println(" mConfiguration: " + mConfiguration); 12812 } 12813 if (dumpAll) { 12814 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12815 if (mCompatModePackages.getPackages().size() > 0) { 12816 boolean printed = false; 12817 for (Map.Entry<String, Integer> entry 12818 : mCompatModePackages.getPackages().entrySet()) { 12819 String pkg = entry.getKey(); 12820 int mode = entry.getValue(); 12821 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12822 continue; 12823 } 12824 if (!printed) { 12825 pw.println(" mScreenCompatPackages:"); 12826 printed = true; 12827 } 12828 pw.print(" "); pw.print(pkg); pw.print(": "); 12829 pw.print(mode); pw.println(); 12830 } 12831 } 12832 } 12833 if (dumpPackage == null) { 12834 if (mSleeping || mWentToSleep || mLockScreenShown) { 12835 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12836 + " mLockScreenShown " + mLockScreenShown); 12837 } 12838 if (mShuttingDown || mRunningVoice) { 12839 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12840 } 12841 } 12842 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12843 || mOrigWaitForDebugger) { 12844 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12845 || dumpPackage.equals(mOrigDebugApp)) { 12846 if (needSep) { 12847 pw.println(); 12848 needSep = false; 12849 } 12850 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12851 + " mDebugTransient=" + mDebugTransient 12852 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12853 } 12854 } 12855 if (mOpenGlTraceApp != null) { 12856 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12857 if (needSep) { 12858 pw.println(); 12859 needSep = false; 12860 } 12861 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12862 } 12863 } 12864 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12865 || mProfileFd != null) { 12866 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12867 if (needSep) { 12868 pw.println(); 12869 needSep = false; 12870 } 12871 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12872 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12873 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12874 + mAutoStopProfiler); 12875 pw.println(" mProfileType=" + mProfileType); 12876 } 12877 } 12878 if (dumpPackage == null) { 12879 if (mAlwaysFinishActivities || mController != null) { 12880 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12881 + " mController=" + mController); 12882 } 12883 if (dumpAll) { 12884 pw.println(" Total persistent processes: " + numPers); 12885 pw.println(" mProcessesReady=" + mProcessesReady 12886 + " mSystemReady=" + mSystemReady); 12887 pw.println(" mBooting=" + mBooting 12888 + " mBooted=" + mBooted 12889 + " mFactoryTest=" + mFactoryTest); 12890 pw.print(" mLastPowerCheckRealtime="); 12891 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12892 pw.println(""); 12893 pw.print(" mLastPowerCheckUptime="); 12894 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12895 pw.println(""); 12896 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12897 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12898 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12899 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12900 + " (" + mLruProcesses.size() + " total)" 12901 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12902 + " mNumServiceProcs=" + mNumServiceProcs 12903 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12904 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12905 + " mLastMemoryLevel" + mLastMemoryLevel 12906 + " mLastNumProcesses" + mLastNumProcesses); 12907 long now = SystemClock.uptimeMillis(); 12908 pw.print(" mLastIdleTime="); 12909 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12910 pw.print(" mLowRamSinceLastIdle="); 12911 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12912 pw.println(); 12913 } 12914 } 12915 12916 if (!printedAnything) { 12917 pw.println(" (nothing)"); 12918 } 12919 } 12920 12921 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12922 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12923 if (mProcessesToGc.size() > 0) { 12924 boolean printed = false; 12925 long now = SystemClock.uptimeMillis(); 12926 for (int i=0; i<mProcessesToGc.size(); i++) { 12927 ProcessRecord proc = mProcessesToGc.get(i); 12928 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12929 continue; 12930 } 12931 if (!printed) { 12932 if (needSep) pw.println(); 12933 needSep = true; 12934 pw.println(" Processes that are waiting to GC:"); 12935 printed = true; 12936 } 12937 pw.print(" Process "); pw.println(proc); 12938 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12939 pw.print(", last gced="); 12940 pw.print(now-proc.lastRequestedGc); 12941 pw.print(" ms ago, last lowMem="); 12942 pw.print(now-proc.lastLowMemory); 12943 pw.println(" ms ago"); 12944 12945 } 12946 } 12947 return needSep; 12948 } 12949 12950 void printOomLevel(PrintWriter pw, String name, int adj) { 12951 pw.print(" "); 12952 if (adj >= 0) { 12953 pw.print(' '); 12954 if (adj < 10) pw.print(' '); 12955 } else { 12956 if (adj > -10) pw.print(' '); 12957 } 12958 pw.print(adj); 12959 pw.print(": "); 12960 pw.print(name); 12961 pw.print(" ("); 12962 pw.print(mProcessList.getMemLevel(adj)/1024); 12963 pw.println(" kB)"); 12964 } 12965 12966 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12967 int opti, boolean dumpAll) { 12968 boolean needSep = false; 12969 12970 if (mLruProcesses.size() > 0) { 12971 if (needSep) pw.println(); 12972 needSep = true; 12973 pw.println(" OOM levels:"); 12974 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12975 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12976 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12977 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12978 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12979 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12980 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12981 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12982 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12983 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12984 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12985 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12986 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12987 12988 if (needSep) pw.println(); 12989 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12990 pw.print(" total, non-act at "); 12991 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12992 pw.print(", non-svc at "); 12993 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12994 pw.println("):"); 12995 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12996 needSep = true; 12997 } 12998 12999 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13000 13001 pw.println(); 13002 pw.println(" mHomeProcess: " + mHomeProcess); 13003 pw.println(" mPreviousProcess: " + mPreviousProcess); 13004 if (mHeavyWeightProcess != null) { 13005 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13006 } 13007 13008 return true; 13009 } 13010 13011 /** 13012 * There are three ways to call this: 13013 * - no provider specified: dump all the providers 13014 * - a flattened component name that matched an existing provider was specified as the 13015 * first arg: dump that one provider 13016 * - the first arg isn't the flattened component name of an existing provider: 13017 * dump all providers whose component contains the first arg as a substring 13018 */ 13019 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13020 int opti, boolean dumpAll) { 13021 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13022 } 13023 13024 static class ItemMatcher { 13025 ArrayList<ComponentName> components; 13026 ArrayList<String> strings; 13027 ArrayList<Integer> objects; 13028 boolean all; 13029 13030 ItemMatcher() { 13031 all = true; 13032 } 13033 13034 void build(String name) { 13035 ComponentName componentName = ComponentName.unflattenFromString(name); 13036 if (componentName != null) { 13037 if (components == null) { 13038 components = new ArrayList<ComponentName>(); 13039 } 13040 components.add(componentName); 13041 all = false; 13042 } else { 13043 int objectId = 0; 13044 // Not a '/' separated full component name; maybe an object ID? 13045 try { 13046 objectId = Integer.parseInt(name, 16); 13047 if (objects == null) { 13048 objects = new ArrayList<Integer>(); 13049 } 13050 objects.add(objectId); 13051 all = false; 13052 } catch (RuntimeException e) { 13053 // Not an integer; just do string match. 13054 if (strings == null) { 13055 strings = new ArrayList<String>(); 13056 } 13057 strings.add(name); 13058 all = false; 13059 } 13060 } 13061 } 13062 13063 int build(String[] args, int opti) { 13064 for (; opti<args.length; opti++) { 13065 String name = args[opti]; 13066 if ("--".equals(name)) { 13067 return opti+1; 13068 } 13069 build(name); 13070 } 13071 return opti; 13072 } 13073 13074 boolean match(Object object, ComponentName comp) { 13075 if (all) { 13076 return true; 13077 } 13078 if (components != null) { 13079 for (int i=0; i<components.size(); i++) { 13080 if (components.get(i).equals(comp)) { 13081 return true; 13082 } 13083 } 13084 } 13085 if (objects != null) { 13086 for (int i=0; i<objects.size(); i++) { 13087 if (System.identityHashCode(object) == objects.get(i)) { 13088 return true; 13089 } 13090 } 13091 } 13092 if (strings != null) { 13093 String flat = comp.flattenToString(); 13094 for (int i=0; i<strings.size(); i++) { 13095 if (flat.contains(strings.get(i))) { 13096 return true; 13097 } 13098 } 13099 } 13100 return false; 13101 } 13102 } 13103 13104 /** 13105 * There are three things that cmd can be: 13106 * - a flattened component name that matches an existing activity 13107 * - the cmd arg isn't the flattened component name of an existing activity: 13108 * dump all activity whose component contains the cmd as a substring 13109 * - A hex number of the ActivityRecord object instance. 13110 */ 13111 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13112 int opti, boolean dumpAll) { 13113 ArrayList<ActivityRecord> activities; 13114 13115 synchronized (this) { 13116 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13117 } 13118 13119 if (activities.size() <= 0) { 13120 return false; 13121 } 13122 13123 String[] newArgs = new String[args.length - opti]; 13124 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13125 13126 TaskRecord lastTask = null; 13127 boolean needSep = false; 13128 for (int i=activities.size()-1; i>=0; i--) { 13129 ActivityRecord r = activities.get(i); 13130 if (needSep) { 13131 pw.println(); 13132 } 13133 needSep = true; 13134 synchronized (this) { 13135 if (lastTask != r.task) { 13136 lastTask = r.task; 13137 pw.print("TASK "); pw.print(lastTask.affinity); 13138 pw.print(" id="); pw.println(lastTask.taskId); 13139 if (dumpAll) { 13140 lastTask.dump(pw, " "); 13141 } 13142 } 13143 } 13144 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13145 } 13146 return true; 13147 } 13148 13149 /** 13150 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13151 * there is a thread associated with the activity. 13152 */ 13153 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13154 final ActivityRecord r, String[] args, boolean dumpAll) { 13155 String innerPrefix = prefix + " "; 13156 synchronized (this) { 13157 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13158 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13159 pw.print(" pid="); 13160 if (r.app != null) pw.println(r.app.pid); 13161 else pw.println("(not running)"); 13162 if (dumpAll) { 13163 r.dump(pw, innerPrefix); 13164 } 13165 } 13166 if (r.app != null && r.app.thread != null) { 13167 // flush anything that is already in the PrintWriter since the thread is going 13168 // to write to the file descriptor directly 13169 pw.flush(); 13170 try { 13171 TransferPipe tp = new TransferPipe(); 13172 try { 13173 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13174 r.appToken, innerPrefix, args); 13175 tp.go(fd); 13176 } finally { 13177 tp.kill(); 13178 } 13179 } catch (IOException e) { 13180 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13181 } catch (RemoteException e) { 13182 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13183 } 13184 } 13185 } 13186 13187 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13188 int opti, boolean dumpAll, String dumpPackage) { 13189 boolean needSep = false; 13190 boolean onlyHistory = false; 13191 boolean printedAnything = false; 13192 13193 if ("history".equals(dumpPackage)) { 13194 if (opti < args.length && "-s".equals(args[opti])) { 13195 dumpAll = false; 13196 } 13197 onlyHistory = true; 13198 dumpPackage = null; 13199 } 13200 13201 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13202 if (!onlyHistory && dumpAll) { 13203 if (mRegisteredReceivers.size() > 0) { 13204 boolean printed = false; 13205 Iterator it = mRegisteredReceivers.values().iterator(); 13206 while (it.hasNext()) { 13207 ReceiverList r = (ReceiverList)it.next(); 13208 if (dumpPackage != null && (r.app == null || 13209 !dumpPackage.equals(r.app.info.packageName))) { 13210 continue; 13211 } 13212 if (!printed) { 13213 pw.println(" Registered Receivers:"); 13214 needSep = true; 13215 printed = true; 13216 printedAnything = true; 13217 } 13218 pw.print(" * "); pw.println(r); 13219 r.dump(pw, " "); 13220 } 13221 } 13222 13223 if (mReceiverResolver.dump(pw, needSep ? 13224 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13225 " ", dumpPackage, false)) { 13226 needSep = true; 13227 printedAnything = true; 13228 } 13229 } 13230 13231 for (BroadcastQueue q : mBroadcastQueues) { 13232 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13233 printedAnything |= needSep; 13234 } 13235 13236 needSep = true; 13237 13238 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13239 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13240 if (needSep) { 13241 pw.println(); 13242 } 13243 needSep = true; 13244 printedAnything = true; 13245 pw.print(" Sticky broadcasts for user "); 13246 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13247 StringBuilder sb = new StringBuilder(128); 13248 for (Map.Entry<String, ArrayList<Intent>> ent 13249 : mStickyBroadcasts.valueAt(user).entrySet()) { 13250 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13251 if (dumpAll) { 13252 pw.println(":"); 13253 ArrayList<Intent> intents = ent.getValue(); 13254 final int N = intents.size(); 13255 for (int i=0; i<N; i++) { 13256 sb.setLength(0); 13257 sb.append(" Intent: "); 13258 intents.get(i).toShortString(sb, false, true, false, false); 13259 pw.println(sb.toString()); 13260 Bundle bundle = intents.get(i).getExtras(); 13261 if (bundle != null) { 13262 pw.print(" "); 13263 pw.println(bundle.toString()); 13264 } 13265 } 13266 } else { 13267 pw.println(""); 13268 } 13269 } 13270 } 13271 } 13272 13273 if (!onlyHistory && dumpAll) { 13274 pw.println(); 13275 for (BroadcastQueue queue : mBroadcastQueues) { 13276 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13277 + queue.mBroadcastsScheduled); 13278 } 13279 pw.println(" mHandler:"); 13280 mHandler.dump(new PrintWriterPrinter(pw), " "); 13281 needSep = true; 13282 printedAnything = true; 13283 } 13284 13285 if (!printedAnything) { 13286 pw.println(" (nothing)"); 13287 } 13288 } 13289 13290 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13291 int opti, boolean dumpAll, String dumpPackage) { 13292 boolean needSep; 13293 boolean printedAnything = false; 13294 13295 ItemMatcher matcher = new ItemMatcher(); 13296 matcher.build(args, opti); 13297 13298 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13299 13300 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13301 printedAnything |= needSep; 13302 13303 if (mLaunchingProviders.size() > 0) { 13304 boolean printed = false; 13305 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13306 ContentProviderRecord r = mLaunchingProviders.get(i); 13307 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13308 continue; 13309 } 13310 if (!printed) { 13311 if (needSep) pw.println(); 13312 needSep = true; 13313 pw.println(" Launching content providers:"); 13314 printed = true; 13315 printedAnything = true; 13316 } 13317 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13318 pw.println(r); 13319 } 13320 } 13321 13322 if (mGrantedUriPermissions.size() > 0) { 13323 boolean printed = false; 13324 int dumpUid = -2; 13325 if (dumpPackage != null) { 13326 try { 13327 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13328 } catch (NameNotFoundException e) { 13329 dumpUid = -1; 13330 } 13331 } 13332 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13333 int uid = mGrantedUriPermissions.keyAt(i); 13334 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13335 continue; 13336 } 13337 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13338 if (!printed) { 13339 if (needSep) pw.println(); 13340 needSep = true; 13341 pw.println(" Granted Uri Permissions:"); 13342 printed = true; 13343 printedAnything = true; 13344 } 13345 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13346 for (UriPermission perm : perms.values()) { 13347 pw.print(" "); pw.println(perm); 13348 if (dumpAll) { 13349 perm.dump(pw, " "); 13350 } 13351 } 13352 } 13353 } 13354 13355 if (!printedAnything) { 13356 pw.println(" (nothing)"); 13357 } 13358 } 13359 13360 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13361 int opti, boolean dumpAll, String dumpPackage) { 13362 boolean printed = false; 13363 13364 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13365 13366 if (mIntentSenderRecords.size() > 0) { 13367 Iterator<WeakReference<PendingIntentRecord>> it 13368 = mIntentSenderRecords.values().iterator(); 13369 while (it.hasNext()) { 13370 WeakReference<PendingIntentRecord> ref = it.next(); 13371 PendingIntentRecord rec = ref != null ? ref.get(): null; 13372 if (dumpPackage != null && (rec == null 13373 || !dumpPackage.equals(rec.key.packageName))) { 13374 continue; 13375 } 13376 printed = true; 13377 if (rec != null) { 13378 pw.print(" * "); pw.println(rec); 13379 if (dumpAll) { 13380 rec.dump(pw, " "); 13381 } 13382 } else { 13383 pw.print(" * "); pw.println(ref); 13384 } 13385 } 13386 } 13387 13388 if (!printed) { 13389 pw.println(" (nothing)"); 13390 } 13391 } 13392 13393 private static final int dumpProcessList(PrintWriter pw, 13394 ActivityManagerService service, List list, 13395 String prefix, String normalLabel, String persistentLabel, 13396 String dumpPackage) { 13397 int numPers = 0; 13398 final int N = list.size()-1; 13399 for (int i=N; i>=0; i--) { 13400 ProcessRecord r = (ProcessRecord)list.get(i); 13401 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13402 continue; 13403 } 13404 pw.println(String.format("%s%s #%2d: %s", 13405 prefix, (r.persistent ? persistentLabel : normalLabel), 13406 i, r.toString())); 13407 if (r.persistent) { 13408 numPers++; 13409 } 13410 } 13411 return numPers; 13412 } 13413 13414 private static final boolean dumpProcessOomList(PrintWriter pw, 13415 ActivityManagerService service, List<ProcessRecord> origList, 13416 String prefix, String normalLabel, String persistentLabel, 13417 boolean inclDetails, String dumpPackage) { 13418 13419 ArrayList<Pair<ProcessRecord, Integer>> list 13420 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13421 for (int i=0; i<origList.size(); i++) { 13422 ProcessRecord r = origList.get(i); 13423 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13424 continue; 13425 } 13426 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13427 } 13428 13429 if (list.size() <= 0) { 13430 return false; 13431 } 13432 13433 Comparator<Pair<ProcessRecord, Integer>> comparator 13434 = new Comparator<Pair<ProcessRecord, Integer>>() { 13435 @Override 13436 public int compare(Pair<ProcessRecord, Integer> object1, 13437 Pair<ProcessRecord, Integer> object2) { 13438 if (object1.first.setAdj != object2.first.setAdj) { 13439 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13440 } 13441 if (object1.second.intValue() != object2.second.intValue()) { 13442 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13443 } 13444 return 0; 13445 } 13446 }; 13447 13448 Collections.sort(list, comparator); 13449 13450 final long curRealtime = SystemClock.elapsedRealtime(); 13451 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13452 final long curUptime = SystemClock.uptimeMillis(); 13453 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13454 13455 for (int i=list.size()-1; i>=0; i--) { 13456 ProcessRecord r = list.get(i).first; 13457 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13458 char schedGroup; 13459 switch (r.setSchedGroup) { 13460 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13461 schedGroup = 'B'; 13462 break; 13463 case Process.THREAD_GROUP_DEFAULT: 13464 schedGroup = 'F'; 13465 break; 13466 default: 13467 schedGroup = '?'; 13468 break; 13469 } 13470 char foreground; 13471 if (r.foregroundActivities) { 13472 foreground = 'A'; 13473 } else if (r.foregroundServices) { 13474 foreground = 'S'; 13475 } else { 13476 foreground = ' '; 13477 } 13478 String procState = ProcessList.makeProcStateString(r.curProcState); 13479 pw.print(prefix); 13480 pw.print(r.persistent ? persistentLabel : normalLabel); 13481 pw.print(" #"); 13482 int num = (origList.size()-1)-list.get(i).second; 13483 if (num < 10) pw.print(' '); 13484 pw.print(num); 13485 pw.print(": "); 13486 pw.print(oomAdj); 13487 pw.print(' '); 13488 pw.print(schedGroup); 13489 pw.print('/'); 13490 pw.print(foreground); 13491 pw.print('/'); 13492 pw.print(procState); 13493 pw.print(" trm:"); 13494 if (r.trimMemoryLevel < 10) pw.print(' '); 13495 pw.print(r.trimMemoryLevel); 13496 pw.print(' '); 13497 pw.print(r.toShortString()); 13498 pw.print(" ("); 13499 pw.print(r.adjType); 13500 pw.println(')'); 13501 if (r.adjSource != null || r.adjTarget != null) { 13502 pw.print(prefix); 13503 pw.print(" "); 13504 if (r.adjTarget instanceof ComponentName) { 13505 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13506 } else if (r.adjTarget != null) { 13507 pw.print(r.adjTarget.toString()); 13508 } else { 13509 pw.print("{null}"); 13510 } 13511 pw.print("<="); 13512 if (r.adjSource instanceof ProcessRecord) { 13513 pw.print("Proc{"); 13514 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13515 pw.println("}"); 13516 } else if (r.adjSource != null) { 13517 pw.println(r.adjSource.toString()); 13518 } else { 13519 pw.println("{null}"); 13520 } 13521 } 13522 if (inclDetails) { 13523 pw.print(prefix); 13524 pw.print(" "); 13525 pw.print("oom: max="); pw.print(r.maxAdj); 13526 pw.print(" curRaw="); pw.print(r.curRawAdj); 13527 pw.print(" setRaw="); pw.print(r.setRawAdj); 13528 pw.print(" cur="); pw.print(r.curAdj); 13529 pw.print(" set="); pw.println(r.setAdj); 13530 pw.print(prefix); 13531 pw.print(" "); 13532 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13533 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13534 pw.print(" lastPss="); pw.print(r.lastPss); 13535 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13536 pw.print(prefix); 13537 pw.print(" "); 13538 pw.print("cached="); pw.print(r.cached); 13539 pw.print(" empty="); pw.print(r.empty); 13540 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13541 13542 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13543 if (r.lastWakeTime != 0) { 13544 long wtime; 13545 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13546 synchronized (stats) { 13547 wtime = stats.getProcessWakeTime(r.info.uid, 13548 r.pid, curRealtime); 13549 } 13550 long timeUsed = wtime - r.lastWakeTime; 13551 pw.print(prefix); 13552 pw.print(" "); 13553 pw.print("keep awake over "); 13554 TimeUtils.formatDuration(realtimeSince, pw); 13555 pw.print(" used "); 13556 TimeUtils.formatDuration(timeUsed, pw); 13557 pw.print(" ("); 13558 pw.print((timeUsed*100)/realtimeSince); 13559 pw.println("%)"); 13560 } 13561 if (r.lastCpuTime != 0) { 13562 long timeUsed = r.curCpuTime - r.lastCpuTime; 13563 pw.print(prefix); 13564 pw.print(" "); 13565 pw.print("run cpu over "); 13566 TimeUtils.formatDuration(uptimeSince, pw); 13567 pw.print(" used "); 13568 TimeUtils.formatDuration(timeUsed, pw); 13569 pw.print(" ("); 13570 pw.print((timeUsed*100)/uptimeSince); 13571 pw.println("%)"); 13572 } 13573 } 13574 } 13575 } 13576 return true; 13577 } 13578 13579 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13580 ArrayList<ProcessRecord> procs; 13581 synchronized (this) { 13582 if (args != null && args.length > start 13583 && args[start].charAt(0) != '-') { 13584 procs = new ArrayList<ProcessRecord>(); 13585 int pid = -1; 13586 try { 13587 pid = Integer.parseInt(args[start]); 13588 } catch (NumberFormatException e) { 13589 } 13590 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13591 ProcessRecord proc = mLruProcesses.get(i); 13592 if (proc.pid == pid) { 13593 procs.add(proc); 13594 } else if (proc.processName.equals(args[start])) { 13595 procs.add(proc); 13596 } 13597 } 13598 if (procs.size() <= 0) { 13599 return null; 13600 } 13601 } else { 13602 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13603 } 13604 } 13605 return procs; 13606 } 13607 13608 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13609 PrintWriter pw, String[] args) { 13610 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13611 if (procs == null) { 13612 pw.println("No process found for: " + args[0]); 13613 return; 13614 } 13615 13616 long uptime = SystemClock.uptimeMillis(); 13617 long realtime = SystemClock.elapsedRealtime(); 13618 pw.println("Applications Graphics Acceleration Info:"); 13619 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13620 13621 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13622 ProcessRecord r = procs.get(i); 13623 if (r.thread != null) { 13624 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13625 pw.flush(); 13626 try { 13627 TransferPipe tp = new TransferPipe(); 13628 try { 13629 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13630 tp.go(fd); 13631 } finally { 13632 tp.kill(); 13633 } 13634 } catch (IOException e) { 13635 pw.println("Failure while dumping the app: " + r); 13636 pw.flush(); 13637 } catch (RemoteException e) { 13638 pw.println("Got a RemoteException while dumping the app " + r); 13639 pw.flush(); 13640 } 13641 } 13642 } 13643 } 13644 13645 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13646 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13647 if (procs == null) { 13648 pw.println("No process found for: " + args[0]); 13649 return; 13650 } 13651 13652 pw.println("Applications Database Info:"); 13653 13654 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13655 ProcessRecord r = procs.get(i); 13656 if (r.thread != null) { 13657 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13658 pw.flush(); 13659 try { 13660 TransferPipe tp = new TransferPipe(); 13661 try { 13662 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13663 tp.go(fd); 13664 } finally { 13665 tp.kill(); 13666 } 13667 } catch (IOException e) { 13668 pw.println("Failure while dumping the app: " + r); 13669 pw.flush(); 13670 } catch (RemoteException e) { 13671 pw.println("Got a RemoteException while dumping the app " + r); 13672 pw.flush(); 13673 } 13674 } 13675 } 13676 } 13677 13678 final static class MemItem { 13679 final boolean isProc; 13680 final String label; 13681 final String shortLabel; 13682 final long pss; 13683 final int id; 13684 final boolean hasActivities; 13685 ArrayList<MemItem> subitems; 13686 13687 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13688 boolean _hasActivities) { 13689 isProc = true; 13690 label = _label; 13691 shortLabel = _shortLabel; 13692 pss = _pss; 13693 id = _id; 13694 hasActivities = _hasActivities; 13695 } 13696 13697 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13698 isProc = false; 13699 label = _label; 13700 shortLabel = _shortLabel; 13701 pss = _pss; 13702 id = _id; 13703 hasActivities = false; 13704 } 13705 } 13706 13707 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13708 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13709 if (sort && !isCompact) { 13710 Collections.sort(items, new Comparator<MemItem>() { 13711 @Override 13712 public int compare(MemItem lhs, MemItem rhs) { 13713 if (lhs.pss < rhs.pss) { 13714 return 1; 13715 } else if (lhs.pss > rhs.pss) { 13716 return -1; 13717 } 13718 return 0; 13719 } 13720 }); 13721 } 13722 13723 for (int i=0; i<items.size(); i++) { 13724 MemItem mi = items.get(i); 13725 if (!isCompact) { 13726 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13727 } else if (mi.isProc) { 13728 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13729 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13730 pw.println(mi.hasActivities ? ",a" : ",e"); 13731 } else { 13732 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13733 pw.println(mi.pss); 13734 } 13735 if (mi.subitems != null) { 13736 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13737 true, isCompact); 13738 } 13739 } 13740 } 13741 13742 // These are in KB. 13743 static final long[] DUMP_MEM_BUCKETS = new long[] { 13744 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13745 120*1024, 160*1024, 200*1024, 13746 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13747 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13748 }; 13749 13750 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13751 boolean stackLike) { 13752 int start = label.lastIndexOf('.'); 13753 if (start >= 0) start++; 13754 else start = 0; 13755 int end = label.length(); 13756 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13757 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13758 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13759 out.append(bucket); 13760 out.append(stackLike ? "MB." : "MB "); 13761 out.append(label, start, end); 13762 return; 13763 } 13764 } 13765 out.append(memKB/1024); 13766 out.append(stackLike ? "MB." : "MB "); 13767 out.append(label, start, end); 13768 } 13769 13770 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13771 ProcessList.NATIVE_ADJ, 13772 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13773 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13774 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13775 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13776 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13777 }; 13778 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13779 "Native", 13780 "System", "Persistent", "Foreground", 13781 "Visible", "Perceptible", 13782 "Heavy Weight", "Backup", 13783 "A Services", "Home", 13784 "Previous", "B Services", "Cached" 13785 }; 13786 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13787 "native", 13788 "sys", "pers", "fore", 13789 "vis", "percept", 13790 "heavy", "backup", 13791 "servicea", "home", 13792 "prev", "serviceb", "cached" 13793 }; 13794 13795 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13796 long realtime, boolean isCheckinRequest, boolean isCompact) { 13797 if (isCheckinRequest || isCompact) { 13798 // short checkin version 13799 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13800 } else { 13801 pw.println("Applications Memory Usage (kB):"); 13802 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13803 } 13804 } 13805 13806 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13807 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13808 boolean dumpDetails = false; 13809 boolean dumpFullDetails = false; 13810 boolean dumpDalvik = false; 13811 boolean oomOnly = false; 13812 boolean isCompact = false; 13813 boolean localOnly = false; 13814 13815 int opti = 0; 13816 while (opti < args.length) { 13817 String opt = args[opti]; 13818 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13819 break; 13820 } 13821 opti++; 13822 if ("-a".equals(opt)) { 13823 dumpDetails = true; 13824 dumpFullDetails = true; 13825 dumpDalvik = true; 13826 } else if ("-d".equals(opt)) { 13827 dumpDalvik = true; 13828 } else if ("-c".equals(opt)) { 13829 isCompact = true; 13830 } else if ("--oom".equals(opt)) { 13831 oomOnly = true; 13832 } else if ("--local".equals(opt)) { 13833 localOnly = true; 13834 } else if ("-h".equals(opt)) { 13835 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13836 pw.println(" -a: include all available information for each process."); 13837 pw.println(" -d: include dalvik details when dumping process details."); 13838 pw.println(" -c: dump in a compact machine-parseable representation."); 13839 pw.println(" --oom: only show processes organized by oom adj."); 13840 pw.println(" --local: only collect details locally, don't call process."); 13841 pw.println("If [process] is specified it can be the name or "); 13842 pw.println("pid of a specific process to dump."); 13843 return; 13844 } else { 13845 pw.println("Unknown argument: " + opt + "; use -h for help"); 13846 } 13847 } 13848 13849 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13850 long uptime = SystemClock.uptimeMillis(); 13851 long realtime = SystemClock.elapsedRealtime(); 13852 final long[] tmpLong = new long[1]; 13853 13854 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13855 if (procs == null) { 13856 // No Java processes. Maybe they want to print a native process. 13857 if (args != null && args.length > opti 13858 && args[opti].charAt(0) != '-') { 13859 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13860 = new ArrayList<ProcessCpuTracker.Stats>(); 13861 updateCpuStatsNow(); 13862 int findPid = -1; 13863 try { 13864 findPid = Integer.parseInt(args[opti]); 13865 } catch (NumberFormatException e) { 13866 } 13867 synchronized (mProcessCpuTracker) { 13868 final int N = mProcessCpuTracker.countStats(); 13869 for (int i=0; i<N; i++) { 13870 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13871 if (st.pid == findPid || (st.baseName != null 13872 && st.baseName.equals(args[opti]))) { 13873 nativeProcs.add(st); 13874 } 13875 } 13876 } 13877 if (nativeProcs.size() > 0) { 13878 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13879 isCompact); 13880 Debug.MemoryInfo mi = null; 13881 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13882 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13883 final int pid = r.pid; 13884 if (!isCheckinRequest && dumpDetails) { 13885 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13886 } 13887 if (mi == null) { 13888 mi = new Debug.MemoryInfo(); 13889 } 13890 if (dumpDetails || (!brief && !oomOnly)) { 13891 Debug.getMemoryInfo(pid, mi); 13892 } else { 13893 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13894 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13895 } 13896 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13897 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13898 if (isCheckinRequest) { 13899 pw.println(); 13900 } 13901 } 13902 return; 13903 } 13904 } 13905 pw.println("No process found for: " + args[opti]); 13906 return; 13907 } 13908 13909 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13910 dumpDetails = true; 13911 } 13912 13913 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13914 13915 String[] innerArgs = new String[args.length-opti]; 13916 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13917 13918 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13919 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13920 long nativePss=0, dalvikPss=0, otherPss=0; 13921 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13922 13923 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13924 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13925 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13926 13927 long totalPss = 0; 13928 long cachedPss = 0; 13929 13930 Debug.MemoryInfo mi = null; 13931 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13932 final ProcessRecord r = procs.get(i); 13933 final IApplicationThread thread; 13934 final int pid; 13935 final int oomAdj; 13936 final boolean hasActivities; 13937 synchronized (this) { 13938 thread = r.thread; 13939 pid = r.pid; 13940 oomAdj = r.getSetAdjWithServices(); 13941 hasActivities = r.activities.size() > 0; 13942 } 13943 if (thread != null) { 13944 if (!isCheckinRequest && dumpDetails) { 13945 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13946 } 13947 if (mi == null) { 13948 mi = new Debug.MemoryInfo(); 13949 } 13950 if (dumpDetails || (!brief && !oomOnly)) { 13951 Debug.getMemoryInfo(pid, mi); 13952 } else { 13953 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13954 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13955 } 13956 if (dumpDetails) { 13957 if (localOnly) { 13958 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13959 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13960 if (isCheckinRequest) { 13961 pw.println(); 13962 } 13963 } else { 13964 try { 13965 pw.flush(); 13966 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13967 dumpDalvik, innerArgs); 13968 } catch (RemoteException e) { 13969 if (!isCheckinRequest) { 13970 pw.println("Got RemoteException!"); 13971 pw.flush(); 13972 } 13973 } 13974 } 13975 } 13976 13977 final long myTotalPss = mi.getTotalPss(); 13978 final long myTotalUss = mi.getTotalUss(); 13979 13980 synchronized (this) { 13981 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13982 // Record this for posterity if the process has been stable. 13983 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13984 } 13985 } 13986 13987 if (!isCheckinRequest && mi != null) { 13988 totalPss += myTotalPss; 13989 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13990 (hasActivities ? " / activities)" : ")"), 13991 r.processName, myTotalPss, pid, hasActivities); 13992 procMems.add(pssItem); 13993 procMemsMap.put(pid, pssItem); 13994 13995 nativePss += mi.nativePss; 13996 dalvikPss += mi.dalvikPss; 13997 otherPss += mi.otherPss; 13998 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13999 long mem = mi.getOtherPss(j); 14000 miscPss[j] += mem; 14001 otherPss -= mem; 14002 } 14003 14004 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14005 cachedPss += myTotalPss; 14006 } 14007 14008 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14009 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14010 || oomIndex == (oomPss.length-1)) { 14011 oomPss[oomIndex] += myTotalPss; 14012 if (oomProcs[oomIndex] == null) { 14013 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14014 } 14015 oomProcs[oomIndex].add(pssItem); 14016 break; 14017 } 14018 } 14019 } 14020 } 14021 } 14022 14023 long nativeProcTotalPss = 0; 14024 14025 if (!isCheckinRequest && procs.size() > 1) { 14026 // If we are showing aggregations, also look for native processes to 14027 // include so that our aggregations are more accurate. 14028 updateCpuStatsNow(); 14029 synchronized (mProcessCpuTracker) { 14030 final int N = mProcessCpuTracker.countStats(); 14031 for (int i=0; i<N; i++) { 14032 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14033 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14034 if (mi == null) { 14035 mi = new Debug.MemoryInfo(); 14036 } 14037 if (!brief && !oomOnly) { 14038 Debug.getMemoryInfo(st.pid, mi); 14039 } else { 14040 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14041 mi.nativePrivateDirty = (int)tmpLong[0]; 14042 } 14043 14044 final long myTotalPss = mi.getTotalPss(); 14045 totalPss += myTotalPss; 14046 nativeProcTotalPss += myTotalPss; 14047 14048 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14049 st.name, myTotalPss, st.pid, false); 14050 procMems.add(pssItem); 14051 14052 nativePss += mi.nativePss; 14053 dalvikPss += mi.dalvikPss; 14054 otherPss += mi.otherPss; 14055 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14056 long mem = mi.getOtherPss(j); 14057 miscPss[j] += mem; 14058 otherPss -= mem; 14059 } 14060 oomPss[0] += myTotalPss; 14061 if (oomProcs[0] == null) { 14062 oomProcs[0] = new ArrayList<MemItem>(); 14063 } 14064 oomProcs[0].add(pssItem); 14065 } 14066 } 14067 } 14068 14069 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14070 14071 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14072 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14073 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14074 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14075 String label = Debug.MemoryInfo.getOtherLabel(j); 14076 catMems.add(new MemItem(label, label, miscPss[j], j)); 14077 } 14078 14079 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14080 for (int j=0; j<oomPss.length; j++) { 14081 if (oomPss[j] != 0) { 14082 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14083 : DUMP_MEM_OOM_LABEL[j]; 14084 MemItem item = new MemItem(label, label, oomPss[j], 14085 DUMP_MEM_OOM_ADJ[j]); 14086 item.subitems = oomProcs[j]; 14087 oomMems.add(item); 14088 } 14089 } 14090 14091 if (!brief && !oomOnly && !isCompact) { 14092 pw.println(); 14093 pw.println("Total PSS by process:"); 14094 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14095 pw.println(); 14096 } 14097 if (!isCompact) { 14098 pw.println("Total PSS by OOM adjustment:"); 14099 } 14100 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14101 if (!brief && !oomOnly) { 14102 PrintWriter out = categoryPw != null ? categoryPw : pw; 14103 if (!isCompact) { 14104 out.println(); 14105 out.println("Total PSS by category:"); 14106 } 14107 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14108 } 14109 if (!isCompact) { 14110 pw.println(); 14111 } 14112 MemInfoReader memInfo = new MemInfoReader(); 14113 memInfo.readMemInfo(); 14114 if (nativeProcTotalPss > 0) { 14115 synchronized (this) { 14116 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14117 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14118 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14119 nativeProcTotalPss); 14120 } 14121 } 14122 if (!brief) { 14123 if (!isCompact) { 14124 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14125 pw.print(" kB (status "); 14126 switch (mLastMemoryLevel) { 14127 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14128 pw.println("normal)"); 14129 break; 14130 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14131 pw.println("moderate)"); 14132 break; 14133 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14134 pw.println("low)"); 14135 break; 14136 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14137 pw.println("critical)"); 14138 break; 14139 default: 14140 pw.print(mLastMemoryLevel); 14141 pw.println(")"); 14142 break; 14143 } 14144 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14145 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14146 pw.print(cachedPss); pw.print(" cached pss + "); 14147 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14148 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14149 } else { 14150 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14151 pw.print(cachedPss + memInfo.getCachedSizeKb() 14152 + memInfo.getFreeSizeKb()); pw.print(","); 14153 pw.println(totalPss - cachedPss); 14154 } 14155 } 14156 if (!isCompact) { 14157 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14158 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14159 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14160 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14161 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14162 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14163 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14164 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14165 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14166 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14167 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14168 } 14169 if (!brief) { 14170 if (memInfo.getZramTotalSizeKb() != 0) { 14171 if (!isCompact) { 14172 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14173 pw.print(" kB physical used for "); 14174 pw.print(memInfo.getSwapTotalSizeKb() 14175 - memInfo.getSwapFreeSizeKb()); 14176 pw.print(" kB in swap ("); 14177 pw.print(memInfo.getSwapTotalSizeKb()); 14178 pw.println(" kB total swap)"); 14179 } else { 14180 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14181 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14182 pw.println(memInfo.getSwapFreeSizeKb()); 14183 } 14184 } 14185 final int[] SINGLE_LONG_FORMAT = new int[] { 14186 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14187 }; 14188 long[] longOut = new long[1]; 14189 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14190 SINGLE_LONG_FORMAT, null, longOut, null); 14191 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14192 longOut[0] = 0; 14193 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14194 SINGLE_LONG_FORMAT, null, longOut, null); 14195 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14196 longOut[0] = 0; 14197 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14198 SINGLE_LONG_FORMAT, null, longOut, null); 14199 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14200 longOut[0] = 0; 14201 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14202 SINGLE_LONG_FORMAT, null, longOut, null); 14203 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14204 if (!isCompact) { 14205 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14206 pw.print(" KSM: "); pw.print(sharing); 14207 pw.print(" kB saved from shared "); 14208 pw.print(shared); pw.println(" kB"); 14209 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14210 pw.print(voltile); pw.println(" kB volatile"); 14211 } 14212 pw.print(" Tuning: "); 14213 pw.print(ActivityManager.staticGetMemoryClass()); 14214 pw.print(" (large "); 14215 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14216 pw.print("), oom "); 14217 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14218 pw.print(" kB"); 14219 pw.print(", restore limit "); 14220 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14221 pw.print(" kB"); 14222 if (ActivityManager.isLowRamDeviceStatic()) { 14223 pw.print(" (low-ram)"); 14224 } 14225 if (ActivityManager.isHighEndGfx()) { 14226 pw.print(" (high-end-gfx)"); 14227 } 14228 pw.println(); 14229 } else { 14230 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14231 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14232 pw.println(voltile); 14233 pw.print("tuning,"); 14234 pw.print(ActivityManager.staticGetMemoryClass()); 14235 pw.print(','); 14236 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14237 pw.print(','); 14238 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14239 if (ActivityManager.isLowRamDeviceStatic()) { 14240 pw.print(",low-ram"); 14241 } 14242 if (ActivityManager.isHighEndGfx()) { 14243 pw.print(",high-end-gfx"); 14244 } 14245 pw.println(); 14246 } 14247 } 14248 } 14249 } 14250 14251 /** 14252 * Searches array of arguments for the specified string 14253 * @param args array of argument strings 14254 * @param value value to search for 14255 * @return true if the value is contained in the array 14256 */ 14257 private static boolean scanArgs(String[] args, String value) { 14258 if (args != null) { 14259 for (String arg : args) { 14260 if (value.equals(arg)) { 14261 return true; 14262 } 14263 } 14264 } 14265 return false; 14266 } 14267 14268 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14269 ContentProviderRecord cpr, boolean always) { 14270 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14271 14272 if (!inLaunching || always) { 14273 synchronized (cpr) { 14274 cpr.launchingApp = null; 14275 cpr.notifyAll(); 14276 } 14277 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14278 String names[] = cpr.info.authority.split(";"); 14279 for (int j = 0; j < names.length; j++) { 14280 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14281 } 14282 } 14283 14284 for (int i=0; i<cpr.connections.size(); i++) { 14285 ContentProviderConnection conn = cpr.connections.get(i); 14286 if (conn.waiting) { 14287 // If this connection is waiting for the provider, then we don't 14288 // need to mess with its process unless we are always removing 14289 // or for some reason the provider is not currently launching. 14290 if (inLaunching && !always) { 14291 continue; 14292 } 14293 } 14294 ProcessRecord capp = conn.client; 14295 conn.dead = true; 14296 if (conn.stableCount > 0) { 14297 if (!capp.persistent && capp.thread != null 14298 && capp.pid != 0 14299 && capp.pid != MY_PID) { 14300 capp.kill("depends on provider " 14301 + cpr.name.flattenToShortString() 14302 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14303 } 14304 } else if (capp.thread != null && conn.provider.provider != null) { 14305 try { 14306 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14307 } catch (RemoteException e) { 14308 } 14309 // In the protocol here, we don't expect the client to correctly 14310 // clean up this connection, we'll just remove it. 14311 cpr.connections.remove(i); 14312 conn.client.conProviders.remove(conn); 14313 } 14314 } 14315 14316 if (inLaunching && always) { 14317 mLaunchingProviders.remove(cpr); 14318 } 14319 return inLaunching; 14320 } 14321 14322 /** 14323 * Main code for cleaning up a process when it has gone away. This is 14324 * called both as a result of the process dying, or directly when stopping 14325 * a process when running in single process mode. 14326 * 14327 * @return Returns true if the given process has been restarted, so the 14328 * app that was passed in must remain on the process lists. 14329 */ 14330 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14331 boolean restarting, boolean allowRestart, int index) { 14332 if (index >= 0) { 14333 removeLruProcessLocked(app); 14334 ProcessList.remove(app.pid); 14335 } 14336 14337 mProcessesToGc.remove(app); 14338 mPendingPssProcesses.remove(app); 14339 14340 // Dismiss any open dialogs. 14341 if (app.crashDialog != null && !app.forceCrashReport) { 14342 app.crashDialog.dismiss(); 14343 app.crashDialog = null; 14344 } 14345 if (app.anrDialog != null) { 14346 app.anrDialog.dismiss(); 14347 app.anrDialog = null; 14348 } 14349 if (app.waitDialog != null) { 14350 app.waitDialog.dismiss(); 14351 app.waitDialog = null; 14352 } 14353 14354 app.crashing = false; 14355 app.notResponding = false; 14356 14357 app.resetPackageList(mProcessStats); 14358 app.unlinkDeathRecipient(); 14359 app.makeInactive(mProcessStats); 14360 app.waitingToKill = null; 14361 app.forcingToForeground = null; 14362 updateProcessForegroundLocked(app, false, false); 14363 app.foregroundActivities = false; 14364 app.hasShownUi = false; 14365 app.treatLikeActivity = false; 14366 app.hasAboveClient = false; 14367 app.hasClientActivities = false; 14368 14369 mServices.killServicesLocked(app, allowRestart); 14370 14371 boolean restart = false; 14372 14373 // Remove published content providers. 14374 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14375 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14376 final boolean always = app.bad || !allowRestart; 14377 if (removeDyingProviderLocked(app, cpr, always) || always) { 14378 // We left the provider in the launching list, need to 14379 // restart it. 14380 restart = true; 14381 } 14382 14383 cpr.provider = null; 14384 cpr.proc = null; 14385 } 14386 app.pubProviders.clear(); 14387 14388 // Take care of any launching providers waiting for this process. 14389 if (checkAppInLaunchingProvidersLocked(app, false)) { 14390 restart = true; 14391 } 14392 14393 // Unregister from connected content providers. 14394 if (!app.conProviders.isEmpty()) { 14395 for (int i=0; i<app.conProviders.size(); i++) { 14396 ContentProviderConnection conn = app.conProviders.get(i); 14397 conn.provider.connections.remove(conn); 14398 } 14399 app.conProviders.clear(); 14400 } 14401 14402 // At this point there may be remaining entries in mLaunchingProviders 14403 // where we were the only one waiting, so they are no longer of use. 14404 // Look for these and clean up if found. 14405 // XXX Commented out for now. Trying to figure out a way to reproduce 14406 // the actual situation to identify what is actually going on. 14407 if (false) { 14408 for (int i=0; i<mLaunchingProviders.size(); i++) { 14409 ContentProviderRecord cpr = (ContentProviderRecord) 14410 mLaunchingProviders.get(i); 14411 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14412 synchronized (cpr) { 14413 cpr.launchingApp = null; 14414 cpr.notifyAll(); 14415 } 14416 } 14417 } 14418 } 14419 14420 skipCurrentReceiverLocked(app); 14421 14422 // Unregister any receivers. 14423 for (int i=app.receivers.size()-1; i>=0; i--) { 14424 removeReceiverLocked(app.receivers.valueAt(i)); 14425 } 14426 app.receivers.clear(); 14427 14428 // If the app is undergoing backup, tell the backup manager about it 14429 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14430 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14431 + mBackupTarget.appInfo + " died during backup"); 14432 try { 14433 IBackupManager bm = IBackupManager.Stub.asInterface( 14434 ServiceManager.getService(Context.BACKUP_SERVICE)); 14435 bm.agentDisconnected(app.info.packageName); 14436 } catch (RemoteException e) { 14437 // can't happen; backup manager is local 14438 } 14439 } 14440 14441 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14442 ProcessChangeItem item = mPendingProcessChanges.get(i); 14443 if (item.pid == app.pid) { 14444 mPendingProcessChanges.remove(i); 14445 mAvailProcessChanges.add(item); 14446 } 14447 } 14448 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14449 14450 // If the caller is restarting this app, then leave it in its 14451 // current lists and let the caller take care of it. 14452 if (restarting) { 14453 return false; 14454 } 14455 14456 if (!app.persistent || app.isolated) { 14457 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14458 "Removing non-persistent process during cleanup: " + app); 14459 mProcessNames.remove(app.processName, app.uid); 14460 mIsolatedProcesses.remove(app.uid); 14461 if (mHeavyWeightProcess == app) { 14462 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14463 mHeavyWeightProcess.userId, 0)); 14464 mHeavyWeightProcess = null; 14465 } 14466 } else if (!app.removed) { 14467 // This app is persistent, so we need to keep its record around. 14468 // If it is not already on the pending app list, add it there 14469 // and start a new process for it. 14470 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14471 mPersistentStartingProcesses.add(app); 14472 restart = true; 14473 } 14474 } 14475 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14476 "Clean-up removing on hold: " + app); 14477 mProcessesOnHold.remove(app); 14478 14479 if (app == mHomeProcess) { 14480 mHomeProcess = null; 14481 } 14482 if (app == mPreviousProcess) { 14483 mPreviousProcess = null; 14484 } 14485 14486 if (restart && !app.isolated) { 14487 // We have components that still need to be running in the 14488 // process, so re-launch it. 14489 if (index < 0) { 14490 ProcessList.remove(app.pid); 14491 } 14492 mProcessNames.put(app.processName, app.uid, app); 14493 startProcessLocked(app, "restart", app.processName); 14494 return true; 14495 } else if (app.pid > 0 && app.pid != MY_PID) { 14496 // Goodbye! 14497 boolean removed; 14498 synchronized (mPidsSelfLocked) { 14499 mPidsSelfLocked.remove(app.pid); 14500 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14501 } 14502 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14503 if (app.isolated) { 14504 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14505 } 14506 app.setPid(0); 14507 } 14508 return false; 14509 } 14510 14511 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14512 // Look through the content providers we are waiting to have launched, 14513 // and if any run in this process then either schedule a restart of 14514 // the process or kill the client waiting for it if this process has 14515 // gone bad. 14516 int NL = mLaunchingProviders.size(); 14517 boolean restart = false; 14518 for (int i=0; i<NL; i++) { 14519 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14520 if (cpr.launchingApp == app) { 14521 if (!alwaysBad && !app.bad) { 14522 restart = true; 14523 } else { 14524 removeDyingProviderLocked(app, cpr, true); 14525 // cpr should have been removed from mLaunchingProviders 14526 NL = mLaunchingProviders.size(); 14527 i--; 14528 } 14529 } 14530 } 14531 return restart; 14532 } 14533 14534 // ========================================================= 14535 // SERVICES 14536 // ========================================================= 14537 14538 @Override 14539 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14540 int flags) { 14541 enforceNotIsolatedCaller("getServices"); 14542 synchronized (this) { 14543 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14544 } 14545 } 14546 14547 @Override 14548 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14549 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14550 synchronized (this) { 14551 return mServices.getRunningServiceControlPanelLocked(name); 14552 } 14553 } 14554 14555 @Override 14556 public ComponentName startService(IApplicationThread caller, Intent service, 14557 String resolvedType, int userId) { 14558 enforceNotIsolatedCaller("startService"); 14559 // Refuse possible leaked file descriptors 14560 if (service != null && service.hasFileDescriptors() == true) { 14561 throw new IllegalArgumentException("File descriptors passed in Intent"); 14562 } 14563 14564 if (DEBUG_SERVICE) 14565 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14566 synchronized(this) { 14567 final int callingPid = Binder.getCallingPid(); 14568 final int callingUid = Binder.getCallingUid(); 14569 final long origId = Binder.clearCallingIdentity(); 14570 ComponentName res = mServices.startServiceLocked(caller, service, 14571 resolvedType, callingPid, callingUid, userId); 14572 Binder.restoreCallingIdentity(origId); 14573 return res; 14574 } 14575 } 14576 14577 ComponentName startServiceInPackage(int uid, 14578 Intent service, String resolvedType, int userId) { 14579 synchronized(this) { 14580 if (DEBUG_SERVICE) 14581 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14582 final long origId = Binder.clearCallingIdentity(); 14583 ComponentName res = mServices.startServiceLocked(null, service, 14584 resolvedType, -1, uid, userId); 14585 Binder.restoreCallingIdentity(origId); 14586 return res; 14587 } 14588 } 14589 14590 @Override 14591 public int stopService(IApplicationThread caller, Intent service, 14592 String resolvedType, int userId) { 14593 enforceNotIsolatedCaller("stopService"); 14594 // Refuse possible leaked file descriptors 14595 if (service != null && service.hasFileDescriptors() == true) { 14596 throw new IllegalArgumentException("File descriptors passed in Intent"); 14597 } 14598 14599 synchronized(this) { 14600 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14601 } 14602 } 14603 14604 @Override 14605 public IBinder peekService(Intent service, String resolvedType) { 14606 enforceNotIsolatedCaller("peekService"); 14607 // Refuse possible leaked file descriptors 14608 if (service != null && service.hasFileDescriptors() == true) { 14609 throw new IllegalArgumentException("File descriptors passed in Intent"); 14610 } 14611 synchronized(this) { 14612 return mServices.peekServiceLocked(service, resolvedType); 14613 } 14614 } 14615 14616 @Override 14617 public boolean stopServiceToken(ComponentName className, IBinder token, 14618 int startId) { 14619 synchronized(this) { 14620 return mServices.stopServiceTokenLocked(className, token, startId); 14621 } 14622 } 14623 14624 @Override 14625 public void setServiceForeground(ComponentName className, IBinder token, 14626 int id, Notification notification, boolean removeNotification) { 14627 synchronized(this) { 14628 mServices.setServiceForegroundLocked(className, token, id, notification, 14629 removeNotification); 14630 } 14631 } 14632 14633 @Override 14634 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14635 boolean requireFull, String name, String callerPackage) { 14636 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14637 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14638 } 14639 14640 int unsafeConvertIncomingUser(int userId) { 14641 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14642 ? mCurrentUserId : userId; 14643 } 14644 14645 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14646 int allowMode, String name, String callerPackage) { 14647 final int callingUserId = UserHandle.getUserId(callingUid); 14648 if (callingUserId == userId) { 14649 return userId; 14650 } 14651 14652 // Note that we may be accessing mCurrentUserId outside of a lock... 14653 // shouldn't be a big deal, if this is being called outside 14654 // of a locked context there is intrinsically a race with 14655 // the value the caller will receive and someone else changing it. 14656 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14657 // we will switch to the calling user if access to the current user fails. 14658 int targetUserId = unsafeConvertIncomingUser(userId); 14659 14660 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14661 final boolean allow; 14662 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14663 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14664 // If the caller has this permission, they always pass go. And collect $200. 14665 allow = true; 14666 } else if (allowMode == ALLOW_FULL_ONLY) { 14667 // We require full access, sucks to be you. 14668 allow = false; 14669 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14670 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14671 // If the caller does not have either permission, they are always doomed. 14672 allow = false; 14673 } else if (allowMode == ALLOW_NON_FULL) { 14674 // We are blanket allowing non-full access, you lucky caller! 14675 allow = true; 14676 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14677 // We may or may not allow this depending on whether the two users are 14678 // in the same profile. 14679 synchronized (mUserProfileGroupIdsSelfLocked) { 14680 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14681 UserInfo.NO_PROFILE_GROUP_ID); 14682 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14683 UserInfo.NO_PROFILE_GROUP_ID); 14684 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14685 && callingProfile == targetProfile; 14686 } 14687 } else { 14688 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14689 } 14690 if (!allow) { 14691 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14692 // In this case, they would like to just execute as their 14693 // owner user instead of failing. 14694 targetUserId = callingUserId; 14695 } else { 14696 StringBuilder builder = new StringBuilder(128); 14697 builder.append("Permission Denial: "); 14698 builder.append(name); 14699 if (callerPackage != null) { 14700 builder.append(" from "); 14701 builder.append(callerPackage); 14702 } 14703 builder.append(" asks to run as user "); 14704 builder.append(userId); 14705 builder.append(" but is calling from user "); 14706 builder.append(UserHandle.getUserId(callingUid)); 14707 builder.append("; this requires "); 14708 builder.append(INTERACT_ACROSS_USERS_FULL); 14709 if (allowMode != ALLOW_FULL_ONLY) { 14710 builder.append(" or "); 14711 builder.append(INTERACT_ACROSS_USERS); 14712 } 14713 String msg = builder.toString(); 14714 Slog.w(TAG, msg); 14715 throw new SecurityException(msg); 14716 } 14717 } 14718 } 14719 if (!allowAll && targetUserId < 0) { 14720 throw new IllegalArgumentException( 14721 "Call does not support special user #" + targetUserId); 14722 } 14723 // Check shell permission 14724 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14725 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14726 targetUserId)) { 14727 throw new SecurityException("Shell does not have permission to access user " 14728 + targetUserId + "\n " + Debug.getCallers(3)); 14729 } 14730 } 14731 return targetUserId; 14732 } 14733 14734 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14735 String className, int flags) { 14736 boolean result = false; 14737 // For apps that don't have pre-defined UIDs, check for permission 14738 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14739 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14740 if (ActivityManager.checkUidPermission( 14741 INTERACT_ACROSS_USERS, 14742 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14743 ComponentName comp = new ComponentName(aInfo.packageName, className); 14744 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14745 + " requests FLAG_SINGLE_USER, but app does not hold " 14746 + INTERACT_ACROSS_USERS; 14747 Slog.w(TAG, msg); 14748 throw new SecurityException(msg); 14749 } 14750 // Permission passed 14751 result = true; 14752 } 14753 } else if ("system".equals(componentProcessName)) { 14754 result = true; 14755 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14756 // Phone app and persistent apps are allowed to export singleuser providers. 14757 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14758 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14759 } 14760 if (DEBUG_MU) { 14761 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14762 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14763 } 14764 return result; 14765 } 14766 14767 /** 14768 * Checks to see if the caller is in the same app as the singleton 14769 * component, or the component is in a special app. It allows special apps 14770 * to export singleton components but prevents exporting singleton 14771 * components for regular apps. 14772 */ 14773 boolean isValidSingletonCall(int callingUid, int componentUid) { 14774 int componentAppId = UserHandle.getAppId(componentUid); 14775 return UserHandle.isSameApp(callingUid, componentUid) 14776 || componentAppId == Process.SYSTEM_UID 14777 || componentAppId == Process.PHONE_UID 14778 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14779 == PackageManager.PERMISSION_GRANTED; 14780 } 14781 14782 public int bindService(IApplicationThread caller, IBinder token, 14783 Intent service, String resolvedType, 14784 IServiceConnection connection, int flags, int userId) { 14785 enforceNotIsolatedCaller("bindService"); 14786 14787 // Refuse possible leaked file descriptors 14788 if (service != null && service.hasFileDescriptors() == true) { 14789 throw new IllegalArgumentException("File descriptors passed in Intent"); 14790 } 14791 14792 synchronized(this) { 14793 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14794 connection, flags, userId); 14795 } 14796 } 14797 14798 public boolean unbindService(IServiceConnection connection) { 14799 synchronized (this) { 14800 return mServices.unbindServiceLocked(connection); 14801 } 14802 } 14803 14804 public void publishService(IBinder token, Intent intent, IBinder service) { 14805 // Refuse possible leaked file descriptors 14806 if (intent != null && intent.hasFileDescriptors() == true) { 14807 throw new IllegalArgumentException("File descriptors passed in Intent"); 14808 } 14809 14810 synchronized(this) { 14811 if (!(token instanceof ServiceRecord)) { 14812 throw new IllegalArgumentException("Invalid service token"); 14813 } 14814 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14815 } 14816 } 14817 14818 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14819 // Refuse possible leaked file descriptors 14820 if (intent != null && intent.hasFileDescriptors() == true) { 14821 throw new IllegalArgumentException("File descriptors passed in Intent"); 14822 } 14823 14824 synchronized(this) { 14825 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14826 } 14827 } 14828 14829 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14830 synchronized(this) { 14831 if (!(token instanceof ServiceRecord)) { 14832 throw new IllegalArgumentException("Invalid service token"); 14833 } 14834 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14835 } 14836 } 14837 14838 // ========================================================= 14839 // BACKUP AND RESTORE 14840 // ========================================================= 14841 14842 // Cause the target app to be launched if necessary and its backup agent 14843 // instantiated. The backup agent will invoke backupAgentCreated() on the 14844 // activity manager to announce its creation. 14845 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14846 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14847 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14848 14849 synchronized(this) { 14850 // !!! TODO: currently no check here that we're already bound 14851 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14852 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14853 synchronized (stats) { 14854 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14855 } 14856 14857 // Backup agent is now in use, its package can't be stopped. 14858 try { 14859 AppGlobals.getPackageManager().setPackageStoppedState( 14860 app.packageName, false, UserHandle.getUserId(app.uid)); 14861 } catch (RemoteException e) { 14862 } catch (IllegalArgumentException e) { 14863 Slog.w(TAG, "Failed trying to unstop package " 14864 + app.packageName + ": " + e); 14865 } 14866 14867 BackupRecord r = new BackupRecord(ss, app, backupMode); 14868 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14869 ? new ComponentName(app.packageName, app.backupAgentName) 14870 : new ComponentName("android", "FullBackupAgent"); 14871 // startProcessLocked() returns existing proc's record if it's already running 14872 ProcessRecord proc = startProcessLocked(app.processName, app, 14873 false, 0, "backup", hostingName, false, false, false); 14874 if (proc == null) { 14875 Slog.e(TAG, "Unable to start backup agent process " + r); 14876 return false; 14877 } 14878 14879 r.app = proc; 14880 mBackupTarget = r; 14881 mBackupAppName = app.packageName; 14882 14883 // Try not to kill the process during backup 14884 updateOomAdjLocked(proc); 14885 14886 // If the process is already attached, schedule the creation of the backup agent now. 14887 // If it is not yet live, this will be done when it attaches to the framework. 14888 if (proc.thread != null) { 14889 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14890 try { 14891 proc.thread.scheduleCreateBackupAgent(app, 14892 compatibilityInfoForPackageLocked(app), backupMode); 14893 } catch (RemoteException e) { 14894 // Will time out on the backup manager side 14895 } 14896 } else { 14897 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14898 } 14899 // Invariants: at this point, the target app process exists and the application 14900 // is either already running or in the process of coming up. mBackupTarget and 14901 // mBackupAppName describe the app, so that when it binds back to the AM we 14902 // know that it's scheduled for a backup-agent operation. 14903 } 14904 14905 return true; 14906 } 14907 14908 @Override 14909 public void clearPendingBackup() { 14910 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14911 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14912 14913 synchronized (this) { 14914 mBackupTarget = null; 14915 mBackupAppName = null; 14916 } 14917 } 14918 14919 // A backup agent has just come up 14920 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14921 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14922 + " = " + agent); 14923 14924 synchronized(this) { 14925 if (!agentPackageName.equals(mBackupAppName)) { 14926 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14927 return; 14928 } 14929 } 14930 14931 long oldIdent = Binder.clearCallingIdentity(); 14932 try { 14933 IBackupManager bm = IBackupManager.Stub.asInterface( 14934 ServiceManager.getService(Context.BACKUP_SERVICE)); 14935 bm.agentConnected(agentPackageName, agent); 14936 } catch (RemoteException e) { 14937 // can't happen; the backup manager service is local 14938 } catch (Exception e) { 14939 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14940 e.printStackTrace(); 14941 } finally { 14942 Binder.restoreCallingIdentity(oldIdent); 14943 } 14944 } 14945 14946 // done with this agent 14947 public void unbindBackupAgent(ApplicationInfo appInfo) { 14948 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14949 if (appInfo == null) { 14950 Slog.w(TAG, "unbind backup agent for null app"); 14951 return; 14952 } 14953 14954 synchronized(this) { 14955 try { 14956 if (mBackupAppName == null) { 14957 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14958 return; 14959 } 14960 14961 if (!mBackupAppName.equals(appInfo.packageName)) { 14962 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14963 return; 14964 } 14965 14966 // Not backing this app up any more; reset its OOM adjustment 14967 final ProcessRecord proc = mBackupTarget.app; 14968 updateOomAdjLocked(proc); 14969 14970 // If the app crashed during backup, 'thread' will be null here 14971 if (proc.thread != null) { 14972 try { 14973 proc.thread.scheduleDestroyBackupAgent(appInfo, 14974 compatibilityInfoForPackageLocked(appInfo)); 14975 } catch (Exception e) { 14976 Slog.e(TAG, "Exception when unbinding backup agent:"); 14977 e.printStackTrace(); 14978 } 14979 } 14980 } finally { 14981 mBackupTarget = null; 14982 mBackupAppName = null; 14983 } 14984 } 14985 } 14986 // ========================================================= 14987 // BROADCASTS 14988 // ========================================================= 14989 14990 private final List getStickiesLocked(String action, IntentFilter filter, 14991 List cur, int userId) { 14992 final ContentResolver resolver = mContext.getContentResolver(); 14993 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14994 if (stickies == null) { 14995 return cur; 14996 } 14997 final ArrayList<Intent> list = stickies.get(action); 14998 if (list == null) { 14999 return cur; 15000 } 15001 int N = list.size(); 15002 for (int i=0; i<N; i++) { 15003 Intent intent = list.get(i); 15004 if (filter.match(resolver, intent, true, TAG) >= 0) { 15005 if (cur == null) { 15006 cur = new ArrayList<Intent>(); 15007 } 15008 cur.add(intent); 15009 } 15010 } 15011 return cur; 15012 } 15013 15014 boolean isPendingBroadcastProcessLocked(int pid) { 15015 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15016 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15017 } 15018 15019 void skipPendingBroadcastLocked(int pid) { 15020 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15021 for (BroadcastQueue queue : mBroadcastQueues) { 15022 queue.skipPendingBroadcastLocked(pid); 15023 } 15024 } 15025 15026 // The app just attached; send any pending broadcasts that it should receive 15027 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15028 boolean didSomething = false; 15029 for (BroadcastQueue queue : mBroadcastQueues) { 15030 didSomething |= queue.sendPendingBroadcastsLocked(app); 15031 } 15032 return didSomething; 15033 } 15034 15035 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15036 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15037 enforceNotIsolatedCaller("registerReceiver"); 15038 int callingUid; 15039 int callingPid; 15040 synchronized(this) { 15041 ProcessRecord callerApp = null; 15042 if (caller != null) { 15043 callerApp = getRecordForAppLocked(caller); 15044 if (callerApp == null) { 15045 throw new SecurityException( 15046 "Unable to find app for caller " + caller 15047 + " (pid=" + Binder.getCallingPid() 15048 + ") when registering receiver " + receiver); 15049 } 15050 if (callerApp.info.uid != Process.SYSTEM_UID && 15051 !callerApp.pkgList.containsKey(callerPackage) && 15052 !"android".equals(callerPackage)) { 15053 throw new SecurityException("Given caller package " + callerPackage 15054 + " is not running in process " + callerApp); 15055 } 15056 callingUid = callerApp.info.uid; 15057 callingPid = callerApp.pid; 15058 } else { 15059 callerPackage = null; 15060 callingUid = Binder.getCallingUid(); 15061 callingPid = Binder.getCallingPid(); 15062 } 15063 15064 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15065 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15066 15067 List allSticky = null; 15068 15069 // Look for any matching sticky broadcasts... 15070 Iterator actions = filter.actionsIterator(); 15071 if (actions != null) { 15072 while (actions.hasNext()) { 15073 String action = (String)actions.next(); 15074 allSticky = getStickiesLocked(action, filter, allSticky, 15075 UserHandle.USER_ALL); 15076 allSticky = getStickiesLocked(action, filter, allSticky, 15077 UserHandle.getUserId(callingUid)); 15078 } 15079 } else { 15080 allSticky = getStickiesLocked(null, filter, allSticky, 15081 UserHandle.USER_ALL); 15082 allSticky = getStickiesLocked(null, filter, allSticky, 15083 UserHandle.getUserId(callingUid)); 15084 } 15085 15086 // The first sticky in the list is returned directly back to 15087 // the client. 15088 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15089 15090 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15091 + ": " + sticky); 15092 15093 if (receiver == null) { 15094 return sticky; 15095 } 15096 15097 ReceiverList rl 15098 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15099 if (rl == null) { 15100 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15101 userId, receiver); 15102 if (rl.app != null) { 15103 rl.app.receivers.add(rl); 15104 } else { 15105 try { 15106 receiver.asBinder().linkToDeath(rl, 0); 15107 } catch (RemoteException e) { 15108 return sticky; 15109 } 15110 rl.linkedToDeath = true; 15111 } 15112 mRegisteredReceivers.put(receiver.asBinder(), rl); 15113 } else if (rl.uid != callingUid) { 15114 throw new IllegalArgumentException( 15115 "Receiver requested to register for uid " + callingUid 15116 + " was previously registered for uid " + rl.uid); 15117 } else if (rl.pid != callingPid) { 15118 throw new IllegalArgumentException( 15119 "Receiver requested to register for pid " + callingPid 15120 + " was previously registered for pid " + rl.pid); 15121 } else if (rl.userId != userId) { 15122 throw new IllegalArgumentException( 15123 "Receiver requested to register for user " + userId 15124 + " was previously registered for user " + rl.userId); 15125 } 15126 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15127 permission, callingUid, userId); 15128 rl.add(bf); 15129 if (!bf.debugCheck()) { 15130 Slog.w(TAG, "==> For Dynamic broadast"); 15131 } 15132 mReceiverResolver.addFilter(bf); 15133 15134 // Enqueue broadcasts for all existing stickies that match 15135 // this filter. 15136 if (allSticky != null) { 15137 ArrayList receivers = new ArrayList(); 15138 receivers.add(bf); 15139 15140 int N = allSticky.size(); 15141 for (int i=0; i<N; i++) { 15142 Intent intent = (Intent)allSticky.get(i); 15143 BroadcastQueue queue = broadcastQueueForIntent(intent); 15144 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15145 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15146 null, null, false, true, true, -1); 15147 queue.enqueueParallelBroadcastLocked(r); 15148 queue.scheduleBroadcastsLocked(); 15149 } 15150 } 15151 15152 return sticky; 15153 } 15154 } 15155 15156 public void unregisterReceiver(IIntentReceiver receiver) { 15157 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15158 15159 final long origId = Binder.clearCallingIdentity(); 15160 try { 15161 boolean doTrim = false; 15162 15163 synchronized(this) { 15164 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15165 if (rl != null) { 15166 if (rl.curBroadcast != null) { 15167 BroadcastRecord r = rl.curBroadcast; 15168 final boolean doNext = finishReceiverLocked( 15169 receiver.asBinder(), r.resultCode, r.resultData, 15170 r.resultExtras, r.resultAbort); 15171 if (doNext) { 15172 doTrim = true; 15173 r.queue.processNextBroadcast(false); 15174 } 15175 } 15176 15177 if (rl.app != null) { 15178 rl.app.receivers.remove(rl); 15179 } 15180 removeReceiverLocked(rl); 15181 if (rl.linkedToDeath) { 15182 rl.linkedToDeath = false; 15183 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15184 } 15185 } 15186 } 15187 15188 // If we actually concluded any broadcasts, we might now be able 15189 // to trim the recipients' apps from our working set 15190 if (doTrim) { 15191 trimApplications(); 15192 return; 15193 } 15194 15195 } finally { 15196 Binder.restoreCallingIdentity(origId); 15197 } 15198 } 15199 15200 void removeReceiverLocked(ReceiverList rl) { 15201 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15202 int N = rl.size(); 15203 for (int i=0; i<N; i++) { 15204 mReceiverResolver.removeFilter(rl.get(i)); 15205 } 15206 } 15207 15208 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15209 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15210 ProcessRecord r = mLruProcesses.get(i); 15211 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15212 try { 15213 r.thread.dispatchPackageBroadcast(cmd, packages); 15214 } catch (RemoteException ex) { 15215 } 15216 } 15217 } 15218 } 15219 15220 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15221 int callingUid, int[] users) { 15222 List<ResolveInfo> receivers = null; 15223 try { 15224 HashSet<ComponentName> singleUserReceivers = null; 15225 boolean scannedFirstReceivers = false; 15226 for (int user : users) { 15227 // Skip users that have Shell restrictions 15228 if (callingUid == Process.SHELL_UID 15229 && getUserManagerLocked().hasUserRestriction( 15230 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15231 continue; 15232 } 15233 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15234 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15235 if (user != 0 && newReceivers != null) { 15236 // If this is not the primary user, we need to check for 15237 // any receivers that should be filtered out. 15238 for (int i=0; i<newReceivers.size(); i++) { 15239 ResolveInfo ri = newReceivers.get(i); 15240 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15241 newReceivers.remove(i); 15242 i--; 15243 } 15244 } 15245 } 15246 if (newReceivers != null && newReceivers.size() == 0) { 15247 newReceivers = null; 15248 } 15249 if (receivers == null) { 15250 receivers = newReceivers; 15251 } else if (newReceivers != null) { 15252 // We need to concatenate the additional receivers 15253 // found with what we have do far. This would be easy, 15254 // but we also need to de-dup any receivers that are 15255 // singleUser. 15256 if (!scannedFirstReceivers) { 15257 // Collect any single user receivers we had already retrieved. 15258 scannedFirstReceivers = true; 15259 for (int i=0; i<receivers.size(); i++) { 15260 ResolveInfo ri = receivers.get(i); 15261 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15262 ComponentName cn = new ComponentName( 15263 ri.activityInfo.packageName, ri.activityInfo.name); 15264 if (singleUserReceivers == null) { 15265 singleUserReceivers = new HashSet<ComponentName>(); 15266 } 15267 singleUserReceivers.add(cn); 15268 } 15269 } 15270 } 15271 // Add the new results to the existing results, tracking 15272 // and de-dupping single user receivers. 15273 for (int i=0; i<newReceivers.size(); i++) { 15274 ResolveInfo ri = newReceivers.get(i); 15275 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15276 ComponentName cn = new ComponentName( 15277 ri.activityInfo.packageName, ri.activityInfo.name); 15278 if (singleUserReceivers == null) { 15279 singleUserReceivers = new HashSet<ComponentName>(); 15280 } 15281 if (!singleUserReceivers.contains(cn)) { 15282 singleUserReceivers.add(cn); 15283 receivers.add(ri); 15284 } 15285 } else { 15286 receivers.add(ri); 15287 } 15288 } 15289 } 15290 } 15291 } catch (RemoteException ex) { 15292 // pm is in same process, this will never happen. 15293 } 15294 return receivers; 15295 } 15296 15297 private final int broadcastIntentLocked(ProcessRecord callerApp, 15298 String callerPackage, Intent intent, String resolvedType, 15299 IIntentReceiver resultTo, int resultCode, String resultData, 15300 Bundle map, String requiredPermission, int appOp, 15301 boolean ordered, boolean sticky, int callingPid, int callingUid, 15302 int userId) { 15303 intent = new Intent(intent); 15304 15305 // By default broadcasts do not go to stopped apps. 15306 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15307 15308 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15309 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15310 + " ordered=" + ordered + " userid=" + userId); 15311 if ((resultTo != null) && !ordered) { 15312 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15313 } 15314 15315 userId = handleIncomingUser(callingPid, callingUid, userId, 15316 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15317 15318 // Make sure that the user who is receiving this broadcast is started. 15319 // If not, we will just skip it. 15320 15321 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15322 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15323 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15324 Slog.w(TAG, "Skipping broadcast of " + intent 15325 + ": user " + userId + " is stopped"); 15326 return ActivityManager.BROADCAST_SUCCESS; 15327 } 15328 } 15329 15330 /* 15331 * Prevent non-system code (defined here to be non-persistent 15332 * processes) from sending protected broadcasts. 15333 */ 15334 int callingAppId = UserHandle.getAppId(callingUid); 15335 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15336 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15337 || callingAppId == Process.NFC_UID || callingUid == 0) { 15338 // Always okay. 15339 } else if (callerApp == null || !callerApp.persistent) { 15340 try { 15341 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15342 intent.getAction())) { 15343 String msg = "Permission Denial: not allowed to send broadcast " 15344 + intent.getAction() + " from pid=" 15345 + callingPid + ", uid=" + callingUid; 15346 Slog.w(TAG, msg); 15347 throw new SecurityException(msg); 15348 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15349 // Special case for compatibility: we don't want apps to send this, 15350 // but historically it has not been protected and apps may be using it 15351 // to poke their own app widget. So, instead of making it protected, 15352 // just limit it to the caller. 15353 if (callerApp == null) { 15354 String msg = "Permission Denial: not allowed to send broadcast " 15355 + intent.getAction() + " from unknown caller."; 15356 Slog.w(TAG, msg); 15357 throw new SecurityException(msg); 15358 } else if (intent.getComponent() != null) { 15359 // They are good enough to send to an explicit component... verify 15360 // it is being sent to the calling app. 15361 if (!intent.getComponent().getPackageName().equals( 15362 callerApp.info.packageName)) { 15363 String msg = "Permission Denial: not allowed to send broadcast " 15364 + intent.getAction() + " to " 15365 + intent.getComponent().getPackageName() + " from " 15366 + callerApp.info.packageName; 15367 Slog.w(TAG, msg); 15368 throw new SecurityException(msg); 15369 } 15370 } else { 15371 // Limit broadcast to their own package. 15372 intent.setPackage(callerApp.info.packageName); 15373 } 15374 } 15375 } catch (RemoteException e) { 15376 Slog.w(TAG, "Remote exception", e); 15377 return ActivityManager.BROADCAST_SUCCESS; 15378 } 15379 } 15380 15381 // Handle special intents: if this broadcast is from the package 15382 // manager about a package being removed, we need to remove all of 15383 // its activities from the history stack. 15384 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15385 intent.getAction()); 15386 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15387 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15388 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15389 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15390 || uidRemoved) { 15391 if (checkComponentPermission( 15392 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15393 callingPid, callingUid, -1, true) 15394 == PackageManager.PERMISSION_GRANTED) { 15395 if (uidRemoved) { 15396 final Bundle intentExtras = intent.getExtras(); 15397 final int uid = intentExtras != null 15398 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15399 if (uid >= 0) { 15400 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15401 synchronized (bs) { 15402 bs.removeUidStatsLocked(uid); 15403 } 15404 mAppOpsService.uidRemoved(uid); 15405 } 15406 } else { 15407 // If resources are unavailable just force stop all 15408 // those packages and flush the attribute cache as well. 15409 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15410 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15411 if (list != null && (list.length > 0)) { 15412 for (String pkg : list) { 15413 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15414 "storage unmount"); 15415 } 15416 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15417 sendPackageBroadcastLocked( 15418 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15419 } 15420 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15421 intent.getAction())) { 15422 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15423 } else { 15424 Uri data = intent.getData(); 15425 String ssp; 15426 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15427 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15428 intent.getAction()); 15429 boolean fullUninstall = removed && 15430 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15431 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15432 forceStopPackageLocked(ssp, UserHandle.getAppId( 15433 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15434 false, fullUninstall, userId, 15435 removed ? "pkg removed" : "pkg changed"); 15436 } 15437 if (removed) { 15438 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15439 new String[] {ssp}, userId); 15440 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15441 mAppOpsService.packageRemoved( 15442 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15443 15444 // Remove all permissions granted from/to this package 15445 removeUriPermissionsForPackageLocked(ssp, userId, true); 15446 } 15447 } 15448 } 15449 } 15450 } 15451 } else { 15452 String msg = "Permission Denial: " + intent.getAction() 15453 + " broadcast from " + callerPackage + " (pid=" + callingPid 15454 + ", uid=" + callingUid + ")" 15455 + " requires " 15456 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15457 Slog.w(TAG, msg); 15458 throw new SecurityException(msg); 15459 } 15460 15461 // Special case for adding a package: by default turn on compatibility 15462 // mode. 15463 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15464 Uri data = intent.getData(); 15465 String ssp; 15466 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15467 mCompatModePackages.handlePackageAddedLocked(ssp, 15468 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15469 } 15470 } 15471 15472 /* 15473 * If this is the time zone changed action, queue up a message that will reset the timezone 15474 * of all currently running processes. This message will get queued up before the broadcast 15475 * happens. 15476 */ 15477 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15478 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15479 } 15480 15481 /* 15482 * If the user set the time, let all running processes know. 15483 */ 15484 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15485 final int is24Hour = intent.getBooleanExtra( 15486 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15487 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15488 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15489 synchronized (stats) { 15490 stats.noteCurrentTimeChangedLocked(); 15491 } 15492 } 15493 15494 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15495 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15496 } 15497 15498 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15499 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15500 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15501 } 15502 15503 // Add to the sticky list if requested. 15504 if (sticky) { 15505 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15506 callingPid, callingUid) 15507 != PackageManager.PERMISSION_GRANTED) { 15508 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15509 + callingPid + ", uid=" + callingUid 15510 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15511 Slog.w(TAG, msg); 15512 throw new SecurityException(msg); 15513 } 15514 if (requiredPermission != null) { 15515 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15516 + " and enforce permission " + requiredPermission); 15517 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15518 } 15519 if (intent.getComponent() != null) { 15520 throw new SecurityException( 15521 "Sticky broadcasts can't target a specific component"); 15522 } 15523 // We use userId directly here, since the "all" target is maintained 15524 // as a separate set of sticky broadcasts. 15525 if (userId != UserHandle.USER_ALL) { 15526 // But first, if this is not a broadcast to all users, then 15527 // make sure it doesn't conflict with an existing broadcast to 15528 // all users. 15529 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15530 UserHandle.USER_ALL); 15531 if (stickies != null) { 15532 ArrayList<Intent> list = stickies.get(intent.getAction()); 15533 if (list != null) { 15534 int N = list.size(); 15535 int i; 15536 for (i=0; i<N; i++) { 15537 if (intent.filterEquals(list.get(i))) { 15538 throw new IllegalArgumentException( 15539 "Sticky broadcast " + intent + " for user " 15540 + userId + " conflicts with existing global broadcast"); 15541 } 15542 } 15543 } 15544 } 15545 } 15546 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15547 if (stickies == null) { 15548 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15549 mStickyBroadcasts.put(userId, stickies); 15550 } 15551 ArrayList<Intent> list = stickies.get(intent.getAction()); 15552 if (list == null) { 15553 list = new ArrayList<Intent>(); 15554 stickies.put(intent.getAction(), list); 15555 } 15556 int N = list.size(); 15557 int i; 15558 for (i=0; i<N; i++) { 15559 if (intent.filterEquals(list.get(i))) { 15560 // This sticky already exists, replace it. 15561 list.set(i, new Intent(intent)); 15562 break; 15563 } 15564 } 15565 if (i >= N) { 15566 list.add(new Intent(intent)); 15567 } 15568 } 15569 15570 int[] users; 15571 if (userId == UserHandle.USER_ALL) { 15572 // Caller wants broadcast to go to all started users. 15573 users = mStartedUserArray; 15574 } else { 15575 // Caller wants broadcast to go to one specific user. 15576 users = new int[] {userId}; 15577 } 15578 15579 // Figure out who all will receive this broadcast. 15580 List receivers = null; 15581 List<BroadcastFilter> registeredReceivers = null; 15582 // Need to resolve the intent to interested receivers... 15583 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15584 == 0) { 15585 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15586 } 15587 if (intent.getComponent() == null) { 15588 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15589 // Query one target user at a time, excluding shell-restricted users 15590 UserManagerService ums = getUserManagerLocked(); 15591 for (int i = 0; i < users.length; i++) { 15592 if (ums.hasUserRestriction( 15593 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15594 continue; 15595 } 15596 List<BroadcastFilter> registeredReceiversForUser = 15597 mReceiverResolver.queryIntent(intent, 15598 resolvedType, false, users[i]); 15599 if (registeredReceivers == null) { 15600 registeredReceivers = registeredReceiversForUser; 15601 } else if (registeredReceiversForUser != null) { 15602 registeredReceivers.addAll(registeredReceiversForUser); 15603 } 15604 } 15605 } else { 15606 registeredReceivers = mReceiverResolver.queryIntent(intent, 15607 resolvedType, false, userId); 15608 } 15609 } 15610 15611 final boolean replacePending = 15612 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15613 15614 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15615 + " replacePending=" + replacePending); 15616 15617 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15618 if (!ordered && NR > 0) { 15619 // If we are not serializing this broadcast, then send the 15620 // registered receivers separately so they don't wait for the 15621 // components to be launched. 15622 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15623 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15624 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15625 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15626 ordered, sticky, false, userId); 15627 if (DEBUG_BROADCAST) Slog.v( 15628 TAG, "Enqueueing parallel broadcast " + r); 15629 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15630 if (!replaced) { 15631 queue.enqueueParallelBroadcastLocked(r); 15632 queue.scheduleBroadcastsLocked(); 15633 } 15634 registeredReceivers = null; 15635 NR = 0; 15636 } 15637 15638 // Merge into one list. 15639 int ir = 0; 15640 if (receivers != null) { 15641 // A special case for PACKAGE_ADDED: do not allow the package 15642 // being added to see this broadcast. This prevents them from 15643 // using this as a back door to get run as soon as they are 15644 // installed. Maybe in the future we want to have a special install 15645 // broadcast or such for apps, but we'd like to deliberately make 15646 // this decision. 15647 String skipPackages[] = null; 15648 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15649 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15650 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15651 Uri data = intent.getData(); 15652 if (data != null) { 15653 String pkgName = data.getSchemeSpecificPart(); 15654 if (pkgName != null) { 15655 skipPackages = new String[] { pkgName }; 15656 } 15657 } 15658 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15659 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15660 } 15661 if (skipPackages != null && (skipPackages.length > 0)) { 15662 for (String skipPackage : skipPackages) { 15663 if (skipPackage != null) { 15664 int NT = receivers.size(); 15665 for (int it=0; it<NT; it++) { 15666 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15667 if (curt.activityInfo.packageName.equals(skipPackage)) { 15668 receivers.remove(it); 15669 it--; 15670 NT--; 15671 } 15672 } 15673 } 15674 } 15675 } 15676 15677 int NT = receivers != null ? receivers.size() : 0; 15678 int it = 0; 15679 ResolveInfo curt = null; 15680 BroadcastFilter curr = null; 15681 while (it < NT && ir < NR) { 15682 if (curt == null) { 15683 curt = (ResolveInfo)receivers.get(it); 15684 } 15685 if (curr == null) { 15686 curr = registeredReceivers.get(ir); 15687 } 15688 if (curr.getPriority() >= curt.priority) { 15689 // Insert this broadcast record into the final list. 15690 receivers.add(it, curr); 15691 ir++; 15692 curr = null; 15693 it++; 15694 NT++; 15695 } else { 15696 // Skip to the next ResolveInfo in the final list. 15697 it++; 15698 curt = null; 15699 } 15700 } 15701 } 15702 while (ir < NR) { 15703 if (receivers == null) { 15704 receivers = new ArrayList(); 15705 } 15706 receivers.add(registeredReceivers.get(ir)); 15707 ir++; 15708 } 15709 15710 if ((receivers != null && receivers.size() > 0) 15711 || resultTo != null) { 15712 BroadcastQueue queue = broadcastQueueForIntent(intent); 15713 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15714 callerPackage, callingPid, callingUid, resolvedType, 15715 requiredPermission, appOp, receivers, resultTo, resultCode, 15716 resultData, map, ordered, sticky, false, userId); 15717 if (DEBUG_BROADCAST) Slog.v( 15718 TAG, "Enqueueing ordered broadcast " + r 15719 + ": prev had " + queue.mOrderedBroadcasts.size()); 15720 if (DEBUG_BROADCAST) { 15721 int seq = r.intent.getIntExtra("seq", -1); 15722 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15723 } 15724 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15725 if (!replaced) { 15726 queue.enqueueOrderedBroadcastLocked(r); 15727 queue.scheduleBroadcastsLocked(); 15728 } 15729 } 15730 15731 return ActivityManager.BROADCAST_SUCCESS; 15732 } 15733 15734 final Intent verifyBroadcastLocked(Intent intent) { 15735 // Refuse possible leaked file descriptors 15736 if (intent != null && intent.hasFileDescriptors() == true) { 15737 throw new IllegalArgumentException("File descriptors passed in Intent"); 15738 } 15739 15740 int flags = intent.getFlags(); 15741 15742 if (!mProcessesReady) { 15743 // if the caller really truly claims to know what they're doing, go 15744 // ahead and allow the broadcast without launching any receivers 15745 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15746 intent = new Intent(intent); 15747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15748 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15749 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15750 + " before boot completion"); 15751 throw new IllegalStateException("Cannot broadcast before boot completed"); 15752 } 15753 } 15754 15755 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15756 throw new IllegalArgumentException( 15757 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15758 } 15759 15760 return intent; 15761 } 15762 15763 public final int broadcastIntent(IApplicationThread caller, 15764 Intent intent, String resolvedType, IIntentReceiver resultTo, 15765 int resultCode, String resultData, Bundle map, 15766 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15767 enforceNotIsolatedCaller("broadcastIntent"); 15768 synchronized(this) { 15769 intent = verifyBroadcastLocked(intent); 15770 15771 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15772 final int callingPid = Binder.getCallingPid(); 15773 final int callingUid = Binder.getCallingUid(); 15774 final long origId = Binder.clearCallingIdentity(); 15775 int res = broadcastIntentLocked(callerApp, 15776 callerApp != null ? callerApp.info.packageName : null, 15777 intent, resolvedType, resultTo, 15778 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15779 callingPid, callingUid, userId); 15780 Binder.restoreCallingIdentity(origId); 15781 return res; 15782 } 15783 } 15784 15785 int broadcastIntentInPackage(String packageName, int uid, 15786 Intent intent, String resolvedType, IIntentReceiver resultTo, 15787 int resultCode, String resultData, Bundle map, 15788 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15789 synchronized(this) { 15790 intent = verifyBroadcastLocked(intent); 15791 15792 final long origId = Binder.clearCallingIdentity(); 15793 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15794 resultTo, resultCode, resultData, map, requiredPermission, 15795 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15796 Binder.restoreCallingIdentity(origId); 15797 return res; 15798 } 15799 } 15800 15801 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15802 // Refuse possible leaked file descriptors 15803 if (intent != null && intent.hasFileDescriptors() == true) { 15804 throw new IllegalArgumentException("File descriptors passed in Intent"); 15805 } 15806 15807 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15808 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15809 15810 synchronized(this) { 15811 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15812 != PackageManager.PERMISSION_GRANTED) { 15813 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15814 + Binder.getCallingPid() 15815 + ", uid=" + Binder.getCallingUid() 15816 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15817 Slog.w(TAG, msg); 15818 throw new SecurityException(msg); 15819 } 15820 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15821 if (stickies != null) { 15822 ArrayList<Intent> list = stickies.get(intent.getAction()); 15823 if (list != null) { 15824 int N = list.size(); 15825 int i; 15826 for (i=0; i<N; i++) { 15827 if (intent.filterEquals(list.get(i))) { 15828 list.remove(i); 15829 break; 15830 } 15831 } 15832 if (list.size() <= 0) { 15833 stickies.remove(intent.getAction()); 15834 } 15835 } 15836 if (stickies.size() <= 0) { 15837 mStickyBroadcasts.remove(userId); 15838 } 15839 } 15840 } 15841 } 15842 15843 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15844 String resultData, Bundle resultExtras, boolean resultAbort) { 15845 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15846 if (r == null) { 15847 Slog.w(TAG, "finishReceiver called but not found on queue"); 15848 return false; 15849 } 15850 15851 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15852 } 15853 15854 void backgroundServicesFinishedLocked(int userId) { 15855 for (BroadcastQueue queue : mBroadcastQueues) { 15856 queue.backgroundServicesFinishedLocked(userId); 15857 } 15858 } 15859 15860 public void finishReceiver(IBinder who, int resultCode, String resultData, 15861 Bundle resultExtras, boolean resultAbort) { 15862 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15863 15864 // Refuse possible leaked file descriptors 15865 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15866 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15867 } 15868 15869 final long origId = Binder.clearCallingIdentity(); 15870 try { 15871 boolean doNext = false; 15872 BroadcastRecord r; 15873 15874 synchronized(this) { 15875 r = broadcastRecordForReceiverLocked(who); 15876 if (r != null) { 15877 doNext = r.queue.finishReceiverLocked(r, resultCode, 15878 resultData, resultExtras, resultAbort, true); 15879 } 15880 } 15881 15882 if (doNext) { 15883 r.queue.processNextBroadcast(false); 15884 } 15885 trimApplications(); 15886 } finally { 15887 Binder.restoreCallingIdentity(origId); 15888 } 15889 } 15890 15891 // ========================================================= 15892 // INSTRUMENTATION 15893 // ========================================================= 15894 15895 public boolean startInstrumentation(ComponentName className, 15896 String profileFile, int flags, Bundle arguments, 15897 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15898 int userId, String abiOverride) { 15899 enforceNotIsolatedCaller("startInstrumentation"); 15900 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15901 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15902 // Refuse possible leaked file descriptors 15903 if (arguments != null && arguments.hasFileDescriptors()) { 15904 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15905 } 15906 15907 synchronized(this) { 15908 InstrumentationInfo ii = null; 15909 ApplicationInfo ai = null; 15910 try { 15911 ii = mContext.getPackageManager().getInstrumentationInfo( 15912 className, STOCK_PM_FLAGS); 15913 ai = AppGlobals.getPackageManager().getApplicationInfo( 15914 ii.targetPackage, STOCK_PM_FLAGS, userId); 15915 } catch (PackageManager.NameNotFoundException e) { 15916 } catch (RemoteException e) { 15917 } 15918 if (ii == null) { 15919 reportStartInstrumentationFailure(watcher, className, 15920 "Unable to find instrumentation info for: " + className); 15921 return false; 15922 } 15923 if (ai == null) { 15924 reportStartInstrumentationFailure(watcher, className, 15925 "Unable to find instrumentation target package: " + ii.targetPackage); 15926 return false; 15927 } 15928 15929 int match = mContext.getPackageManager().checkSignatures( 15930 ii.targetPackage, ii.packageName); 15931 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15932 String msg = "Permission Denial: starting instrumentation " 15933 + className + " from pid=" 15934 + Binder.getCallingPid() 15935 + ", uid=" + Binder.getCallingPid() 15936 + " not allowed because package " + ii.packageName 15937 + " does not have a signature matching the target " 15938 + ii.targetPackage; 15939 reportStartInstrumentationFailure(watcher, className, msg); 15940 throw new SecurityException(msg); 15941 } 15942 15943 final long origId = Binder.clearCallingIdentity(); 15944 // Instrumentation can kill and relaunch even persistent processes 15945 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15946 "start instr"); 15947 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15948 app.instrumentationClass = className; 15949 app.instrumentationInfo = ai; 15950 app.instrumentationProfileFile = profileFile; 15951 app.instrumentationArguments = arguments; 15952 app.instrumentationWatcher = watcher; 15953 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15954 app.instrumentationResultClass = className; 15955 Binder.restoreCallingIdentity(origId); 15956 } 15957 15958 return true; 15959 } 15960 15961 /** 15962 * Report errors that occur while attempting to start Instrumentation. Always writes the 15963 * error to the logs, but if somebody is watching, send the report there too. This enables 15964 * the "am" command to report errors with more information. 15965 * 15966 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15967 * @param cn The component name of the instrumentation. 15968 * @param report The error report. 15969 */ 15970 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15971 ComponentName cn, String report) { 15972 Slog.w(TAG, report); 15973 try { 15974 if (watcher != null) { 15975 Bundle results = new Bundle(); 15976 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15977 results.putString("Error", report); 15978 watcher.instrumentationStatus(cn, -1, results); 15979 } 15980 } catch (RemoteException e) { 15981 Slog.w(TAG, e); 15982 } 15983 } 15984 15985 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15986 if (app.instrumentationWatcher != null) { 15987 try { 15988 // NOTE: IInstrumentationWatcher *must* be oneway here 15989 app.instrumentationWatcher.instrumentationFinished( 15990 app.instrumentationClass, 15991 resultCode, 15992 results); 15993 } catch (RemoteException e) { 15994 } 15995 } 15996 if (app.instrumentationUiAutomationConnection != null) { 15997 try { 15998 app.instrumentationUiAutomationConnection.shutdown(); 15999 } catch (RemoteException re) { 16000 /* ignore */ 16001 } 16002 // Only a UiAutomation can set this flag and now that 16003 // it is finished we make sure it is reset to its default. 16004 mUserIsMonkey = false; 16005 } 16006 app.instrumentationWatcher = null; 16007 app.instrumentationUiAutomationConnection = null; 16008 app.instrumentationClass = null; 16009 app.instrumentationInfo = null; 16010 app.instrumentationProfileFile = null; 16011 app.instrumentationArguments = null; 16012 16013 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16014 "finished inst"); 16015 } 16016 16017 public void finishInstrumentation(IApplicationThread target, 16018 int resultCode, Bundle results) { 16019 int userId = UserHandle.getCallingUserId(); 16020 // Refuse possible leaked file descriptors 16021 if (results != null && results.hasFileDescriptors()) { 16022 throw new IllegalArgumentException("File descriptors passed in Intent"); 16023 } 16024 16025 synchronized(this) { 16026 ProcessRecord app = getRecordForAppLocked(target); 16027 if (app == null) { 16028 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16029 return; 16030 } 16031 final long origId = Binder.clearCallingIdentity(); 16032 finishInstrumentationLocked(app, resultCode, results); 16033 Binder.restoreCallingIdentity(origId); 16034 } 16035 } 16036 16037 // ========================================================= 16038 // CONFIGURATION 16039 // ========================================================= 16040 16041 public ConfigurationInfo getDeviceConfigurationInfo() { 16042 ConfigurationInfo config = new ConfigurationInfo(); 16043 synchronized (this) { 16044 config.reqTouchScreen = mConfiguration.touchscreen; 16045 config.reqKeyboardType = mConfiguration.keyboard; 16046 config.reqNavigation = mConfiguration.navigation; 16047 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16048 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16049 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16050 } 16051 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16052 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16053 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16054 } 16055 config.reqGlEsVersion = GL_ES_VERSION; 16056 } 16057 return config; 16058 } 16059 16060 ActivityStack getFocusedStack() { 16061 return mStackSupervisor.getFocusedStack(); 16062 } 16063 16064 public Configuration getConfiguration() { 16065 Configuration ci; 16066 synchronized(this) { 16067 ci = new Configuration(mConfiguration); 16068 } 16069 return ci; 16070 } 16071 16072 public void updatePersistentConfiguration(Configuration values) { 16073 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16074 "updateConfiguration()"); 16075 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16076 "updateConfiguration()"); 16077 if (values == null) { 16078 throw new NullPointerException("Configuration must not be null"); 16079 } 16080 16081 synchronized(this) { 16082 final long origId = Binder.clearCallingIdentity(); 16083 updateConfigurationLocked(values, null, true, false); 16084 Binder.restoreCallingIdentity(origId); 16085 } 16086 } 16087 16088 public void updateConfiguration(Configuration values) { 16089 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16090 "updateConfiguration()"); 16091 16092 synchronized(this) { 16093 if (values == null && mWindowManager != null) { 16094 // sentinel: fetch the current configuration from the window manager 16095 values = mWindowManager.computeNewConfiguration(); 16096 } 16097 16098 if (mWindowManager != null) { 16099 mProcessList.applyDisplaySize(mWindowManager); 16100 } 16101 16102 final long origId = Binder.clearCallingIdentity(); 16103 if (values != null) { 16104 Settings.System.clearConfiguration(values); 16105 } 16106 updateConfigurationLocked(values, null, false, false); 16107 Binder.restoreCallingIdentity(origId); 16108 } 16109 } 16110 16111 /** 16112 * Do either or both things: (1) change the current configuration, and (2) 16113 * make sure the given activity is running with the (now) current 16114 * configuration. Returns true if the activity has been left running, or 16115 * false if <var>starting</var> is being destroyed to match the new 16116 * configuration. 16117 * @param persistent TODO 16118 */ 16119 boolean updateConfigurationLocked(Configuration values, 16120 ActivityRecord starting, boolean persistent, boolean initLocale) { 16121 int changes = 0; 16122 16123 if (values != null) { 16124 Configuration newConfig = new Configuration(mConfiguration); 16125 changes = newConfig.updateFrom(values); 16126 if (changes != 0) { 16127 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16128 Slog.i(TAG, "Updating configuration to: " + values); 16129 } 16130 16131 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16132 16133 if (values.locale != null && !initLocale) { 16134 saveLocaleLocked(values.locale, 16135 !values.locale.equals(mConfiguration.locale), 16136 values.userSetLocale); 16137 } 16138 16139 mConfigurationSeq++; 16140 if (mConfigurationSeq <= 0) { 16141 mConfigurationSeq = 1; 16142 } 16143 newConfig.seq = mConfigurationSeq; 16144 mConfiguration = newConfig; 16145 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16146 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16147 //mUsageStatsService.noteStartConfig(newConfig); 16148 16149 final Configuration configCopy = new Configuration(mConfiguration); 16150 16151 // TODO: If our config changes, should we auto dismiss any currently 16152 // showing dialogs? 16153 mShowDialogs = shouldShowDialogs(newConfig); 16154 16155 AttributeCache ac = AttributeCache.instance(); 16156 if (ac != null) { 16157 ac.updateConfiguration(configCopy); 16158 } 16159 16160 // Make sure all resources in our process are updated 16161 // right now, so that anyone who is going to retrieve 16162 // resource values after we return will be sure to get 16163 // the new ones. This is especially important during 16164 // boot, where the first config change needs to guarantee 16165 // all resources have that config before following boot 16166 // code is executed. 16167 mSystemThread.applyConfigurationToResources(configCopy); 16168 16169 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16170 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16171 msg.obj = new Configuration(configCopy); 16172 mHandler.sendMessage(msg); 16173 } 16174 16175 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16176 ProcessRecord app = mLruProcesses.get(i); 16177 try { 16178 if (app.thread != null) { 16179 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16180 + app.processName + " new config " + mConfiguration); 16181 app.thread.scheduleConfigurationChanged(configCopy); 16182 } 16183 } catch (Exception e) { 16184 } 16185 } 16186 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16187 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16188 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16189 | Intent.FLAG_RECEIVER_FOREGROUND); 16190 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16191 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16192 Process.SYSTEM_UID, UserHandle.USER_ALL); 16193 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16194 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16195 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16196 broadcastIntentLocked(null, null, intent, 16197 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16198 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16199 } 16200 } 16201 } 16202 16203 boolean kept = true; 16204 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16205 // mainStack is null during startup. 16206 if (mainStack != null) { 16207 if (changes != 0 && starting == null) { 16208 // If the configuration changed, and the caller is not already 16209 // in the process of starting an activity, then find the top 16210 // activity to check if its configuration needs to change. 16211 starting = mainStack.topRunningActivityLocked(null); 16212 } 16213 16214 if (starting != null) { 16215 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16216 // And we need to make sure at this point that all other activities 16217 // are made visible with the correct configuration. 16218 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16219 } 16220 } 16221 16222 if (values != null && mWindowManager != null) { 16223 mWindowManager.setNewConfiguration(mConfiguration); 16224 } 16225 16226 return kept; 16227 } 16228 16229 /** 16230 * Decide based on the configuration whether we should shouw the ANR, 16231 * crash, etc dialogs. The idea is that if there is no affordnace to 16232 * press the on-screen buttons, we shouldn't show the dialog. 16233 * 16234 * A thought: SystemUI might also want to get told about this, the Power 16235 * dialog / global actions also might want different behaviors. 16236 */ 16237 private static final boolean shouldShowDialogs(Configuration config) { 16238 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16239 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16240 } 16241 16242 /** 16243 * Save the locale. You must be inside a synchronized (this) block. 16244 */ 16245 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16246 if(isDiff) { 16247 SystemProperties.set("user.language", l.getLanguage()); 16248 SystemProperties.set("user.region", l.getCountry()); 16249 } 16250 16251 if(isPersist) { 16252 SystemProperties.set("persist.sys.language", l.getLanguage()); 16253 SystemProperties.set("persist.sys.country", l.getCountry()); 16254 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16255 } 16256 } 16257 16258 @Override 16259 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16260 synchronized (this) { 16261 ActivityRecord srec = ActivityRecord.forToken(token); 16262 if (srec.task != null && srec.task.stack != null) { 16263 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16264 } 16265 } 16266 return false; 16267 } 16268 16269 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16270 Intent resultData) { 16271 16272 synchronized (this) { 16273 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16274 if (stack != null) { 16275 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16276 } 16277 return false; 16278 } 16279 } 16280 16281 public int getLaunchedFromUid(IBinder activityToken) { 16282 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16283 if (srec == null) { 16284 return -1; 16285 } 16286 return srec.launchedFromUid; 16287 } 16288 16289 public String getLaunchedFromPackage(IBinder activityToken) { 16290 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16291 if (srec == null) { 16292 return null; 16293 } 16294 return srec.launchedFromPackage; 16295 } 16296 16297 // ========================================================= 16298 // LIFETIME MANAGEMENT 16299 // ========================================================= 16300 16301 // Returns which broadcast queue the app is the current [or imminent] receiver 16302 // on, or 'null' if the app is not an active broadcast recipient. 16303 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16304 BroadcastRecord r = app.curReceiver; 16305 if (r != null) { 16306 return r.queue; 16307 } 16308 16309 // It's not the current receiver, but it might be starting up to become one 16310 synchronized (this) { 16311 for (BroadcastQueue queue : mBroadcastQueues) { 16312 r = queue.mPendingBroadcast; 16313 if (r != null && r.curApp == app) { 16314 // found it; report which queue it's in 16315 return queue; 16316 } 16317 } 16318 } 16319 16320 return null; 16321 } 16322 16323 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16324 boolean doingAll, long now) { 16325 if (mAdjSeq == app.adjSeq) { 16326 // This adjustment has already been computed. 16327 return app.curRawAdj; 16328 } 16329 16330 if (app.thread == null) { 16331 app.adjSeq = mAdjSeq; 16332 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16333 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16334 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16335 } 16336 16337 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16338 app.adjSource = null; 16339 app.adjTarget = null; 16340 app.empty = false; 16341 app.cached = false; 16342 16343 final int activitiesSize = app.activities.size(); 16344 16345 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16346 // The max adjustment doesn't allow this app to be anything 16347 // below foreground, so it is not worth doing work for it. 16348 app.adjType = "fixed"; 16349 app.adjSeq = mAdjSeq; 16350 app.curRawAdj = app.maxAdj; 16351 app.foregroundActivities = false; 16352 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16353 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16354 // System processes can do UI, and when they do we want to have 16355 // them trim their memory after the user leaves the UI. To 16356 // facilitate this, here we need to determine whether or not it 16357 // is currently showing UI. 16358 app.systemNoUi = true; 16359 if (app == TOP_APP) { 16360 app.systemNoUi = false; 16361 } else if (activitiesSize > 0) { 16362 for (int j = 0; j < activitiesSize; j++) { 16363 final ActivityRecord r = app.activities.get(j); 16364 if (r.visible) { 16365 app.systemNoUi = false; 16366 } 16367 } 16368 } 16369 if (!app.systemNoUi) { 16370 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16371 } 16372 return (app.curAdj=app.maxAdj); 16373 } 16374 16375 app.systemNoUi = false; 16376 16377 // Determine the importance of the process, starting with most 16378 // important to least, and assign an appropriate OOM adjustment. 16379 int adj; 16380 int schedGroup; 16381 int procState; 16382 boolean foregroundActivities = false; 16383 BroadcastQueue queue; 16384 if (app == TOP_APP) { 16385 // The last app on the list is the foreground app. 16386 adj = ProcessList.FOREGROUND_APP_ADJ; 16387 schedGroup = Process.THREAD_GROUP_DEFAULT; 16388 app.adjType = "top-activity"; 16389 foregroundActivities = true; 16390 procState = ActivityManager.PROCESS_STATE_TOP; 16391 } else if (app.instrumentationClass != null) { 16392 // Don't want to kill running instrumentation. 16393 adj = ProcessList.FOREGROUND_APP_ADJ; 16394 schedGroup = Process.THREAD_GROUP_DEFAULT; 16395 app.adjType = "instrumentation"; 16396 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16397 } else if ((queue = isReceivingBroadcast(app)) != null) { 16398 // An app that is currently receiving a broadcast also 16399 // counts as being in the foreground for OOM killer purposes. 16400 // It's placed in a sched group based on the nature of the 16401 // broadcast as reflected by which queue it's active in. 16402 adj = ProcessList.FOREGROUND_APP_ADJ; 16403 schedGroup = (queue == mFgBroadcastQueue) 16404 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16405 app.adjType = "broadcast"; 16406 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16407 } else if (app.executingServices.size() > 0) { 16408 // An app that is currently executing a service callback also 16409 // counts as being in the foreground. 16410 adj = ProcessList.FOREGROUND_APP_ADJ; 16411 schedGroup = app.execServicesFg ? 16412 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16413 app.adjType = "exec-service"; 16414 procState = ActivityManager.PROCESS_STATE_SERVICE; 16415 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16416 } else { 16417 // As far as we know the process is empty. We may change our mind later. 16418 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16419 // At this point we don't actually know the adjustment. Use the cached adj 16420 // value that the caller wants us to. 16421 adj = cachedAdj; 16422 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16423 app.cached = true; 16424 app.empty = true; 16425 app.adjType = "cch-empty"; 16426 } 16427 16428 // Examine all activities if not already foreground. 16429 if (!foregroundActivities && activitiesSize > 0) { 16430 for (int j = 0; j < activitiesSize; j++) { 16431 final ActivityRecord r = app.activities.get(j); 16432 if (r.app != app) { 16433 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16434 + app + "?!?"); 16435 continue; 16436 } 16437 if (r.visible) { 16438 // App has a visible activity; only upgrade adjustment. 16439 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16440 adj = ProcessList.VISIBLE_APP_ADJ; 16441 app.adjType = "visible"; 16442 } 16443 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16444 procState = ActivityManager.PROCESS_STATE_TOP; 16445 } 16446 schedGroup = Process.THREAD_GROUP_DEFAULT; 16447 app.cached = false; 16448 app.empty = false; 16449 foregroundActivities = true; 16450 break; 16451 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16452 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16453 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16454 app.adjType = "pausing"; 16455 } 16456 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16457 procState = ActivityManager.PROCESS_STATE_TOP; 16458 } 16459 schedGroup = Process.THREAD_GROUP_DEFAULT; 16460 app.cached = false; 16461 app.empty = false; 16462 foregroundActivities = true; 16463 } else if (r.state == ActivityState.STOPPING) { 16464 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16465 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16466 app.adjType = "stopping"; 16467 } 16468 // For the process state, we will at this point consider the 16469 // process to be cached. It will be cached either as an activity 16470 // or empty depending on whether the activity is finishing. We do 16471 // this so that we can treat the process as cached for purposes of 16472 // memory trimming (determing current memory level, trim command to 16473 // send to process) since there can be an arbitrary number of stopping 16474 // processes and they should soon all go into the cached state. 16475 if (!r.finishing) { 16476 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16477 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16478 } 16479 } 16480 app.cached = false; 16481 app.empty = false; 16482 foregroundActivities = true; 16483 } else { 16484 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16485 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16486 app.adjType = "cch-act"; 16487 } 16488 } 16489 } 16490 } 16491 16492 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16493 if (app.foregroundServices) { 16494 // The user is aware of this app, so make it visible. 16495 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16496 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16497 app.cached = false; 16498 app.adjType = "fg-service"; 16499 schedGroup = Process.THREAD_GROUP_DEFAULT; 16500 } else if (app.forcingToForeground != null) { 16501 // The user is aware of this app, so make it visible. 16502 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16503 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16504 app.cached = false; 16505 app.adjType = "force-fg"; 16506 app.adjSource = app.forcingToForeground; 16507 schedGroup = Process.THREAD_GROUP_DEFAULT; 16508 } 16509 } 16510 16511 if (app == mHeavyWeightProcess) { 16512 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16513 // We don't want to kill the current heavy-weight process. 16514 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16515 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16516 app.cached = false; 16517 app.adjType = "heavy"; 16518 } 16519 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16520 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16521 } 16522 } 16523 16524 if (app == mHomeProcess) { 16525 if (adj > ProcessList.HOME_APP_ADJ) { 16526 // This process is hosting what we currently consider to be the 16527 // home app, so we don't want to let it go into the background. 16528 adj = ProcessList.HOME_APP_ADJ; 16529 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16530 app.cached = false; 16531 app.adjType = "home"; 16532 } 16533 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16534 procState = ActivityManager.PROCESS_STATE_HOME; 16535 } 16536 } 16537 16538 if (app == mPreviousProcess && app.activities.size() > 0) { 16539 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16540 // This was the previous process that showed UI to the user. 16541 // We want to try to keep it around more aggressively, to give 16542 // a good experience around switching between two apps. 16543 adj = ProcessList.PREVIOUS_APP_ADJ; 16544 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16545 app.cached = false; 16546 app.adjType = "previous"; 16547 } 16548 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16549 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16550 } 16551 } 16552 16553 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16554 + " reason=" + app.adjType); 16555 16556 // By default, we use the computed adjustment. It may be changed if 16557 // there are applications dependent on our services or providers, but 16558 // this gives us a baseline and makes sure we don't get into an 16559 // infinite recursion. 16560 app.adjSeq = mAdjSeq; 16561 app.curRawAdj = adj; 16562 app.hasStartedServices = false; 16563 16564 if (mBackupTarget != null && app == mBackupTarget.app) { 16565 // If possible we want to avoid killing apps while they're being backed up 16566 if (adj > ProcessList.BACKUP_APP_ADJ) { 16567 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16568 adj = ProcessList.BACKUP_APP_ADJ; 16569 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16570 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16571 } 16572 app.adjType = "backup"; 16573 app.cached = false; 16574 } 16575 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16576 procState = ActivityManager.PROCESS_STATE_BACKUP; 16577 } 16578 } 16579 16580 boolean mayBeTop = false; 16581 16582 for (int is = app.services.size()-1; 16583 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16584 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16585 || procState > ActivityManager.PROCESS_STATE_TOP); 16586 is--) { 16587 ServiceRecord s = app.services.valueAt(is); 16588 if (s.startRequested) { 16589 app.hasStartedServices = true; 16590 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16591 procState = ActivityManager.PROCESS_STATE_SERVICE; 16592 } 16593 if (app.hasShownUi && app != mHomeProcess) { 16594 // If this process has shown some UI, let it immediately 16595 // go to the LRU list because it may be pretty heavy with 16596 // UI stuff. We'll tag it with a label just to help 16597 // debug and understand what is going on. 16598 if (adj > ProcessList.SERVICE_ADJ) { 16599 app.adjType = "cch-started-ui-services"; 16600 } 16601 } else { 16602 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16603 // This service has seen some activity within 16604 // recent memory, so we will keep its process ahead 16605 // of the background processes. 16606 if (adj > ProcessList.SERVICE_ADJ) { 16607 adj = ProcessList.SERVICE_ADJ; 16608 app.adjType = "started-services"; 16609 app.cached = false; 16610 } 16611 } 16612 // If we have let the service slide into the background 16613 // state, still have some text describing what it is doing 16614 // even though the service no longer has an impact. 16615 if (adj > ProcessList.SERVICE_ADJ) { 16616 app.adjType = "cch-started-services"; 16617 } 16618 } 16619 } 16620 for (int conni = s.connections.size()-1; 16621 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16622 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16623 || procState > ActivityManager.PROCESS_STATE_TOP); 16624 conni--) { 16625 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16626 for (int i = 0; 16627 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16628 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16629 || procState > ActivityManager.PROCESS_STATE_TOP); 16630 i++) { 16631 // XXX should compute this based on the max of 16632 // all connected clients. 16633 ConnectionRecord cr = clist.get(i); 16634 if (cr.binding.client == app) { 16635 // Binding to ourself is not interesting. 16636 continue; 16637 } 16638 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16639 ProcessRecord client = cr.binding.client; 16640 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16641 TOP_APP, doingAll, now); 16642 int clientProcState = client.curProcState; 16643 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16644 // If the other app is cached for any reason, for purposes here 16645 // we are going to consider it empty. The specific cached state 16646 // doesn't propagate except under certain conditions. 16647 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16648 } 16649 String adjType = null; 16650 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16651 // Not doing bind OOM management, so treat 16652 // this guy more like a started service. 16653 if (app.hasShownUi && app != mHomeProcess) { 16654 // If this process has shown some UI, let it immediately 16655 // go to the LRU list because it may be pretty heavy with 16656 // UI stuff. We'll tag it with a label just to help 16657 // debug and understand what is going on. 16658 if (adj > clientAdj) { 16659 adjType = "cch-bound-ui-services"; 16660 } 16661 app.cached = false; 16662 clientAdj = adj; 16663 clientProcState = procState; 16664 } else { 16665 if (now >= (s.lastActivity 16666 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16667 // This service has not seen activity within 16668 // recent memory, so allow it to drop to the 16669 // LRU list if there is no other reason to keep 16670 // it around. We'll also tag it with a label just 16671 // to help debug and undertand what is going on. 16672 if (adj > clientAdj) { 16673 adjType = "cch-bound-services"; 16674 } 16675 clientAdj = adj; 16676 } 16677 } 16678 } 16679 if (adj > clientAdj) { 16680 // If this process has recently shown UI, and 16681 // the process that is binding to it is less 16682 // important than being visible, then we don't 16683 // care about the binding as much as we care 16684 // about letting this process get into the LRU 16685 // list to be killed and restarted if needed for 16686 // memory. 16687 if (app.hasShownUi && app != mHomeProcess 16688 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16689 adjType = "cch-bound-ui-services"; 16690 } else { 16691 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16692 |Context.BIND_IMPORTANT)) != 0) { 16693 adj = clientAdj; 16694 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16695 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16696 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16697 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16698 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16699 adj = clientAdj; 16700 } else { 16701 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16702 adj = ProcessList.VISIBLE_APP_ADJ; 16703 } 16704 } 16705 if (!client.cached) { 16706 app.cached = false; 16707 } 16708 adjType = "service"; 16709 } 16710 } 16711 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16712 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16713 schedGroup = Process.THREAD_GROUP_DEFAULT; 16714 } 16715 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16716 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16717 // Special handling of clients who are in the top state. 16718 // We *may* want to consider this process to be in the 16719 // top state as well, but only if there is not another 16720 // reason for it to be running. Being on the top is a 16721 // special state, meaning you are specifically running 16722 // for the current top app. If the process is already 16723 // running in the background for some other reason, it 16724 // is more important to continue considering it to be 16725 // in the background state. 16726 mayBeTop = true; 16727 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16728 } else { 16729 // Special handling for above-top states (persistent 16730 // processes). These should not bring the current process 16731 // into the top state, since they are not on top. Instead 16732 // give them the best state after that. 16733 clientProcState = 16734 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16735 } 16736 } 16737 } else { 16738 if (clientProcState < 16739 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16740 clientProcState = 16741 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16742 } 16743 } 16744 if (procState > clientProcState) { 16745 procState = clientProcState; 16746 } 16747 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16748 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16749 app.pendingUiClean = true; 16750 } 16751 if (adjType != null) { 16752 app.adjType = adjType; 16753 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16754 .REASON_SERVICE_IN_USE; 16755 app.adjSource = cr.binding.client; 16756 app.adjSourceProcState = clientProcState; 16757 app.adjTarget = s.name; 16758 } 16759 } 16760 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16761 app.treatLikeActivity = true; 16762 } 16763 final ActivityRecord a = cr.activity; 16764 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16765 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16766 (a.visible || a.state == ActivityState.RESUMED 16767 || a.state == ActivityState.PAUSING)) { 16768 adj = ProcessList.FOREGROUND_APP_ADJ; 16769 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16770 schedGroup = Process.THREAD_GROUP_DEFAULT; 16771 } 16772 app.cached = false; 16773 app.adjType = "service"; 16774 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16775 .REASON_SERVICE_IN_USE; 16776 app.adjSource = a; 16777 app.adjSourceProcState = procState; 16778 app.adjTarget = s.name; 16779 } 16780 } 16781 } 16782 } 16783 } 16784 16785 for (int provi = app.pubProviders.size()-1; 16786 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16787 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16788 || procState > ActivityManager.PROCESS_STATE_TOP); 16789 provi--) { 16790 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16791 for (int i = cpr.connections.size()-1; 16792 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16793 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16794 || procState > ActivityManager.PROCESS_STATE_TOP); 16795 i--) { 16796 ContentProviderConnection conn = cpr.connections.get(i); 16797 ProcessRecord client = conn.client; 16798 if (client == app) { 16799 // Being our own client is not interesting. 16800 continue; 16801 } 16802 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16803 int clientProcState = client.curProcState; 16804 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16805 // If the other app is cached for any reason, for purposes here 16806 // we are going to consider it empty. 16807 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16808 } 16809 if (adj > clientAdj) { 16810 if (app.hasShownUi && app != mHomeProcess 16811 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16812 app.adjType = "cch-ui-provider"; 16813 } else { 16814 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16815 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16816 app.adjType = "provider"; 16817 } 16818 app.cached &= client.cached; 16819 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16820 .REASON_PROVIDER_IN_USE; 16821 app.adjSource = client; 16822 app.adjSourceProcState = clientProcState; 16823 app.adjTarget = cpr.name; 16824 } 16825 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16826 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16827 // Special handling of clients who are in the top state. 16828 // We *may* want to consider this process to be in the 16829 // top state as well, but only if there is not another 16830 // reason for it to be running. Being on the top is a 16831 // special state, meaning you are specifically running 16832 // for the current top app. If the process is already 16833 // running in the background for some other reason, it 16834 // is more important to continue considering it to be 16835 // in the background state. 16836 mayBeTop = true; 16837 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16838 } else { 16839 // Special handling for above-top states (persistent 16840 // processes). These should not bring the current process 16841 // into the top state, since they are not on top. Instead 16842 // give them the best state after that. 16843 clientProcState = 16844 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16845 } 16846 } 16847 if (procState > clientProcState) { 16848 procState = clientProcState; 16849 } 16850 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16851 schedGroup = Process.THREAD_GROUP_DEFAULT; 16852 } 16853 } 16854 // If the provider has external (non-framework) process 16855 // dependencies, ensure that its adjustment is at least 16856 // FOREGROUND_APP_ADJ. 16857 if (cpr.hasExternalProcessHandles()) { 16858 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16859 adj = ProcessList.FOREGROUND_APP_ADJ; 16860 schedGroup = Process.THREAD_GROUP_DEFAULT; 16861 app.cached = false; 16862 app.adjType = "provider"; 16863 app.adjTarget = cpr.name; 16864 } 16865 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16866 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16867 } 16868 } 16869 } 16870 16871 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16872 // A client of one of our services or providers is in the top state. We 16873 // *may* want to be in the top state, but not if we are already running in 16874 // the background for some other reason. For the decision here, we are going 16875 // to pick out a few specific states that we want to remain in when a client 16876 // is top (states that tend to be longer-term) and otherwise allow it to go 16877 // to the top state. 16878 switch (procState) { 16879 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16880 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16881 case ActivityManager.PROCESS_STATE_SERVICE: 16882 // These all are longer-term states, so pull them up to the top 16883 // of the background states, but not all the way to the top state. 16884 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16885 break; 16886 default: 16887 // Otherwise, top is a better choice, so take it. 16888 procState = ActivityManager.PROCESS_STATE_TOP; 16889 break; 16890 } 16891 } 16892 16893 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16894 if (app.hasClientActivities) { 16895 // This is a cached process, but with client activities. Mark it so. 16896 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16897 app.adjType = "cch-client-act"; 16898 } else if (app.treatLikeActivity) { 16899 // This is a cached process, but somebody wants us to treat it like it has 16900 // an activity, okay! 16901 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16902 app.adjType = "cch-as-act"; 16903 } 16904 } 16905 16906 if (adj == ProcessList.SERVICE_ADJ) { 16907 if (doingAll) { 16908 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16909 mNewNumServiceProcs++; 16910 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16911 if (!app.serviceb) { 16912 // This service isn't far enough down on the LRU list to 16913 // normally be a B service, but if we are low on RAM and it 16914 // is large we want to force it down since we would prefer to 16915 // keep launcher over it. 16916 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16917 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16918 app.serviceHighRam = true; 16919 app.serviceb = true; 16920 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16921 } else { 16922 mNewNumAServiceProcs++; 16923 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16924 } 16925 } else { 16926 app.serviceHighRam = false; 16927 } 16928 } 16929 if (app.serviceb) { 16930 adj = ProcessList.SERVICE_B_ADJ; 16931 } 16932 } 16933 16934 app.curRawAdj = adj; 16935 16936 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16937 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16938 if (adj > app.maxAdj) { 16939 adj = app.maxAdj; 16940 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16941 schedGroup = Process.THREAD_GROUP_DEFAULT; 16942 } 16943 } 16944 16945 // Do final modification to adj. Everything we do between here and applying 16946 // the final setAdj must be done in this function, because we will also use 16947 // it when computing the final cached adj later. Note that we don't need to 16948 // worry about this for max adj above, since max adj will always be used to 16949 // keep it out of the cached vaues. 16950 app.curAdj = app.modifyRawOomAdj(adj); 16951 app.curSchedGroup = schedGroup; 16952 app.curProcState = procState; 16953 app.foregroundActivities = foregroundActivities; 16954 16955 return app.curRawAdj; 16956 } 16957 16958 /** 16959 * Schedule PSS collection of a process. 16960 */ 16961 void requestPssLocked(ProcessRecord proc, int procState) { 16962 if (mPendingPssProcesses.contains(proc)) { 16963 return; 16964 } 16965 if (mPendingPssProcesses.size() == 0) { 16966 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16967 } 16968 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16969 proc.pssProcState = procState; 16970 mPendingPssProcesses.add(proc); 16971 } 16972 16973 /** 16974 * Schedule PSS collection of all processes. 16975 */ 16976 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16977 if (!always) { 16978 if (now < (mLastFullPssTime + 16979 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16980 return; 16981 } 16982 } 16983 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16984 mLastFullPssTime = now; 16985 mFullPssPending = true; 16986 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16987 mPendingPssProcesses.clear(); 16988 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16989 ProcessRecord app = mLruProcesses.get(i); 16990 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16991 app.pssProcState = app.setProcState; 16992 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16993 isSleeping(), now); 16994 mPendingPssProcesses.add(app); 16995 } 16996 } 16997 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16998 } 16999 17000 /** 17001 * Ask a given process to GC right now. 17002 */ 17003 final void performAppGcLocked(ProcessRecord app) { 17004 try { 17005 app.lastRequestedGc = SystemClock.uptimeMillis(); 17006 if (app.thread != null) { 17007 if (app.reportLowMemory) { 17008 app.reportLowMemory = false; 17009 app.thread.scheduleLowMemory(); 17010 } else { 17011 app.thread.processInBackground(); 17012 } 17013 } 17014 } catch (Exception e) { 17015 // whatever. 17016 } 17017 } 17018 17019 /** 17020 * Returns true if things are idle enough to perform GCs. 17021 */ 17022 private final boolean canGcNowLocked() { 17023 boolean processingBroadcasts = false; 17024 for (BroadcastQueue q : mBroadcastQueues) { 17025 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17026 processingBroadcasts = true; 17027 } 17028 } 17029 return !processingBroadcasts 17030 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17031 } 17032 17033 /** 17034 * Perform GCs on all processes that are waiting for it, but only 17035 * if things are idle. 17036 */ 17037 final void performAppGcsLocked() { 17038 final int N = mProcessesToGc.size(); 17039 if (N <= 0) { 17040 return; 17041 } 17042 if (canGcNowLocked()) { 17043 while (mProcessesToGc.size() > 0) { 17044 ProcessRecord proc = mProcessesToGc.remove(0); 17045 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17046 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17047 <= SystemClock.uptimeMillis()) { 17048 // To avoid spamming the system, we will GC processes one 17049 // at a time, waiting a few seconds between each. 17050 performAppGcLocked(proc); 17051 scheduleAppGcsLocked(); 17052 return; 17053 } else { 17054 // It hasn't been long enough since we last GCed this 17055 // process... put it in the list to wait for its time. 17056 addProcessToGcListLocked(proc); 17057 break; 17058 } 17059 } 17060 } 17061 17062 scheduleAppGcsLocked(); 17063 } 17064 } 17065 17066 /** 17067 * If all looks good, perform GCs on all processes waiting for them. 17068 */ 17069 final void performAppGcsIfAppropriateLocked() { 17070 if (canGcNowLocked()) { 17071 performAppGcsLocked(); 17072 return; 17073 } 17074 // Still not idle, wait some more. 17075 scheduleAppGcsLocked(); 17076 } 17077 17078 /** 17079 * Schedule the execution of all pending app GCs. 17080 */ 17081 final void scheduleAppGcsLocked() { 17082 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17083 17084 if (mProcessesToGc.size() > 0) { 17085 // Schedule a GC for the time to the next process. 17086 ProcessRecord proc = mProcessesToGc.get(0); 17087 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17088 17089 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17090 long now = SystemClock.uptimeMillis(); 17091 if (when < (now+GC_TIMEOUT)) { 17092 when = now + GC_TIMEOUT; 17093 } 17094 mHandler.sendMessageAtTime(msg, when); 17095 } 17096 } 17097 17098 /** 17099 * Add a process to the array of processes waiting to be GCed. Keeps the 17100 * list in sorted order by the last GC time. The process can't already be 17101 * on the list. 17102 */ 17103 final void addProcessToGcListLocked(ProcessRecord proc) { 17104 boolean added = false; 17105 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17106 if (mProcessesToGc.get(i).lastRequestedGc < 17107 proc.lastRequestedGc) { 17108 added = true; 17109 mProcessesToGc.add(i+1, proc); 17110 break; 17111 } 17112 } 17113 if (!added) { 17114 mProcessesToGc.add(0, proc); 17115 } 17116 } 17117 17118 /** 17119 * Set up to ask a process to GC itself. This will either do it 17120 * immediately, or put it on the list of processes to gc the next 17121 * time things are idle. 17122 */ 17123 final void scheduleAppGcLocked(ProcessRecord app) { 17124 long now = SystemClock.uptimeMillis(); 17125 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17126 return; 17127 } 17128 if (!mProcessesToGc.contains(app)) { 17129 addProcessToGcListLocked(app); 17130 scheduleAppGcsLocked(); 17131 } 17132 } 17133 17134 final void checkExcessivePowerUsageLocked(boolean doKills) { 17135 updateCpuStatsNow(); 17136 17137 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17138 boolean doWakeKills = doKills; 17139 boolean doCpuKills = doKills; 17140 if (mLastPowerCheckRealtime == 0) { 17141 doWakeKills = false; 17142 } 17143 if (mLastPowerCheckUptime == 0) { 17144 doCpuKills = false; 17145 } 17146 if (stats.isScreenOn()) { 17147 doWakeKills = false; 17148 } 17149 final long curRealtime = SystemClock.elapsedRealtime(); 17150 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17151 final long curUptime = SystemClock.uptimeMillis(); 17152 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17153 mLastPowerCheckRealtime = curRealtime; 17154 mLastPowerCheckUptime = curUptime; 17155 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17156 doWakeKills = false; 17157 } 17158 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17159 doCpuKills = false; 17160 } 17161 int i = mLruProcesses.size(); 17162 while (i > 0) { 17163 i--; 17164 ProcessRecord app = mLruProcesses.get(i); 17165 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17166 long wtime; 17167 synchronized (stats) { 17168 wtime = stats.getProcessWakeTime(app.info.uid, 17169 app.pid, curRealtime); 17170 } 17171 long wtimeUsed = wtime - app.lastWakeTime; 17172 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17173 if (DEBUG_POWER) { 17174 StringBuilder sb = new StringBuilder(128); 17175 sb.append("Wake for "); 17176 app.toShortString(sb); 17177 sb.append(": over "); 17178 TimeUtils.formatDuration(realtimeSince, sb); 17179 sb.append(" used "); 17180 TimeUtils.formatDuration(wtimeUsed, sb); 17181 sb.append(" ("); 17182 sb.append((wtimeUsed*100)/realtimeSince); 17183 sb.append("%)"); 17184 Slog.i(TAG, sb.toString()); 17185 sb.setLength(0); 17186 sb.append("CPU for "); 17187 app.toShortString(sb); 17188 sb.append(": over "); 17189 TimeUtils.formatDuration(uptimeSince, sb); 17190 sb.append(" used "); 17191 TimeUtils.formatDuration(cputimeUsed, sb); 17192 sb.append(" ("); 17193 sb.append((cputimeUsed*100)/uptimeSince); 17194 sb.append("%)"); 17195 Slog.i(TAG, sb.toString()); 17196 } 17197 // If a process has held a wake lock for more 17198 // than 50% of the time during this period, 17199 // that sounds bad. Kill! 17200 if (doWakeKills && realtimeSince > 0 17201 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17202 synchronized (stats) { 17203 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17204 realtimeSince, wtimeUsed); 17205 } 17206 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17207 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17208 } else if (doCpuKills && uptimeSince > 0 17209 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17210 synchronized (stats) { 17211 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17212 uptimeSince, cputimeUsed); 17213 } 17214 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17215 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17216 } else { 17217 app.lastWakeTime = wtime; 17218 app.lastCpuTime = app.curCpuTime; 17219 } 17220 } 17221 } 17222 } 17223 17224 private final boolean applyOomAdjLocked(ProcessRecord app, 17225 ProcessRecord TOP_APP, boolean doingAll, long now) { 17226 boolean success = true; 17227 17228 if (app.curRawAdj != app.setRawAdj) { 17229 app.setRawAdj = app.curRawAdj; 17230 } 17231 17232 int changes = 0; 17233 17234 if (app.curAdj != app.setAdj) { 17235 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17236 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17237 TAG, "Set " + app.pid + " " + app.processName + 17238 " adj " + app.curAdj + ": " + app.adjType); 17239 app.setAdj = app.curAdj; 17240 } 17241 17242 if (app.setSchedGroup != app.curSchedGroup) { 17243 app.setSchedGroup = app.curSchedGroup; 17244 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17245 "Setting process group of " + app.processName 17246 + " to " + app.curSchedGroup); 17247 if (app.waitingToKill != null && 17248 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17249 app.kill(app.waitingToKill, true); 17250 success = false; 17251 } else { 17252 if (true) { 17253 long oldId = Binder.clearCallingIdentity(); 17254 try { 17255 Process.setProcessGroup(app.pid, app.curSchedGroup); 17256 } catch (Exception e) { 17257 Slog.w(TAG, "Failed setting process group of " + app.pid 17258 + " to " + app.curSchedGroup); 17259 e.printStackTrace(); 17260 } finally { 17261 Binder.restoreCallingIdentity(oldId); 17262 } 17263 } else { 17264 if (app.thread != null) { 17265 try { 17266 app.thread.setSchedulingGroup(app.curSchedGroup); 17267 } catch (RemoteException e) { 17268 } 17269 } 17270 } 17271 Process.setSwappiness(app.pid, 17272 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17273 } 17274 } 17275 if (app.repForegroundActivities != app.foregroundActivities) { 17276 app.repForegroundActivities = app.foregroundActivities; 17277 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17278 } 17279 if (app.repProcState != app.curProcState) { 17280 app.repProcState = app.curProcState; 17281 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17282 if (app.thread != null) { 17283 try { 17284 if (false) { 17285 //RuntimeException h = new RuntimeException("here"); 17286 Slog.i(TAG, "Sending new process state " + app.repProcState 17287 + " to " + app /*, h*/); 17288 } 17289 app.thread.setProcessState(app.repProcState); 17290 } catch (RemoteException e) { 17291 } 17292 } 17293 } 17294 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17295 app.setProcState)) { 17296 app.lastStateTime = now; 17297 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17298 isSleeping(), now); 17299 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17300 + ProcessList.makeProcStateString(app.setProcState) + " to " 17301 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17302 + (app.nextPssTime-now) + ": " + app); 17303 } else { 17304 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17305 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17306 requestPssLocked(app, app.setProcState); 17307 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17308 isSleeping(), now); 17309 } else if (false && DEBUG_PSS) { 17310 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17311 } 17312 } 17313 if (app.setProcState != app.curProcState) { 17314 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17315 "Proc state change of " + app.processName 17316 + " to " + app.curProcState); 17317 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17318 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17319 if (setImportant && !curImportant) { 17320 // This app is no longer something we consider important enough to allow to 17321 // use arbitrary amounts of battery power. Note 17322 // its current wake lock time to later know to kill it if 17323 // it is not behaving well. 17324 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17325 synchronized (stats) { 17326 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17327 app.pid, SystemClock.elapsedRealtime()); 17328 } 17329 app.lastCpuTime = app.curCpuTime; 17330 17331 } 17332 app.setProcState = app.curProcState; 17333 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17334 app.notCachedSinceIdle = false; 17335 } 17336 if (!doingAll) { 17337 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17338 } else { 17339 app.procStateChanged = true; 17340 } 17341 } 17342 17343 if (changes != 0) { 17344 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17345 int i = mPendingProcessChanges.size()-1; 17346 ProcessChangeItem item = null; 17347 while (i >= 0) { 17348 item = mPendingProcessChanges.get(i); 17349 if (item.pid == app.pid) { 17350 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17351 break; 17352 } 17353 i--; 17354 } 17355 if (i < 0) { 17356 // No existing item in pending changes; need a new one. 17357 final int NA = mAvailProcessChanges.size(); 17358 if (NA > 0) { 17359 item = mAvailProcessChanges.remove(NA-1); 17360 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17361 } else { 17362 item = new ProcessChangeItem(); 17363 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17364 } 17365 item.changes = 0; 17366 item.pid = app.pid; 17367 item.uid = app.info.uid; 17368 if (mPendingProcessChanges.size() == 0) { 17369 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17370 "*** Enqueueing dispatch processes changed!"); 17371 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17372 } 17373 mPendingProcessChanges.add(item); 17374 } 17375 item.changes |= changes; 17376 item.processState = app.repProcState; 17377 item.foregroundActivities = app.repForegroundActivities; 17378 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17379 + Integer.toHexString(System.identityHashCode(item)) 17380 + " " + app.toShortString() + ": changes=" + item.changes 17381 + " procState=" + item.processState 17382 + " foreground=" + item.foregroundActivities 17383 + " type=" + app.adjType + " source=" + app.adjSource 17384 + " target=" + app.adjTarget); 17385 } 17386 17387 return success; 17388 } 17389 17390 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17391 if (proc.thread != null) { 17392 if (proc.baseProcessTracker != null) { 17393 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17394 } 17395 if (proc.repProcState >= 0) { 17396 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17397 proc.repProcState); 17398 } 17399 } 17400 } 17401 17402 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17403 ProcessRecord TOP_APP, boolean doingAll, long now) { 17404 if (app.thread == null) { 17405 return false; 17406 } 17407 17408 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17409 17410 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17411 } 17412 17413 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17414 boolean oomAdj) { 17415 if (isForeground != proc.foregroundServices) { 17416 proc.foregroundServices = isForeground; 17417 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17418 proc.info.uid); 17419 if (isForeground) { 17420 if (curProcs == null) { 17421 curProcs = new ArrayList<ProcessRecord>(); 17422 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17423 } 17424 if (!curProcs.contains(proc)) { 17425 curProcs.add(proc); 17426 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17427 proc.info.packageName, proc.info.uid); 17428 } 17429 } else { 17430 if (curProcs != null) { 17431 if (curProcs.remove(proc)) { 17432 mBatteryStatsService.noteEvent( 17433 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17434 proc.info.packageName, proc.info.uid); 17435 if (curProcs.size() <= 0) { 17436 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17437 } 17438 } 17439 } 17440 } 17441 if (oomAdj) { 17442 updateOomAdjLocked(); 17443 } 17444 } 17445 } 17446 17447 private final ActivityRecord resumedAppLocked() { 17448 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17449 String pkg; 17450 int uid; 17451 if (act != null) { 17452 pkg = act.packageName; 17453 uid = act.info.applicationInfo.uid; 17454 } else { 17455 pkg = null; 17456 uid = -1; 17457 } 17458 // Has the UID or resumed package name changed? 17459 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17460 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17461 if (mCurResumedPackage != null) { 17462 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17463 mCurResumedPackage, mCurResumedUid); 17464 } 17465 mCurResumedPackage = pkg; 17466 mCurResumedUid = uid; 17467 if (mCurResumedPackage != null) { 17468 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17469 mCurResumedPackage, mCurResumedUid); 17470 } 17471 } 17472 return act; 17473 } 17474 17475 final boolean updateOomAdjLocked(ProcessRecord app) { 17476 final ActivityRecord TOP_ACT = resumedAppLocked(); 17477 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17478 final boolean wasCached = app.cached; 17479 17480 mAdjSeq++; 17481 17482 // This is the desired cached adjusment we want to tell it to use. 17483 // If our app is currently cached, we know it, and that is it. Otherwise, 17484 // we don't know it yet, and it needs to now be cached we will then 17485 // need to do a complete oom adj. 17486 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17487 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17488 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17489 SystemClock.uptimeMillis()); 17490 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17491 // Changed to/from cached state, so apps after it in the LRU 17492 // list may also be changed. 17493 updateOomAdjLocked(); 17494 } 17495 return success; 17496 } 17497 17498 final void updateOomAdjLocked() { 17499 final ActivityRecord TOP_ACT = resumedAppLocked(); 17500 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17501 final long now = SystemClock.uptimeMillis(); 17502 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17503 final int N = mLruProcesses.size(); 17504 17505 if (false) { 17506 RuntimeException e = new RuntimeException(); 17507 e.fillInStackTrace(); 17508 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17509 } 17510 17511 mAdjSeq++; 17512 mNewNumServiceProcs = 0; 17513 mNewNumAServiceProcs = 0; 17514 17515 final int emptyProcessLimit; 17516 final int cachedProcessLimit; 17517 if (mProcessLimit <= 0) { 17518 emptyProcessLimit = cachedProcessLimit = 0; 17519 } else if (mProcessLimit == 1) { 17520 emptyProcessLimit = 1; 17521 cachedProcessLimit = 0; 17522 } else { 17523 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17524 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17525 } 17526 17527 // Let's determine how many processes we have running vs. 17528 // how many slots we have for background processes; we may want 17529 // to put multiple processes in a slot of there are enough of 17530 // them. 17531 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17532 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17533 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17534 if (numEmptyProcs > cachedProcessLimit) { 17535 // If there are more empty processes than our limit on cached 17536 // processes, then use the cached process limit for the factor. 17537 // This ensures that the really old empty processes get pushed 17538 // down to the bottom, so if we are running low on memory we will 17539 // have a better chance at keeping around more cached processes 17540 // instead of a gazillion empty processes. 17541 numEmptyProcs = cachedProcessLimit; 17542 } 17543 int emptyFactor = numEmptyProcs/numSlots; 17544 if (emptyFactor < 1) emptyFactor = 1; 17545 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17546 if (cachedFactor < 1) cachedFactor = 1; 17547 int stepCached = 0; 17548 int stepEmpty = 0; 17549 int numCached = 0; 17550 int numEmpty = 0; 17551 int numTrimming = 0; 17552 17553 mNumNonCachedProcs = 0; 17554 mNumCachedHiddenProcs = 0; 17555 17556 // First update the OOM adjustment for each of the 17557 // application processes based on their current state. 17558 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17559 int nextCachedAdj = curCachedAdj+1; 17560 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17561 int nextEmptyAdj = curEmptyAdj+2; 17562 for (int i=N-1; i>=0; i--) { 17563 ProcessRecord app = mLruProcesses.get(i); 17564 if (!app.killedByAm && app.thread != null) { 17565 app.procStateChanged = false; 17566 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17567 17568 // If we haven't yet assigned the final cached adj 17569 // to the process, do that now. 17570 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17571 switch (app.curProcState) { 17572 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17573 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17574 // This process is a cached process holding activities... 17575 // assign it the next cached value for that type, and then 17576 // step that cached level. 17577 app.curRawAdj = curCachedAdj; 17578 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17579 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17580 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17581 + ")"); 17582 if (curCachedAdj != nextCachedAdj) { 17583 stepCached++; 17584 if (stepCached >= cachedFactor) { 17585 stepCached = 0; 17586 curCachedAdj = nextCachedAdj; 17587 nextCachedAdj += 2; 17588 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17589 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17590 } 17591 } 17592 } 17593 break; 17594 default: 17595 // For everything else, assign next empty cached process 17596 // level and bump that up. Note that this means that 17597 // long-running services that have dropped down to the 17598 // cached level will be treated as empty (since their process 17599 // state is still as a service), which is what we want. 17600 app.curRawAdj = curEmptyAdj; 17601 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17602 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17603 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17604 + ")"); 17605 if (curEmptyAdj != nextEmptyAdj) { 17606 stepEmpty++; 17607 if (stepEmpty >= emptyFactor) { 17608 stepEmpty = 0; 17609 curEmptyAdj = nextEmptyAdj; 17610 nextEmptyAdj += 2; 17611 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17612 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17613 } 17614 } 17615 } 17616 break; 17617 } 17618 } 17619 17620 applyOomAdjLocked(app, TOP_APP, true, now); 17621 17622 // Count the number of process types. 17623 switch (app.curProcState) { 17624 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17625 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17626 mNumCachedHiddenProcs++; 17627 numCached++; 17628 if (numCached > cachedProcessLimit) { 17629 app.kill("cached #" + numCached, true); 17630 } 17631 break; 17632 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17633 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17634 && app.lastActivityTime < oldTime) { 17635 app.kill("empty for " 17636 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17637 / 1000) + "s", true); 17638 } else { 17639 numEmpty++; 17640 if (numEmpty > emptyProcessLimit) { 17641 app.kill("empty #" + numEmpty, true); 17642 } 17643 } 17644 break; 17645 default: 17646 mNumNonCachedProcs++; 17647 break; 17648 } 17649 17650 if (app.isolated && app.services.size() <= 0) { 17651 // If this is an isolated process, and there are no 17652 // services running in it, then the process is no longer 17653 // needed. We agressively kill these because we can by 17654 // definition not re-use the same process again, and it is 17655 // good to avoid having whatever code was running in them 17656 // left sitting around after no longer needed. 17657 app.kill("isolated not needed", true); 17658 } 17659 17660 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17661 && !app.killedByAm) { 17662 numTrimming++; 17663 } 17664 } 17665 } 17666 17667 mNumServiceProcs = mNewNumServiceProcs; 17668 17669 // Now determine the memory trimming level of background processes. 17670 // Unfortunately we need to start at the back of the list to do this 17671 // properly. We only do this if the number of background apps we 17672 // are managing to keep around is less than half the maximum we desire; 17673 // if we are keeping a good number around, we'll let them use whatever 17674 // memory they want. 17675 final int numCachedAndEmpty = numCached + numEmpty; 17676 int memFactor; 17677 if (numCached <= ProcessList.TRIM_CACHED_APPS 17678 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17679 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17680 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17681 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17682 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17683 } else { 17684 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17685 } 17686 } else { 17687 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17688 } 17689 // We always allow the memory level to go up (better). We only allow it to go 17690 // down if we are in a state where that is allowed, *and* the total number of processes 17691 // has gone down since last time. 17692 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17693 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17694 + " last=" + mLastNumProcesses); 17695 if (memFactor > mLastMemoryLevel) { 17696 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17697 memFactor = mLastMemoryLevel; 17698 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17699 } 17700 } 17701 mLastMemoryLevel = memFactor; 17702 mLastNumProcesses = mLruProcesses.size(); 17703 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17704 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17705 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17706 if (mLowRamStartTime == 0) { 17707 mLowRamStartTime = now; 17708 } 17709 int step = 0; 17710 int fgTrimLevel; 17711 switch (memFactor) { 17712 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17713 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17714 break; 17715 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17716 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17717 break; 17718 default: 17719 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17720 break; 17721 } 17722 int factor = numTrimming/3; 17723 int minFactor = 2; 17724 if (mHomeProcess != null) minFactor++; 17725 if (mPreviousProcess != null) minFactor++; 17726 if (factor < minFactor) factor = minFactor; 17727 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17728 for (int i=N-1; i>=0; i--) { 17729 ProcessRecord app = mLruProcesses.get(i); 17730 if (allChanged || app.procStateChanged) { 17731 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17732 app.procStateChanged = false; 17733 } 17734 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17735 && !app.killedByAm) { 17736 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17737 try { 17738 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17739 "Trimming memory of " + app.processName 17740 + " to " + curLevel); 17741 app.thread.scheduleTrimMemory(curLevel); 17742 } catch (RemoteException e) { 17743 } 17744 if (false) { 17745 // For now we won't do this; our memory trimming seems 17746 // to be good enough at this point that destroying 17747 // activities causes more harm than good. 17748 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17749 && app != mHomeProcess && app != mPreviousProcess) { 17750 // Need to do this on its own message because the stack may not 17751 // be in a consistent state at this point. 17752 // For these apps we will also finish their activities 17753 // to help them free memory. 17754 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17755 } 17756 } 17757 } 17758 app.trimMemoryLevel = curLevel; 17759 step++; 17760 if (step >= factor) { 17761 step = 0; 17762 switch (curLevel) { 17763 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17764 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17765 break; 17766 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17767 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17768 break; 17769 } 17770 } 17771 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17772 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17773 && app.thread != null) { 17774 try { 17775 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17776 "Trimming memory of heavy-weight " + app.processName 17777 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17778 app.thread.scheduleTrimMemory( 17779 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17780 } catch (RemoteException e) { 17781 } 17782 } 17783 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17784 } else { 17785 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17786 || app.systemNoUi) && app.pendingUiClean) { 17787 // If this application is now in the background and it 17788 // had done UI, then give it the special trim level to 17789 // have it free UI resources. 17790 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17791 if (app.trimMemoryLevel < level && app.thread != null) { 17792 try { 17793 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17794 "Trimming memory of bg-ui " + app.processName 17795 + " to " + level); 17796 app.thread.scheduleTrimMemory(level); 17797 } catch (RemoteException e) { 17798 } 17799 } 17800 app.pendingUiClean = false; 17801 } 17802 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17803 try { 17804 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17805 "Trimming memory of fg " + app.processName 17806 + " to " + fgTrimLevel); 17807 app.thread.scheduleTrimMemory(fgTrimLevel); 17808 } catch (RemoteException e) { 17809 } 17810 } 17811 app.trimMemoryLevel = fgTrimLevel; 17812 } 17813 } 17814 } else { 17815 if (mLowRamStartTime != 0) { 17816 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17817 mLowRamStartTime = 0; 17818 } 17819 for (int i=N-1; i>=0; i--) { 17820 ProcessRecord app = mLruProcesses.get(i); 17821 if (allChanged || app.procStateChanged) { 17822 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17823 app.procStateChanged = false; 17824 } 17825 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17826 || app.systemNoUi) && app.pendingUiClean) { 17827 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17828 && app.thread != null) { 17829 try { 17830 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17831 "Trimming memory of ui hidden " + app.processName 17832 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17833 app.thread.scheduleTrimMemory( 17834 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17835 } catch (RemoteException e) { 17836 } 17837 } 17838 app.pendingUiClean = false; 17839 } 17840 app.trimMemoryLevel = 0; 17841 } 17842 } 17843 17844 if (mAlwaysFinishActivities) { 17845 // Need to do this on its own message because the stack may not 17846 // be in a consistent state at this point. 17847 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17848 } 17849 17850 if (allChanged) { 17851 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17852 } 17853 17854 if (mProcessStats.shouldWriteNowLocked(now)) { 17855 mHandler.post(new Runnable() { 17856 @Override public void run() { 17857 synchronized (ActivityManagerService.this) { 17858 mProcessStats.writeStateAsyncLocked(); 17859 } 17860 } 17861 }); 17862 } 17863 17864 if (DEBUG_OOM_ADJ) { 17865 if (false) { 17866 RuntimeException here = new RuntimeException("here"); 17867 here.fillInStackTrace(); 17868 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17869 } else { 17870 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17871 } 17872 } 17873 } 17874 17875 final void trimApplications() { 17876 synchronized (this) { 17877 int i; 17878 17879 // First remove any unused application processes whose package 17880 // has been removed. 17881 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17882 final ProcessRecord app = mRemovedProcesses.get(i); 17883 if (app.activities.size() == 0 17884 && app.curReceiver == null && app.services.size() == 0) { 17885 Slog.i( 17886 TAG, "Exiting empty application process " 17887 + app.processName + " (" 17888 + (app.thread != null ? app.thread.asBinder() : null) 17889 + ")\n"); 17890 if (app.pid > 0 && app.pid != MY_PID) { 17891 app.kill("empty", false); 17892 } else { 17893 try { 17894 app.thread.scheduleExit(); 17895 } catch (Exception e) { 17896 // Ignore exceptions. 17897 } 17898 } 17899 cleanUpApplicationRecordLocked(app, false, true, -1); 17900 mRemovedProcesses.remove(i); 17901 17902 if (app.persistent) { 17903 addAppLocked(app.info, false, null /* ABI override */); 17904 } 17905 } 17906 } 17907 17908 // Now update the oom adj for all processes. 17909 updateOomAdjLocked(); 17910 } 17911 } 17912 17913 /** This method sends the specified signal to each of the persistent apps */ 17914 public void signalPersistentProcesses(int sig) throws RemoteException { 17915 if (sig != Process.SIGNAL_USR1) { 17916 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17917 } 17918 17919 synchronized (this) { 17920 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17921 != PackageManager.PERMISSION_GRANTED) { 17922 throw new SecurityException("Requires permission " 17923 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17924 } 17925 17926 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17927 ProcessRecord r = mLruProcesses.get(i); 17928 if (r.thread != null && r.persistent) { 17929 Process.sendSignal(r.pid, sig); 17930 } 17931 } 17932 } 17933 } 17934 17935 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17936 if (proc == null || proc == mProfileProc) { 17937 proc = mProfileProc; 17938 profileType = mProfileType; 17939 clearProfilerLocked(); 17940 } 17941 if (proc == null) { 17942 return; 17943 } 17944 try { 17945 proc.thread.profilerControl(false, null, profileType); 17946 } catch (RemoteException e) { 17947 throw new IllegalStateException("Process disappeared"); 17948 } 17949 } 17950 17951 private void clearProfilerLocked() { 17952 if (mProfileFd != null) { 17953 try { 17954 mProfileFd.close(); 17955 } catch (IOException e) { 17956 } 17957 } 17958 mProfileApp = null; 17959 mProfileProc = null; 17960 mProfileFile = null; 17961 mProfileType = 0; 17962 mAutoStopProfiler = false; 17963 mSamplingInterval = 0; 17964 } 17965 17966 public boolean profileControl(String process, int userId, boolean start, 17967 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17968 17969 try { 17970 synchronized (this) { 17971 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17972 // its own permission. 17973 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17974 != PackageManager.PERMISSION_GRANTED) { 17975 throw new SecurityException("Requires permission " 17976 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17977 } 17978 17979 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17980 throw new IllegalArgumentException("null profile info or fd"); 17981 } 17982 17983 ProcessRecord proc = null; 17984 if (process != null) { 17985 proc = findProcessLocked(process, userId, "profileControl"); 17986 } 17987 17988 if (start && (proc == null || proc.thread == null)) { 17989 throw new IllegalArgumentException("Unknown process: " + process); 17990 } 17991 17992 if (start) { 17993 stopProfilerLocked(null, 0); 17994 setProfileApp(proc.info, proc.processName, profilerInfo); 17995 mProfileProc = proc; 17996 mProfileType = profileType; 17997 ParcelFileDescriptor fd = profilerInfo.profileFd; 17998 try { 17999 fd = fd.dup(); 18000 } catch (IOException e) { 18001 fd = null; 18002 } 18003 profilerInfo.profileFd = fd; 18004 proc.thread.profilerControl(start, profilerInfo, profileType); 18005 fd = null; 18006 mProfileFd = null; 18007 } else { 18008 stopProfilerLocked(proc, profileType); 18009 if (profilerInfo != null && profilerInfo.profileFd != null) { 18010 try { 18011 profilerInfo.profileFd.close(); 18012 } catch (IOException e) { 18013 } 18014 } 18015 } 18016 18017 return true; 18018 } 18019 } catch (RemoteException e) { 18020 throw new IllegalStateException("Process disappeared"); 18021 } finally { 18022 if (profilerInfo != null && profilerInfo.profileFd != null) { 18023 try { 18024 profilerInfo.profileFd.close(); 18025 } catch (IOException e) { 18026 } 18027 } 18028 } 18029 } 18030 18031 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18032 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18033 userId, true, ALLOW_FULL_ONLY, callName, null); 18034 ProcessRecord proc = null; 18035 try { 18036 int pid = Integer.parseInt(process); 18037 synchronized (mPidsSelfLocked) { 18038 proc = mPidsSelfLocked.get(pid); 18039 } 18040 } catch (NumberFormatException e) { 18041 } 18042 18043 if (proc == null) { 18044 ArrayMap<String, SparseArray<ProcessRecord>> all 18045 = mProcessNames.getMap(); 18046 SparseArray<ProcessRecord> procs = all.get(process); 18047 if (procs != null && procs.size() > 0) { 18048 proc = procs.valueAt(0); 18049 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18050 for (int i=1; i<procs.size(); i++) { 18051 ProcessRecord thisProc = procs.valueAt(i); 18052 if (thisProc.userId == userId) { 18053 proc = thisProc; 18054 break; 18055 } 18056 } 18057 } 18058 } 18059 } 18060 18061 return proc; 18062 } 18063 18064 public boolean dumpHeap(String process, int userId, boolean managed, 18065 String path, ParcelFileDescriptor fd) throws RemoteException { 18066 18067 try { 18068 synchronized (this) { 18069 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18070 // its own permission (same as profileControl). 18071 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18072 != PackageManager.PERMISSION_GRANTED) { 18073 throw new SecurityException("Requires permission " 18074 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18075 } 18076 18077 if (fd == null) { 18078 throw new IllegalArgumentException("null fd"); 18079 } 18080 18081 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18082 if (proc == null || proc.thread == null) { 18083 throw new IllegalArgumentException("Unknown process: " + process); 18084 } 18085 18086 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18087 if (!isDebuggable) { 18088 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18089 throw new SecurityException("Process not debuggable: " + proc); 18090 } 18091 } 18092 18093 proc.thread.dumpHeap(managed, path, fd); 18094 fd = null; 18095 return true; 18096 } 18097 } catch (RemoteException e) { 18098 throw new IllegalStateException("Process disappeared"); 18099 } finally { 18100 if (fd != null) { 18101 try { 18102 fd.close(); 18103 } catch (IOException e) { 18104 } 18105 } 18106 } 18107 } 18108 18109 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18110 public void monitor() { 18111 synchronized (this) { } 18112 } 18113 18114 void onCoreSettingsChange(Bundle settings) { 18115 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18116 ProcessRecord processRecord = mLruProcesses.get(i); 18117 try { 18118 if (processRecord.thread != null) { 18119 processRecord.thread.setCoreSettings(settings); 18120 } 18121 } catch (RemoteException re) { 18122 /* ignore */ 18123 } 18124 } 18125 } 18126 18127 // Multi-user methods 18128 18129 /** 18130 * Start user, if its not already running, but don't bring it to foreground. 18131 */ 18132 @Override 18133 public boolean startUserInBackground(final int userId) { 18134 return startUser(userId, /* foreground */ false); 18135 } 18136 18137 /** 18138 * Start user, if its not already running, and bring it to foreground. 18139 */ 18140 boolean startUserInForeground(final int userId, Dialog dlg) { 18141 boolean result = startUser(userId, /* foreground */ true); 18142 dlg.dismiss(); 18143 return result; 18144 } 18145 18146 /** 18147 * Refreshes the list of users related to the current user when either a 18148 * user switch happens or when a new related user is started in the 18149 * background. 18150 */ 18151 private void updateCurrentProfileIdsLocked() { 18152 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18153 mCurrentUserId, false /* enabledOnly */); 18154 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18155 for (int i = 0; i < currentProfileIds.length; i++) { 18156 currentProfileIds[i] = profiles.get(i).id; 18157 } 18158 mCurrentProfileIds = currentProfileIds; 18159 18160 synchronized (mUserProfileGroupIdsSelfLocked) { 18161 mUserProfileGroupIdsSelfLocked.clear(); 18162 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18163 for (int i = 0; i < users.size(); i++) { 18164 UserInfo user = users.get(i); 18165 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18166 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18167 } 18168 } 18169 } 18170 } 18171 18172 private Set getProfileIdsLocked(int userId) { 18173 Set userIds = new HashSet<Integer>(); 18174 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18175 userId, false /* enabledOnly */); 18176 for (UserInfo user : profiles) { 18177 userIds.add(Integer.valueOf(user.id)); 18178 } 18179 return userIds; 18180 } 18181 18182 @Override 18183 public boolean switchUser(final int userId) { 18184 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18185 String userName; 18186 synchronized (this) { 18187 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18188 if (userInfo == null) { 18189 Slog.w(TAG, "No user info for user #" + userId); 18190 return false; 18191 } 18192 if (userInfo.isManagedProfile()) { 18193 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18194 return false; 18195 } 18196 userName = userInfo.name; 18197 mTargetUserId = userId; 18198 } 18199 mHandler.removeMessages(START_USER_SWITCH_MSG); 18200 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18201 return true; 18202 } 18203 18204 private void showUserSwitchDialog(int userId, String userName) { 18205 // The dialog will show and then initiate the user switch by calling startUserInForeground 18206 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18207 true /* above system */); 18208 d.show(); 18209 } 18210 18211 private boolean startUser(final int userId, final boolean foreground) { 18212 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18213 != PackageManager.PERMISSION_GRANTED) { 18214 String msg = "Permission Denial: switchUser() from pid=" 18215 + Binder.getCallingPid() 18216 + ", uid=" + Binder.getCallingUid() 18217 + " requires " + INTERACT_ACROSS_USERS_FULL; 18218 Slog.w(TAG, msg); 18219 throw new SecurityException(msg); 18220 } 18221 18222 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18223 18224 final long ident = Binder.clearCallingIdentity(); 18225 try { 18226 synchronized (this) { 18227 final int oldUserId = mCurrentUserId; 18228 if (oldUserId == userId) { 18229 return true; 18230 } 18231 18232 mStackSupervisor.setLockTaskModeLocked(null, false); 18233 18234 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18235 if (userInfo == null) { 18236 Slog.w(TAG, "No user info for user #" + userId); 18237 return false; 18238 } 18239 if (foreground && userInfo.isManagedProfile()) { 18240 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18241 return false; 18242 } 18243 18244 if (foreground) { 18245 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18246 R.anim.screen_user_enter); 18247 } 18248 18249 boolean needStart = false; 18250 18251 // If the user we are switching to is not currently started, then 18252 // we need to start it now. 18253 if (mStartedUsers.get(userId) == null) { 18254 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18255 updateStartedUserArrayLocked(); 18256 needStart = true; 18257 } 18258 18259 final Integer userIdInt = Integer.valueOf(userId); 18260 mUserLru.remove(userIdInt); 18261 mUserLru.add(userIdInt); 18262 18263 if (foreground) { 18264 mCurrentUserId = userId; 18265 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18266 updateCurrentProfileIdsLocked(); 18267 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18268 // Once the internal notion of the active user has switched, we lock the device 18269 // with the option to show the user switcher on the keyguard. 18270 mWindowManager.lockNow(null); 18271 } else { 18272 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18273 updateCurrentProfileIdsLocked(); 18274 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18275 mUserLru.remove(currentUserIdInt); 18276 mUserLru.add(currentUserIdInt); 18277 } 18278 18279 final UserStartedState uss = mStartedUsers.get(userId); 18280 18281 // Make sure user is in the started state. If it is currently 18282 // stopping, we need to knock that off. 18283 if (uss.mState == UserStartedState.STATE_STOPPING) { 18284 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18285 // so we can just fairly silently bring the user back from 18286 // the almost-dead. 18287 uss.mState = UserStartedState.STATE_RUNNING; 18288 updateStartedUserArrayLocked(); 18289 needStart = true; 18290 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18291 // This means ACTION_SHUTDOWN has been sent, so we will 18292 // need to treat this as a new boot of the user. 18293 uss.mState = UserStartedState.STATE_BOOTING; 18294 updateStartedUserArrayLocked(); 18295 needStart = true; 18296 } 18297 18298 if (uss.mState == UserStartedState.STATE_BOOTING) { 18299 // Booting up a new user, need to tell system services about it. 18300 // Note that this is on the same handler as scheduling of broadcasts, 18301 // which is important because it needs to go first. 18302 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18303 } 18304 18305 if (foreground) { 18306 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18307 oldUserId)); 18308 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18309 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18310 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18311 oldUserId, userId, uss)); 18312 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18313 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18314 } 18315 18316 if (needStart) { 18317 // Send USER_STARTED broadcast 18318 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18320 | Intent.FLAG_RECEIVER_FOREGROUND); 18321 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18322 broadcastIntentLocked(null, null, intent, 18323 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18324 false, false, MY_PID, Process.SYSTEM_UID, userId); 18325 } 18326 18327 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18328 if (userId != UserHandle.USER_OWNER) { 18329 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18330 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18331 broadcastIntentLocked(null, null, intent, null, 18332 new IIntentReceiver.Stub() { 18333 public void performReceive(Intent intent, int resultCode, 18334 String data, Bundle extras, boolean ordered, 18335 boolean sticky, int sendingUser) { 18336 onUserInitialized(uss, foreground, oldUserId, userId); 18337 } 18338 }, 0, null, null, null, AppOpsManager.OP_NONE, 18339 true, false, MY_PID, Process.SYSTEM_UID, 18340 userId); 18341 uss.initializing = true; 18342 } else { 18343 getUserManagerLocked().makeInitialized(userInfo.id); 18344 } 18345 } 18346 18347 if (foreground) { 18348 if (!uss.initializing) { 18349 moveUserToForeground(uss, oldUserId, userId); 18350 } 18351 } else { 18352 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18353 } 18354 18355 if (needStart) { 18356 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18357 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18358 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18359 broadcastIntentLocked(null, null, intent, 18360 null, new IIntentReceiver.Stub() { 18361 @Override 18362 public void performReceive(Intent intent, int resultCode, String data, 18363 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18364 throws RemoteException { 18365 } 18366 }, 0, null, null, 18367 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18368 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18369 } 18370 } 18371 } finally { 18372 Binder.restoreCallingIdentity(ident); 18373 } 18374 18375 return true; 18376 } 18377 18378 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18379 long ident = Binder.clearCallingIdentity(); 18380 try { 18381 Intent intent; 18382 if (oldUserId >= 0) { 18383 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18384 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18385 int count = profiles.size(); 18386 for (int i = 0; i < count; i++) { 18387 int profileUserId = profiles.get(i).id; 18388 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18390 | Intent.FLAG_RECEIVER_FOREGROUND); 18391 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18392 broadcastIntentLocked(null, null, intent, 18393 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18394 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18395 } 18396 } 18397 if (newUserId >= 0) { 18398 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18399 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18400 int count = profiles.size(); 18401 for (int i = 0; i < count; i++) { 18402 int profileUserId = profiles.get(i).id; 18403 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18404 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18405 | Intent.FLAG_RECEIVER_FOREGROUND); 18406 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18407 broadcastIntentLocked(null, null, intent, 18408 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18409 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18410 } 18411 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18413 | Intent.FLAG_RECEIVER_FOREGROUND); 18414 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18415 broadcastIntentLocked(null, null, intent, 18416 null, null, 0, null, null, 18417 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18418 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18419 } 18420 } finally { 18421 Binder.restoreCallingIdentity(ident); 18422 } 18423 } 18424 18425 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18426 final int newUserId) { 18427 final int N = mUserSwitchObservers.beginBroadcast(); 18428 if (N > 0) { 18429 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18430 int mCount = 0; 18431 @Override 18432 public void sendResult(Bundle data) throws RemoteException { 18433 synchronized (ActivityManagerService.this) { 18434 if (mCurUserSwitchCallback == this) { 18435 mCount++; 18436 if (mCount == N) { 18437 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18438 } 18439 } 18440 } 18441 } 18442 }; 18443 synchronized (this) { 18444 uss.switching = true; 18445 mCurUserSwitchCallback = callback; 18446 } 18447 for (int i=0; i<N; i++) { 18448 try { 18449 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18450 newUserId, callback); 18451 } catch (RemoteException e) { 18452 } 18453 } 18454 } else { 18455 synchronized (this) { 18456 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18457 } 18458 } 18459 mUserSwitchObservers.finishBroadcast(); 18460 } 18461 18462 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18463 synchronized (this) { 18464 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18465 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18466 } 18467 } 18468 18469 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18470 mCurUserSwitchCallback = null; 18471 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18472 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18473 oldUserId, newUserId, uss)); 18474 } 18475 18476 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18477 synchronized (this) { 18478 if (foreground) { 18479 moveUserToForeground(uss, oldUserId, newUserId); 18480 } 18481 } 18482 18483 completeSwitchAndInitalize(uss, newUserId, true, false); 18484 } 18485 18486 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18487 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18488 if (homeInFront) { 18489 startHomeActivityLocked(newUserId); 18490 } else { 18491 mStackSupervisor.resumeTopActivitiesLocked(); 18492 } 18493 EventLogTags.writeAmSwitchUser(newUserId); 18494 getUserManagerLocked().userForeground(newUserId); 18495 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18496 } 18497 18498 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18499 completeSwitchAndInitalize(uss, newUserId, false, true); 18500 } 18501 18502 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18503 boolean clearInitializing, boolean clearSwitching) { 18504 boolean unfrozen = false; 18505 synchronized (this) { 18506 if (clearInitializing) { 18507 uss.initializing = false; 18508 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18509 } 18510 if (clearSwitching) { 18511 uss.switching = false; 18512 } 18513 if (!uss.switching && !uss.initializing) { 18514 mWindowManager.stopFreezingScreen(); 18515 unfrozen = true; 18516 } 18517 } 18518 if (unfrozen) { 18519 final int N = mUserSwitchObservers.beginBroadcast(); 18520 for (int i=0; i<N; i++) { 18521 try { 18522 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18523 } catch (RemoteException e) { 18524 } 18525 } 18526 mUserSwitchObservers.finishBroadcast(); 18527 } 18528 } 18529 18530 void scheduleStartProfilesLocked() { 18531 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18532 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18533 DateUtils.SECOND_IN_MILLIS); 18534 } 18535 } 18536 18537 void startProfilesLocked() { 18538 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18539 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18540 mCurrentUserId, false /* enabledOnly */); 18541 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18542 for (UserInfo user : profiles) { 18543 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18544 && user.id != mCurrentUserId) { 18545 toStart.add(user); 18546 } 18547 } 18548 final int n = toStart.size(); 18549 int i = 0; 18550 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18551 startUserInBackground(toStart.get(i).id); 18552 } 18553 if (i < n) { 18554 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18555 } 18556 } 18557 18558 void finishUserBoot(UserStartedState uss) { 18559 synchronized (this) { 18560 if (uss.mState == UserStartedState.STATE_BOOTING 18561 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18562 uss.mState = UserStartedState.STATE_RUNNING; 18563 final int userId = uss.mHandle.getIdentifier(); 18564 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18565 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18566 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18567 broadcastIntentLocked(null, null, intent, 18568 null, null, 0, null, null, 18569 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18570 true, false, MY_PID, Process.SYSTEM_UID, userId); 18571 } 18572 } 18573 } 18574 18575 void finishUserSwitch(UserStartedState uss) { 18576 synchronized (this) { 18577 finishUserBoot(uss); 18578 18579 startProfilesLocked(); 18580 18581 int num = mUserLru.size(); 18582 int i = 0; 18583 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18584 Integer oldUserId = mUserLru.get(i); 18585 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18586 if (oldUss == null) { 18587 // Shouldn't happen, but be sane if it does. 18588 mUserLru.remove(i); 18589 num--; 18590 continue; 18591 } 18592 if (oldUss.mState == UserStartedState.STATE_STOPPING 18593 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18594 // This user is already stopping, doesn't count. 18595 num--; 18596 i++; 18597 continue; 18598 } 18599 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18600 // Owner and current can't be stopped, but count as running. 18601 i++; 18602 continue; 18603 } 18604 // This is a user to be stopped. 18605 stopUserLocked(oldUserId, null); 18606 num--; 18607 i++; 18608 } 18609 } 18610 } 18611 18612 @Override 18613 public int stopUser(final int userId, final IStopUserCallback callback) { 18614 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18615 != PackageManager.PERMISSION_GRANTED) { 18616 String msg = "Permission Denial: switchUser() from pid=" 18617 + Binder.getCallingPid() 18618 + ", uid=" + Binder.getCallingUid() 18619 + " requires " + INTERACT_ACROSS_USERS_FULL; 18620 Slog.w(TAG, msg); 18621 throw new SecurityException(msg); 18622 } 18623 if (userId <= 0) { 18624 throw new IllegalArgumentException("Can't stop primary user " + userId); 18625 } 18626 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18627 synchronized (this) { 18628 return stopUserLocked(userId, callback); 18629 } 18630 } 18631 18632 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18633 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18634 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18635 return ActivityManager.USER_OP_IS_CURRENT; 18636 } 18637 18638 final UserStartedState uss = mStartedUsers.get(userId); 18639 if (uss == null) { 18640 // User is not started, nothing to do... but we do need to 18641 // callback if requested. 18642 if (callback != null) { 18643 mHandler.post(new Runnable() { 18644 @Override 18645 public void run() { 18646 try { 18647 callback.userStopped(userId); 18648 } catch (RemoteException e) { 18649 } 18650 } 18651 }); 18652 } 18653 return ActivityManager.USER_OP_SUCCESS; 18654 } 18655 18656 if (callback != null) { 18657 uss.mStopCallbacks.add(callback); 18658 } 18659 18660 if (uss.mState != UserStartedState.STATE_STOPPING 18661 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18662 uss.mState = UserStartedState.STATE_STOPPING; 18663 updateStartedUserArrayLocked(); 18664 18665 long ident = Binder.clearCallingIdentity(); 18666 try { 18667 // We are going to broadcast ACTION_USER_STOPPING and then 18668 // once that is done send a final ACTION_SHUTDOWN and then 18669 // stop the user. 18670 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18671 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18672 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18673 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18674 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18675 // This is the result receiver for the final shutdown broadcast. 18676 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18677 @Override 18678 public void performReceive(Intent intent, int resultCode, String data, 18679 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18680 finishUserStop(uss); 18681 } 18682 }; 18683 // This is the result receiver for the initial stopping broadcast. 18684 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18685 @Override 18686 public void performReceive(Intent intent, int resultCode, String data, 18687 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18688 // On to the next. 18689 synchronized (ActivityManagerService.this) { 18690 if (uss.mState != UserStartedState.STATE_STOPPING) { 18691 // Whoops, we are being started back up. Abort, abort! 18692 return; 18693 } 18694 uss.mState = UserStartedState.STATE_SHUTDOWN; 18695 } 18696 mBatteryStatsService.noteEvent( 18697 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18698 Integer.toString(userId), userId); 18699 mSystemServiceManager.stopUser(userId); 18700 broadcastIntentLocked(null, null, shutdownIntent, 18701 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18702 true, false, MY_PID, Process.SYSTEM_UID, userId); 18703 } 18704 }; 18705 // Kick things off. 18706 broadcastIntentLocked(null, null, stoppingIntent, 18707 null, stoppingReceiver, 0, null, null, 18708 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18709 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18710 } finally { 18711 Binder.restoreCallingIdentity(ident); 18712 } 18713 } 18714 18715 return ActivityManager.USER_OP_SUCCESS; 18716 } 18717 18718 void finishUserStop(UserStartedState uss) { 18719 final int userId = uss.mHandle.getIdentifier(); 18720 boolean stopped; 18721 ArrayList<IStopUserCallback> callbacks; 18722 synchronized (this) { 18723 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18724 if (mStartedUsers.get(userId) != uss) { 18725 stopped = false; 18726 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18727 stopped = false; 18728 } else { 18729 stopped = true; 18730 // User can no longer run. 18731 mStartedUsers.remove(userId); 18732 mUserLru.remove(Integer.valueOf(userId)); 18733 updateStartedUserArrayLocked(); 18734 18735 // Clean up all state and processes associated with the user. 18736 // Kill all the processes for the user. 18737 forceStopUserLocked(userId, "finish user"); 18738 } 18739 18740 // Explicitly remove the old information in mRecentTasks. 18741 removeRecentTasksForUserLocked(userId); 18742 } 18743 18744 for (int i=0; i<callbacks.size(); i++) { 18745 try { 18746 if (stopped) callbacks.get(i).userStopped(userId); 18747 else callbacks.get(i).userStopAborted(userId); 18748 } catch (RemoteException e) { 18749 } 18750 } 18751 18752 if (stopped) { 18753 mSystemServiceManager.cleanupUser(userId); 18754 synchronized (this) { 18755 mStackSupervisor.removeUserLocked(userId); 18756 } 18757 } 18758 } 18759 18760 @Override 18761 public UserInfo getCurrentUser() { 18762 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18763 != PackageManager.PERMISSION_GRANTED) && ( 18764 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18765 != PackageManager.PERMISSION_GRANTED)) { 18766 String msg = "Permission Denial: getCurrentUser() from pid=" 18767 + Binder.getCallingPid() 18768 + ", uid=" + Binder.getCallingUid() 18769 + " requires " + INTERACT_ACROSS_USERS; 18770 Slog.w(TAG, msg); 18771 throw new SecurityException(msg); 18772 } 18773 synchronized (this) { 18774 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18775 return getUserManagerLocked().getUserInfo(userId); 18776 } 18777 } 18778 18779 int getCurrentUserIdLocked() { 18780 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18781 } 18782 18783 @Override 18784 public boolean isUserRunning(int userId, boolean orStopped) { 18785 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18786 != PackageManager.PERMISSION_GRANTED) { 18787 String msg = "Permission Denial: isUserRunning() from pid=" 18788 + Binder.getCallingPid() 18789 + ", uid=" + Binder.getCallingUid() 18790 + " requires " + INTERACT_ACROSS_USERS; 18791 Slog.w(TAG, msg); 18792 throw new SecurityException(msg); 18793 } 18794 synchronized (this) { 18795 return isUserRunningLocked(userId, orStopped); 18796 } 18797 } 18798 18799 boolean isUserRunningLocked(int userId, boolean orStopped) { 18800 UserStartedState state = mStartedUsers.get(userId); 18801 if (state == null) { 18802 return false; 18803 } 18804 if (orStopped) { 18805 return true; 18806 } 18807 return state.mState != UserStartedState.STATE_STOPPING 18808 && state.mState != UserStartedState.STATE_SHUTDOWN; 18809 } 18810 18811 @Override 18812 public int[] getRunningUserIds() { 18813 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18814 != PackageManager.PERMISSION_GRANTED) { 18815 String msg = "Permission Denial: isUserRunning() from pid=" 18816 + Binder.getCallingPid() 18817 + ", uid=" + Binder.getCallingUid() 18818 + " requires " + INTERACT_ACROSS_USERS; 18819 Slog.w(TAG, msg); 18820 throw new SecurityException(msg); 18821 } 18822 synchronized (this) { 18823 return mStartedUserArray; 18824 } 18825 } 18826 18827 private void updateStartedUserArrayLocked() { 18828 int num = 0; 18829 for (int i=0; i<mStartedUsers.size(); i++) { 18830 UserStartedState uss = mStartedUsers.valueAt(i); 18831 // This list does not include stopping users. 18832 if (uss.mState != UserStartedState.STATE_STOPPING 18833 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18834 num++; 18835 } 18836 } 18837 mStartedUserArray = new int[num]; 18838 num = 0; 18839 for (int i=0; i<mStartedUsers.size(); i++) { 18840 UserStartedState uss = mStartedUsers.valueAt(i); 18841 if (uss.mState != UserStartedState.STATE_STOPPING 18842 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18843 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18844 num++; 18845 } 18846 } 18847 } 18848 18849 @Override 18850 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18851 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18852 != PackageManager.PERMISSION_GRANTED) { 18853 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18854 + Binder.getCallingPid() 18855 + ", uid=" + Binder.getCallingUid() 18856 + " requires " + INTERACT_ACROSS_USERS_FULL; 18857 Slog.w(TAG, msg); 18858 throw new SecurityException(msg); 18859 } 18860 18861 mUserSwitchObservers.register(observer); 18862 } 18863 18864 @Override 18865 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18866 mUserSwitchObservers.unregister(observer); 18867 } 18868 18869 private boolean userExists(int userId) { 18870 if (userId == 0) { 18871 return true; 18872 } 18873 UserManagerService ums = getUserManagerLocked(); 18874 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18875 } 18876 18877 int[] getUsersLocked() { 18878 UserManagerService ums = getUserManagerLocked(); 18879 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18880 } 18881 18882 UserManagerService getUserManagerLocked() { 18883 if (mUserManager == null) { 18884 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18885 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18886 } 18887 return mUserManager; 18888 } 18889 18890 private int applyUserId(int uid, int userId) { 18891 return UserHandle.getUid(userId, uid); 18892 } 18893 18894 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18895 if (info == null) return null; 18896 ApplicationInfo newInfo = new ApplicationInfo(info); 18897 newInfo.uid = applyUserId(info.uid, userId); 18898 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18899 + info.packageName; 18900 return newInfo; 18901 } 18902 18903 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18904 if (aInfo == null 18905 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18906 return aInfo; 18907 } 18908 18909 ActivityInfo info = new ActivityInfo(aInfo); 18910 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18911 return info; 18912 } 18913 18914 private final class LocalService extends ActivityManagerInternal { 18915 @Override 18916 public void goingToSleep() { 18917 ActivityManagerService.this.goingToSleep(); 18918 } 18919 18920 @Override 18921 public void wakingUp() { 18922 ActivityManagerService.this.wakingUp(); 18923 } 18924 18925 @Override 18926 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18927 String processName, String abiOverride, int uid, Runnable crashHandler) { 18928 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18929 processName, abiOverride, uid, crashHandler); 18930 } 18931 } 18932 18933 /** 18934 * An implementation of IAppTask, that allows an app to manage its own tasks via 18935 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18936 * only the process that calls getAppTasks() can call the AppTask methods. 18937 */ 18938 class AppTaskImpl extends IAppTask.Stub { 18939 private int mTaskId; 18940 private int mCallingUid; 18941 18942 public AppTaskImpl(int taskId, int callingUid) { 18943 mTaskId = taskId; 18944 mCallingUid = callingUid; 18945 } 18946 18947 private void checkCaller() { 18948 if (mCallingUid != Binder.getCallingUid()) { 18949 throw new SecurityException("Caller " + mCallingUid 18950 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18951 } 18952 } 18953 18954 @Override 18955 public void finishAndRemoveTask() { 18956 checkCaller(); 18957 18958 synchronized (ActivityManagerService.this) { 18959 long origId = Binder.clearCallingIdentity(); 18960 try { 18961 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18962 if (tr == null) { 18963 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18964 } 18965 // Only kill the process if we are not a new document 18966 int flags = tr.getBaseIntent().getFlags(); 18967 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18968 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18969 removeTaskByIdLocked(mTaskId, 18970 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18971 } finally { 18972 Binder.restoreCallingIdentity(origId); 18973 } 18974 } 18975 } 18976 18977 @Override 18978 public ActivityManager.RecentTaskInfo getTaskInfo() { 18979 checkCaller(); 18980 18981 synchronized (ActivityManagerService.this) { 18982 long origId = Binder.clearCallingIdentity(); 18983 try { 18984 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18985 if (tr == null) { 18986 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18987 } 18988 return createRecentTaskInfoFromTaskRecord(tr); 18989 } finally { 18990 Binder.restoreCallingIdentity(origId); 18991 } 18992 } 18993 } 18994 18995 @Override 18996 public void moveToFront() { 18997 checkCaller(); 18998 18999 final TaskRecord tr; 19000 synchronized (ActivityManagerService.this) { 19001 tr = recentTaskForIdLocked(mTaskId); 19002 if (tr == null) { 19003 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19004 } 19005 if (tr.getRootActivity() != null) { 19006 moveTaskToFrontLocked(tr.taskId, 0, null); 19007 return; 19008 } 19009 } 19010 19011 startActivityFromRecentsInner(tr.taskId, null); 19012 } 19013 19014 @Override 19015 public int startActivity(IBinder whoThread, String callingPackage, 19016 Intent intent, String resolvedType, Bundle options) { 19017 checkCaller(); 19018 19019 int callingUser = UserHandle.getCallingUserId(); 19020 TaskRecord tr; 19021 IApplicationThread appThread; 19022 synchronized (ActivityManagerService.this) { 19023 tr = recentTaskForIdLocked(mTaskId); 19024 if (tr == null) { 19025 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19026 } 19027 appThread = ApplicationThreadNative.asInterface(whoThread); 19028 if (appThread == null) { 19029 throw new IllegalArgumentException("Bad app thread " + appThread); 19030 } 19031 } 19032 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19033 resolvedType, null, null, null, null, 0, 0, null, null, 19034 null, options, callingUser, null, tr); 19035 } 19036 19037 @Override 19038 public void setExcludeFromRecents(boolean exclude) { 19039 checkCaller(); 19040 19041 synchronized (ActivityManagerService.this) { 19042 long origId = Binder.clearCallingIdentity(); 19043 try { 19044 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19045 if (tr == null) { 19046 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19047 } 19048 Intent intent = tr.getBaseIntent(); 19049 if (exclude) { 19050 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19051 } else { 19052 intent.setFlags(intent.getFlags() 19053 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19054 } 19055 } finally { 19056 Binder.restoreCallingIdentity(origId); 19057 } 19058 } 19059 } 19060 } 19061} 19062