ActivityManagerService.java revision a4ccb86ddc8f9f486aee25fb836f4aff97bf7679
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.IActivityContainer; 37import android.app.IActivityContainerCallback; 38import android.app.IAppTask; 39import android.app.admin.DevicePolicyManager; 40import android.app.usage.UsageEvents; 41import android.app.usage.UsageStatsManagerInternal; 42import android.appwidget.AppWidgetManager; 43import android.content.res.Resources; 44import android.graphics.Bitmap; 45import android.graphics.Point; 46import android.graphics.Rect; 47import android.os.BatteryStats; 48import android.os.PersistableBundle; 49import android.service.voice.IVoiceInteractionSession; 50import android.util.ArrayMap; 51import android.util.ArraySet; 52import android.util.SparseIntArray; 53 54import com.android.internal.R; 55import com.android.internal.annotations.GuardedBy; 56import com.android.internal.app.IAppOpsService; 57import com.android.internal.app.IVoiceInteractor; 58import com.android.internal.app.ProcessMap; 59import com.android.internal.app.ProcessStats; 60import com.android.internal.content.PackageMonitor; 61import com.android.internal.os.BackgroundThread; 62import com.android.internal.os.BatteryStatsImpl; 63import com.android.internal.os.ProcessCpuTracker; 64import com.android.internal.os.TransferPipe; 65import com.android.internal.os.Zygote; 66import com.android.internal.util.FastPrintWriter; 67import com.android.internal.util.FastXmlSerializer; 68import com.android.internal.util.MemInfoReader; 69import com.android.internal.util.Preconditions; 70import com.android.server.AppOpsService; 71import com.android.server.AttributeCache; 72import com.android.server.IntentResolver; 73import com.android.server.LocalServices; 74import com.android.server.ServiceThread; 75import com.android.server.SystemService; 76import com.android.server.SystemServiceManager; 77import com.android.server.Watchdog; 78import com.android.server.am.ActivityStack.ActivityState; 79import com.android.server.firewall.IntentFirewall; 80import com.android.server.pm.UserManagerService; 81import com.android.server.wm.AppTransition; 82import com.android.server.wm.WindowManagerService; 83import com.google.android.collect.Lists; 84import com.google.android.collect.Maps; 85 86import libcore.io.IoUtils; 87 88import org.xmlpull.v1.XmlPullParser; 89import org.xmlpull.v1.XmlPullParserException; 90import org.xmlpull.v1.XmlSerializer; 91 92import android.app.Activity; 93import android.app.ActivityManager; 94import android.app.ActivityManager.RunningTaskInfo; 95import android.app.ActivityManager.StackInfo; 96import android.app.ActivityManagerInternal; 97import android.app.ActivityManagerNative; 98import android.app.ActivityOptions; 99import android.app.ActivityThread; 100import android.app.AlertDialog; 101import android.app.AppGlobals; 102import android.app.ApplicationErrorReport; 103import android.app.Dialog; 104import android.app.IActivityController; 105import android.app.IApplicationThread; 106import android.app.IInstrumentationWatcher; 107import android.app.INotificationManager; 108import android.app.IProcessObserver; 109import android.app.IServiceConnection; 110import android.app.IStopUserCallback; 111import android.app.IUiAutomationConnection; 112import android.app.IUserSwitchObserver; 113import android.app.Instrumentation; 114import android.app.Notification; 115import android.app.NotificationManager; 116import android.app.PendingIntent; 117import android.app.backup.IBackupManager; 118import android.content.ActivityNotFoundException; 119import android.content.BroadcastReceiver; 120import android.content.ClipData; 121import android.content.ComponentCallbacks2; 122import android.content.ComponentName; 123import android.content.ContentProvider; 124import android.content.ContentResolver; 125import android.content.Context; 126import android.content.DialogInterface; 127import android.content.IContentProvider; 128import android.content.IIntentReceiver; 129import android.content.IIntentSender; 130import android.content.Intent; 131import android.content.IntentFilter; 132import android.content.IntentSender; 133import android.content.pm.ActivityInfo; 134import android.content.pm.ApplicationInfo; 135import android.content.pm.ConfigurationInfo; 136import android.content.pm.IPackageDataObserver; 137import android.content.pm.IPackageManager; 138import android.content.pm.InstrumentationInfo; 139import android.content.pm.PackageInfo; 140import android.content.pm.PackageManager; 141import android.content.pm.ParceledListSlice; 142import android.content.pm.UserInfo; 143import android.content.pm.PackageManager.NameNotFoundException; 144import android.content.pm.PathPermission; 145import android.content.pm.ProviderInfo; 146import android.content.pm.ResolveInfo; 147import android.content.pm.ServiceInfo; 148import android.content.res.CompatibilityInfo; 149import android.content.res.Configuration; 150import android.net.Proxy; 151import android.net.ProxyInfo; 152import android.net.Uri; 153import android.os.Binder; 154import android.os.Build; 155import android.os.Bundle; 156import android.os.Debug; 157import android.os.DropBoxManager; 158import android.os.Environment; 159import android.os.FactoryTest; 160import android.os.FileObserver; 161import android.os.FileUtils; 162import android.os.Handler; 163import android.os.IBinder; 164import android.os.IPermissionController; 165import android.os.IRemoteCallback; 166import android.os.IUserManager; 167import android.os.Looper; 168import android.os.Message; 169import android.os.Parcel; 170import android.os.ParcelFileDescriptor; 171import android.os.Process; 172import android.os.RemoteCallbackList; 173import android.os.RemoteException; 174import android.os.SELinux; 175import android.os.ServiceManager; 176import android.os.StrictMode; 177import android.os.SystemClock; 178import android.os.SystemProperties; 179import android.os.UpdateLock; 180import android.os.UserHandle; 181import android.provider.Settings; 182import android.text.format.DateUtils; 183import android.text.format.Time; 184import android.util.AtomicFile; 185import android.util.EventLog; 186import android.util.Log; 187import android.util.Pair; 188import android.util.PrintWriterPrinter; 189import android.util.Slog; 190import android.util.SparseArray; 191import android.util.TimeUtils; 192import android.util.Xml; 193import android.view.Gravity; 194import android.view.LayoutInflater; 195import android.view.View; 196import android.view.WindowManager; 197 198import java.io.BufferedInputStream; 199import java.io.BufferedOutputStream; 200import java.io.DataInputStream; 201import java.io.DataOutputStream; 202import java.io.File; 203import java.io.FileDescriptor; 204import java.io.FileInputStream; 205import java.io.FileNotFoundException; 206import java.io.FileOutputStream; 207import java.io.IOException; 208import java.io.InputStreamReader; 209import java.io.PrintWriter; 210import java.io.StringWriter; 211import java.lang.ref.WeakReference; 212import java.util.ArrayList; 213import java.util.Arrays; 214import java.util.Collections; 215import java.util.Comparator; 216import java.util.HashMap; 217import java.util.HashSet; 218import java.util.Iterator; 219import java.util.List; 220import java.util.Locale; 221import java.util.Map; 222import java.util.Set; 223import java.util.concurrent.atomic.AtomicBoolean; 224import java.util.concurrent.atomic.AtomicLong; 225 226public final class ActivityManagerService extends ActivityManagerNative 227 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 228 229 private static final String USER_DATA_DIR = "/data/user/"; 230 // File that stores last updated system version and called preboot receivers 231 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 232 233 static final String TAG = "ActivityManager"; 234 static final String TAG_MU = "ActivityManagerServiceMU"; 235 static final boolean DEBUG = false; 236 static final boolean localLOGV = DEBUG; 237 static final boolean DEBUG_BACKUP = localLOGV || false; 238 static final boolean DEBUG_BROADCAST = localLOGV || false; 239 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 240 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 241 static final boolean DEBUG_CLEANUP = localLOGV || false; 242 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 243 static final boolean DEBUG_FOCUS = false; 244 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 245 static final boolean DEBUG_MU = localLOGV || false; 246 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 247 static final boolean DEBUG_LRU = localLOGV || false; 248 static final boolean DEBUG_PAUSE = localLOGV || false; 249 static final boolean DEBUG_POWER = localLOGV || false; 250 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 251 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 252 static final boolean DEBUG_PROCESSES = localLOGV || false; 253 static final boolean DEBUG_PROVIDER = localLOGV || false; 254 static final boolean DEBUG_RESULTS = localLOGV || false; 255 static final boolean DEBUG_SERVICE = localLOGV || false; 256 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 257 static final boolean DEBUG_STACK = localLOGV || false; 258 static final boolean DEBUG_SWITCH = localLOGV || false; 259 static final boolean DEBUG_TASKS = localLOGV || false; 260 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 261 static final boolean DEBUG_TRANSITION = localLOGV || false; 262 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 263 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 264 static final boolean DEBUG_VISBILITY = localLOGV || false; 265 static final boolean DEBUG_PSS = localLOGV || false; 266 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 267 static final boolean DEBUG_RECENTS = localLOGV || false; 268 static final boolean VALIDATE_TOKENS = false; 269 static final boolean SHOW_ACTIVITY_START_TIME = true; 270 271 // Control over CPU and battery monitoring. 272 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 273 static final boolean MONITOR_CPU_USAGE = true; 274 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 275 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 276 static final boolean MONITOR_THREAD_CPU_USAGE = false; 277 278 // The flags that are set for all calls we make to the package manager. 279 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 280 281 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 282 283 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 284 285 // Maximum number of recent tasks that we can remember. 286 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mWaitingUpdate = false; 892 boolean mDidUpdate = false; 893 boolean mOnBattery = false; 894 boolean mLaunchWarningShown = false; 895 896 Context mContext; 897 898 int mFactoryTest; 899 900 boolean mCheckedForSetup; 901 902 /** 903 * The time at which we will allow normal application switches again, 904 * after a call to {@link #stopAppSwitches()}. 905 */ 906 long mAppSwitchesAllowedTime; 907 908 /** 909 * This is set to true after the first switch after mAppSwitchesAllowedTime 910 * is set; any switches after that will clear the time. 911 */ 912 boolean mDidAppSwitch; 913 914 /** 915 * Last time (in realtime) at which we checked for power usage. 916 */ 917 long mLastPowerCheckRealtime; 918 919 /** 920 * Last time (in uptime) at which we checked for power usage. 921 */ 922 long mLastPowerCheckUptime; 923 924 /** 925 * Set while we are wanting to sleep, to prevent any 926 * activities from being started/resumed. 927 */ 928 private boolean mSleeping = false; 929 930 /** 931 * Set while we are running a voice interaction. This overrides 932 * sleeping while it is active. 933 */ 934 private boolean mRunningVoice = false; 935 936 /** 937 * State of external calls telling us if the device is asleep. 938 */ 939 private boolean mWentToSleep = false; 940 941 /** 942 * State of external call telling us if the lock screen is shown. 943 */ 944 private boolean mLockScreenShown = false; 945 946 /** 947 * Set if we are shutting down the system, similar to sleeping. 948 */ 949 boolean mShuttingDown = false; 950 951 /** 952 * Current sequence id for oom_adj computation traversal. 953 */ 954 int mAdjSeq = 0; 955 956 /** 957 * Current sequence id for process LRU updating. 958 */ 959 int mLruSeq = 0; 960 961 /** 962 * Keep track of the non-cached/empty process we last found, to help 963 * determine how to distribute cached/empty processes next time. 964 */ 965 int mNumNonCachedProcs = 0; 966 967 /** 968 * Keep track of the number of cached hidden procs, to balance oom adj 969 * distribution between those and empty procs. 970 */ 971 int mNumCachedHiddenProcs = 0; 972 973 /** 974 * Keep track of the number of service processes we last found, to 975 * determine on the next iteration which should be B services. 976 */ 977 int mNumServiceProcs = 0; 978 int mNewNumAServiceProcs = 0; 979 int mNewNumServiceProcs = 0; 980 981 /** 982 * Allow the current computed overall memory level of the system to go down? 983 * This is set to false when we are killing processes for reasons other than 984 * memory management, so that the now smaller process list will not be taken as 985 * an indication that memory is tighter. 986 */ 987 boolean mAllowLowerMemLevel = false; 988 989 /** 990 * The last computed memory level, for holding when we are in a state that 991 * processes are going away for other reasons. 992 */ 993 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 994 995 /** 996 * The last total number of process we have, to determine if changes actually look 997 * like a shrinking number of process due to lower RAM. 998 */ 999 int mLastNumProcesses; 1000 1001 /** 1002 * The uptime of the last time we performed idle maintenance. 1003 */ 1004 long mLastIdleTime = SystemClock.uptimeMillis(); 1005 1006 /** 1007 * Total time spent with RAM that has been added in the past since the last idle time. 1008 */ 1009 long mLowRamTimeSinceLastIdle = 0; 1010 1011 /** 1012 * If RAM is currently low, when that horrible situation started. 1013 */ 1014 long mLowRamStartTime = 0; 1015 1016 /** 1017 * For reporting to battery stats the current top application. 1018 */ 1019 private String mCurResumedPackage = null; 1020 private int mCurResumedUid = -1; 1021 1022 /** 1023 * For reporting to battery stats the apps currently running foreground 1024 * service. The ProcessMap is package/uid tuples; each of these contain 1025 * an array of the currently foreground processes. 1026 */ 1027 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1028 = new ProcessMap<ArrayList<ProcessRecord>>(); 1029 1030 /** 1031 * This is set if we had to do a delayed dexopt of an app before launching 1032 * it, to increase the ANR timeouts in that case. 1033 */ 1034 boolean mDidDexOpt; 1035 1036 /** 1037 * Set if the systemServer made a call to enterSafeMode. 1038 */ 1039 boolean mSafeMode; 1040 1041 String mDebugApp = null; 1042 boolean mWaitForDebugger = false; 1043 boolean mDebugTransient = false; 1044 String mOrigDebugApp = null; 1045 boolean mOrigWaitForDebugger = false; 1046 boolean mAlwaysFinishActivities = false; 1047 IActivityController mController = null; 1048 String mProfileApp = null; 1049 ProcessRecord mProfileProc = null; 1050 String mProfileFile; 1051 ParcelFileDescriptor mProfileFd; 1052 int mProfileType = 0; 1053 boolean mAutoStopProfiler = false; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 1183 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1184 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1185 static final int FIRST_COMPAT_MODE_MSG = 300; 1186 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1187 1188 AlertDialog mUidAlert; 1189 CompatModeDialog mCompatModeDialog; 1190 long mLastMemUsageReportTime = 0; 1191 1192 private LockToAppRequestDialog mLockToAppRequest; 1193 1194 /** 1195 * Flag whether the current user is a "monkey", i.e. whether 1196 * the UI is driven by a UI automation tool. 1197 */ 1198 private boolean mUserIsMonkey; 1199 1200 /** Flag whether the device has a recents UI */ 1201 final boolean mHasRecents; 1202 1203 final int mThumbnailWidth; 1204 final int mThumbnailHeight; 1205 1206 final ServiceThread mHandlerThread; 1207 final MainHandler mHandler; 1208 1209 final class MainHandler extends Handler { 1210 public MainHandler(Looper looper) { 1211 super(looper, null, true); 1212 } 1213 1214 @Override 1215 public void handleMessage(Message msg) { 1216 switch (msg.what) { 1217 case SHOW_ERROR_MSG: { 1218 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1219 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1220 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1221 synchronized (ActivityManagerService.this) { 1222 ProcessRecord proc = (ProcessRecord)data.get("app"); 1223 AppErrorResult res = (AppErrorResult) data.get("result"); 1224 if (proc != null && proc.crashDialog != null) { 1225 Slog.e(TAG, "App already has crash dialog: " + proc); 1226 if (res != null) { 1227 res.set(0); 1228 } 1229 return; 1230 } 1231 boolean isBackground = (UserHandle.getAppId(proc.uid) 1232 >= Process.FIRST_APPLICATION_UID 1233 && proc.pid != MY_PID); 1234 for (int userId : mCurrentProfileIds) { 1235 isBackground &= (proc.userId != userId); 1236 } 1237 if (isBackground && !showBackground) { 1238 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1239 if (res != null) { 1240 res.set(0); 1241 } 1242 return; 1243 } 1244 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1245 Dialog d = new AppErrorDialog(mContext, 1246 ActivityManagerService.this, res, proc); 1247 d.show(); 1248 proc.crashDialog = d; 1249 } else { 1250 // The device is asleep, so just pretend that the user 1251 // saw a crash dialog and hit "force quit". 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 } 1256 } 1257 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_NOT_RESPONDING_MSG: { 1261 synchronized (ActivityManagerService.this) { 1262 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1263 ProcessRecord proc = (ProcessRecord)data.get("app"); 1264 if (proc != null && proc.anrDialog != null) { 1265 Slog.e(TAG, "App already has anr dialog: " + proc); 1266 return; 1267 } 1268 1269 Intent intent = new Intent("android.intent.action.ANR"); 1270 if (!mProcessesReady) { 1271 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1272 | Intent.FLAG_RECEIVER_FOREGROUND); 1273 } 1274 broadcastIntentLocked(null, null, intent, 1275 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1276 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1277 1278 if (mShowDialogs) { 1279 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1280 mContext, proc, (ActivityRecord)data.get("activity"), 1281 msg.arg1 != 0); 1282 d.show(); 1283 proc.anrDialog = d; 1284 } else { 1285 // Just kill the app if there is no dialog to be shown. 1286 killAppAtUsersRequest(proc, null); 1287 } 1288 } 1289 1290 ensureBootCompleted(); 1291 } break; 1292 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1293 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1294 synchronized (ActivityManagerService.this) { 1295 ProcessRecord proc = (ProcessRecord) data.get("app"); 1296 if (proc == null) { 1297 Slog.e(TAG, "App not found when showing strict mode dialog."); 1298 break; 1299 } 1300 if (proc.crashDialog != null) { 1301 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1302 return; 1303 } 1304 AppErrorResult res = (AppErrorResult) data.get("result"); 1305 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1306 Dialog d = new StrictModeViolationDialog(mContext, 1307 ActivityManagerService.this, res, proc); 1308 d.show(); 1309 proc.crashDialog = d; 1310 } else { 1311 // The device is asleep, so just pretend that the user 1312 // saw a crash dialog and hit "force quit". 1313 res.set(0); 1314 } 1315 } 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_FACTORY_ERROR_MSG: { 1319 Dialog d = new FactoryErrorDialog( 1320 mContext, msg.getData().getCharSequence("msg")); 1321 d.show(); 1322 ensureBootCompleted(); 1323 } break; 1324 case UPDATE_CONFIGURATION_MSG: { 1325 final ContentResolver resolver = mContext.getContentResolver(); 1326 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1327 } break; 1328 case GC_BACKGROUND_PROCESSES_MSG: { 1329 synchronized (ActivityManagerService.this) { 1330 performAppGcsIfAppropriateLocked(); 1331 } 1332 } break; 1333 case WAIT_FOR_DEBUGGER_MSG: { 1334 synchronized (ActivityManagerService.this) { 1335 ProcessRecord app = (ProcessRecord)msg.obj; 1336 if (msg.arg1 != 0) { 1337 if (!app.waitedForDebugger) { 1338 Dialog d = new AppWaitingForDebuggerDialog( 1339 ActivityManagerService.this, 1340 mContext, app); 1341 app.waitDialog = d; 1342 app.waitedForDebugger = true; 1343 d.show(); 1344 } 1345 } else { 1346 if (app.waitDialog != null) { 1347 app.waitDialog.dismiss(); 1348 app.waitDialog = null; 1349 } 1350 } 1351 } 1352 } break; 1353 case SERVICE_TIMEOUT_MSG: { 1354 if (mDidDexOpt) { 1355 mDidDexOpt = false; 1356 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1357 nmsg.obj = msg.obj; 1358 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1359 return; 1360 } 1361 mServices.serviceTimeout((ProcessRecord)msg.obj); 1362 } break; 1363 case UPDATE_TIME_ZONE: { 1364 synchronized (ActivityManagerService.this) { 1365 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1366 ProcessRecord r = mLruProcesses.get(i); 1367 if (r.thread != null) { 1368 try { 1369 r.thread.updateTimeZone(); 1370 } catch (RemoteException ex) { 1371 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1372 } 1373 } 1374 } 1375 } 1376 } break; 1377 case CLEAR_DNS_CACHE_MSG: { 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.clearDnsCache(); 1384 } catch (RemoteException ex) { 1385 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1386 } 1387 } 1388 } 1389 } 1390 } break; 1391 case UPDATE_HTTP_PROXY_MSG: { 1392 ProxyInfo proxy = (ProxyInfo)msg.obj; 1393 String host = ""; 1394 String port = ""; 1395 String exclList = ""; 1396 Uri pacFileUrl = Uri.EMPTY; 1397 if (proxy != null) { 1398 host = proxy.getHost(); 1399 port = Integer.toString(proxy.getPort()); 1400 exclList = proxy.getExclusionListAsString(); 1401 pacFileUrl = proxy.getPacFileUrl(); 1402 } 1403 synchronized (ActivityManagerService.this) { 1404 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1405 ProcessRecord r = mLruProcesses.get(i); 1406 if (r.thread != null) { 1407 try { 1408 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1409 } catch (RemoteException ex) { 1410 Slog.w(TAG, "Failed to update http proxy for: " + 1411 r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case SHOW_UID_ERROR_MSG: { 1418 String title = "System UIDs Inconsistent"; 1419 String text = "UIDs on the system are inconsistent, you need to wipe your" 1420 + " data partition or your device will be unstable."; 1421 Log.e(TAG, title + ": " + text); 1422 if (mShowDialogs) { 1423 // XXX This is a temporary dialog, no need to localize. 1424 AlertDialog d = new BaseErrorDialog(mContext); 1425 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1426 d.setCancelable(false); 1427 d.setTitle(title); 1428 d.setMessage(text); 1429 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1430 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1431 mUidAlert = d; 1432 d.show(); 1433 } 1434 } break; 1435 case IM_FEELING_LUCKY_MSG: { 1436 if (mUidAlert != null) { 1437 mUidAlert.dismiss(); 1438 mUidAlert = null; 1439 } 1440 } break; 1441 case PROC_START_TIMEOUT_MSG: { 1442 if (mDidDexOpt) { 1443 mDidDexOpt = false; 1444 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1445 nmsg.obj = msg.obj; 1446 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1447 return; 1448 } 1449 ProcessRecord app = (ProcessRecord)msg.obj; 1450 synchronized (ActivityManagerService.this) { 1451 processStartTimedOutLocked(app); 1452 } 1453 } break; 1454 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1455 synchronized (ActivityManagerService.this) { 1456 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1457 } 1458 } break; 1459 case KILL_APPLICATION_MSG: { 1460 synchronized (ActivityManagerService.this) { 1461 int appid = msg.arg1; 1462 boolean restart = (msg.arg2 == 1); 1463 Bundle bundle = (Bundle)msg.obj; 1464 String pkg = bundle.getString("pkg"); 1465 String reason = bundle.getString("reason"); 1466 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1467 false, UserHandle.USER_ALL, reason); 1468 } 1469 } break; 1470 case FINALIZE_PENDING_INTENT_MSG: { 1471 ((PendingIntentRecord)msg.obj).completeFinalize(); 1472 } break; 1473 case POST_HEAVY_NOTIFICATION_MSG: { 1474 INotificationManager inm = NotificationManager.getService(); 1475 if (inm == null) { 1476 return; 1477 } 1478 1479 ActivityRecord root = (ActivityRecord)msg.obj; 1480 ProcessRecord process = root.app; 1481 if (process == null) { 1482 return; 1483 } 1484 1485 try { 1486 Context context = mContext.createPackageContext(process.info.packageName, 0); 1487 String text = mContext.getString(R.string.heavy_weight_notification, 1488 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1489 Notification notification = new Notification(); 1490 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1491 notification.when = 0; 1492 notification.flags = Notification.FLAG_ONGOING_EVENT; 1493 notification.tickerText = text; 1494 notification.defaults = 0; // please be quiet 1495 notification.sound = null; 1496 notification.vibrate = null; 1497 notification.color = mContext.getResources().getColor( 1498 com.android.internal.R.color.system_notification_accent_color); 1499 notification.setLatestEventInfo(context, text, 1500 mContext.getText(R.string.heavy_weight_notification_detail), 1501 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1502 PendingIntent.FLAG_CANCEL_CURRENT, null, 1503 new UserHandle(root.userId))); 1504 1505 try { 1506 int[] outId = new int[1]; 1507 inm.enqueueNotificationWithTag("android", "android", null, 1508 R.string.heavy_weight_notification, 1509 notification, outId, root.userId); 1510 } catch (RuntimeException e) { 1511 Slog.w(ActivityManagerService.TAG, 1512 "Error showing notification for heavy-weight app", e); 1513 } catch (RemoteException e) { 1514 } 1515 } catch (NameNotFoundException e) { 1516 Slog.w(TAG, "Unable to create context for heavy notification", e); 1517 } 1518 } break; 1519 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1520 INotificationManager inm = NotificationManager.getService(); 1521 if (inm == null) { 1522 return; 1523 } 1524 try { 1525 inm.cancelNotificationWithTag("android", null, 1526 R.string.heavy_weight_notification, msg.arg1); 1527 } catch (RuntimeException e) { 1528 Slog.w(ActivityManagerService.TAG, 1529 "Error canceling notification for service", e); 1530 } catch (RemoteException e) { 1531 } 1532 } break; 1533 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1534 synchronized (ActivityManagerService.this) { 1535 checkExcessivePowerUsageLocked(true); 1536 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1537 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1538 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1539 } 1540 } break; 1541 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1542 synchronized (ActivityManagerService.this) { 1543 ActivityRecord ar = (ActivityRecord)msg.obj; 1544 if (mCompatModeDialog != null) { 1545 if (mCompatModeDialog.mAppInfo.packageName.equals( 1546 ar.info.applicationInfo.packageName)) { 1547 return; 1548 } 1549 mCompatModeDialog.dismiss(); 1550 mCompatModeDialog = null; 1551 } 1552 if (ar != null && false) { 1553 if (mCompatModePackages.getPackageAskCompatModeLocked( 1554 ar.packageName)) { 1555 int mode = mCompatModePackages.computeCompatModeLocked( 1556 ar.info.applicationInfo); 1557 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1558 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1559 mCompatModeDialog = new CompatModeDialog( 1560 ActivityManagerService.this, mContext, 1561 ar.info.applicationInfo); 1562 mCompatModeDialog.show(); 1563 } 1564 } 1565 } 1566 } 1567 break; 1568 } 1569 case DISPATCH_PROCESSES_CHANGED: { 1570 dispatchProcessesChanged(); 1571 break; 1572 } 1573 case DISPATCH_PROCESS_DIED: { 1574 final int pid = msg.arg1; 1575 final int uid = msg.arg2; 1576 dispatchProcessDied(pid, uid); 1577 break; 1578 } 1579 case REPORT_MEM_USAGE_MSG: { 1580 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1581 Thread thread = new Thread() { 1582 @Override public void run() { 1583 final SparseArray<ProcessMemInfo> infoMap 1584 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1585 for (int i=0, N=memInfos.size(); i<N; i++) { 1586 ProcessMemInfo mi = memInfos.get(i); 1587 infoMap.put(mi.pid, mi); 1588 } 1589 updateCpuStatsNow(); 1590 synchronized (mProcessCpuThread) { 1591 final int N = mProcessCpuTracker.countStats(); 1592 for (int i=0; i<N; i++) { 1593 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1594 if (st.vsize > 0) { 1595 long pss = Debug.getPss(st.pid, null); 1596 if (pss > 0) { 1597 if (infoMap.indexOfKey(st.pid) < 0) { 1598 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1599 ProcessList.NATIVE_ADJ, -1, "native", null); 1600 mi.pss = pss; 1601 memInfos.add(mi); 1602 } 1603 } 1604 } 1605 } 1606 } 1607 1608 long totalPss = 0; 1609 for (int i=0, N=memInfos.size(); i<N; i++) { 1610 ProcessMemInfo mi = memInfos.get(i); 1611 if (mi.pss == 0) { 1612 mi.pss = Debug.getPss(mi.pid, null); 1613 } 1614 totalPss += mi.pss; 1615 } 1616 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1617 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1618 if (lhs.oomAdj != rhs.oomAdj) { 1619 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1620 } 1621 if (lhs.pss != rhs.pss) { 1622 return lhs.pss < rhs.pss ? 1 : -1; 1623 } 1624 return 0; 1625 } 1626 }); 1627 1628 StringBuilder tag = new StringBuilder(128); 1629 StringBuilder stack = new StringBuilder(128); 1630 tag.append("Low on memory -- "); 1631 appendMemBucket(tag, totalPss, "total", false); 1632 appendMemBucket(stack, totalPss, "total", true); 1633 1634 StringBuilder logBuilder = new StringBuilder(1024); 1635 logBuilder.append("Low on memory:\n"); 1636 1637 boolean firstLine = true; 1638 int lastOomAdj = Integer.MIN_VALUE; 1639 for (int i=0, N=memInfos.size(); i<N; i++) { 1640 ProcessMemInfo mi = memInfos.get(i); 1641 1642 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1643 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1644 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1645 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1646 if (lastOomAdj != mi.oomAdj) { 1647 lastOomAdj = mi.oomAdj; 1648 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1649 tag.append(" / "); 1650 } 1651 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1652 if (firstLine) { 1653 stack.append(":"); 1654 firstLine = false; 1655 } 1656 stack.append("\n\t at "); 1657 } else { 1658 stack.append("$"); 1659 } 1660 } else { 1661 tag.append(" "); 1662 stack.append("$"); 1663 } 1664 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1665 appendMemBucket(tag, mi.pss, mi.name, false); 1666 } 1667 appendMemBucket(stack, mi.pss, mi.name, true); 1668 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1669 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1670 stack.append("("); 1671 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1672 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1673 stack.append(DUMP_MEM_OOM_LABEL[k]); 1674 stack.append(":"); 1675 stack.append(DUMP_MEM_OOM_ADJ[k]); 1676 } 1677 } 1678 stack.append(")"); 1679 } 1680 } 1681 1682 logBuilder.append(" "); 1683 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1684 logBuilder.append(' '); 1685 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1686 logBuilder.append(' '); 1687 ProcessList.appendRamKb(logBuilder, mi.pss); 1688 logBuilder.append(" kB: "); 1689 logBuilder.append(mi.name); 1690 logBuilder.append(" ("); 1691 logBuilder.append(mi.pid); 1692 logBuilder.append(") "); 1693 logBuilder.append(mi.adjType); 1694 logBuilder.append('\n'); 1695 if (mi.adjReason != null) { 1696 logBuilder.append(" "); 1697 logBuilder.append(mi.adjReason); 1698 logBuilder.append('\n'); 1699 } 1700 } 1701 1702 logBuilder.append(" "); 1703 ProcessList.appendRamKb(logBuilder, totalPss); 1704 logBuilder.append(" kB: TOTAL\n"); 1705 1706 long[] infos = new long[Debug.MEMINFO_COUNT]; 1707 Debug.getMemInfo(infos); 1708 logBuilder.append(" MemInfo: "); 1709 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1710 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1711 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1712 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1713 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1714 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1715 logBuilder.append(" ZRAM: "); 1716 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1717 logBuilder.append(" kB RAM, "); 1718 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1719 logBuilder.append(" kB swap total, "); 1720 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1721 logBuilder.append(" kB swap free\n"); 1722 } 1723 Slog.i(TAG, logBuilder.toString()); 1724 1725 StringBuilder dropBuilder = new StringBuilder(1024); 1726 /* 1727 StringWriter oomSw = new StringWriter(); 1728 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1729 StringWriter catSw = new StringWriter(); 1730 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1731 String[] emptyArgs = new String[] { }; 1732 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1733 oomPw.flush(); 1734 String oomString = oomSw.toString(); 1735 */ 1736 dropBuilder.append(stack); 1737 dropBuilder.append('\n'); 1738 dropBuilder.append('\n'); 1739 dropBuilder.append(logBuilder); 1740 dropBuilder.append('\n'); 1741 /* 1742 dropBuilder.append(oomString); 1743 dropBuilder.append('\n'); 1744 */ 1745 StringWriter catSw = new StringWriter(); 1746 synchronized (ActivityManagerService.this) { 1747 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1748 String[] emptyArgs = new String[] { }; 1749 catPw.println(); 1750 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1751 catPw.println(); 1752 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1753 false, false, null); 1754 catPw.println(); 1755 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1756 catPw.flush(); 1757 } 1758 dropBuilder.append(catSw.toString()); 1759 addErrorToDropBox("lowmem", null, "system_server", null, 1760 null, tag.toString(), dropBuilder.toString(), null, null); 1761 //Slog.i(TAG, "Sent to dropbox:"); 1762 //Slog.i(TAG, dropBuilder.toString()); 1763 synchronized (ActivityManagerService.this) { 1764 long now = SystemClock.uptimeMillis(); 1765 if (mLastMemUsageReportTime < now) { 1766 mLastMemUsageReportTime = now; 1767 } 1768 } 1769 } 1770 }; 1771 thread.start(); 1772 break; 1773 } 1774 case REPORT_USER_SWITCH_MSG: { 1775 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1776 break; 1777 } 1778 case CONTINUE_USER_SWITCH_MSG: { 1779 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1780 break; 1781 } 1782 case USER_SWITCH_TIMEOUT_MSG: { 1783 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1784 break; 1785 } 1786 case IMMERSIVE_MODE_LOCK_MSG: { 1787 final boolean nextState = (msg.arg1 != 0); 1788 if (mUpdateLock.isHeld() != nextState) { 1789 if (DEBUG_IMMERSIVE) { 1790 final ActivityRecord r = (ActivityRecord) msg.obj; 1791 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1792 } 1793 if (nextState) { 1794 mUpdateLock.acquire(); 1795 } else { 1796 mUpdateLock.release(); 1797 } 1798 } 1799 break; 1800 } 1801 case PERSIST_URI_GRANTS_MSG: { 1802 writeGrantedUriPermissions(); 1803 break; 1804 } 1805 case REQUEST_ALL_PSS_MSG: { 1806 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1807 break; 1808 } 1809 case START_PROFILES_MSG: { 1810 synchronized (ActivityManagerService.this) { 1811 startProfilesLocked(); 1812 } 1813 break; 1814 } 1815 case UPDATE_TIME: { 1816 synchronized (ActivityManagerService.this) { 1817 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1818 ProcessRecord r = mLruProcesses.get(i); 1819 if (r.thread != null) { 1820 try { 1821 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1822 } catch (RemoteException ex) { 1823 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1824 } 1825 } 1826 } 1827 } 1828 break; 1829 } 1830 case SYSTEM_USER_START_MSG: { 1831 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1832 Integer.toString(msg.arg1), msg.arg1); 1833 mSystemServiceManager.startUser(msg.arg1); 1834 break; 1835 } 1836 case SYSTEM_USER_CURRENT_MSG: { 1837 mBatteryStatsService.noteEvent( 1838 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1839 Integer.toString(msg.arg2), msg.arg2); 1840 mBatteryStatsService.noteEvent( 1841 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1842 Integer.toString(msg.arg1), msg.arg1); 1843 mSystemServiceManager.switchUser(msg.arg1); 1844 mLockToAppRequest.clearPrompt(); 1845 break; 1846 } 1847 case ENTER_ANIMATION_COMPLETE_MSG: { 1848 synchronized (ActivityManagerService.this) { 1849 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1850 if (r != null && r.app != null && r.app.thread != null) { 1851 try { 1852 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1853 } catch (RemoteException e) { 1854 } 1855 } 1856 } 1857 break; 1858 } 1859 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1860 enableScreenAfterBoot(); 1861 break; 1862 } 1863 } 1864 } 1865 }; 1866 1867 static final int COLLECT_PSS_BG_MSG = 1; 1868 1869 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1870 @Override 1871 public void handleMessage(Message msg) { 1872 switch (msg.what) { 1873 case COLLECT_PSS_BG_MSG: { 1874 long start = SystemClock.uptimeMillis(); 1875 MemInfoReader memInfo = null; 1876 synchronized (ActivityManagerService.this) { 1877 if (mFullPssPending) { 1878 mFullPssPending = false; 1879 memInfo = new MemInfoReader(); 1880 } 1881 } 1882 if (memInfo != null) { 1883 updateCpuStatsNow(); 1884 long nativeTotalPss = 0; 1885 synchronized (mProcessCpuThread) { 1886 final int N = mProcessCpuTracker.countStats(); 1887 for (int j=0; j<N; j++) { 1888 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1889 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1890 // This is definitely an application process; skip it. 1891 continue; 1892 } 1893 synchronized (mPidsSelfLocked) { 1894 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1895 // This is one of our own processes; skip it. 1896 continue; 1897 } 1898 } 1899 nativeTotalPss += Debug.getPss(st.pid, null); 1900 } 1901 } 1902 memInfo.readMemInfo(); 1903 synchronized (this) { 1904 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1905 + (SystemClock.uptimeMillis()-start) + "ms"); 1906 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1907 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1908 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1909 +memInfo.getSlabSizeKb(), 1910 nativeTotalPss); 1911 } 1912 } 1913 1914 int i=0, num=0; 1915 long[] tmp = new long[1]; 1916 do { 1917 ProcessRecord proc; 1918 int procState; 1919 int pid; 1920 synchronized (ActivityManagerService.this) { 1921 if (i >= mPendingPssProcesses.size()) { 1922 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1923 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1924 mPendingPssProcesses.clear(); 1925 return; 1926 } 1927 proc = mPendingPssProcesses.get(i); 1928 procState = proc.pssProcState; 1929 if (proc.thread != null && procState == proc.setProcState) { 1930 pid = proc.pid; 1931 } else { 1932 proc = null; 1933 pid = 0; 1934 } 1935 i++; 1936 } 1937 if (proc != null) { 1938 long pss = Debug.getPss(pid, tmp); 1939 synchronized (ActivityManagerService.this) { 1940 if (proc.thread != null && proc.setProcState == procState 1941 && proc.pid == pid) { 1942 num++; 1943 proc.lastPssTime = SystemClock.uptimeMillis(); 1944 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1945 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1946 + ": " + pss + " lastPss=" + proc.lastPss 1947 + " state=" + ProcessList.makeProcStateString(procState)); 1948 if (proc.initialIdlePss == 0) { 1949 proc.initialIdlePss = pss; 1950 } 1951 proc.lastPss = pss; 1952 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1953 proc.lastCachedPss = pss; 1954 } 1955 } 1956 } 1957 } 1958 } while (true); 1959 } 1960 } 1961 } 1962 }; 1963 1964 /** 1965 * Monitor for package changes and update our internal state. 1966 */ 1967 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1968 @Override 1969 public void onPackageRemoved(String packageName, int uid) { 1970 // Remove all tasks with activities in the specified package from the list of recent tasks 1971 synchronized (ActivityManagerService.this) { 1972 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1973 TaskRecord tr = mRecentTasks.get(i); 1974 ComponentName cn = tr.intent.getComponent(); 1975 if (cn != null && cn.getPackageName().equals(packageName)) { 1976 // If the package name matches, remove the task and kill the process 1977 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1978 } 1979 } 1980 } 1981 } 1982 1983 @Override 1984 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1985 onPackageModified(packageName); 1986 return true; 1987 } 1988 1989 @Override 1990 public void onPackageModified(String packageName) { 1991 final PackageManager pm = mContext.getPackageManager(); 1992 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1993 new ArrayList<Pair<Intent, Integer>>(); 1994 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1995 // Copy the list of recent tasks so that we don't hold onto the lock on 1996 // ActivityManagerService for long periods while checking if components exist. 1997 synchronized (ActivityManagerService.this) { 1998 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1999 TaskRecord tr = mRecentTasks.get(i); 2000 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2001 } 2002 } 2003 // Check the recent tasks and filter out all tasks with components that no longer exist. 2004 Intent tmpI = new Intent(); 2005 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2006 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2007 ComponentName cn = p.first.getComponent(); 2008 if (cn != null && cn.getPackageName().equals(packageName)) { 2009 try { 2010 // Add the task to the list to remove if the component no longer exists 2011 tmpI.setComponent(cn); 2012 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2013 tasksToRemove.add(p.second); 2014 } 2015 } catch (Exception e) {} 2016 } 2017 } 2018 // Prune all the tasks with removed components from the list of recent tasks 2019 synchronized (ActivityManagerService.this) { 2020 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2021 // Remove the task but don't kill the process (since other components in that 2022 // package may still be running and in the background) 2023 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2024 } 2025 } 2026 } 2027 2028 @Override 2029 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2030 // Force stop the specified packages 2031 if (packages != null) { 2032 for (String pkg : packages) { 2033 synchronized (ActivityManagerService.this) { 2034 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2035 "finished booting")) { 2036 return true; 2037 } 2038 } 2039 } 2040 } 2041 return false; 2042 } 2043 }; 2044 2045 public void setSystemProcess() { 2046 try { 2047 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2048 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2049 ServiceManager.addService("meminfo", new MemBinder(this)); 2050 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2051 ServiceManager.addService("dbinfo", new DbBinder(this)); 2052 if (MONITOR_CPU_USAGE) { 2053 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2054 } 2055 ServiceManager.addService("permission", new PermissionController(this)); 2056 2057 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2058 "android", STOCK_PM_FLAGS); 2059 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2060 2061 synchronized (this) { 2062 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2063 app.persistent = true; 2064 app.pid = MY_PID; 2065 app.maxAdj = ProcessList.SYSTEM_ADJ; 2066 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2067 mProcessNames.put(app.processName, app.uid, app); 2068 synchronized (mPidsSelfLocked) { 2069 mPidsSelfLocked.put(app.pid, app); 2070 } 2071 updateLruProcessLocked(app, false, null); 2072 updateOomAdjLocked(); 2073 } 2074 } catch (PackageManager.NameNotFoundException e) { 2075 throw new RuntimeException( 2076 "Unable to find android system package", e); 2077 } 2078 } 2079 2080 public void setWindowManager(WindowManagerService wm) { 2081 mWindowManager = wm; 2082 mStackSupervisor.setWindowManager(wm); 2083 } 2084 2085 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2086 mUsageStatsService = usageStatsManager; 2087 } 2088 2089 public void startObservingNativeCrashes() { 2090 final NativeCrashListener ncl = new NativeCrashListener(this); 2091 ncl.start(); 2092 } 2093 2094 public IAppOpsService getAppOpsService() { 2095 return mAppOpsService; 2096 } 2097 2098 static class MemBinder extends Binder { 2099 ActivityManagerService mActivityManagerService; 2100 MemBinder(ActivityManagerService activityManagerService) { 2101 mActivityManagerService = activityManagerService; 2102 } 2103 2104 @Override 2105 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2106 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2107 != PackageManager.PERMISSION_GRANTED) { 2108 pw.println("Permission Denial: can't dump meminfo from from pid=" 2109 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2110 + " without permission " + android.Manifest.permission.DUMP); 2111 return; 2112 } 2113 2114 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2115 } 2116 } 2117 2118 static class GraphicsBinder extends Binder { 2119 ActivityManagerService mActivityManagerService; 2120 GraphicsBinder(ActivityManagerService activityManagerService) { 2121 mActivityManagerService = activityManagerService; 2122 } 2123 2124 @Override 2125 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2126 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2127 != PackageManager.PERMISSION_GRANTED) { 2128 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2129 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2130 + " without permission " + android.Manifest.permission.DUMP); 2131 return; 2132 } 2133 2134 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2135 } 2136 } 2137 2138 static class DbBinder extends Binder { 2139 ActivityManagerService mActivityManagerService; 2140 DbBinder(ActivityManagerService activityManagerService) { 2141 mActivityManagerService = activityManagerService; 2142 } 2143 2144 @Override 2145 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2146 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2147 != PackageManager.PERMISSION_GRANTED) { 2148 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2149 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2150 + " without permission " + android.Manifest.permission.DUMP); 2151 return; 2152 } 2153 2154 mActivityManagerService.dumpDbInfo(fd, pw, args); 2155 } 2156 } 2157 2158 static class CpuBinder extends Binder { 2159 ActivityManagerService mActivityManagerService; 2160 CpuBinder(ActivityManagerService activityManagerService) { 2161 mActivityManagerService = activityManagerService; 2162 } 2163 2164 @Override 2165 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2166 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2167 != PackageManager.PERMISSION_GRANTED) { 2168 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2169 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2170 + " without permission " + android.Manifest.permission.DUMP); 2171 return; 2172 } 2173 2174 synchronized (mActivityManagerService.mProcessCpuThread) { 2175 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2176 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2177 SystemClock.uptimeMillis())); 2178 } 2179 } 2180 } 2181 2182 public static final class Lifecycle extends SystemService { 2183 private final ActivityManagerService mService; 2184 2185 public Lifecycle(Context context) { 2186 super(context); 2187 mService = new ActivityManagerService(context); 2188 } 2189 2190 @Override 2191 public void onStart() { 2192 mService.start(); 2193 } 2194 2195 public ActivityManagerService getService() { 2196 return mService; 2197 } 2198 } 2199 2200 // Note: This method is invoked on the main thread but may need to attach various 2201 // handlers to other threads. So take care to be explicit about the looper. 2202 public ActivityManagerService(Context systemContext) { 2203 mContext = systemContext; 2204 mFactoryTest = FactoryTest.getMode(); 2205 mSystemThread = ActivityThread.currentActivityThread(); 2206 2207 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2208 2209 mHandlerThread = new ServiceThread(TAG, 2210 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2211 mHandlerThread.start(); 2212 mHandler = new MainHandler(mHandlerThread.getLooper()); 2213 2214 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2215 "foreground", BROADCAST_FG_TIMEOUT, false); 2216 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2217 "background", BROADCAST_BG_TIMEOUT, true); 2218 mBroadcastQueues[0] = mFgBroadcastQueue; 2219 mBroadcastQueues[1] = mBgBroadcastQueue; 2220 2221 mServices = new ActiveServices(this); 2222 mProviderMap = new ProviderMap(this); 2223 2224 // TODO: Move creation of battery stats service outside of activity manager service. 2225 File dataDir = Environment.getDataDirectory(); 2226 File systemDir = new File(dataDir, "system"); 2227 systemDir.mkdirs(); 2228 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2229 mBatteryStatsService.getActiveStatistics().readLocked(); 2230 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2231 mOnBattery = DEBUG_POWER ? true 2232 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2233 mBatteryStatsService.getActiveStatistics().setCallback(this); 2234 2235 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2236 2237 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2238 2239 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2240 2241 // User 0 is the first and only user that runs at boot. 2242 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2243 mUserLru.add(Integer.valueOf(0)); 2244 updateStartedUserArrayLocked(); 2245 2246 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2247 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2248 2249 mConfiguration.setToDefaults(); 2250 mConfiguration.setLocale(Locale.getDefault()); 2251 2252 mConfigurationSeq = mConfiguration.seq = 1; 2253 mProcessCpuTracker.init(); 2254 2255 final Resources res = mContext.getResources(); 2256 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 2257 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2258 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2259 2260 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2261 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2262 mStackSupervisor = new ActivityStackSupervisor(this); 2263 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2264 2265 mProcessCpuThread = new Thread("CpuTracker") { 2266 @Override 2267 public void run() { 2268 while (true) { 2269 try { 2270 try { 2271 synchronized(this) { 2272 final long now = SystemClock.uptimeMillis(); 2273 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2274 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2275 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2276 // + ", write delay=" + nextWriteDelay); 2277 if (nextWriteDelay < nextCpuDelay) { 2278 nextCpuDelay = nextWriteDelay; 2279 } 2280 if (nextCpuDelay > 0) { 2281 mProcessCpuMutexFree.set(true); 2282 this.wait(nextCpuDelay); 2283 } 2284 } 2285 } catch (InterruptedException e) { 2286 } 2287 updateCpuStatsNow(); 2288 } catch (Exception e) { 2289 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2290 } 2291 } 2292 } 2293 }; 2294 2295 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2296 2297 Watchdog.getInstance().addMonitor(this); 2298 Watchdog.getInstance().addThread(mHandler); 2299 } 2300 2301 public void setSystemServiceManager(SystemServiceManager mgr) { 2302 mSystemServiceManager = mgr; 2303 } 2304 2305 private void start() { 2306 Process.removeAllProcessGroups(); 2307 mProcessCpuThread.start(); 2308 2309 mBatteryStatsService.publish(mContext); 2310 mAppOpsService.publish(mContext); 2311 Slog.d("AppOps", "AppOpsService published"); 2312 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2313 } 2314 2315 public void initPowerManagement() { 2316 mStackSupervisor.initPowerManagement(); 2317 mBatteryStatsService.initPowerManagement(); 2318 } 2319 2320 @Override 2321 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2322 throws RemoteException { 2323 if (code == SYSPROPS_TRANSACTION) { 2324 // We need to tell all apps about the system property change. 2325 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2326 synchronized(this) { 2327 final int NP = mProcessNames.getMap().size(); 2328 for (int ip=0; ip<NP; ip++) { 2329 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2330 final int NA = apps.size(); 2331 for (int ia=0; ia<NA; ia++) { 2332 ProcessRecord app = apps.valueAt(ia); 2333 if (app.thread != null) { 2334 procs.add(app.thread.asBinder()); 2335 } 2336 } 2337 } 2338 } 2339 2340 int N = procs.size(); 2341 for (int i=0; i<N; i++) { 2342 Parcel data2 = Parcel.obtain(); 2343 try { 2344 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2345 } catch (RemoteException e) { 2346 } 2347 data2.recycle(); 2348 } 2349 } 2350 try { 2351 return super.onTransact(code, data, reply, flags); 2352 } catch (RuntimeException e) { 2353 // The activity manager only throws security exceptions, so let's 2354 // log all others. 2355 if (!(e instanceof SecurityException)) { 2356 Slog.wtf(TAG, "Activity Manager Crash", e); 2357 } 2358 throw e; 2359 } 2360 } 2361 2362 void updateCpuStats() { 2363 final long now = SystemClock.uptimeMillis(); 2364 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2365 return; 2366 } 2367 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2368 synchronized (mProcessCpuThread) { 2369 mProcessCpuThread.notify(); 2370 } 2371 } 2372 } 2373 2374 void updateCpuStatsNow() { 2375 synchronized (mProcessCpuThread) { 2376 mProcessCpuMutexFree.set(false); 2377 final long now = SystemClock.uptimeMillis(); 2378 boolean haveNewCpuStats = false; 2379 2380 if (MONITOR_CPU_USAGE && 2381 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2382 mLastCpuTime.set(now); 2383 haveNewCpuStats = true; 2384 mProcessCpuTracker.update(); 2385 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2386 //Slog.i(TAG, "Total CPU usage: " 2387 // + mProcessCpu.getTotalCpuPercent() + "%"); 2388 2389 // Slog the cpu usage if the property is set. 2390 if ("true".equals(SystemProperties.get("events.cpu"))) { 2391 int user = mProcessCpuTracker.getLastUserTime(); 2392 int system = mProcessCpuTracker.getLastSystemTime(); 2393 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2394 int irq = mProcessCpuTracker.getLastIrqTime(); 2395 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2396 int idle = mProcessCpuTracker.getLastIdleTime(); 2397 2398 int total = user + system + iowait + irq + softIrq + idle; 2399 if (total == 0) total = 1; 2400 2401 EventLog.writeEvent(EventLogTags.CPU, 2402 ((user+system+iowait+irq+softIrq) * 100) / total, 2403 (user * 100) / total, 2404 (system * 100) / total, 2405 (iowait * 100) / total, 2406 (irq * 100) / total, 2407 (softIrq * 100) / total); 2408 } 2409 } 2410 2411 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2412 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2413 synchronized(bstats) { 2414 synchronized(mPidsSelfLocked) { 2415 if (haveNewCpuStats) { 2416 if (mOnBattery) { 2417 int perc = bstats.startAddingCpuLocked(); 2418 int totalUTime = 0; 2419 int totalSTime = 0; 2420 final int N = mProcessCpuTracker.countStats(); 2421 for (int i=0; i<N; i++) { 2422 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2423 if (!st.working) { 2424 continue; 2425 } 2426 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2427 int otherUTime = (st.rel_utime*perc)/100; 2428 int otherSTime = (st.rel_stime*perc)/100; 2429 totalUTime += otherUTime; 2430 totalSTime += otherSTime; 2431 if (pr != null) { 2432 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2433 if (ps == null || !ps.isActive()) { 2434 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2435 pr.info.uid, pr.processName); 2436 } 2437 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2438 st.rel_stime-otherSTime); 2439 ps.addSpeedStepTimes(cpuSpeedTimes); 2440 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2441 } else { 2442 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2443 if (ps == null || !ps.isActive()) { 2444 st.batteryStats = ps = bstats.getProcessStatsLocked( 2445 bstats.mapUid(st.uid), st.name); 2446 } 2447 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2448 st.rel_stime-otherSTime); 2449 ps.addSpeedStepTimes(cpuSpeedTimes); 2450 } 2451 } 2452 bstats.finishAddingCpuLocked(perc, totalUTime, 2453 totalSTime, cpuSpeedTimes); 2454 } 2455 } 2456 } 2457 2458 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2459 mLastWriteTime = now; 2460 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2461 } 2462 } 2463 } 2464 } 2465 2466 @Override 2467 public void batteryNeedsCpuUpdate() { 2468 updateCpuStatsNow(); 2469 } 2470 2471 @Override 2472 public void batteryPowerChanged(boolean onBattery) { 2473 // When plugging in, update the CPU stats first before changing 2474 // the plug state. 2475 updateCpuStatsNow(); 2476 synchronized (this) { 2477 synchronized(mPidsSelfLocked) { 2478 mOnBattery = DEBUG_POWER ? true : onBattery; 2479 } 2480 } 2481 } 2482 2483 /** 2484 * Initialize the application bind args. These are passed to each 2485 * process when the bindApplication() IPC is sent to the process. They're 2486 * lazily setup to make sure the services are running when they're asked for. 2487 */ 2488 private HashMap<String, IBinder> getCommonServicesLocked() { 2489 if (mAppBindArgs == null) { 2490 mAppBindArgs = new HashMap<String, IBinder>(); 2491 2492 // Setup the application init args 2493 mAppBindArgs.put("package", ServiceManager.getService("package")); 2494 mAppBindArgs.put("window", ServiceManager.getService("window")); 2495 mAppBindArgs.put(Context.ALARM_SERVICE, 2496 ServiceManager.getService(Context.ALARM_SERVICE)); 2497 } 2498 return mAppBindArgs; 2499 } 2500 2501 final void setFocusedActivityLocked(ActivityRecord r) { 2502 if (mFocusedActivity != r) { 2503 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2504 mFocusedActivity = r; 2505 if (r.task != null && r.task.voiceInteractor != null) { 2506 startRunningVoiceLocked(); 2507 } else { 2508 finishRunningVoiceLocked(); 2509 } 2510 mStackSupervisor.setFocusedStack(r); 2511 if (r != null) { 2512 mWindowManager.setFocusedApp(r.appToken, true); 2513 } 2514 applyUpdateLockStateLocked(r); 2515 } 2516 } 2517 2518 final void clearFocusedActivity(ActivityRecord r) { 2519 if (mFocusedActivity == r) { 2520 mFocusedActivity = null; 2521 } 2522 } 2523 2524 @Override 2525 public void setFocusedStack(int stackId) { 2526 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2527 synchronized (ActivityManagerService.this) { 2528 ActivityStack stack = mStackSupervisor.getStack(stackId); 2529 if (stack != null) { 2530 ActivityRecord r = stack.topRunningActivityLocked(null); 2531 if (r != null) { 2532 setFocusedActivityLocked(r); 2533 } 2534 } 2535 } 2536 } 2537 2538 @Override 2539 public void notifyActivityDrawn(IBinder token) { 2540 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2541 synchronized (this) { 2542 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2543 if (r != null) { 2544 r.task.stack.notifyActivityDrawnLocked(r); 2545 } 2546 } 2547 } 2548 2549 final void applyUpdateLockStateLocked(ActivityRecord r) { 2550 // Modifications to the UpdateLock state are done on our handler, outside 2551 // the activity manager's locks. The new state is determined based on the 2552 // state *now* of the relevant activity record. The object is passed to 2553 // the handler solely for logging detail, not to be consulted/modified. 2554 final boolean nextState = r != null && r.immersive; 2555 mHandler.sendMessage( 2556 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2557 } 2558 2559 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2560 Message msg = Message.obtain(); 2561 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2562 msg.obj = r.task.askedCompatMode ? null : r; 2563 mHandler.sendMessage(msg); 2564 } 2565 2566 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2567 String what, Object obj, ProcessRecord srcApp) { 2568 app.lastActivityTime = now; 2569 2570 if (app.activities.size() > 0) { 2571 // Don't want to touch dependent processes that are hosting activities. 2572 return index; 2573 } 2574 2575 int lrui = mLruProcesses.lastIndexOf(app); 2576 if (lrui < 0) { 2577 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2578 + what + " " + obj + " from " + srcApp); 2579 return index; 2580 } 2581 2582 if (lrui >= index) { 2583 // Don't want to cause this to move dependent processes *back* in the 2584 // list as if they were less frequently used. 2585 return index; 2586 } 2587 2588 if (lrui >= mLruProcessActivityStart) { 2589 // Don't want to touch dependent processes that are hosting activities. 2590 return index; 2591 } 2592 2593 mLruProcesses.remove(lrui); 2594 if (index > 0) { 2595 index--; 2596 } 2597 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2598 + " in LRU list: " + app); 2599 mLruProcesses.add(index, app); 2600 return index; 2601 } 2602 2603 final void removeLruProcessLocked(ProcessRecord app) { 2604 int lrui = mLruProcesses.lastIndexOf(app); 2605 if (lrui >= 0) { 2606 if (lrui <= mLruProcessActivityStart) { 2607 mLruProcessActivityStart--; 2608 } 2609 if (lrui <= mLruProcessServiceStart) { 2610 mLruProcessServiceStart--; 2611 } 2612 mLruProcesses.remove(lrui); 2613 } 2614 } 2615 2616 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2617 ProcessRecord client) { 2618 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2619 || app.treatLikeActivity; 2620 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2621 if (!activityChange && hasActivity) { 2622 // The process has activities, so we are only allowing activity-based adjustments 2623 // to move it. It should be kept in the front of the list with other 2624 // processes that have activities, and we don't want those to change their 2625 // order except due to activity operations. 2626 return; 2627 } 2628 2629 mLruSeq++; 2630 final long now = SystemClock.uptimeMillis(); 2631 app.lastActivityTime = now; 2632 2633 // First a quick reject: if the app is already at the position we will 2634 // put it, then there is nothing to do. 2635 if (hasActivity) { 2636 final int N = mLruProcesses.size(); 2637 if (N > 0 && mLruProcesses.get(N-1) == app) { 2638 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2639 return; 2640 } 2641 } else { 2642 if (mLruProcessServiceStart > 0 2643 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2644 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2645 return; 2646 } 2647 } 2648 2649 int lrui = mLruProcesses.lastIndexOf(app); 2650 2651 if (app.persistent && lrui >= 0) { 2652 // We don't care about the position of persistent processes, as long as 2653 // they are in the list. 2654 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2655 return; 2656 } 2657 2658 /* In progress: compute new position first, so we can avoid doing work 2659 if the process is not actually going to move. Not yet working. 2660 int addIndex; 2661 int nextIndex; 2662 boolean inActivity = false, inService = false; 2663 if (hasActivity) { 2664 // Process has activities, put it at the very tipsy-top. 2665 addIndex = mLruProcesses.size(); 2666 nextIndex = mLruProcessServiceStart; 2667 inActivity = true; 2668 } else if (hasService) { 2669 // Process has services, put it at the top of the service list. 2670 addIndex = mLruProcessActivityStart; 2671 nextIndex = mLruProcessServiceStart; 2672 inActivity = true; 2673 inService = true; 2674 } else { 2675 // Process not otherwise of interest, it goes to the top of the non-service area. 2676 addIndex = mLruProcessServiceStart; 2677 if (client != null) { 2678 int clientIndex = mLruProcesses.lastIndexOf(client); 2679 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2680 + app); 2681 if (clientIndex >= 0 && addIndex > clientIndex) { 2682 addIndex = clientIndex; 2683 } 2684 } 2685 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2686 } 2687 2688 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2689 + mLruProcessActivityStart + "): " + app); 2690 */ 2691 2692 if (lrui >= 0) { 2693 if (lrui < mLruProcessActivityStart) { 2694 mLruProcessActivityStart--; 2695 } 2696 if (lrui < mLruProcessServiceStart) { 2697 mLruProcessServiceStart--; 2698 } 2699 /* 2700 if (addIndex > lrui) { 2701 addIndex--; 2702 } 2703 if (nextIndex > lrui) { 2704 nextIndex--; 2705 } 2706 */ 2707 mLruProcesses.remove(lrui); 2708 } 2709 2710 /* 2711 mLruProcesses.add(addIndex, app); 2712 if (inActivity) { 2713 mLruProcessActivityStart++; 2714 } 2715 if (inService) { 2716 mLruProcessActivityStart++; 2717 } 2718 */ 2719 2720 int nextIndex; 2721 if (hasActivity) { 2722 final int N = mLruProcesses.size(); 2723 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2724 // Process doesn't have activities, but has clients with 2725 // activities... move it up, but one below the top (the top 2726 // should always have a real activity). 2727 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2728 mLruProcesses.add(N-1, app); 2729 // To keep it from spamming the LRU list (by making a bunch of clients), 2730 // we will push down any other entries owned by the app. 2731 final int uid = app.info.uid; 2732 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2733 ProcessRecord subProc = mLruProcesses.get(i); 2734 if (subProc.info.uid == uid) { 2735 // We want to push this one down the list. If the process after 2736 // it is for the same uid, however, don't do so, because we don't 2737 // want them internally to be re-ordered. 2738 if (mLruProcesses.get(i-1).info.uid != uid) { 2739 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2740 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2741 ProcessRecord tmp = mLruProcesses.get(i); 2742 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2743 mLruProcesses.set(i-1, tmp); 2744 i--; 2745 } 2746 } else { 2747 // A gap, we can stop here. 2748 break; 2749 } 2750 } 2751 } else { 2752 // Process has activities, put it at the very tipsy-top. 2753 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2754 mLruProcesses.add(app); 2755 } 2756 nextIndex = mLruProcessServiceStart; 2757 } else if (hasService) { 2758 // Process has services, put it at the top of the service list. 2759 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2760 mLruProcesses.add(mLruProcessActivityStart, app); 2761 nextIndex = mLruProcessServiceStart; 2762 mLruProcessActivityStart++; 2763 } else { 2764 // Process not otherwise of interest, it goes to the top of the non-service area. 2765 int index = mLruProcessServiceStart; 2766 if (client != null) { 2767 // If there is a client, don't allow the process to be moved up higher 2768 // in the list than that client. 2769 int clientIndex = mLruProcesses.lastIndexOf(client); 2770 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2771 + " when updating " + app); 2772 if (clientIndex <= lrui) { 2773 // Don't allow the client index restriction to push it down farther in the 2774 // list than it already is. 2775 clientIndex = lrui; 2776 } 2777 if (clientIndex >= 0 && index > clientIndex) { 2778 index = clientIndex; 2779 } 2780 } 2781 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2782 mLruProcesses.add(index, app); 2783 nextIndex = index-1; 2784 mLruProcessActivityStart++; 2785 mLruProcessServiceStart++; 2786 } 2787 2788 // If the app is currently using a content provider or service, 2789 // bump those processes as well. 2790 for (int j=app.connections.size()-1; j>=0; j--) { 2791 ConnectionRecord cr = app.connections.valueAt(j); 2792 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2793 && cr.binding.service.app != null 2794 && cr.binding.service.app.lruSeq != mLruSeq 2795 && !cr.binding.service.app.persistent) { 2796 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2797 "service connection", cr, app); 2798 } 2799 } 2800 for (int j=app.conProviders.size()-1; j>=0; j--) { 2801 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2802 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2803 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2804 "provider reference", cpr, app); 2805 } 2806 } 2807 } 2808 2809 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2810 if (uid == Process.SYSTEM_UID) { 2811 // The system gets to run in any process. If there are multiple 2812 // processes with the same uid, just pick the first (this 2813 // should never happen). 2814 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2815 if (procs == null) return null; 2816 final int N = procs.size(); 2817 for (int i = 0; i < N; i++) { 2818 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2819 } 2820 } 2821 ProcessRecord proc = mProcessNames.get(processName, uid); 2822 if (false && proc != null && !keepIfLarge 2823 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2824 && proc.lastCachedPss >= 4000) { 2825 // Turn this condition on to cause killing to happen regularly, for testing. 2826 if (proc.baseProcessTracker != null) { 2827 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2828 } 2829 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2830 + "k from cached"); 2831 } else if (proc != null && !keepIfLarge 2832 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2833 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2834 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2835 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2836 if (proc.baseProcessTracker != null) { 2837 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2838 } 2839 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2840 + "k from cached"); 2841 } 2842 } 2843 return proc; 2844 } 2845 2846 void ensurePackageDexOpt(String packageName) { 2847 IPackageManager pm = AppGlobals.getPackageManager(); 2848 try { 2849 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2850 mDidDexOpt = true; 2851 } 2852 } catch (RemoteException e) { 2853 } 2854 } 2855 2856 boolean isNextTransitionForward() { 2857 int transit = mWindowManager.getPendingAppTransition(); 2858 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2859 || transit == AppTransition.TRANSIT_TASK_OPEN 2860 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2861 } 2862 2863 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2864 String processName, String abiOverride, int uid, Runnable crashHandler) { 2865 synchronized(this) { 2866 ApplicationInfo info = new ApplicationInfo(); 2867 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2868 // For isolated processes, the former contains the parent's uid and the latter the 2869 // actual uid of the isolated process. 2870 // In the special case introduced by this method (which is, starting an isolated 2871 // process directly from the SystemServer without an actual parent app process) the 2872 // closest thing to a parent's uid is SYSTEM_UID. 2873 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2874 // the |isolated| logic in the ProcessRecord constructor. 2875 info.uid = Process.SYSTEM_UID; 2876 info.processName = processName; 2877 info.className = entryPoint; 2878 info.packageName = "android"; 2879 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2880 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2881 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2882 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2883 crashHandler); 2884 return proc != null ? proc.pid : 0; 2885 } 2886 } 2887 2888 final ProcessRecord startProcessLocked(String processName, 2889 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2890 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2891 boolean isolated, boolean keepIfLarge) { 2892 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2893 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2894 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2895 null /* crashHandler */); 2896 } 2897 2898 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2899 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2900 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2901 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2902 ProcessRecord app; 2903 if (!isolated) { 2904 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2905 } else { 2906 // If this is an isolated process, it can't re-use an existing process. 2907 app = null; 2908 } 2909 // We don't have to do anything more if: 2910 // (1) There is an existing application record; and 2911 // (2) The caller doesn't think it is dead, OR there is no thread 2912 // object attached to it so we know it couldn't have crashed; and 2913 // (3) There is a pid assigned to it, so it is either starting or 2914 // already running. 2915 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2916 + " app=" + app + " knownToBeDead=" + knownToBeDead 2917 + " thread=" + (app != null ? app.thread : null) 2918 + " pid=" + (app != null ? app.pid : -1)); 2919 if (app != null && app.pid > 0) { 2920 if (!knownToBeDead || app.thread == null) { 2921 // We already have the app running, or are waiting for it to 2922 // come up (we have a pid but not yet its thread), so keep it. 2923 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2924 // If this is a new package in the process, add the package to the list 2925 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2926 return app; 2927 } 2928 2929 // An application record is attached to a previous process, 2930 // clean it up now. 2931 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2932 Process.killProcessGroup(app.info.uid, app.pid); 2933 handleAppDiedLocked(app, true, true); 2934 } 2935 2936 String hostingNameStr = hostingName != null 2937 ? hostingName.flattenToShortString() : null; 2938 2939 if (!isolated) { 2940 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2941 // If we are in the background, then check to see if this process 2942 // is bad. If so, we will just silently fail. 2943 if (mBadProcesses.get(info.processName, info.uid) != null) { 2944 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2945 + "/" + info.processName); 2946 return null; 2947 } 2948 } else { 2949 // When the user is explicitly starting a process, then clear its 2950 // crash count so that we won't make it bad until they see at 2951 // least one crash dialog again, and make the process good again 2952 // if it had been bad. 2953 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2954 + "/" + info.processName); 2955 mProcessCrashTimes.remove(info.processName, info.uid); 2956 if (mBadProcesses.get(info.processName, info.uid) != null) { 2957 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2958 UserHandle.getUserId(info.uid), info.uid, 2959 info.processName); 2960 mBadProcesses.remove(info.processName, info.uid); 2961 if (app != null) { 2962 app.bad = false; 2963 } 2964 } 2965 } 2966 } 2967 2968 if (app == null) { 2969 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2970 app.crashHandler = crashHandler; 2971 if (app == null) { 2972 Slog.w(TAG, "Failed making new process record for " 2973 + processName + "/" + info.uid + " isolated=" + isolated); 2974 return null; 2975 } 2976 mProcessNames.put(processName, app.uid, app); 2977 if (isolated) { 2978 mIsolatedProcesses.put(app.uid, app); 2979 } 2980 } else { 2981 // If this is a new package in the process, add the package to the list 2982 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2983 } 2984 2985 // If the system is not ready yet, then hold off on starting this 2986 // process until it is. 2987 if (!mProcessesReady 2988 && !isAllowedWhileBooting(info) 2989 && !allowWhileBooting) { 2990 if (!mProcessesOnHold.contains(app)) { 2991 mProcessesOnHold.add(app); 2992 } 2993 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2994 return app; 2995 } 2996 2997 startProcessLocked( 2998 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2999 return (app.pid != 0) ? app : null; 3000 } 3001 3002 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3003 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3004 } 3005 3006 private final void startProcessLocked(ProcessRecord app, 3007 String hostingType, String hostingNameStr) { 3008 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3009 null /* entryPoint */, null /* entryPointArgs */); 3010 } 3011 3012 private final void startProcessLocked(ProcessRecord app, String hostingType, 3013 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3014 if (app.pid > 0 && app.pid != MY_PID) { 3015 synchronized (mPidsSelfLocked) { 3016 mPidsSelfLocked.remove(app.pid); 3017 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3018 } 3019 app.setPid(0); 3020 } 3021 3022 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3023 "startProcessLocked removing on hold: " + app); 3024 mProcessesOnHold.remove(app); 3025 3026 updateCpuStats(); 3027 3028 try { 3029 int uid = app.uid; 3030 3031 int[] gids = null; 3032 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3033 if (!app.isolated) { 3034 int[] permGids = null; 3035 try { 3036 final PackageManager pm = mContext.getPackageManager(); 3037 permGids = pm.getPackageGids(app.info.packageName); 3038 3039 if (Environment.isExternalStorageEmulated()) { 3040 if (pm.checkPermission( 3041 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3042 app.info.packageName) == PERMISSION_GRANTED) { 3043 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3044 } else { 3045 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3046 } 3047 } 3048 } catch (PackageManager.NameNotFoundException e) { 3049 Slog.w(TAG, "Unable to retrieve gids", e); 3050 } 3051 3052 /* 3053 * Add shared application and profile GIDs so applications can share some 3054 * resources like shared libraries and access user-wide resources 3055 */ 3056 if (permGids == null) { 3057 gids = new int[2]; 3058 } else { 3059 gids = new int[permGids.length + 2]; 3060 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3061 } 3062 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3063 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3064 } 3065 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3066 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3067 && mTopComponent != null 3068 && app.processName.equals(mTopComponent.getPackageName())) { 3069 uid = 0; 3070 } 3071 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3072 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3073 uid = 0; 3074 } 3075 } 3076 int debugFlags = 0; 3077 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3078 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3079 // Also turn on CheckJNI for debuggable apps. It's quite 3080 // awkward to turn on otherwise. 3081 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3082 } 3083 // Run the app in safe mode if its manifest requests so or the 3084 // system is booted in safe mode. 3085 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3086 mSafeMode == true) { 3087 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3088 } 3089 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3090 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3091 } 3092 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3093 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3094 } 3095 if ("1".equals(SystemProperties.get("debug.assert"))) { 3096 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3097 } 3098 3099 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3100 if (requiredAbi == null) { 3101 requiredAbi = Build.SUPPORTED_ABIS[0]; 3102 } 3103 3104 // Start the process. It will either succeed and return a result containing 3105 // the PID of the new process, or else throw a RuntimeException. 3106 boolean isActivityProcess = (entryPoint == null); 3107 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3108 Process.ProcessStartResult startResult = Process.start(entryPoint, 3109 app.processName, uid, uid, gids, debugFlags, mountExternal, 3110 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3111 3112 if (app.isolated) { 3113 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3114 } 3115 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3116 3117 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3118 UserHandle.getUserId(uid), startResult.pid, uid, 3119 app.processName, hostingType, 3120 hostingNameStr != null ? hostingNameStr : ""); 3121 3122 if (app.persistent) { 3123 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3124 } 3125 3126 StringBuilder buf = mStringBuilder; 3127 buf.setLength(0); 3128 buf.append("Start proc "); 3129 buf.append(app.processName); 3130 if (!isActivityProcess) { 3131 buf.append(" ["); 3132 buf.append(entryPoint); 3133 buf.append("]"); 3134 } 3135 buf.append(" for "); 3136 buf.append(hostingType); 3137 if (hostingNameStr != null) { 3138 buf.append(" "); 3139 buf.append(hostingNameStr); 3140 } 3141 buf.append(": pid="); 3142 buf.append(startResult.pid); 3143 buf.append(" uid="); 3144 buf.append(uid); 3145 buf.append(" gids={"); 3146 if (gids != null) { 3147 for (int gi=0; gi<gids.length; gi++) { 3148 if (gi != 0) buf.append(", "); 3149 buf.append(gids[gi]); 3150 3151 } 3152 } 3153 buf.append("}"); 3154 if (requiredAbi != null) { 3155 buf.append(" abi="); 3156 buf.append(requiredAbi); 3157 } 3158 Slog.i(TAG, buf.toString()); 3159 app.setPid(startResult.pid); 3160 app.usingWrapper = startResult.usingWrapper; 3161 app.removed = false; 3162 app.killedByAm = false; 3163 synchronized (mPidsSelfLocked) { 3164 this.mPidsSelfLocked.put(startResult.pid, app); 3165 if (isActivityProcess) { 3166 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3167 msg.obj = app; 3168 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3169 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3170 } 3171 } 3172 } catch (RuntimeException e) { 3173 // XXX do better error recovery. 3174 app.setPid(0); 3175 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3176 if (app.isolated) { 3177 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3178 } 3179 Slog.e(TAG, "Failure starting process " + app.processName, e); 3180 } 3181 } 3182 3183 void updateUsageStats(ActivityRecord component, boolean resumed) { 3184 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3185 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3186 if (resumed) { 3187 if (mUsageStatsService != null) { 3188 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3189 System.currentTimeMillis(), 3190 UsageEvents.Event.MOVE_TO_FOREGROUND); 3191 } 3192 synchronized (stats) { 3193 stats.noteActivityResumedLocked(component.app.uid); 3194 } 3195 } else { 3196 if (mUsageStatsService != null) { 3197 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3198 System.currentTimeMillis(), 3199 UsageEvents.Event.MOVE_TO_BACKGROUND); 3200 } 3201 synchronized (stats) { 3202 stats.noteActivityPausedLocked(component.app.uid); 3203 } 3204 } 3205 } 3206 3207 Intent getHomeIntent() { 3208 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3209 intent.setComponent(mTopComponent); 3210 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3211 intent.addCategory(Intent.CATEGORY_HOME); 3212 } 3213 return intent; 3214 } 3215 3216 boolean startHomeActivityLocked(int userId) { 3217 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3218 && mTopAction == null) { 3219 // We are running in factory test mode, but unable to find 3220 // the factory test app, so just sit around displaying the 3221 // error message and don't try to start anything. 3222 return false; 3223 } 3224 Intent intent = getHomeIntent(); 3225 ActivityInfo aInfo = 3226 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3227 if (aInfo != null) { 3228 intent.setComponent(new ComponentName( 3229 aInfo.applicationInfo.packageName, aInfo.name)); 3230 // Don't do this if the home app is currently being 3231 // instrumented. 3232 aInfo = new ActivityInfo(aInfo); 3233 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3234 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3235 aInfo.applicationInfo.uid, true); 3236 if (app == null || app.instrumentationClass == null) { 3237 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3238 mStackSupervisor.startHomeActivity(intent, aInfo); 3239 } 3240 } 3241 3242 return true; 3243 } 3244 3245 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3246 ActivityInfo ai = null; 3247 ComponentName comp = intent.getComponent(); 3248 try { 3249 if (comp != null) { 3250 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3251 } else { 3252 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3253 intent, 3254 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3255 flags, userId); 3256 3257 if (info != null) { 3258 ai = info.activityInfo; 3259 } 3260 } 3261 } catch (RemoteException e) { 3262 // ignore 3263 } 3264 3265 return ai; 3266 } 3267 3268 /** 3269 * Starts the "new version setup screen" if appropriate. 3270 */ 3271 void startSetupActivityLocked() { 3272 // Only do this once per boot. 3273 if (mCheckedForSetup) { 3274 return; 3275 } 3276 3277 // We will show this screen if the current one is a different 3278 // version than the last one shown, and we are not running in 3279 // low-level factory test mode. 3280 final ContentResolver resolver = mContext.getContentResolver(); 3281 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3282 Settings.Global.getInt(resolver, 3283 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3284 mCheckedForSetup = true; 3285 3286 // See if we should be showing the platform update setup UI. 3287 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3288 List<ResolveInfo> ris = mContext.getPackageManager() 3289 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3290 3291 // We don't allow third party apps to replace this. 3292 ResolveInfo ri = null; 3293 for (int i=0; ris != null && i<ris.size(); i++) { 3294 if ((ris.get(i).activityInfo.applicationInfo.flags 3295 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3296 ri = ris.get(i); 3297 break; 3298 } 3299 } 3300 3301 if (ri != null) { 3302 String vers = ri.activityInfo.metaData != null 3303 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3304 : null; 3305 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3306 vers = ri.activityInfo.applicationInfo.metaData.getString( 3307 Intent.METADATA_SETUP_VERSION); 3308 } 3309 String lastVers = Settings.Secure.getString( 3310 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3311 if (vers != null && !vers.equals(lastVers)) { 3312 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3313 intent.setComponent(new ComponentName( 3314 ri.activityInfo.packageName, ri.activityInfo.name)); 3315 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3316 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3317 } 3318 } 3319 } 3320 } 3321 3322 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3323 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3324 } 3325 3326 void enforceNotIsolatedCaller(String caller) { 3327 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3328 throw new SecurityException("Isolated process not allowed to call " + caller); 3329 } 3330 } 3331 3332 @Override 3333 public int getFrontActivityScreenCompatMode() { 3334 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3335 synchronized (this) { 3336 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3337 } 3338 } 3339 3340 @Override 3341 public void setFrontActivityScreenCompatMode(int mode) { 3342 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3343 "setFrontActivityScreenCompatMode"); 3344 synchronized (this) { 3345 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3346 } 3347 } 3348 3349 @Override 3350 public int getPackageScreenCompatMode(String packageName) { 3351 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3352 synchronized (this) { 3353 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3354 } 3355 } 3356 3357 @Override 3358 public void setPackageScreenCompatMode(String packageName, int mode) { 3359 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3360 "setPackageScreenCompatMode"); 3361 synchronized (this) { 3362 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3363 } 3364 } 3365 3366 @Override 3367 public boolean getPackageAskScreenCompat(String packageName) { 3368 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3369 synchronized (this) { 3370 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3371 } 3372 } 3373 3374 @Override 3375 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3376 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3377 "setPackageAskScreenCompat"); 3378 synchronized (this) { 3379 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3380 } 3381 } 3382 3383 private void dispatchProcessesChanged() { 3384 int N; 3385 synchronized (this) { 3386 N = mPendingProcessChanges.size(); 3387 if (mActiveProcessChanges.length < N) { 3388 mActiveProcessChanges = new ProcessChangeItem[N]; 3389 } 3390 mPendingProcessChanges.toArray(mActiveProcessChanges); 3391 mAvailProcessChanges.addAll(mPendingProcessChanges); 3392 mPendingProcessChanges.clear(); 3393 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3394 } 3395 3396 int i = mProcessObservers.beginBroadcast(); 3397 while (i > 0) { 3398 i--; 3399 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3400 if (observer != null) { 3401 try { 3402 for (int j=0; j<N; j++) { 3403 ProcessChangeItem item = mActiveProcessChanges[j]; 3404 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3405 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3406 + item.pid + " uid=" + item.uid + ": " 3407 + item.foregroundActivities); 3408 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3409 item.foregroundActivities); 3410 } 3411 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3412 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3413 + item.pid + " uid=" + item.uid + ": " + item.processState); 3414 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3415 } 3416 } 3417 } catch (RemoteException e) { 3418 } 3419 } 3420 } 3421 mProcessObservers.finishBroadcast(); 3422 } 3423 3424 private void dispatchProcessDied(int pid, int uid) { 3425 int i = mProcessObservers.beginBroadcast(); 3426 while (i > 0) { 3427 i--; 3428 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3429 if (observer != null) { 3430 try { 3431 observer.onProcessDied(pid, uid); 3432 } catch (RemoteException e) { 3433 } 3434 } 3435 } 3436 mProcessObservers.finishBroadcast(); 3437 } 3438 3439 @Override 3440 public final int startActivity(IApplicationThread caller, String callingPackage, 3441 Intent intent, String resolvedType, IBinder resultTo, 3442 String resultWho, int requestCode, int startFlags, 3443 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3444 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3445 resultWho, requestCode, 3446 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3447 } 3448 3449 @Override 3450 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3451 Intent intent, String resolvedType, IBinder resultTo, 3452 String resultWho, int requestCode, int startFlags, 3453 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3454 enforceNotIsolatedCaller("startActivity"); 3455 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3456 false, ALLOW_FULL_ONLY, "startActivity", null); 3457 // TODO: Switch to user app stacks here. 3458 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3459 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3460 null, null, options, userId, null); 3461 } 3462 3463 @Override 3464 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3465 Intent intent, String resolvedType, IBinder resultTo, 3466 String resultWho, int requestCode, int startFlags, 3467 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3468 3469 // This is very dangerous -- it allows you to perform a start activity (including 3470 // permission grants) as any app that may launch one of your own activities. So 3471 // we will only allow this to be done from activities that are part of the core framework, 3472 // and then only when they are running as the system. 3473 final ActivityRecord sourceRecord; 3474 final int targetUid; 3475 final String targetPackage; 3476 synchronized (this) { 3477 if (resultTo == null) { 3478 throw new SecurityException("Must be called from an activity"); 3479 } 3480 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3481 if (sourceRecord == null) { 3482 throw new SecurityException("Called with bad activity token: " + resultTo); 3483 } 3484 if (!sourceRecord.info.packageName.equals("android")) { 3485 throw new SecurityException( 3486 "Must be called from an activity that is declared in the android package"); 3487 } 3488 if (sourceRecord.app == null) { 3489 throw new SecurityException("Called without a process attached to activity"); 3490 } 3491 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3492 // This is still okay, as long as this activity is running under the 3493 // uid of the original calling activity. 3494 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3495 throw new SecurityException( 3496 "Calling activity in uid " + sourceRecord.app.uid 3497 + " must be system uid or original calling uid " 3498 + sourceRecord.launchedFromUid); 3499 } 3500 } 3501 targetUid = sourceRecord.launchedFromUid; 3502 targetPackage = sourceRecord.launchedFromPackage; 3503 } 3504 3505 // TODO: Switch to user app stacks here. 3506 try { 3507 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3508 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3509 null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid), 3510 null); 3511 return ret; 3512 } catch (SecurityException e) { 3513 // XXX need to figure out how to propagate to original app. 3514 // A SecurityException here is generally actually a fault of the original 3515 // calling activity (such as a fairly granting permissions), so propagate it 3516 // back to them. 3517 /* 3518 StringBuilder msg = new StringBuilder(); 3519 msg.append("While launching"); 3520 msg.append(intent.toString()); 3521 msg.append(": "); 3522 msg.append(e.getMessage()); 3523 */ 3524 throw e; 3525 } 3526 } 3527 3528 @Override 3529 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3530 Intent intent, String resolvedType, IBinder resultTo, 3531 String resultWho, int requestCode, int startFlags, String profileFile, 3532 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3533 enforceNotIsolatedCaller("startActivityAndWait"); 3534 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3535 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3536 WaitResult res = new WaitResult(); 3537 // TODO: Switch to user app stacks here. 3538 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3539 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3540 res, null, options, userId, null); 3541 return res; 3542 } 3543 3544 @Override 3545 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3546 Intent intent, String resolvedType, IBinder resultTo, 3547 String resultWho, int requestCode, int startFlags, Configuration config, 3548 Bundle options, int userId) { 3549 enforceNotIsolatedCaller("startActivityWithConfig"); 3550 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3551 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3552 // TODO: Switch to user app stacks here. 3553 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3554 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3555 null, null, null, config, options, userId, null); 3556 return ret; 3557 } 3558 3559 @Override 3560 public int startActivityIntentSender(IApplicationThread caller, 3561 IntentSender intent, Intent fillInIntent, String resolvedType, 3562 IBinder resultTo, String resultWho, int requestCode, 3563 int flagsMask, int flagsValues, Bundle options) { 3564 enforceNotIsolatedCaller("startActivityIntentSender"); 3565 // Refuse possible leaked file descriptors 3566 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3567 throw new IllegalArgumentException("File descriptors passed in Intent"); 3568 } 3569 3570 IIntentSender sender = intent.getTarget(); 3571 if (!(sender instanceof PendingIntentRecord)) { 3572 throw new IllegalArgumentException("Bad PendingIntent object"); 3573 } 3574 3575 PendingIntentRecord pir = (PendingIntentRecord)sender; 3576 3577 synchronized (this) { 3578 // If this is coming from the currently resumed activity, it is 3579 // effectively saying that app switches are allowed at this point. 3580 final ActivityStack stack = getFocusedStack(); 3581 if (stack.mResumedActivity != null && 3582 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3583 mAppSwitchesAllowedTime = 0; 3584 } 3585 } 3586 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3587 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3588 return ret; 3589 } 3590 3591 @Override 3592 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3593 Intent intent, String resolvedType, IVoiceInteractionSession session, 3594 IVoiceInteractor interactor, int startFlags, String profileFile, 3595 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3596 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3597 != PackageManager.PERMISSION_GRANTED) { 3598 String msg = "Permission Denial: startVoiceActivity() from pid=" 3599 + Binder.getCallingPid() 3600 + ", uid=" + Binder.getCallingUid() 3601 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3602 Slog.w(TAG, msg); 3603 throw new SecurityException(msg); 3604 } 3605 if (session == null || interactor == null) { 3606 throw new NullPointerException("null session or interactor"); 3607 } 3608 userId = handleIncomingUser(callingPid, callingUid, userId, 3609 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3610 // TODO: Switch to user app stacks here. 3611 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3612 resolvedType, session, interactor, null, null, 0, startFlags, 3613 profileFile, profileFd, null, null, options, userId, null); 3614 } 3615 3616 @Override 3617 public boolean startNextMatchingActivity(IBinder callingActivity, 3618 Intent intent, Bundle options) { 3619 // Refuse possible leaked file descriptors 3620 if (intent != null && intent.hasFileDescriptors() == true) { 3621 throw new IllegalArgumentException("File descriptors passed in Intent"); 3622 } 3623 3624 synchronized (this) { 3625 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3626 if (r == null) { 3627 ActivityOptions.abort(options); 3628 return false; 3629 } 3630 if (r.app == null || r.app.thread == null) { 3631 // The caller is not running... d'oh! 3632 ActivityOptions.abort(options); 3633 return false; 3634 } 3635 intent = new Intent(intent); 3636 // The caller is not allowed to change the data. 3637 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3638 // And we are resetting to find the next component... 3639 intent.setComponent(null); 3640 3641 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3642 3643 ActivityInfo aInfo = null; 3644 try { 3645 List<ResolveInfo> resolves = 3646 AppGlobals.getPackageManager().queryIntentActivities( 3647 intent, r.resolvedType, 3648 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3649 UserHandle.getCallingUserId()); 3650 3651 // Look for the original activity in the list... 3652 final int N = resolves != null ? resolves.size() : 0; 3653 for (int i=0; i<N; i++) { 3654 ResolveInfo rInfo = resolves.get(i); 3655 if (rInfo.activityInfo.packageName.equals(r.packageName) 3656 && rInfo.activityInfo.name.equals(r.info.name)) { 3657 // We found the current one... the next matching is 3658 // after it. 3659 i++; 3660 if (i<N) { 3661 aInfo = resolves.get(i).activityInfo; 3662 } 3663 if (debug) { 3664 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3665 + "/" + r.info.name); 3666 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3667 + "/" + aInfo.name); 3668 } 3669 break; 3670 } 3671 } 3672 } catch (RemoteException e) { 3673 } 3674 3675 if (aInfo == null) { 3676 // Nobody who is next! 3677 ActivityOptions.abort(options); 3678 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3679 return false; 3680 } 3681 3682 intent.setComponent(new ComponentName( 3683 aInfo.applicationInfo.packageName, aInfo.name)); 3684 intent.setFlags(intent.getFlags()&~( 3685 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3686 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3687 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3688 Intent.FLAG_ACTIVITY_NEW_TASK)); 3689 3690 // Okay now we need to start the new activity, replacing the 3691 // currently running activity. This is a little tricky because 3692 // we want to start the new one as if the current one is finished, 3693 // but not finish the current one first so that there is no flicker. 3694 // And thus... 3695 final boolean wasFinishing = r.finishing; 3696 r.finishing = true; 3697 3698 // Propagate reply information over to the new activity. 3699 final ActivityRecord resultTo = r.resultTo; 3700 final String resultWho = r.resultWho; 3701 final int requestCode = r.requestCode; 3702 r.resultTo = null; 3703 if (resultTo != null) { 3704 resultTo.removeResultsLocked(r, resultWho, requestCode); 3705 } 3706 3707 final long origId = Binder.clearCallingIdentity(); 3708 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3709 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3710 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3711 options, false, null, null); 3712 Binder.restoreCallingIdentity(origId); 3713 3714 r.finishing = wasFinishing; 3715 if (res != ActivityManager.START_SUCCESS) { 3716 return false; 3717 } 3718 return true; 3719 } 3720 } 3721 3722 @Override 3723 public final int startActivityFromRecents(int taskId, Bundle options) { 3724 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3725 String msg = "Permission Denial: startActivityFromRecents called without " + 3726 START_TASKS_FROM_RECENTS; 3727 Slog.w(TAG, msg); 3728 throw new SecurityException(msg); 3729 } 3730 final int callingUid; 3731 final String callingPackage; 3732 final Intent intent; 3733 final int userId; 3734 synchronized (this) { 3735 final TaskRecord task = recentTaskForIdLocked(taskId); 3736 if (task == null) { 3737 throw new ActivityNotFoundException("Task " + taskId + " not found."); 3738 } 3739 callingUid = task.mCallingUid; 3740 callingPackage = task.mCallingPackage; 3741 intent = task.intent; 3742 userId = task.userId; 3743 } 3744 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3745 options, userId, null); 3746 } 3747 3748 final int startActivityInPackage(int uid, String callingPackage, 3749 Intent intent, String resolvedType, IBinder resultTo, 3750 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3751 IActivityContainer container) { 3752 3753 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3754 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3755 3756 // TODO: Switch to user app stacks here. 3757 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3758 null, null, resultTo, resultWho, requestCode, startFlags, 3759 null, null, null, null, options, userId, container); 3760 return ret; 3761 } 3762 3763 @Override 3764 public final int startActivities(IApplicationThread caller, String callingPackage, 3765 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3766 int userId) { 3767 enforceNotIsolatedCaller("startActivities"); 3768 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3769 false, ALLOW_FULL_ONLY, "startActivity", null); 3770 // TODO: Switch to user app stacks here. 3771 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3772 resolvedTypes, resultTo, options, userId); 3773 return ret; 3774 } 3775 3776 final int startActivitiesInPackage(int uid, String callingPackage, 3777 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3778 Bundle options, int userId) { 3779 3780 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3781 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3782 // TODO: Switch to user app stacks here. 3783 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3784 resultTo, options, userId); 3785 return ret; 3786 } 3787 3788 //explicitly remove thd old information in mRecentTasks when removing existing user. 3789 private void removeRecentTasksForUserLocked(int userId) { 3790 if(userId <= 0) { 3791 Slog.i(TAG, "Can't remove recent task on user " + userId); 3792 return; 3793 } 3794 3795 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3796 TaskRecord tr = mRecentTasks.get(i); 3797 if (tr.userId == userId) { 3798 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3799 + " when finishing user" + userId); 3800 tr.disposeThumbnail(); 3801 mRecentTasks.remove(i); 3802 } 3803 } 3804 3805 // Remove tasks from persistent storage. 3806 mTaskPersister.wakeup(null, true); 3807 } 3808 3809 final void addRecentTaskLocked(TaskRecord task) { 3810 final int N = mRecentTasks.size(); 3811 // Quick case: check if the top-most recent task is the same. 3812 if (N > 0 && mRecentTasks.get(0) == task) { 3813 return; 3814 } 3815 // Another quick case: never add voice sessions. 3816 if (task.voiceSession != null) { 3817 return; 3818 } 3819 3820 trimRecentsForTask(task, true); 3821 3822 if (N >= MAX_RECENT_TASKS) { 3823 final TaskRecord tr = mRecentTasks.remove(N - 1); 3824 tr.disposeThumbnail(); 3825 tr.closeRecentsChain(); 3826 } 3827 mRecentTasks.add(0, task); 3828 } 3829 3830 /** 3831 * If needed, remove oldest existing entries in recents that are for the same kind 3832 * of task as the given one. 3833 */ 3834 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 3835 int N = mRecentTasks.size(); 3836 final Intent intent = task.intent; 3837 final boolean document = intent != null && intent.isDocument(); 3838 3839 int maxRecents = task.maxRecents - 1; 3840 for (int i=0; i<N; i++) { 3841 final TaskRecord tr = mRecentTasks.get(i); 3842 if (task != tr) { 3843 if (task.userId != tr.userId) { 3844 continue; 3845 } 3846 if (i > MAX_RECENT_BITMAPS) { 3847 tr.freeLastThumbnail(); 3848 } 3849 final Intent trIntent = tr.intent; 3850 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3851 (intent == null || !intent.filterEquals(trIntent))) { 3852 continue; 3853 } 3854 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3855 if (document && trIsDocument) { 3856 // These are the same document activity (not necessarily the same doc). 3857 if (maxRecents > 0) { 3858 --maxRecents; 3859 continue; 3860 } 3861 // Hit the maximum number of documents for this task. Fall through 3862 // and remove this document from recents. 3863 } else if (document || trIsDocument) { 3864 // Only one of these is a document. Not the droid we're looking for. 3865 continue; 3866 } 3867 } 3868 3869 if (!doTrim) { 3870 // If the caller is not actually asking for a trim, just tell them we reached 3871 // a point where the trim would happen. 3872 return i; 3873 } 3874 3875 // Either task and tr are the same or, their affinities match or their intents match 3876 // and neither of them is a document, or they are documents using the same activity 3877 // and their maxRecents has been reached. 3878 tr.disposeThumbnail(); 3879 mRecentTasks.remove(i); 3880 if (task != tr) { 3881 tr.closeRecentsChain(); 3882 } 3883 i--; 3884 N--; 3885 if (task.intent == null) { 3886 // If the new recent task we are adding is not fully 3887 // specified, then replace it with the existing recent task. 3888 task = tr; 3889 } 3890 notifyTaskPersisterLocked(tr, false); 3891 } 3892 3893 return -1; 3894 } 3895 3896 @Override 3897 public void reportActivityFullyDrawn(IBinder token) { 3898 synchronized (this) { 3899 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3900 if (r == null) { 3901 return; 3902 } 3903 r.reportFullyDrawnLocked(); 3904 } 3905 } 3906 3907 @Override 3908 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3909 synchronized (this) { 3910 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3911 if (r == null) { 3912 return; 3913 } 3914 final long origId = Binder.clearCallingIdentity(); 3915 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3916 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3917 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3918 if (config != null) { 3919 r.frozenBeforeDestroy = true; 3920 if (!updateConfigurationLocked(config, r, false, false)) { 3921 mStackSupervisor.resumeTopActivitiesLocked(); 3922 } 3923 } 3924 Binder.restoreCallingIdentity(origId); 3925 } 3926 } 3927 3928 @Override 3929 public int getRequestedOrientation(IBinder token) { 3930 synchronized (this) { 3931 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3932 if (r == null) { 3933 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3934 } 3935 return mWindowManager.getAppOrientation(r.appToken); 3936 } 3937 } 3938 3939 /** 3940 * This is the internal entry point for handling Activity.finish(). 3941 * 3942 * @param token The Binder token referencing the Activity we want to finish. 3943 * @param resultCode Result code, if any, from this Activity. 3944 * @param resultData Result data (Intent), if any, from this Activity. 3945 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3946 * the root Activity in the task. 3947 * 3948 * @return Returns true if the activity successfully finished, or false if it is still running. 3949 */ 3950 @Override 3951 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3952 boolean finishTask) { 3953 // Refuse possible leaked file descriptors 3954 if (resultData != null && resultData.hasFileDescriptors() == true) { 3955 throw new IllegalArgumentException("File descriptors passed in Intent"); 3956 } 3957 3958 synchronized(this) { 3959 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3960 if (r == null) { 3961 return true; 3962 } 3963 // Keep track of the root activity of the task before we finish it 3964 TaskRecord tr = r.task; 3965 ActivityRecord rootR = tr.getRootActivity(); 3966 // Do not allow task to finish in Lock Task mode. 3967 if (tr == mStackSupervisor.mLockTaskModeTask) { 3968 if (rootR == r) { 3969 mStackSupervisor.showLockTaskToast(); 3970 return false; 3971 } 3972 } 3973 if (mController != null) { 3974 // Find the first activity that is not finishing. 3975 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3976 if (next != null) { 3977 // ask watcher if this is allowed 3978 boolean resumeOK = true; 3979 try { 3980 resumeOK = mController.activityResuming(next.packageName); 3981 } catch (RemoteException e) { 3982 mController = null; 3983 Watchdog.getInstance().setActivityController(null); 3984 } 3985 3986 if (!resumeOK) { 3987 return false; 3988 } 3989 } 3990 } 3991 final long origId = Binder.clearCallingIdentity(); 3992 try { 3993 boolean res; 3994 if (finishTask && r == rootR) { 3995 // If requested, remove the task that is associated to this activity only if it 3996 // was the root activity in the task. The result code and data is ignored because 3997 // we don't support returning them across task boundaries. 3998 res = removeTaskByIdLocked(tr.taskId, 0); 3999 } else { 4000 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4001 resultData, "app-request", true); 4002 } 4003 return res; 4004 } finally { 4005 Binder.restoreCallingIdentity(origId); 4006 } 4007 } 4008 } 4009 4010 @Override 4011 public final void finishHeavyWeightApp() { 4012 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4013 != PackageManager.PERMISSION_GRANTED) { 4014 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4015 + Binder.getCallingPid() 4016 + ", uid=" + Binder.getCallingUid() 4017 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4018 Slog.w(TAG, msg); 4019 throw new SecurityException(msg); 4020 } 4021 4022 synchronized(this) { 4023 if (mHeavyWeightProcess == null) { 4024 return; 4025 } 4026 4027 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4028 mHeavyWeightProcess.activities); 4029 for (int i=0; i<activities.size(); i++) { 4030 ActivityRecord r = activities.get(i); 4031 if (!r.finishing) { 4032 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4033 null, "finish-heavy", true); 4034 } 4035 } 4036 4037 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4038 mHeavyWeightProcess.userId, 0)); 4039 mHeavyWeightProcess = null; 4040 } 4041 } 4042 4043 @Override 4044 public void crashApplication(int uid, int initialPid, String packageName, 4045 String message) { 4046 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4047 != PackageManager.PERMISSION_GRANTED) { 4048 String msg = "Permission Denial: crashApplication() from pid=" 4049 + Binder.getCallingPid() 4050 + ", uid=" + Binder.getCallingUid() 4051 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4052 Slog.w(TAG, msg); 4053 throw new SecurityException(msg); 4054 } 4055 4056 synchronized(this) { 4057 ProcessRecord proc = null; 4058 4059 // Figure out which process to kill. We don't trust that initialPid 4060 // still has any relation to current pids, so must scan through the 4061 // list. 4062 synchronized (mPidsSelfLocked) { 4063 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4064 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4065 if (p.uid != uid) { 4066 continue; 4067 } 4068 if (p.pid == initialPid) { 4069 proc = p; 4070 break; 4071 } 4072 if (p.pkgList.containsKey(packageName)) { 4073 proc = p; 4074 } 4075 } 4076 } 4077 4078 if (proc == null) { 4079 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4080 + " initialPid=" + initialPid 4081 + " packageName=" + packageName); 4082 return; 4083 } 4084 4085 if (proc.thread != null) { 4086 if (proc.pid == Process.myPid()) { 4087 Log.w(TAG, "crashApplication: trying to crash self!"); 4088 return; 4089 } 4090 long ident = Binder.clearCallingIdentity(); 4091 try { 4092 proc.thread.scheduleCrash(message); 4093 } catch (RemoteException e) { 4094 } 4095 Binder.restoreCallingIdentity(ident); 4096 } 4097 } 4098 } 4099 4100 @Override 4101 public final void finishSubActivity(IBinder token, String resultWho, 4102 int requestCode) { 4103 synchronized(this) { 4104 final long origId = Binder.clearCallingIdentity(); 4105 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4106 if (r != null) { 4107 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4108 } 4109 Binder.restoreCallingIdentity(origId); 4110 } 4111 } 4112 4113 @Override 4114 public boolean finishActivityAffinity(IBinder token) { 4115 synchronized(this) { 4116 final long origId = Binder.clearCallingIdentity(); 4117 try { 4118 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4119 4120 ActivityRecord rootR = r.task.getRootActivity(); 4121 // Do not allow task to finish in Lock Task mode. 4122 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4123 if (rootR == r) { 4124 mStackSupervisor.showLockTaskToast(); 4125 return false; 4126 } 4127 } 4128 boolean res = false; 4129 if (r != null) { 4130 res = r.task.stack.finishActivityAffinityLocked(r); 4131 } 4132 return res; 4133 } finally { 4134 Binder.restoreCallingIdentity(origId); 4135 } 4136 } 4137 } 4138 4139 @Override 4140 public void finishVoiceTask(IVoiceInteractionSession session) { 4141 synchronized(this) { 4142 final long origId = Binder.clearCallingIdentity(); 4143 try { 4144 mStackSupervisor.finishVoiceTask(session); 4145 } finally { 4146 Binder.restoreCallingIdentity(origId); 4147 } 4148 } 4149 4150 } 4151 4152 @Override 4153 public boolean willActivityBeVisible(IBinder token) { 4154 synchronized(this) { 4155 ActivityStack stack = ActivityRecord.getStackLocked(token); 4156 if (stack != null) { 4157 return stack.willActivityBeVisibleLocked(token); 4158 } 4159 return false; 4160 } 4161 } 4162 4163 @Override 4164 public void overridePendingTransition(IBinder token, String packageName, 4165 int enterAnim, int exitAnim) { 4166 synchronized(this) { 4167 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4168 if (self == null) { 4169 return; 4170 } 4171 4172 final long origId = Binder.clearCallingIdentity(); 4173 4174 if (self.state == ActivityState.RESUMED 4175 || self.state == ActivityState.PAUSING) { 4176 mWindowManager.overridePendingAppTransition(packageName, 4177 enterAnim, exitAnim, null); 4178 } 4179 4180 Binder.restoreCallingIdentity(origId); 4181 } 4182 } 4183 4184 /** 4185 * Main function for removing an existing process from the activity manager 4186 * as a result of that process going away. Clears out all connections 4187 * to the process. 4188 */ 4189 private final void handleAppDiedLocked(ProcessRecord app, 4190 boolean restarting, boolean allowRestart) { 4191 int pid = app.pid; 4192 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4193 if (!restarting) { 4194 removeLruProcessLocked(app); 4195 if (pid > 0) { 4196 ProcessList.remove(pid); 4197 } 4198 } 4199 4200 if (mProfileProc == app) { 4201 clearProfilerLocked(); 4202 } 4203 4204 // Remove this application's activities from active lists. 4205 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4206 4207 app.activities.clear(); 4208 4209 if (app.instrumentationClass != null) { 4210 Slog.w(TAG, "Crash of app " + app.processName 4211 + " running instrumentation " + app.instrumentationClass); 4212 Bundle info = new Bundle(); 4213 info.putString("shortMsg", "Process crashed."); 4214 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4215 } 4216 4217 if (!restarting) { 4218 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4219 // If there was nothing to resume, and we are not already 4220 // restarting this process, but there is a visible activity that 4221 // is hosted by the process... then make sure all visible 4222 // activities are running, taking care of restarting this 4223 // process. 4224 if (hasVisibleActivities) { 4225 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4226 } 4227 } 4228 } 4229 } 4230 4231 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4232 IBinder threadBinder = thread.asBinder(); 4233 // Find the application record. 4234 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4235 ProcessRecord rec = mLruProcesses.get(i); 4236 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4237 return i; 4238 } 4239 } 4240 return -1; 4241 } 4242 4243 final ProcessRecord getRecordForAppLocked( 4244 IApplicationThread thread) { 4245 if (thread == null) { 4246 return null; 4247 } 4248 4249 int appIndex = getLRURecordIndexForAppLocked(thread); 4250 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4251 } 4252 4253 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4254 // If there are no longer any background processes running, 4255 // and the app that died was not running instrumentation, 4256 // then tell everyone we are now low on memory. 4257 boolean haveBg = false; 4258 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4259 ProcessRecord rec = mLruProcesses.get(i); 4260 if (rec.thread != null 4261 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4262 haveBg = true; 4263 break; 4264 } 4265 } 4266 4267 if (!haveBg) { 4268 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4269 if (doReport) { 4270 long now = SystemClock.uptimeMillis(); 4271 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4272 doReport = false; 4273 } else { 4274 mLastMemUsageReportTime = now; 4275 } 4276 } 4277 final ArrayList<ProcessMemInfo> memInfos 4278 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4279 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4280 long now = SystemClock.uptimeMillis(); 4281 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4282 ProcessRecord rec = mLruProcesses.get(i); 4283 if (rec == dyingProc || rec.thread == null) { 4284 continue; 4285 } 4286 if (doReport) { 4287 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4288 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4289 } 4290 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4291 // The low memory report is overriding any current 4292 // state for a GC request. Make sure to do 4293 // heavy/important/visible/foreground processes first. 4294 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4295 rec.lastRequestedGc = 0; 4296 } else { 4297 rec.lastRequestedGc = rec.lastLowMemory; 4298 } 4299 rec.reportLowMemory = true; 4300 rec.lastLowMemory = now; 4301 mProcessesToGc.remove(rec); 4302 addProcessToGcListLocked(rec); 4303 } 4304 } 4305 if (doReport) { 4306 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4307 mHandler.sendMessage(msg); 4308 } 4309 scheduleAppGcsLocked(); 4310 } 4311 } 4312 4313 final void appDiedLocked(ProcessRecord app) { 4314 appDiedLocked(app, app.pid, app.thread); 4315 } 4316 4317 final void appDiedLocked(ProcessRecord app, int pid, 4318 IApplicationThread thread) { 4319 4320 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4321 synchronized (stats) { 4322 stats.noteProcessDiedLocked(app.info.uid, pid); 4323 } 4324 4325 Process.killProcessGroup(app.info.uid, pid); 4326 4327 // Clean up already done if the process has been re-started. 4328 if (app.pid == pid && app.thread != null && 4329 app.thread.asBinder() == thread.asBinder()) { 4330 boolean doLowMem = app.instrumentationClass == null; 4331 boolean doOomAdj = doLowMem; 4332 if (!app.killedByAm) { 4333 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4334 + ") has died."); 4335 mAllowLowerMemLevel = true; 4336 } else { 4337 // Note that we always want to do oom adj to update our state with the 4338 // new number of procs. 4339 mAllowLowerMemLevel = false; 4340 doLowMem = false; 4341 } 4342 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4343 if (DEBUG_CLEANUP) Slog.v( 4344 TAG, "Dying app: " + app + ", pid: " + pid 4345 + ", thread: " + thread.asBinder()); 4346 handleAppDiedLocked(app, false, true); 4347 4348 if (doOomAdj) { 4349 updateOomAdjLocked(); 4350 } 4351 if (doLowMem) { 4352 doLowMemReportIfNeededLocked(app); 4353 } 4354 } else if (app.pid != pid) { 4355 // A new process has already been started. 4356 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4357 + ") has died and restarted (pid " + app.pid + ")."); 4358 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4359 } else if (DEBUG_PROCESSES) { 4360 Slog.d(TAG, "Received spurious death notification for thread " 4361 + thread.asBinder()); 4362 } 4363 } 4364 4365 /** 4366 * If a stack trace dump file is configured, dump process stack traces. 4367 * @param clearTraces causes the dump file to be erased prior to the new 4368 * traces being written, if true; when false, the new traces will be 4369 * appended to any existing file content. 4370 * @param firstPids of dalvik VM processes to dump stack traces for first 4371 * @param lastPids of dalvik VM processes to dump stack traces for last 4372 * @param nativeProcs optional list of native process names to dump stack crawls 4373 * @return file containing stack traces, or null if no dump file is configured 4374 */ 4375 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4376 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4377 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4378 if (tracesPath == null || tracesPath.length() == 0) { 4379 return null; 4380 } 4381 4382 File tracesFile = new File(tracesPath); 4383 try { 4384 File tracesDir = tracesFile.getParentFile(); 4385 if (!tracesDir.exists()) { 4386 tracesFile.mkdirs(); 4387 if (!SELinux.restorecon(tracesDir)) { 4388 return null; 4389 } 4390 } 4391 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4392 4393 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4394 tracesFile.createNewFile(); 4395 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4396 } catch (IOException e) { 4397 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4398 return null; 4399 } 4400 4401 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4402 return tracesFile; 4403 } 4404 4405 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4406 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4407 // Use a FileObserver to detect when traces finish writing. 4408 // The order of traces is considered important to maintain for legibility. 4409 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4410 @Override 4411 public synchronized void onEvent(int event, String path) { notify(); } 4412 }; 4413 4414 try { 4415 observer.startWatching(); 4416 4417 // First collect all of the stacks of the most important pids. 4418 if (firstPids != null) { 4419 try { 4420 int num = firstPids.size(); 4421 for (int i = 0; i < num; i++) { 4422 synchronized (observer) { 4423 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4424 observer.wait(200); // Wait for write-close, give up after 200msec 4425 } 4426 } 4427 } catch (InterruptedException e) { 4428 Log.wtf(TAG, e); 4429 } 4430 } 4431 4432 // Next collect the stacks of the native pids 4433 if (nativeProcs != null) { 4434 int[] pids = Process.getPidsForCommands(nativeProcs); 4435 if (pids != null) { 4436 for (int pid : pids) { 4437 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4438 } 4439 } 4440 } 4441 4442 // Lastly, measure CPU usage. 4443 if (processCpuTracker != null) { 4444 processCpuTracker.init(); 4445 System.gc(); 4446 processCpuTracker.update(); 4447 try { 4448 synchronized (processCpuTracker) { 4449 processCpuTracker.wait(500); // measure over 1/2 second. 4450 } 4451 } catch (InterruptedException e) { 4452 } 4453 processCpuTracker.update(); 4454 4455 // We'll take the stack crawls of just the top apps using CPU. 4456 final int N = processCpuTracker.countWorkingStats(); 4457 int numProcs = 0; 4458 for (int i=0; i<N && numProcs<5; i++) { 4459 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4460 if (lastPids.indexOfKey(stats.pid) >= 0) { 4461 numProcs++; 4462 try { 4463 synchronized (observer) { 4464 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4465 observer.wait(200); // Wait for write-close, give up after 200msec 4466 } 4467 } catch (InterruptedException e) { 4468 Log.wtf(TAG, e); 4469 } 4470 4471 } 4472 } 4473 } 4474 } finally { 4475 observer.stopWatching(); 4476 } 4477 } 4478 4479 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4480 if (true || IS_USER_BUILD) { 4481 return; 4482 } 4483 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4484 if (tracesPath == null || tracesPath.length() == 0) { 4485 return; 4486 } 4487 4488 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4489 StrictMode.allowThreadDiskWrites(); 4490 try { 4491 final File tracesFile = new File(tracesPath); 4492 final File tracesDir = tracesFile.getParentFile(); 4493 final File tracesTmp = new File(tracesDir, "__tmp__"); 4494 try { 4495 if (!tracesDir.exists()) { 4496 tracesFile.mkdirs(); 4497 if (!SELinux.restorecon(tracesDir.getPath())) { 4498 return; 4499 } 4500 } 4501 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4502 4503 if (tracesFile.exists()) { 4504 tracesTmp.delete(); 4505 tracesFile.renameTo(tracesTmp); 4506 } 4507 StringBuilder sb = new StringBuilder(); 4508 Time tobj = new Time(); 4509 tobj.set(System.currentTimeMillis()); 4510 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4511 sb.append(": "); 4512 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4513 sb.append(" since "); 4514 sb.append(msg); 4515 FileOutputStream fos = new FileOutputStream(tracesFile); 4516 fos.write(sb.toString().getBytes()); 4517 if (app == null) { 4518 fos.write("\n*** No application process!".getBytes()); 4519 } 4520 fos.close(); 4521 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4522 } catch (IOException e) { 4523 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4524 return; 4525 } 4526 4527 if (app != null) { 4528 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4529 firstPids.add(app.pid); 4530 dumpStackTraces(tracesPath, firstPids, null, null, null); 4531 } 4532 4533 File lastTracesFile = null; 4534 File curTracesFile = null; 4535 for (int i=9; i>=0; i--) { 4536 String name = String.format(Locale.US, "slow%02d.txt", i); 4537 curTracesFile = new File(tracesDir, name); 4538 if (curTracesFile.exists()) { 4539 if (lastTracesFile != null) { 4540 curTracesFile.renameTo(lastTracesFile); 4541 } else { 4542 curTracesFile.delete(); 4543 } 4544 } 4545 lastTracesFile = curTracesFile; 4546 } 4547 tracesFile.renameTo(curTracesFile); 4548 if (tracesTmp.exists()) { 4549 tracesTmp.renameTo(tracesFile); 4550 } 4551 } finally { 4552 StrictMode.setThreadPolicy(oldPolicy); 4553 } 4554 } 4555 4556 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4557 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4558 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4559 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4560 4561 if (mController != null) { 4562 try { 4563 // 0 == continue, -1 = kill process immediately 4564 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4565 if (res < 0 && app.pid != MY_PID) { 4566 Process.killProcess(app.pid); 4567 Process.killProcessGroup(app.info.uid, app.pid); 4568 } 4569 } catch (RemoteException e) { 4570 mController = null; 4571 Watchdog.getInstance().setActivityController(null); 4572 } 4573 } 4574 4575 long anrTime = SystemClock.uptimeMillis(); 4576 if (MONITOR_CPU_USAGE) { 4577 updateCpuStatsNow(); 4578 } 4579 4580 synchronized (this) { 4581 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4582 if (mShuttingDown) { 4583 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4584 return; 4585 } else if (app.notResponding) { 4586 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4587 return; 4588 } else if (app.crashing) { 4589 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4590 return; 4591 } 4592 4593 // In case we come through here for the same app before completing 4594 // this one, mark as anring now so we will bail out. 4595 app.notResponding = true; 4596 4597 // Log the ANR to the event log. 4598 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4599 app.processName, app.info.flags, annotation); 4600 4601 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4602 firstPids.add(app.pid); 4603 4604 int parentPid = app.pid; 4605 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4606 if (parentPid != app.pid) firstPids.add(parentPid); 4607 4608 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4609 4610 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4611 ProcessRecord r = mLruProcesses.get(i); 4612 if (r != null && r.thread != null) { 4613 int pid = r.pid; 4614 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4615 if (r.persistent) { 4616 firstPids.add(pid); 4617 } else { 4618 lastPids.put(pid, Boolean.TRUE); 4619 } 4620 } 4621 } 4622 } 4623 } 4624 4625 // Log the ANR to the main log. 4626 StringBuilder info = new StringBuilder(); 4627 info.setLength(0); 4628 info.append("ANR in ").append(app.processName); 4629 if (activity != null && activity.shortComponentName != null) { 4630 info.append(" (").append(activity.shortComponentName).append(")"); 4631 } 4632 info.append("\n"); 4633 info.append("PID: ").append(app.pid).append("\n"); 4634 if (annotation != null) { 4635 info.append("Reason: ").append(annotation).append("\n"); 4636 } 4637 if (parent != null && parent != activity) { 4638 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4639 } 4640 4641 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4642 4643 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4644 NATIVE_STACKS_OF_INTEREST); 4645 4646 String cpuInfo = null; 4647 if (MONITOR_CPU_USAGE) { 4648 updateCpuStatsNow(); 4649 synchronized (mProcessCpuThread) { 4650 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4651 } 4652 info.append(processCpuTracker.printCurrentLoad()); 4653 info.append(cpuInfo); 4654 } 4655 4656 info.append(processCpuTracker.printCurrentState(anrTime)); 4657 4658 Slog.e(TAG, info.toString()); 4659 if (tracesFile == null) { 4660 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4661 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4662 } 4663 4664 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4665 cpuInfo, tracesFile, null); 4666 4667 if (mController != null) { 4668 try { 4669 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4670 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4671 if (res != 0) { 4672 if (res < 0 && app.pid != MY_PID) { 4673 Process.killProcess(app.pid); 4674 Process.killProcessGroup(app.info.uid, app.pid); 4675 } else { 4676 synchronized (this) { 4677 mServices.scheduleServiceTimeoutLocked(app); 4678 } 4679 } 4680 return; 4681 } 4682 } catch (RemoteException e) { 4683 mController = null; 4684 Watchdog.getInstance().setActivityController(null); 4685 } 4686 } 4687 4688 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4689 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4690 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4691 4692 synchronized (this) { 4693 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4694 killUnneededProcessLocked(app, "background ANR"); 4695 return; 4696 } 4697 4698 // Set the app's notResponding state, and look up the errorReportReceiver 4699 makeAppNotRespondingLocked(app, 4700 activity != null ? activity.shortComponentName : null, 4701 annotation != null ? "ANR " + annotation : "ANR", 4702 info.toString()); 4703 4704 // Bring up the infamous App Not Responding dialog 4705 Message msg = Message.obtain(); 4706 HashMap<String, Object> map = new HashMap<String, Object>(); 4707 msg.what = SHOW_NOT_RESPONDING_MSG; 4708 msg.obj = map; 4709 msg.arg1 = aboveSystem ? 1 : 0; 4710 map.put("app", app); 4711 if (activity != null) { 4712 map.put("activity", activity); 4713 } 4714 4715 mHandler.sendMessage(msg); 4716 } 4717 } 4718 4719 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4720 if (!mLaunchWarningShown) { 4721 mLaunchWarningShown = true; 4722 mHandler.post(new Runnable() { 4723 @Override 4724 public void run() { 4725 synchronized (ActivityManagerService.this) { 4726 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4727 d.show(); 4728 mHandler.postDelayed(new Runnable() { 4729 @Override 4730 public void run() { 4731 synchronized (ActivityManagerService.this) { 4732 d.dismiss(); 4733 mLaunchWarningShown = false; 4734 } 4735 } 4736 }, 4000); 4737 } 4738 } 4739 }); 4740 } 4741 } 4742 4743 @Override 4744 public boolean clearApplicationUserData(final String packageName, 4745 final IPackageDataObserver observer, int userId) { 4746 enforceNotIsolatedCaller("clearApplicationUserData"); 4747 int uid = Binder.getCallingUid(); 4748 int pid = Binder.getCallingPid(); 4749 userId = handleIncomingUser(pid, uid, 4750 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4751 long callingId = Binder.clearCallingIdentity(); 4752 try { 4753 IPackageManager pm = AppGlobals.getPackageManager(); 4754 int pkgUid = -1; 4755 synchronized(this) { 4756 try { 4757 pkgUid = pm.getPackageUid(packageName, userId); 4758 } catch (RemoteException e) { 4759 } 4760 if (pkgUid == -1) { 4761 Slog.w(TAG, "Invalid packageName: " + packageName); 4762 if (observer != null) { 4763 try { 4764 observer.onRemoveCompleted(packageName, false); 4765 } catch (RemoteException e) { 4766 Slog.i(TAG, "Observer no longer exists."); 4767 } 4768 } 4769 return false; 4770 } 4771 if (uid == pkgUid || checkComponentPermission( 4772 android.Manifest.permission.CLEAR_APP_USER_DATA, 4773 pid, uid, -1, true) 4774 == PackageManager.PERMISSION_GRANTED) { 4775 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4776 } else { 4777 throw new SecurityException("PID " + pid + " does not have permission " 4778 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4779 + " of package " + packageName); 4780 } 4781 4782 // Remove all tasks match the cleared application package and user 4783 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 4784 final TaskRecord tr = mRecentTasks.get(i); 4785 final String taskPackageName = 4786 tr.getBaseIntent().getComponent().getPackageName(); 4787 if (tr.userId != userId) continue; 4788 if (!taskPackageName.equals(packageName)) continue; 4789 removeTaskByIdLocked(tr.taskId, 0); 4790 } 4791 } 4792 4793 try { 4794 // Clear application user data 4795 pm.clearApplicationUserData(packageName, observer, userId); 4796 4797 synchronized(this) { 4798 // Remove all permissions granted from/to this package 4799 removeUriPermissionsForPackageLocked(packageName, userId, true); 4800 } 4801 4802 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4803 Uri.fromParts("package", packageName, null)); 4804 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4805 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4806 null, null, 0, null, null, null, false, false, userId); 4807 } catch (RemoteException e) { 4808 } 4809 } finally { 4810 Binder.restoreCallingIdentity(callingId); 4811 } 4812 return true; 4813 } 4814 4815 @Override 4816 public void killBackgroundProcesses(final String packageName, int userId) { 4817 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4818 != PackageManager.PERMISSION_GRANTED && 4819 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4820 != PackageManager.PERMISSION_GRANTED) { 4821 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4822 + Binder.getCallingPid() 4823 + ", uid=" + Binder.getCallingUid() 4824 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4825 Slog.w(TAG, msg); 4826 throw new SecurityException(msg); 4827 } 4828 4829 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4830 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4831 long callingId = Binder.clearCallingIdentity(); 4832 try { 4833 IPackageManager pm = AppGlobals.getPackageManager(); 4834 synchronized(this) { 4835 int appId = -1; 4836 try { 4837 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4838 } catch (RemoteException e) { 4839 } 4840 if (appId == -1) { 4841 Slog.w(TAG, "Invalid packageName: " + packageName); 4842 return; 4843 } 4844 killPackageProcessesLocked(packageName, appId, userId, 4845 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4846 } 4847 } finally { 4848 Binder.restoreCallingIdentity(callingId); 4849 } 4850 } 4851 4852 @Override 4853 public void killAllBackgroundProcesses() { 4854 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4855 != PackageManager.PERMISSION_GRANTED) { 4856 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4857 + Binder.getCallingPid() 4858 + ", uid=" + Binder.getCallingUid() 4859 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4860 Slog.w(TAG, msg); 4861 throw new SecurityException(msg); 4862 } 4863 4864 long callingId = Binder.clearCallingIdentity(); 4865 try { 4866 synchronized(this) { 4867 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4868 final int NP = mProcessNames.getMap().size(); 4869 for (int ip=0; ip<NP; ip++) { 4870 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4871 final int NA = apps.size(); 4872 for (int ia=0; ia<NA; ia++) { 4873 ProcessRecord app = apps.valueAt(ia); 4874 if (app.persistent) { 4875 // we don't kill persistent processes 4876 continue; 4877 } 4878 if (app.removed) { 4879 procs.add(app); 4880 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4881 app.removed = true; 4882 procs.add(app); 4883 } 4884 } 4885 } 4886 4887 int N = procs.size(); 4888 for (int i=0; i<N; i++) { 4889 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4890 } 4891 mAllowLowerMemLevel = true; 4892 updateOomAdjLocked(); 4893 doLowMemReportIfNeededLocked(null); 4894 } 4895 } finally { 4896 Binder.restoreCallingIdentity(callingId); 4897 } 4898 } 4899 4900 @Override 4901 public void forceStopPackage(final String packageName, int userId) { 4902 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4903 != PackageManager.PERMISSION_GRANTED) { 4904 String msg = "Permission Denial: forceStopPackage() from pid=" 4905 + Binder.getCallingPid() 4906 + ", uid=" + Binder.getCallingUid() 4907 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4908 Slog.w(TAG, msg); 4909 throw new SecurityException(msg); 4910 } 4911 final int callingPid = Binder.getCallingPid(); 4912 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4913 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4914 long callingId = Binder.clearCallingIdentity(); 4915 try { 4916 IPackageManager pm = AppGlobals.getPackageManager(); 4917 synchronized(this) { 4918 int[] users = userId == UserHandle.USER_ALL 4919 ? getUsersLocked() : new int[] { userId }; 4920 for (int user : users) { 4921 int pkgUid = -1; 4922 try { 4923 pkgUid = pm.getPackageUid(packageName, user); 4924 } catch (RemoteException e) { 4925 } 4926 if (pkgUid == -1) { 4927 Slog.w(TAG, "Invalid packageName: " + packageName); 4928 continue; 4929 } 4930 try { 4931 pm.setPackageStoppedState(packageName, true, user); 4932 } catch (RemoteException e) { 4933 } catch (IllegalArgumentException e) { 4934 Slog.w(TAG, "Failed trying to unstop package " 4935 + packageName + ": " + e); 4936 } 4937 if (isUserRunningLocked(user, false)) { 4938 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4939 } 4940 } 4941 } 4942 } finally { 4943 Binder.restoreCallingIdentity(callingId); 4944 } 4945 } 4946 4947 @Override 4948 public void addPackageDependency(String packageName) { 4949 synchronized (this) { 4950 int callingPid = Binder.getCallingPid(); 4951 if (callingPid == Process.myPid()) { 4952 // Yeah, um, no. 4953 Slog.w(TAG, "Can't addPackageDependency on system process"); 4954 return; 4955 } 4956 ProcessRecord proc; 4957 synchronized (mPidsSelfLocked) { 4958 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4959 } 4960 if (proc != null) { 4961 if (proc.pkgDeps == null) { 4962 proc.pkgDeps = new ArraySet<String>(1); 4963 } 4964 proc.pkgDeps.add(packageName); 4965 } 4966 } 4967 } 4968 4969 /* 4970 * The pkg name and app id have to be specified. 4971 */ 4972 @Override 4973 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4974 if (pkg == null) { 4975 return; 4976 } 4977 // Make sure the uid is valid. 4978 if (appid < 0) { 4979 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4980 return; 4981 } 4982 int callerUid = Binder.getCallingUid(); 4983 // Only the system server can kill an application 4984 if (callerUid == Process.SYSTEM_UID) { 4985 // Post an aysnc message to kill the application 4986 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4987 msg.arg1 = appid; 4988 msg.arg2 = 0; 4989 Bundle bundle = new Bundle(); 4990 bundle.putString("pkg", pkg); 4991 bundle.putString("reason", reason); 4992 msg.obj = bundle; 4993 mHandler.sendMessage(msg); 4994 } else { 4995 throw new SecurityException(callerUid + " cannot kill pkg: " + 4996 pkg); 4997 } 4998 } 4999 5000 @Override 5001 public void closeSystemDialogs(String reason) { 5002 enforceNotIsolatedCaller("closeSystemDialogs"); 5003 5004 final int pid = Binder.getCallingPid(); 5005 final int uid = Binder.getCallingUid(); 5006 final long origId = Binder.clearCallingIdentity(); 5007 try { 5008 synchronized (this) { 5009 // Only allow this from foreground processes, so that background 5010 // applications can't abuse it to prevent system UI from being shown. 5011 if (uid >= Process.FIRST_APPLICATION_UID) { 5012 ProcessRecord proc; 5013 synchronized (mPidsSelfLocked) { 5014 proc = mPidsSelfLocked.get(pid); 5015 } 5016 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5017 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5018 + " from background process " + proc); 5019 return; 5020 } 5021 } 5022 closeSystemDialogsLocked(reason); 5023 } 5024 } finally { 5025 Binder.restoreCallingIdentity(origId); 5026 } 5027 } 5028 5029 void closeSystemDialogsLocked(String reason) { 5030 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5031 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5032 | Intent.FLAG_RECEIVER_FOREGROUND); 5033 if (reason != null) { 5034 intent.putExtra("reason", reason); 5035 } 5036 mWindowManager.closeSystemDialogs(reason); 5037 5038 mStackSupervisor.closeSystemDialogsLocked(); 5039 5040 broadcastIntentLocked(null, null, intent, null, 5041 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5042 Process.SYSTEM_UID, UserHandle.USER_ALL); 5043 } 5044 5045 @Override 5046 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5047 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5048 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5049 for (int i=pids.length-1; i>=0; i--) { 5050 ProcessRecord proc; 5051 int oomAdj; 5052 synchronized (this) { 5053 synchronized (mPidsSelfLocked) { 5054 proc = mPidsSelfLocked.get(pids[i]); 5055 oomAdj = proc != null ? proc.setAdj : 0; 5056 } 5057 } 5058 infos[i] = new Debug.MemoryInfo(); 5059 Debug.getMemoryInfo(pids[i], infos[i]); 5060 if (proc != null) { 5061 synchronized (this) { 5062 if (proc.thread != null && proc.setAdj == oomAdj) { 5063 // Record this for posterity if the process has been stable. 5064 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5065 infos[i].getTotalUss(), false, proc.pkgList); 5066 } 5067 } 5068 } 5069 } 5070 return infos; 5071 } 5072 5073 @Override 5074 public long[] getProcessPss(int[] pids) { 5075 enforceNotIsolatedCaller("getProcessPss"); 5076 long[] pss = new long[pids.length]; 5077 for (int i=pids.length-1; i>=0; i--) { 5078 ProcessRecord proc; 5079 int oomAdj; 5080 synchronized (this) { 5081 synchronized (mPidsSelfLocked) { 5082 proc = mPidsSelfLocked.get(pids[i]); 5083 oomAdj = proc != null ? proc.setAdj : 0; 5084 } 5085 } 5086 long[] tmpUss = new long[1]; 5087 pss[i] = Debug.getPss(pids[i], tmpUss); 5088 if (proc != null) { 5089 synchronized (this) { 5090 if (proc.thread != null && proc.setAdj == oomAdj) { 5091 // Record this for posterity if the process has been stable. 5092 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5093 } 5094 } 5095 } 5096 } 5097 return pss; 5098 } 5099 5100 @Override 5101 public void killApplicationProcess(String processName, int uid) { 5102 if (processName == null) { 5103 return; 5104 } 5105 5106 int callerUid = Binder.getCallingUid(); 5107 // Only the system server can kill an application 5108 if (callerUid == Process.SYSTEM_UID) { 5109 synchronized (this) { 5110 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5111 if (app != null && app.thread != null) { 5112 try { 5113 app.thread.scheduleSuicide(); 5114 } catch (RemoteException e) { 5115 // If the other end already died, then our work here is done. 5116 } 5117 } else { 5118 Slog.w(TAG, "Process/uid not found attempting kill of " 5119 + processName + " / " + uid); 5120 } 5121 } 5122 } else { 5123 throw new SecurityException(callerUid + " cannot kill app process: " + 5124 processName); 5125 } 5126 } 5127 5128 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5129 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5130 false, true, false, false, UserHandle.getUserId(uid), reason); 5131 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5132 Uri.fromParts("package", packageName, null)); 5133 if (!mProcessesReady) { 5134 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5135 | Intent.FLAG_RECEIVER_FOREGROUND); 5136 } 5137 intent.putExtra(Intent.EXTRA_UID, uid); 5138 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5139 broadcastIntentLocked(null, null, intent, 5140 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5141 false, false, 5142 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5143 } 5144 5145 private void forceStopUserLocked(int userId, String reason) { 5146 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5147 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5148 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5149 | Intent.FLAG_RECEIVER_FOREGROUND); 5150 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5151 broadcastIntentLocked(null, null, intent, 5152 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5153 false, false, 5154 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5155 } 5156 5157 private final boolean killPackageProcessesLocked(String packageName, int appId, 5158 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5159 boolean doit, boolean evenPersistent, String reason) { 5160 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5161 5162 // Remove all processes this package may have touched: all with the 5163 // same UID (except for the system or root user), and all whose name 5164 // matches the package name. 5165 final int NP = mProcessNames.getMap().size(); 5166 for (int ip=0; ip<NP; ip++) { 5167 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5168 final int NA = apps.size(); 5169 for (int ia=0; ia<NA; ia++) { 5170 ProcessRecord app = apps.valueAt(ia); 5171 if (app.persistent && !evenPersistent) { 5172 // we don't kill persistent processes 5173 continue; 5174 } 5175 if (app.removed) { 5176 if (doit) { 5177 procs.add(app); 5178 } 5179 continue; 5180 } 5181 5182 // Skip process if it doesn't meet our oom adj requirement. 5183 if (app.setAdj < minOomAdj) { 5184 continue; 5185 } 5186 5187 // If no package is specified, we call all processes under the 5188 // give user id. 5189 if (packageName == null) { 5190 if (app.userId != userId) { 5191 continue; 5192 } 5193 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5194 continue; 5195 } 5196 // Package has been specified, we want to hit all processes 5197 // that match it. We need to qualify this by the processes 5198 // that are running under the specified app and user ID. 5199 } else { 5200 final boolean isDep = app.pkgDeps != null 5201 && app.pkgDeps.contains(packageName); 5202 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5203 continue; 5204 } 5205 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5206 continue; 5207 } 5208 if (!app.pkgList.containsKey(packageName) && !isDep) { 5209 continue; 5210 } 5211 } 5212 5213 // Process has passed all conditions, kill it! 5214 if (!doit) { 5215 return true; 5216 } 5217 app.removed = true; 5218 procs.add(app); 5219 } 5220 } 5221 5222 int N = procs.size(); 5223 for (int i=0; i<N; i++) { 5224 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5225 } 5226 updateOomAdjLocked(); 5227 return N > 0; 5228 } 5229 5230 private final boolean forceStopPackageLocked(String name, int appId, 5231 boolean callerWillRestart, boolean purgeCache, boolean doit, 5232 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5233 int i; 5234 int N; 5235 5236 if (userId == UserHandle.USER_ALL && name == null) { 5237 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5238 } 5239 5240 if (appId < 0 && name != null) { 5241 try { 5242 appId = UserHandle.getAppId( 5243 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5244 } catch (RemoteException e) { 5245 } 5246 } 5247 5248 if (doit) { 5249 if (name != null) { 5250 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5251 + " user=" + userId + ": " + reason); 5252 } else { 5253 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5254 } 5255 5256 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5257 for (int ip=pmap.size()-1; ip>=0; ip--) { 5258 SparseArray<Long> ba = pmap.valueAt(ip); 5259 for (i=ba.size()-1; i>=0; i--) { 5260 boolean remove = false; 5261 final int entUid = ba.keyAt(i); 5262 if (name != null) { 5263 if (userId == UserHandle.USER_ALL) { 5264 if (UserHandle.getAppId(entUid) == appId) { 5265 remove = true; 5266 } 5267 } else { 5268 if (entUid == UserHandle.getUid(userId, appId)) { 5269 remove = true; 5270 } 5271 } 5272 } else if (UserHandle.getUserId(entUid) == userId) { 5273 remove = true; 5274 } 5275 if (remove) { 5276 ba.removeAt(i); 5277 } 5278 } 5279 if (ba.size() == 0) { 5280 pmap.removeAt(ip); 5281 } 5282 } 5283 } 5284 5285 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5286 -100, callerWillRestart, true, doit, evenPersistent, 5287 name == null ? ("stop user " + userId) : ("stop " + name)); 5288 5289 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5290 if (!doit) { 5291 return true; 5292 } 5293 didSomething = true; 5294 } 5295 5296 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5297 if (!doit) { 5298 return true; 5299 } 5300 didSomething = true; 5301 } 5302 5303 if (name == null) { 5304 // Remove all sticky broadcasts from this user. 5305 mStickyBroadcasts.remove(userId); 5306 } 5307 5308 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5309 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5310 userId, providers)) { 5311 if (!doit) { 5312 return true; 5313 } 5314 didSomething = true; 5315 } 5316 N = providers.size(); 5317 for (i=0; i<N; i++) { 5318 removeDyingProviderLocked(null, providers.get(i), true); 5319 } 5320 5321 // Remove transient permissions granted from/to this package/user 5322 removeUriPermissionsForPackageLocked(name, userId, false); 5323 5324 if (name == null || uninstalling) { 5325 // Remove pending intents. For now we only do this when force 5326 // stopping users, because we have some problems when doing this 5327 // for packages -- app widgets are not currently cleaned up for 5328 // such packages, so they can be left with bad pending intents. 5329 if (mIntentSenderRecords.size() > 0) { 5330 Iterator<WeakReference<PendingIntentRecord>> it 5331 = mIntentSenderRecords.values().iterator(); 5332 while (it.hasNext()) { 5333 WeakReference<PendingIntentRecord> wpir = it.next(); 5334 if (wpir == null) { 5335 it.remove(); 5336 continue; 5337 } 5338 PendingIntentRecord pir = wpir.get(); 5339 if (pir == null) { 5340 it.remove(); 5341 continue; 5342 } 5343 if (name == null) { 5344 // Stopping user, remove all objects for the user. 5345 if (pir.key.userId != userId) { 5346 // Not the same user, skip it. 5347 continue; 5348 } 5349 } else { 5350 if (UserHandle.getAppId(pir.uid) != appId) { 5351 // Different app id, skip it. 5352 continue; 5353 } 5354 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5355 // Different user, skip it. 5356 continue; 5357 } 5358 if (!pir.key.packageName.equals(name)) { 5359 // Different package, skip it. 5360 continue; 5361 } 5362 } 5363 if (!doit) { 5364 return true; 5365 } 5366 didSomething = true; 5367 it.remove(); 5368 pir.canceled = true; 5369 if (pir.key.activity != null) { 5370 pir.key.activity.pendingResults.remove(pir.ref); 5371 } 5372 } 5373 } 5374 } 5375 5376 if (doit) { 5377 if (purgeCache && name != null) { 5378 AttributeCache ac = AttributeCache.instance(); 5379 if (ac != null) { 5380 ac.removePackage(name); 5381 } 5382 } 5383 if (mBooted) { 5384 mStackSupervisor.resumeTopActivitiesLocked(); 5385 mStackSupervisor.scheduleIdleLocked(); 5386 } 5387 } 5388 5389 return didSomething; 5390 } 5391 5392 private final boolean removeProcessLocked(ProcessRecord app, 5393 boolean callerWillRestart, boolean allowRestart, String reason) { 5394 final String name = app.processName; 5395 final int uid = app.uid; 5396 if (DEBUG_PROCESSES) Slog.d( 5397 TAG, "Force removing proc " + app.toShortString() + " (" + name 5398 + "/" + uid + ")"); 5399 5400 mProcessNames.remove(name, uid); 5401 mIsolatedProcesses.remove(app.uid); 5402 if (mHeavyWeightProcess == app) { 5403 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5404 mHeavyWeightProcess.userId, 0)); 5405 mHeavyWeightProcess = null; 5406 } 5407 boolean needRestart = false; 5408 if (app.pid > 0 && app.pid != MY_PID) { 5409 int pid = app.pid; 5410 synchronized (mPidsSelfLocked) { 5411 mPidsSelfLocked.remove(pid); 5412 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5413 } 5414 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5415 if (app.isolated) { 5416 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5417 } 5418 killUnneededProcessLocked(app, reason); 5419 Process.killProcessGroup(app.info.uid, app.pid); 5420 handleAppDiedLocked(app, true, allowRestart); 5421 removeLruProcessLocked(app); 5422 5423 if (app.persistent && !app.isolated) { 5424 if (!callerWillRestart) { 5425 addAppLocked(app.info, false, null /* ABI override */); 5426 } else { 5427 needRestart = true; 5428 } 5429 } 5430 } else { 5431 mRemovedProcesses.add(app); 5432 } 5433 5434 return needRestart; 5435 } 5436 5437 private final void processStartTimedOutLocked(ProcessRecord app) { 5438 final int pid = app.pid; 5439 boolean gone = false; 5440 synchronized (mPidsSelfLocked) { 5441 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5442 if (knownApp != null && knownApp.thread == null) { 5443 mPidsSelfLocked.remove(pid); 5444 gone = true; 5445 } 5446 } 5447 5448 if (gone) { 5449 Slog.w(TAG, "Process " + app + " failed to attach"); 5450 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5451 pid, app.uid, app.processName); 5452 mProcessNames.remove(app.processName, app.uid); 5453 mIsolatedProcesses.remove(app.uid); 5454 if (mHeavyWeightProcess == app) { 5455 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5456 mHeavyWeightProcess.userId, 0)); 5457 mHeavyWeightProcess = null; 5458 } 5459 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5460 if (app.isolated) { 5461 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5462 } 5463 // Take care of any launching providers waiting for this process. 5464 checkAppInLaunchingProvidersLocked(app, true); 5465 // Take care of any services that are waiting for the process. 5466 mServices.processStartTimedOutLocked(app); 5467 killUnneededProcessLocked(app, "start timeout"); 5468 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5469 Slog.w(TAG, "Unattached app died before backup, skipping"); 5470 try { 5471 IBackupManager bm = IBackupManager.Stub.asInterface( 5472 ServiceManager.getService(Context.BACKUP_SERVICE)); 5473 bm.agentDisconnected(app.info.packageName); 5474 } catch (RemoteException e) { 5475 // Can't happen; the backup manager is local 5476 } 5477 } 5478 if (isPendingBroadcastProcessLocked(pid)) { 5479 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5480 skipPendingBroadcastLocked(pid); 5481 } 5482 } else { 5483 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5484 } 5485 } 5486 5487 private final boolean attachApplicationLocked(IApplicationThread thread, 5488 int pid) { 5489 5490 // Find the application record that is being attached... either via 5491 // the pid if we are running in multiple processes, or just pull the 5492 // next app record if we are emulating process with anonymous threads. 5493 ProcessRecord app; 5494 if (pid != MY_PID && pid >= 0) { 5495 synchronized (mPidsSelfLocked) { 5496 app = mPidsSelfLocked.get(pid); 5497 } 5498 } else { 5499 app = null; 5500 } 5501 5502 if (app == null) { 5503 Slog.w(TAG, "No pending application record for pid " + pid 5504 + " (IApplicationThread " + thread + "); dropping process"); 5505 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5506 if (pid > 0 && pid != MY_PID) { 5507 Process.killProcessQuiet(pid); 5508 //TODO: Process.killProcessGroup(app.info.uid, pid); 5509 } else { 5510 try { 5511 thread.scheduleExit(); 5512 } catch (Exception e) { 5513 // Ignore exceptions. 5514 } 5515 } 5516 return false; 5517 } 5518 5519 // If this application record is still attached to a previous 5520 // process, clean it up now. 5521 if (app.thread != null) { 5522 handleAppDiedLocked(app, true, true); 5523 } 5524 5525 // Tell the process all about itself. 5526 5527 if (localLOGV) Slog.v( 5528 TAG, "Binding process pid " + pid + " to record " + app); 5529 5530 final String processName = app.processName; 5531 try { 5532 AppDeathRecipient adr = new AppDeathRecipient( 5533 app, pid, thread); 5534 thread.asBinder().linkToDeath(adr, 0); 5535 app.deathRecipient = adr; 5536 } catch (RemoteException e) { 5537 app.resetPackageList(mProcessStats); 5538 startProcessLocked(app, "link fail", processName); 5539 return false; 5540 } 5541 5542 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5543 5544 app.makeActive(thread, mProcessStats); 5545 app.curAdj = app.setAdj = -100; 5546 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5547 app.forcingToForeground = null; 5548 updateProcessForegroundLocked(app, false, false); 5549 app.hasShownUi = false; 5550 app.debugging = false; 5551 app.cached = false; 5552 5553 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5554 5555 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5556 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5557 5558 if (!normalMode) { 5559 Slog.i(TAG, "Launching preboot mode app: " + app); 5560 } 5561 5562 if (localLOGV) Slog.v( 5563 TAG, "New app record " + app 5564 + " thread=" + thread.asBinder() + " pid=" + pid); 5565 try { 5566 int testMode = IApplicationThread.DEBUG_OFF; 5567 if (mDebugApp != null && mDebugApp.equals(processName)) { 5568 testMode = mWaitForDebugger 5569 ? IApplicationThread.DEBUG_WAIT 5570 : IApplicationThread.DEBUG_ON; 5571 app.debugging = true; 5572 if (mDebugTransient) { 5573 mDebugApp = mOrigDebugApp; 5574 mWaitForDebugger = mOrigWaitForDebugger; 5575 } 5576 } 5577 String profileFile = app.instrumentationProfileFile; 5578 ParcelFileDescriptor profileFd = null; 5579 boolean profileAutoStop = false; 5580 if (mProfileApp != null && mProfileApp.equals(processName)) { 5581 mProfileProc = app; 5582 profileFile = mProfileFile; 5583 profileFd = mProfileFd; 5584 profileAutoStop = mAutoStopProfiler; 5585 } 5586 boolean enableOpenGlTrace = false; 5587 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5588 enableOpenGlTrace = true; 5589 mOpenGlTraceApp = null; 5590 } 5591 5592 // If the app is being launched for restore or full backup, set it up specially 5593 boolean isRestrictedBackupMode = false; 5594 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5595 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5596 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5597 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5598 } 5599 5600 ensurePackageDexOpt(app.instrumentationInfo != null 5601 ? app.instrumentationInfo.packageName 5602 : app.info.packageName); 5603 if (app.instrumentationClass != null) { 5604 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5605 } 5606 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5607 + processName + " with config " + mConfiguration); 5608 ApplicationInfo appInfo = app.instrumentationInfo != null 5609 ? app.instrumentationInfo : app.info; 5610 app.compat = compatibilityInfoForPackageLocked(appInfo); 5611 if (profileFd != null) { 5612 profileFd = profileFd.dup(); 5613 } 5614 thread.bindApplication(processName, appInfo, providers, 5615 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5616 app.instrumentationArguments, app.instrumentationWatcher, 5617 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5618 isRestrictedBackupMode || !normalMode, app.persistent, 5619 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5620 mCoreSettingsObserver.getCoreSettingsLocked()); 5621 updateLruProcessLocked(app, false, null); 5622 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5623 } catch (Exception e) { 5624 // todo: Yikes! What should we do? For now we will try to 5625 // start another process, but that could easily get us in 5626 // an infinite loop of restarting processes... 5627 Slog.w(TAG, "Exception thrown during bind!", e); 5628 5629 app.resetPackageList(mProcessStats); 5630 app.unlinkDeathRecipient(); 5631 startProcessLocked(app, "bind fail", processName); 5632 return false; 5633 } 5634 5635 // Remove this record from the list of starting applications. 5636 mPersistentStartingProcesses.remove(app); 5637 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5638 "Attach application locked removing on hold: " + app); 5639 mProcessesOnHold.remove(app); 5640 5641 boolean badApp = false; 5642 boolean didSomething = false; 5643 5644 // See if the top visible activity is waiting to run in this process... 5645 if (normalMode) { 5646 try { 5647 if (mStackSupervisor.attachApplicationLocked(app)) { 5648 didSomething = true; 5649 } 5650 } catch (Exception e) { 5651 badApp = true; 5652 } 5653 } 5654 5655 // Find any services that should be running in this process... 5656 if (!badApp) { 5657 try { 5658 didSomething |= mServices.attachApplicationLocked(app, processName); 5659 } catch (Exception e) { 5660 badApp = true; 5661 } 5662 } 5663 5664 // Check if a next-broadcast receiver is in this process... 5665 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5666 try { 5667 didSomething |= sendPendingBroadcastsLocked(app); 5668 } catch (Exception e) { 5669 // If the app died trying to launch the receiver we declare it 'bad' 5670 badApp = true; 5671 } 5672 } 5673 5674 // Check whether the next backup agent is in this process... 5675 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5676 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5677 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5678 try { 5679 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5680 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5681 mBackupTarget.backupMode); 5682 } catch (Exception e) { 5683 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5684 e.printStackTrace(); 5685 } 5686 } 5687 5688 if (badApp) { 5689 // todo: Also need to kill application to deal with all 5690 // kinds of exceptions. 5691 handleAppDiedLocked(app, false, true); 5692 return false; 5693 } 5694 5695 if (!didSomething) { 5696 updateOomAdjLocked(); 5697 } 5698 5699 return true; 5700 } 5701 5702 @Override 5703 public final void attachApplication(IApplicationThread thread) { 5704 synchronized (this) { 5705 int callingPid = Binder.getCallingPid(); 5706 final long origId = Binder.clearCallingIdentity(); 5707 attachApplicationLocked(thread, callingPid); 5708 Binder.restoreCallingIdentity(origId); 5709 } 5710 } 5711 5712 @Override 5713 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5714 final long origId = Binder.clearCallingIdentity(); 5715 synchronized (this) { 5716 ActivityStack stack = ActivityRecord.getStackLocked(token); 5717 if (stack != null) { 5718 ActivityRecord r = 5719 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5720 if (stopProfiling) { 5721 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5722 try { 5723 mProfileFd.close(); 5724 } catch (IOException e) { 5725 } 5726 clearProfilerLocked(); 5727 } 5728 } 5729 } 5730 } 5731 Binder.restoreCallingIdentity(origId); 5732 } 5733 5734 void postEnableScreenAfterBootLocked() { 5735 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 5736 } 5737 5738 void enableScreenAfterBoot() { 5739 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5740 SystemClock.uptimeMillis()); 5741 mWindowManager.enableScreenAfterBoot(); 5742 5743 synchronized (this) { 5744 updateEventDispatchingLocked(); 5745 } 5746 } 5747 5748 @Override 5749 public void showBootMessage(final CharSequence msg, final boolean always) { 5750 enforceNotIsolatedCaller("showBootMessage"); 5751 mWindowManager.showBootMessage(msg, always); 5752 } 5753 5754 @Override 5755 public void keyguardWaitingForActivityDrawn() { 5756 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 5757 final long token = Binder.clearCallingIdentity(); 5758 try { 5759 synchronized (this) { 5760 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5761 mWindowManager.keyguardWaitingForActivityDrawn(); 5762 } 5763 } finally { 5764 Binder.restoreCallingIdentity(token); 5765 } 5766 } 5767 5768 final void finishBooting() { 5769 // Register receivers to handle package update events 5770 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5771 5772 // Let system services know. 5773 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 5774 5775 synchronized (this) { 5776 // Ensure that any processes we had put on hold are now started 5777 // up. 5778 final int NP = mProcessesOnHold.size(); 5779 if (NP > 0) { 5780 ArrayList<ProcessRecord> procs = 5781 new ArrayList<ProcessRecord>(mProcessesOnHold); 5782 for (int ip=0; ip<NP; ip++) { 5783 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5784 + procs.get(ip)); 5785 startProcessLocked(procs.get(ip), "on-hold", null); 5786 } 5787 } 5788 5789 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5790 // Start looking for apps that are abusing wake locks. 5791 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5792 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5793 // Tell anyone interested that we are done booting! 5794 SystemProperties.set("sys.boot_completed", "1"); 5795 SystemProperties.set("dev.bootcomplete", "1"); 5796 for (int i=0; i<mStartedUsers.size(); i++) { 5797 UserStartedState uss = mStartedUsers.valueAt(i); 5798 if (uss.mState == UserStartedState.STATE_BOOTING) { 5799 uss.mState = UserStartedState.STATE_RUNNING; 5800 final int userId = mStartedUsers.keyAt(i); 5801 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5802 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5803 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5804 broadcastIntentLocked(null, null, intent, null, 5805 new IIntentReceiver.Stub() { 5806 @Override 5807 public void performReceive(Intent intent, int resultCode, 5808 String data, Bundle extras, boolean ordered, 5809 boolean sticky, int sendingUser) { 5810 synchronized (ActivityManagerService.this) { 5811 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5812 true, false); 5813 } 5814 } 5815 }, 5816 0, null, null, 5817 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5818 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5819 userId); 5820 } 5821 } 5822 scheduleStartProfilesLocked(); 5823 } 5824 } 5825 } 5826 5827 final void ensureBootCompleted() { 5828 boolean booting; 5829 boolean enableScreen; 5830 synchronized (this) { 5831 booting = mBooting; 5832 mBooting = false; 5833 enableScreen = !mBooted; 5834 mBooted = true; 5835 } 5836 5837 if (booting) { 5838 finishBooting(); 5839 } 5840 5841 if (enableScreen) { 5842 enableScreenAfterBoot(); 5843 } 5844 } 5845 5846 @Override 5847 public final void activityResumed(IBinder token) { 5848 final long origId = Binder.clearCallingIdentity(); 5849 synchronized(this) { 5850 ActivityStack stack = ActivityRecord.getStackLocked(token); 5851 if (stack != null) { 5852 ActivityRecord.activityResumedLocked(token); 5853 } 5854 } 5855 Binder.restoreCallingIdentity(origId); 5856 } 5857 5858 @Override 5859 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5860 final long origId = Binder.clearCallingIdentity(); 5861 synchronized(this) { 5862 ActivityStack stack = ActivityRecord.getStackLocked(token); 5863 if (stack != null) { 5864 stack.activityPausedLocked(token, false, persistentState); 5865 } 5866 } 5867 Binder.restoreCallingIdentity(origId); 5868 } 5869 5870 @Override 5871 public final void activityStopped(IBinder token, Bundle icicle, 5872 PersistableBundle persistentState, CharSequence description) { 5873 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5874 5875 // Refuse possible leaked file descriptors 5876 if (icicle != null && icicle.hasFileDescriptors()) { 5877 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5878 } 5879 5880 final long origId = Binder.clearCallingIdentity(); 5881 5882 synchronized (this) { 5883 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5884 if (r != null) { 5885 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5886 } 5887 } 5888 5889 trimApplications(); 5890 5891 Binder.restoreCallingIdentity(origId); 5892 } 5893 5894 @Override 5895 public final void activityDestroyed(IBinder token) { 5896 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5897 synchronized (this) { 5898 ActivityStack stack = ActivityRecord.getStackLocked(token); 5899 if (stack != null) { 5900 stack.activityDestroyedLocked(token); 5901 } 5902 } 5903 } 5904 5905 @Override 5906 public final void backgroundResourcesReleased(IBinder token) { 5907 final long origId = Binder.clearCallingIdentity(); 5908 try { 5909 synchronized (this) { 5910 ActivityStack stack = ActivityRecord.getStackLocked(token); 5911 if (stack != null) { 5912 stack.backgroundResourcesReleased(token); 5913 } 5914 } 5915 } finally { 5916 Binder.restoreCallingIdentity(origId); 5917 } 5918 } 5919 5920 @Override 5921 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5922 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5923 } 5924 5925 @Override 5926 public final void notifyEnterAnimationComplete(IBinder token) { 5927 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 5928 } 5929 5930 @Override 5931 public String getCallingPackage(IBinder token) { 5932 synchronized (this) { 5933 ActivityRecord r = getCallingRecordLocked(token); 5934 return r != null ? r.info.packageName : null; 5935 } 5936 } 5937 5938 @Override 5939 public ComponentName getCallingActivity(IBinder token) { 5940 synchronized (this) { 5941 ActivityRecord r = getCallingRecordLocked(token); 5942 return r != null ? r.intent.getComponent() : null; 5943 } 5944 } 5945 5946 private ActivityRecord getCallingRecordLocked(IBinder token) { 5947 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5948 if (r == null) { 5949 return null; 5950 } 5951 return r.resultTo; 5952 } 5953 5954 @Override 5955 public ComponentName getActivityClassForToken(IBinder token) { 5956 synchronized(this) { 5957 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5958 if (r == null) { 5959 return null; 5960 } 5961 return r.intent.getComponent(); 5962 } 5963 } 5964 5965 @Override 5966 public String getPackageForToken(IBinder token) { 5967 synchronized(this) { 5968 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5969 if (r == null) { 5970 return null; 5971 } 5972 return r.packageName; 5973 } 5974 } 5975 5976 @Override 5977 public IIntentSender getIntentSender(int type, 5978 String packageName, IBinder token, String resultWho, 5979 int requestCode, Intent[] intents, String[] resolvedTypes, 5980 int flags, Bundle options, int userId) { 5981 enforceNotIsolatedCaller("getIntentSender"); 5982 // Refuse possible leaked file descriptors 5983 if (intents != null) { 5984 if (intents.length < 1) { 5985 throw new IllegalArgumentException("Intents array length must be >= 1"); 5986 } 5987 for (int i=0; i<intents.length; i++) { 5988 Intent intent = intents[i]; 5989 if (intent != null) { 5990 if (intent.hasFileDescriptors()) { 5991 throw new IllegalArgumentException("File descriptors passed in Intent"); 5992 } 5993 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5994 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5995 throw new IllegalArgumentException( 5996 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5997 } 5998 intents[i] = new Intent(intent); 5999 } 6000 } 6001 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6002 throw new IllegalArgumentException( 6003 "Intent array length does not match resolvedTypes length"); 6004 } 6005 } 6006 if (options != null) { 6007 if (options.hasFileDescriptors()) { 6008 throw new IllegalArgumentException("File descriptors passed in options"); 6009 } 6010 } 6011 6012 synchronized(this) { 6013 int callingUid = Binder.getCallingUid(); 6014 int origUserId = userId; 6015 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6016 type == ActivityManager.INTENT_SENDER_BROADCAST, 6017 ALLOW_NON_FULL, "getIntentSender", null); 6018 if (origUserId == UserHandle.USER_CURRENT) { 6019 // We don't want to evaluate this until the pending intent is 6020 // actually executed. However, we do want to always do the 6021 // security checking for it above. 6022 userId = UserHandle.USER_CURRENT; 6023 } 6024 try { 6025 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6026 int uid = AppGlobals.getPackageManager() 6027 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6028 if (!UserHandle.isSameApp(callingUid, uid)) { 6029 String msg = "Permission Denial: getIntentSender() from pid=" 6030 + Binder.getCallingPid() 6031 + ", uid=" + Binder.getCallingUid() 6032 + ", (need uid=" + uid + ")" 6033 + " is not allowed to send as package " + packageName; 6034 Slog.w(TAG, msg); 6035 throw new SecurityException(msg); 6036 } 6037 } 6038 6039 return getIntentSenderLocked(type, packageName, callingUid, userId, 6040 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6041 6042 } catch (RemoteException e) { 6043 throw new SecurityException(e); 6044 } 6045 } 6046 } 6047 6048 IIntentSender getIntentSenderLocked(int type, String packageName, 6049 int callingUid, int userId, IBinder token, String resultWho, 6050 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6051 Bundle options) { 6052 if (DEBUG_MU) 6053 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6054 ActivityRecord activity = null; 6055 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6056 activity = ActivityRecord.isInStackLocked(token); 6057 if (activity == null) { 6058 return null; 6059 } 6060 if (activity.finishing) { 6061 return null; 6062 } 6063 } 6064 6065 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6066 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6067 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6068 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6069 |PendingIntent.FLAG_UPDATE_CURRENT); 6070 6071 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6072 type, packageName, activity, resultWho, 6073 requestCode, intents, resolvedTypes, flags, options, userId); 6074 WeakReference<PendingIntentRecord> ref; 6075 ref = mIntentSenderRecords.get(key); 6076 PendingIntentRecord rec = ref != null ? ref.get() : null; 6077 if (rec != null) { 6078 if (!cancelCurrent) { 6079 if (updateCurrent) { 6080 if (rec.key.requestIntent != null) { 6081 rec.key.requestIntent.replaceExtras(intents != null ? 6082 intents[intents.length - 1] : null); 6083 } 6084 if (intents != null) { 6085 intents[intents.length-1] = rec.key.requestIntent; 6086 rec.key.allIntents = intents; 6087 rec.key.allResolvedTypes = resolvedTypes; 6088 } else { 6089 rec.key.allIntents = null; 6090 rec.key.allResolvedTypes = null; 6091 } 6092 } 6093 return rec; 6094 } 6095 rec.canceled = true; 6096 mIntentSenderRecords.remove(key); 6097 } 6098 if (noCreate) { 6099 return rec; 6100 } 6101 rec = new PendingIntentRecord(this, key, callingUid); 6102 mIntentSenderRecords.put(key, rec.ref); 6103 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6104 if (activity.pendingResults == null) { 6105 activity.pendingResults 6106 = new HashSet<WeakReference<PendingIntentRecord>>(); 6107 } 6108 activity.pendingResults.add(rec.ref); 6109 } 6110 return rec; 6111 } 6112 6113 @Override 6114 public void cancelIntentSender(IIntentSender sender) { 6115 if (!(sender instanceof PendingIntentRecord)) { 6116 return; 6117 } 6118 synchronized(this) { 6119 PendingIntentRecord rec = (PendingIntentRecord)sender; 6120 try { 6121 int uid = AppGlobals.getPackageManager() 6122 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6123 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6124 String msg = "Permission Denial: cancelIntentSender() from pid=" 6125 + Binder.getCallingPid() 6126 + ", uid=" + Binder.getCallingUid() 6127 + " is not allowed to cancel packges " 6128 + rec.key.packageName; 6129 Slog.w(TAG, msg); 6130 throw new SecurityException(msg); 6131 } 6132 } catch (RemoteException e) { 6133 throw new SecurityException(e); 6134 } 6135 cancelIntentSenderLocked(rec, true); 6136 } 6137 } 6138 6139 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6140 rec.canceled = true; 6141 mIntentSenderRecords.remove(rec.key); 6142 if (cleanActivity && rec.key.activity != null) { 6143 rec.key.activity.pendingResults.remove(rec.ref); 6144 } 6145 } 6146 6147 @Override 6148 public String getPackageForIntentSender(IIntentSender pendingResult) { 6149 if (!(pendingResult instanceof PendingIntentRecord)) { 6150 return null; 6151 } 6152 try { 6153 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6154 return res.key.packageName; 6155 } catch (ClassCastException e) { 6156 } 6157 return null; 6158 } 6159 6160 @Override 6161 public int getUidForIntentSender(IIntentSender sender) { 6162 if (sender instanceof PendingIntentRecord) { 6163 try { 6164 PendingIntentRecord res = (PendingIntentRecord)sender; 6165 return res.uid; 6166 } catch (ClassCastException e) { 6167 } 6168 } 6169 return -1; 6170 } 6171 6172 @Override 6173 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6174 if (!(pendingResult instanceof PendingIntentRecord)) { 6175 return false; 6176 } 6177 try { 6178 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6179 if (res.key.allIntents == null) { 6180 return false; 6181 } 6182 for (int i=0; i<res.key.allIntents.length; i++) { 6183 Intent intent = res.key.allIntents[i]; 6184 if (intent.getPackage() != null && intent.getComponent() != null) { 6185 return false; 6186 } 6187 } 6188 return true; 6189 } catch (ClassCastException e) { 6190 } 6191 return false; 6192 } 6193 6194 @Override 6195 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6196 if (!(pendingResult instanceof PendingIntentRecord)) { 6197 return false; 6198 } 6199 try { 6200 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6201 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6202 return true; 6203 } 6204 return false; 6205 } catch (ClassCastException e) { 6206 } 6207 return false; 6208 } 6209 6210 @Override 6211 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6212 if (!(pendingResult instanceof PendingIntentRecord)) { 6213 return null; 6214 } 6215 try { 6216 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6217 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6218 } catch (ClassCastException e) { 6219 } 6220 return null; 6221 } 6222 6223 @Override 6224 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6225 if (!(pendingResult instanceof PendingIntentRecord)) { 6226 return null; 6227 } 6228 try { 6229 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6230 Intent intent = res.key.requestIntent; 6231 if (intent != null) { 6232 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6233 || res.lastTagPrefix.equals(prefix))) { 6234 return res.lastTag; 6235 } 6236 res.lastTagPrefix = prefix; 6237 StringBuilder sb = new StringBuilder(128); 6238 if (prefix != null) { 6239 sb.append(prefix); 6240 } 6241 if (intent.getAction() != null) { 6242 sb.append(intent.getAction()); 6243 } else if (intent.getComponent() != null) { 6244 intent.getComponent().appendShortString(sb); 6245 } else { 6246 sb.append("?"); 6247 } 6248 return res.lastTag = sb.toString(); 6249 } 6250 } catch (ClassCastException e) { 6251 } 6252 return null; 6253 } 6254 6255 @Override 6256 public void setProcessLimit(int max) { 6257 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6258 "setProcessLimit()"); 6259 synchronized (this) { 6260 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6261 mProcessLimitOverride = max; 6262 } 6263 trimApplications(); 6264 } 6265 6266 @Override 6267 public int getProcessLimit() { 6268 synchronized (this) { 6269 return mProcessLimitOverride; 6270 } 6271 } 6272 6273 void foregroundTokenDied(ForegroundToken token) { 6274 synchronized (ActivityManagerService.this) { 6275 synchronized (mPidsSelfLocked) { 6276 ForegroundToken cur 6277 = mForegroundProcesses.get(token.pid); 6278 if (cur != token) { 6279 return; 6280 } 6281 mForegroundProcesses.remove(token.pid); 6282 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6283 if (pr == null) { 6284 return; 6285 } 6286 pr.forcingToForeground = null; 6287 updateProcessForegroundLocked(pr, false, false); 6288 } 6289 updateOomAdjLocked(); 6290 } 6291 } 6292 6293 @Override 6294 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6295 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6296 "setProcessForeground()"); 6297 synchronized(this) { 6298 boolean changed = false; 6299 6300 synchronized (mPidsSelfLocked) { 6301 ProcessRecord pr = mPidsSelfLocked.get(pid); 6302 if (pr == null && isForeground) { 6303 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6304 return; 6305 } 6306 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6307 if (oldToken != null) { 6308 oldToken.token.unlinkToDeath(oldToken, 0); 6309 mForegroundProcesses.remove(pid); 6310 if (pr != null) { 6311 pr.forcingToForeground = null; 6312 } 6313 changed = true; 6314 } 6315 if (isForeground && token != null) { 6316 ForegroundToken newToken = new ForegroundToken() { 6317 @Override 6318 public void binderDied() { 6319 foregroundTokenDied(this); 6320 } 6321 }; 6322 newToken.pid = pid; 6323 newToken.token = token; 6324 try { 6325 token.linkToDeath(newToken, 0); 6326 mForegroundProcesses.put(pid, newToken); 6327 pr.forcingToForeground = token; 6328 changed = true; 6329 } catch (RemoteException e) { 6330 // If the process died while doing this, we will later 6331 // do the cleanup with the process death link. 6332 } 6333 } 6334 } 6335 6336 if (changed) { 6337 updateOomAdjLocked(); 6338 } 6339 } 6340 } 6341 6342 // ========================================================= 6343 // PERMISSIONS 6344 // ========================================================= 6345 6346 static class PermissionController extends IPermissionController.Stub { 6347 ActivityManagerService mActivityManagerService; 6348 PermissionController(ActivityManagerService activityManagerService) { 6349 mActivityManagerService = activityManagerService; 6350 } 6351 6352 @Override 6353 public boolean checkPermission(String permission, int pid, int uid) { 6354 return mActivityManagerService.checkPermission(permission, pid, 6355 uid) == PackageManager.PERMISSION_GRANTED; 6356 } 6357 } 6358 6359 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6360 @Override 6361 public int checkComponentPermission(String permission, int pid, int uid, 6362 int owningUid, boolean exported) { 6363 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6364 owningUid, exported); 6365 } 6366 6367 @Override 6368 public Object getAMSLock() { 6369 return ActivityManagerService.this; 6370 } 6371 } 6372 6373 /** 6374 * This can be called with or without the global lock held. 6375 */ 6376 int checkComponentPermission(String permission, int pid, int uid, 6377 int owningUid, boolean exported) { 6378 // We might be performing an operation on behalf of an indirect binder 6379 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6380 // client identity accordingly before proceeding. 6381 Identity tlsIdentity = sCallerIdentity.get(); 6382 if (tlsIdentity != null) { 6383 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6384 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6385 uid = tlsIdentity.uid; 6386 pid = tlsIdentity.pid; 6387 } 6388 6389 if (pid == MY_PID) { 6390 return PackageManager.PERMISSION_GRANTED; 6391 } 6392 6393 return ActivityManager.checkComponentPermission(permission, uid, 6394 owningUid, exported); 6395 } 6396 6397 /** 6398 * As the only public entry point for permissions checking, this method 6399 * can enforce the semantic that requesting a check on a null global 6400 * permission is automatically denied. (Internally a null permission 6401 * string is used when calling {@link #checkComponentPermission} in cases 6402 * when only uid-based security is needed.) 6403 * 6404 * This can be called with or without the global lock held. 6405 */ 6406 @Override 6407 public int checkPermission(String permission, int pid, int uid) { 6408 if (permission == null) { 6409 return PackageManager.PERMISSION_DENIED; 6410 } 6411 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6412 } 6413 6414 /** 6415 * Binder IPC calls go through the public entry point. 6416 * This can be called with or without the global lock held. 6417 */ 6418 int checkCallingPermission(String permission) { 6419 return checkPermission(permission, 6420 Binder.getCallingPid(), 6421 UserHandle.getAppId(Binder.getCallingUid())); 6422 } 6423 6424 /** 6425 * This can be called with or without the global lock held. 6426 */ 6427 void enforceCallingPermission(String permission, String func) { 6428 if (checkCallingPermission(permission) 6429 == PackageManager.PERMISSION_GRANTED) { 6430 return; 6431 } 6432 6433 String msg = "Permission Denial: " + func + " from pid=" 6434 + Binder.getCallingPid() 6435 + ", uid=" + Binder.getCallingUid() 6436 + " requires " + permission; 6437 Slog.w(TAG, msg); 6438 throw new SecurityException(msg); 6439 } 6440 6441 /** 6442 * Determine if UID is holding permissions required to access {@link Uri} in 6443 * the given {@link ProviderInfo}. Final permission checking is always done 6444 * in {@link ContentProvider}. 6445 */ 6446 private final boolean checkHoldingPermissionsLocked( 6447 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6448 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6449 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6450 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6451 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6452 != PERMISSION_GRANTED) { 6453 return false; 6454 } 6455 } 6456 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6457 } 6458 6459 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6460 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6461 if (pi.applicationInfo.uid == uid) { 6462 return true; 6463 } else if (!pi.exported) { 6464 return false; 6465 } 6466 6467 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6468 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6469 try { 6470 // check if target holds top-level <provider> permissions 6471 if (!readMet && pi.readPermission != null && considerUidPermissions 6472 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6473 readMet = true; 6474 } 6475 if (!writeMet && pi.writePermission != null && considerUidPermissions 6476 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6477 writeMet = true; 6478 } 6479 6480 // track if unprotected read/write is allowed; any denied 6481 // <path-permission> below removes this ability 6482 boolean allowDefaultRead = pi.readPermission == null; 6483 boolean allowDefaultWrite = pi.writePermission == null; 6484 6485 // check if target holds any <path-permission> that match uri 6486 final PathPermission[] pps = pi.pathPermissions; 6487 if (pps != null) { 6488 final String path = grantUri.uri.getPath(); 6489 int i = pps.length; 6490 while (i > 0 && (!readMet || !writeMet)) { 6491 i--; 6492 PathPermission pp = pps[i]; 6493 if (pp.match(path)) { 6494 if (!readMet) { 6495 final String pprperm = pp.getReadPermission(); 6496 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6497 + pprperm + " for " + pp.getPath() 6498 + ": match=" + pp.match(path) 6499 + " check=" + pm.checkUidPermission(pprperm, uid)); 6500 if (pprperm != null) { 6501 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6502 == PERMISSION_GRANTED) { 6503 readMet = true; 6504 } else { 6505 allowDefaultRead = false; 6506 } 6507 } 6508 } 6509 if (!writeMet) { 6510 final String ppwperm = pp.getWritePermission(); 6511 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6512 + ppwperm + " for " + pp.getPath() 6513 + ": match=" + pp.match(path) 6514 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6515 if (ppwperm != null) { 6516 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6517 == PERMISSION_GRANTED) { 6518 writeMet = true; 6519 } else { 6520 allowDefaultWrite = false; 6521 } 6522 } 6523 } 6524 } 6525 } 6526 } 6527 6528 // grant unprotected <provider> read/write, if not blocked by 6529 // <path-permission> above 6530 if (allowDefaultRead) readMet = true; 6531 if (allowDefaultWrite) writeMet = true; 6532 6533 } catch (RemoteException e) { 6534 return false; 6535 } 6536 6537 return readMet && writeMet; 6538 } 6539 6540 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6541 ProviderInfo pi = null; 6542 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6543 if (cpr != null) { 6544 pi = cpr.info; 6545 } else { 6546 try { 6547 pi = AppGlobals.getPackageManager().resolveContentProvider( 6548 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6549 } catch (RemoteException ex) { 6550 } 6551 } 6552 return pi; 6553 } 6554 6555 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6556 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6557 if (targetUris != null) { 6558 return targetUris.get(grantUri); 6559 } 6560 return null; 6561 } 6562 6563 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6564 String targetPkg, int targetUid, GrantUri grantUri) { 6565 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6566 if (targetUris == null) { 6567 targetUris = Maps.newArrayMap(); 6568 mGrantedUriPermissions.put(targetUid, targetUris); 6569 } 6570 6571 UriPermission perm = targetUris.get(grantUri); 6572 if (perm == null) { 6573 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6574 targetUris.put(grantUri, perm); 6575 } 6576 6577 return perm; 6578 } 6579 6580 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6581 final int modeFlags) { 6582 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6583 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6584 : UriPermission.STRENGTH_OWNED; 6585 6586 // Root gets to do everything. 6587 if (uid == 0) { 6588 return true; 6589 } 6590 6591 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6592 if (perms == null) return false; 6593 6594 // First look for exact match 6595 final UriPermission exactPerm = perms.get(grantUri); 6596 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6597 return true; 6598 } 6599 6600 // No exact match, look for prefixes 6601 final int N = perms.size(); 6602 for (int i = 0; i < N; i++) { 6603 final UriPermission perm = perms.valueAt(i); 6604 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6605 && perm.getStrength(modeFlags) >= minStrength) { 6606 return true; 6607 } 6608 } 6609 6610 return false; 6611 } 6612 6613 @Override 6614 public int checkUriPermission(Uri uri, int pid, int uid, 6615 final int modeFlags, int userId) { 6616 enforceNotIsolatedCaller("checkUriPermission"); 6617 6618 // Another redirected-binder-call permissions check as in 6619 // {@link checkComponentPermission}. 6620 Identity tlsIdentity = sCallerIdentity.get(); 6621 if (tlsIdentity != null) { 6622 uid = tlsIdentity.uid; 6623 pid = tlsIdentity.pid; 6624 } 6625 6626 // Our own process gets to do everything. 6627 if (pid == MY_PID) { 6628 return PackageManager.PERMISSION_GRANTED; 6629 } 6630 synchronized (this) { 6631 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6632 ? PackageManager.PERMISSION_GRANTED 6633 : PackageManager.PERMISSION_DENIED; 6634 } 6635 } 6636 6637 /** 6638 * Check if the targetPkg can be granted permission to access uri by 6639 * the callingUid using the given modeFlags. Throws a security exception 6640 * if callingUid is not allowed to do this. Returns the uid of the target 6641 * if the URI permission grant should be performed; returns -1 if it is not 6642 * needed (for example targetPkg already has permission to access the URI). 6643 * If you already know the uid of the target, you can supply it in 6644 * lastTargetUid else set that to -1. 6645 */ 6646 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6647 final int modeFlags, int lastTargetUid) { 6648 if (!Intent.isAccessUriMode(modeFlags)) { 6649 return -1; 6650 } 6651 6652 if (targetPkg != null) { 6653 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6654 "Checking grant " + targetPkg + " permission to " + grantUri); 6655 } 6656 6657 final IPackageManager pm = AppGlobals.getPackageManager(); 6658 6659 // If this is not a content: uri, we can't do anything with it. 6660 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6661 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6662 "Can't grant URI permission for non-content URI: " + grantUri); 6663 return -1; 6664 } 6665 6666 final String authority = grantUri.uri.getAuthority(); 6667 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6668 if (pi == null) { 6669 Slog.w(TAG, "No content provider found for permission check: " + 6670 grantUri.uri.toSafeString()); 6671 return -1; 6672 } 6673 6674 int targetUid = lastTargetUid; 6675 if (targetUid < 0 && targetPkg != null) { 6676 try { 6677 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6678 if (targetUid < 0) { 6679 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6680 "Can't grant URI permission no uid for: " + targetPkg); 6681 return -1; 6682 } 6683 } catch (RemoteException ex) { 6684 return -1; 6685 } 6686 } 6687 6688 if (targetUid >= 0) { 6689 // First... does the target actually need this permission? 6690 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6691 // No need to grant the target this permission. 6692 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6693 "Target " + targetPkg + " already has full permission to " + grantUri); 6694 return -1; 6695 } 6696 } else { 6697 // First... there is no target package, so can anyone access it? 6698 boolean allowed = pi.exported; 6699 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6700 if (pi.readPermission != null) { 6701 allowed = false; 6702 } 6703 } 6704 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6705 if (pi.writePermission != null) { 6706 allowed = false; 6707 } 6708 } 6709 if (allowed) { 6710 return -1; 6711 } 6712 } 6713 6714 /* There is a special cross user grant if: 6715 * - The target is on another user. 6716 * - Apps on the current user can access the uri without any uid permissions. 6717 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6718 * grant uri permissions. 6719 */ 6720 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6721 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6722 modeFlags, false /*without considering the uid permissions*/); 6723 6724 // Second... is the provider allowing granting of URI permissions? 6725 if (!specialCrossUserGrant) { 6726 if (!pi.grantUriPermissions) { 6727 throw new SecurityException("Provider " + pi.packageName 6728 + "/" + pi.name 6729 + " does not allow granting of Uri permissions (uri " 6730 + grantUri + ")"); 6731 } 6732 if (pi.uriPermissionPatterns != null) { 6733 final int N = pi.uriPermissionPatterns.length; 6734 boolean allowed = false; 6735 for (int i=0; i<N; i++) { 6736 if (pi.uriPermissionPatterns[i] != null 6737 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6738 allowed = true; 6739 break; 6740 } 6741 } 6742 if (!allowed) { 6743 throw new SecurityException("Provider " + pi.packageName 6744 + "/" + pi.name 6745 + " does not allow granting of permission to path of Uri " 6746 + grantUri); 6747 } 6748 } 6749 } 6750 6751 // Third... does the caller itself have permission to access 6752 // this uri? 6753 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6754 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6755 // Require they hold a strong enough Uri permission 6756 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6757 throw new SecurityException("Uid " + callingUid 6758 + " does not have permission to uri " + grantUri); 6759 } 6760 } 6761 } 6762 return targetUid; 6763 } 6764 6765 @Override 6766 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6767 final int modeFlags, int userId) { 6768 enforceNotIsolatedCaller("checkGrantUriPermission"); 6769 synchronized(this) { 6770 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6771 new GrantUri(userId, uri, false), modeFlags, -1); 6772 } 6773 } 6774 6775 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6776 final int modeFlags, UriPermissionOwner owner) { 6777 if (!Intent.isAccessUriMode(modeFlags)) { 6778 return; 6779 } 6780 6781 // So here we are: the caller has the assumed permission 6782 // to the uri, and the target doesn't. Let's now give this to 6783 // the target. 6784 6785 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6786 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6787 6788 final String authority = grantUri.uri.getAuthority(); 6789 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6790 if (pi == null) { 6791 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6792 return; 6793 } 6794 6795 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6796 grantUri.prefix = true; 6797 } 6798 final UriPermission perm = findOrCreateUriPermissionLocked( 6799 pi.packageName, targetPkg, targetUid, grantUri); 6800 perm.grantModes(modeFlags, owner); 6801 } 6802 6803 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6804 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 6805 if (targetPkg == null) { 6806 throw new NullPointerException("targetPkg"); 6807 } 6808 int targetUid; 6809 final IPackageManager pm = AppGlobals.getPackageManager(); 6810 try { 6811 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6812 } catch (RemoteException ex) { 6813 return; 6814 } 6815 6816 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6817 targetUid); 6818 if (targetUid < 0) { 6819 return; 6820 } 6821 6822 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6823 owner); 6824 } 6825 6826 static class NeededUriGrants extends ArrayList<GrantUri> { 6827 final String targetPkg; 6828 final int targetUid; 6829 final int flags; 6830 6831 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6832 this.targetPkg = targetPkg; 6833 this.targetUid = targetUid; 6834 this.flags = flags; 6835 } 6836 } 6837 6838 /** 6839 * Like checkGrantUriPermissionLocked, but takes an Intent. 6840 */ 6841 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6842 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6843 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6844 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6845 + " clip=" + (intent != null ? intent.getClipData() : null) 6846 + " from " + intent + "; flags=0x" 6847 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6848 6849 if (targetPkg == null) { 6850 throw new NullPointerException("targetPkg"); 6851 } 6852 6853 if (intent == null) { 6854 return null; 6855 } 6856 Uri data = intent.getData(); 6857 ClipData clip = intent.getClipData(); 6858 if (data == null && clip == null) { 6859 return null; 6860 } 6861 // Default userId for uris in the intent (if they don't specify it themselves) 6862 int contentUserHint = intent.getContentUserHint(); 6863 if (contentUserHint == UserHandle.USER_CURRENT) { 6864 contentUserHint = UserHandle.getUserId(callingUid); 6865 } 6866 final IPackageManager pm = AppGlobals.getPackageManager(); 6867 int targetUid; 6868 if (needed != null) { 6869 targetUid = needed.targetUid; 6870 } else { 6871 try { 6872 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6873 } catch (RemoteException ex) { 6874 return null; 6875 } 6876 if (targetUid < 0) { 6877 if (DEBUG_URI_PERMISSION) { 6878 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6879 + " on user " + targetUserId); 6880 } 6881 return null; 6882 } 6883 } 6884 if (data != null) { 6885 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 6886 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6887 targetUid); 6888 if (targetUid > 0) { 6889 if (needed == null) { 6890 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6891 } 6892 needed.add(grantUri); 6893 } 6894 } 6895 if (clip != null) { 6896 for (int i=0; i<clip.getItemCount(); i++) { 6897 Uri uri = clip.getItemAt(i).getUri(); 6898 if (uri != null) { 6899 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 6900 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6901 targetUid); 6902 if (targetUid > 0) { 6903 if (needed == null) { 6904 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6905 } 6906 needed.add(grantUri); 6907 } 6908 } else { 6909 Intent clipIntent = clip.getItemAt(i).getIntent(); 6910 if (clipIntent != null) { 6911 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6912 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6913 if (newNeeded != null) { 6914 needed = newNeeded; 6915 } 6916 } 6917 } 6918 } 6919 } 6920 6921 return needed; 6922 } 6923 6924 /** 6925 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6926 */ 6927 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6928 UriPermissionOwner owner) { 6929 if (needed != null) { 6930 for (int i=0; i<needed.size(); i++) { 6931 GrantUri grantUri = needed.get(i); 6932 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6933 grantUri, needed.flags, owner); 6934 } 6935 } 6936 } 6937 6938 void grantUriPermissionFromIntentLocked(int callingUid, 6939 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6940 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6941 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6942 if (needed == null) { 6943 return; 6944 } 6945 6946 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6947 } 6948 6949 @Override 6950 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6951 final int modeFlags, int userId) { 6952 enforceNotIsolatedCaller("grantUriPermission"); 6953 GrantUri grantUri = new GrantUri(userId, uri, false); 6954 synchronized(this) { 6955 final ProcessRecord r = getRecordForAppLocked(caller); 6956 if (r == null) { 6957 throw new SecurityException("Unable to find app for caller " 6958 + caller 6959 + " when granting permission to uri " + grantUri); 6960 } 6961 if (targetPkg == null) { 6962 throw new IllegalArgumentException("null target"); 6963 } 6964 if (grantUri == null) { 6965 throw new IllegalArgumentException("null uri"); 6966 } 6967 6968 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6969 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6970 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6971 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6972 6973 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 6974 UserHandle.getUserId(r.uid)); 6975 } 6976 } 6977 6978 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6979 if (perm.modeFlags == 0) { 6980 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6981 perm.targetUid); 6982 if (perms != null) { 6983 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6984 "Removing " + perm.targetUid + " permission to " + perm.uri); 6985 6986 perms.remove(perm.uri); 6987 if (perms.isEmpty()) { 6988 mGrantedUriPermissions.remove(perm.targetUid); 6989 } 6990 } 6991 } 6992 } 6993 6994 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6995 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6996 6997 final IPackageManager pm = AppGlobals.getPackageManager(); 6998 final String authority = grantUri.uri.getAuthority(); 6999 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7000 if (pi == null) { 7001 Slog.w(TAG, "No content provider found for permission revoke: " 7002 + grantUri.toSafeString()); 7003 return; 7004 } 7005 7006 // Does the caller have this permission on the URI? 7007 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7008 // Right now, if you are not the original owner of the permission, 7009 // you are not allowed to revoke it. 7010 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7011 throw new SecurityException("Uid " + callingUid 7012 + " does not have permission to uri " + grantUri); 7013 //} 7014 } 7015 7016 boolean persistChanged = false; 7017 7018 // Go through all of the permissions and remove any that match. 7019 int N = mGrantedUriPermissions.size(); 7020 for (int i = 0; i < N; i++) { 7021 final int targetUid = mGrantedUriPermissions.keyAt(i); 7022 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7023 7024 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7025 final UriPermission perm = it.next(); 7026 if (perm.uri.sourceUserId == grantUri.sourceUserId 7027 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7028 if (DEBUG_URI_PERMISSION) 7029 Slog.v(TAG, 7030 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7031 persistChanged |= perm.revokeModes( 7032 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7033 if (perm.modeFlags == 0) { 7034 it.remove(); 7035 } 7036 } 7037 } 7038 7039 if (perms.isEmpty()) { 7040 mGrantedUriPermissions.remove(targetUid); 7041 N--; 7042 i--; 7043 } 7044 } 7045 7046 if (persistChanged) { 7047 schedulePersistUriGrants(); 7048 } 7049 } 7050 7051 @Override 7052 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7053 int userId) { 7054 enforceNotIsolatedCaller("revokeUriPermission"); 7055 synchronized(this) { 7056 final ProcessRecord r = getRecordForAppLocked(caller); 7057 if (r == null) { 7058 throw new SecurityException("Unable to find app for caller " 7059 + caller 7060 + " when revoking permission to uri " + uri); 7061 } 7062 if (uri == null) { 7063 Slog.w(TAG, "revokeUriPermission: null uri"); 7064 return; 7065 } 7066 7067 if (!Intent.isAccessUriMode(modeFlags)) { 7068 return; 7069 } 7070 7071 final IPackageManager pm = AppGlobals.getPackageManager(); 7072 final String authority = uri.getAuthority(); 7073 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7074 if (pi == null) { 7075 Slog.w(TAG, "No content provider found for permission revoke: " 7076 + uri.toSafeString()); 7077 return; 7078 } 7079 7080 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7081 } 7082 } 7083 7084 /** 7085 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7086 * given package. 7087 * 7088 * @param packageName Package name to match, or {@code null} to apply to all 7089 * packages. 7090 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7091 * to all users. 7092 * @param persistable If persistable grants should be removed. 7093 */ 7094 private void removeUriPermissionsForPackageLocked( 7095 String packageName, int userHandle, boolean persistable) { 7096 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7097 throw new IllegalArgumentException("Must narrow by either package or user"); 7098 } 7099 7100 boolean persistChanged = false; 7101 7102 int N = mGrantedUriPermissions.size(); 7103 for (int i = 0; i < N; i++) { 7104 final int targetUid = mGrantedUriPermissions.keyAt(i); 7105 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7106 7107 // Only inspect grants matching user 7108 if (userHandle == UserHandle.USER_ALL 7109 || userHandle == UserHandle.getUserId(targetUid)) { 7110 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7111 final UriPermission perm = it.next(); 7112 7113 // Only inspect grants matching package 7114 if (packageName == null || perm.sourcePkg.equals(packageName) 7115 || perm.targetPkg.equals(packageName)) { 7116 persistChanged |= perm.revokeModes( 7117 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7118 7119 // Only remove when no modes remain; any persisted grants 7120 // will keep this alive. 7121 if (perm.modeFlags == 0) { 7122 it.remove(); 7123 } 7124 } 7125 } 7126 7127 if (perms.isEmpty()) { 7128 mGrantedUriPermissions.remove(targetUid); 7129 N--; 7130 i--; 7131 } 7132 } 7133 } 7134 7135 if (persistChanged) { 7136 schedulePersistUriGrants(); 7137 } 7138 } 7139 7140 @Override 7141 public IBinder newUriPermissionOwner(String name) { 7142 enforceNotIsolatedCaller("newUriPermissionOwner"); 7143 synchronized(this) { 7144 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7145 return owner.getExternalTokenLocked(); 7146 } 7147 } 7148 7149 @Override 7150 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7151 final int modeFlags, int sourceUserId, int targetUserId) { 7152 synchronized(this) { 7153 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7154 if (owner == null) { 7155 throw new IllegalArgumentException("Unknown owner: " + token); 7156 } 7157 if (fromUid != Binder.getCallingUid()) { 7158 if (Binder.getCallingUid() != Process.myUid()) { 7159 // Only system code can grant URI permissions on behalf 7160 // of other users. 7161 throw new SecurityException("nice try"); 7162 } 7163 } 7164 if (targetPkg == null) { 7165 throw new IllegalArgumentException("null target"); 7166 } 7167 if (uri == null) { 7168 throw new IllegalArgumentException("null uri"); 7169 } 7170 7171 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7172 modeFlags, owner, targetUserId); 7173 } 7174 } 7175 7176 @Override 7177 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7178 synchronized(this) { 7179 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7180 if (owner == null) { 7181 throw new IllegalArgumentException("Unknown owner: " + token); 7182 } 7183 7184 if (uri == null) { 7185 owner.removeUriPermissionsLocked(mode); 7186 } else { 7187 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7188 } 7189 } 7190 } 7191 7192 private void schedulePersistUriGrants() { 7193 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7194 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7195 10 * DateUtils.SECOND_IN_MILLIS); 7196 } 7197 } 7198 7199 private void writeGrantedUriPermissions() { 7200 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7201 7202 // Snapshot permissions so we can persist without lock 7203 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7204 synchronized (this) { 7205 final int size = mGrantedUriPermissions.size(); 7206 for (int i = 0; i < size; i++) { 7207 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7208 for (UriPermission perm : perms.values()) { 7209 if (perm.persistedModeFlags != 0) { 7210 persist.add(perm.snapshot()); 7211 } 7212 } 7213 } 7214 } 7215 7216 FileOutputStream fos = null; 7217 try { 7218 fos = mGrantFile.startWrite(); 7219 7220 XmlSerializer out = new FastXmlSerializer(); 7221 out.setOutput(fos, "utf-8"); 7222 out.startDocument(null, true); 7223 out.startTag(null, TAG_URI_GRANTS); 7224 for (UriPermission.Snapshot perm : persist) { 7225 out.startTag(null, TAG_URI_GRANT); 7226 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7227 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7228 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7229 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7230 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7231 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7232 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7233 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7234 out.endTag(null, TAG_URI_GRANT); 7235 } 7236 out.endTag(null, TAG_URI_GRANTS); 7237 out.endDocument(); 7238 7239 mGrantFile.finishWrite(fos); 7240 } catch (IOException e) { 7241 if (fos != null) { 7242 mGrantFile.failWrite(fos); 7243 } 7244 } 7245 } 7246 7247 private void readGrantedUriPermissionsLocked() { 7248 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7249 7250 final long now = System.currentTimeMillis(); 7251 7252 FileInputStream fis = null; 7253 try { 7254 fis = mGrantFile.openRead(); 7255 final XmlPullParser in = Xml.newPullParser(); 7256 in.setInput(fis, null); 7257 7258 int type; 7259 while ((type = in.next()) != END_DOCUMENT) { 7260 final String tag = in.getName(); 7261 if (type == START_TAG) { 7262 if (TAG_URI_GRANT.equals(tag)) { 7263 final int sourceUserId; 7264 final int targetUserId; 7265 final int userHandle = readIntAttribute(in, 7266 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7267 if (userHandle != UserHandle.USER_NULL) { 7268 // For backwards compatibility. 7269 sourceUserId = userHandle; 7270 targetUserId = userHandle; 7271 } else { 7272 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7273 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7274 } 7275 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7276 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7277 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7278 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7279 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7280 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7281 7282 // Sanity check that provider still belongs to source package 7283 final ProviderInfo pi = getProviderInfoLocked( 7284 uri.getAuthority(), sourceUserId); 7285 if (pi != null && sourcePkg.equals(pi.packageName)) { 7286 int targetUid = -1; 7287 try { 7288 targetUid = AppGlobals.getPackageManager() 7289 .getPackageUid(targetPkg, targetUserId); 7290 } catch (RemoteException e) { 7291 } 7292 if (targetUid != -1) { 7293 final UriPermission perm = findOrCreateUriPermissionLocked( 7294 sourcePkg, targetPkg, targetUid, 7295 new GrantUri(sourceUserId, uri, prefix)); 7296 perm.initPersistedModes(modeFlags, createdTime); 7297 } 7298 } else { 7299 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7300 + " but instead found " + pi); 7301 } 7302 } 7303 } 7304 } 7305 } catch (FileNotFoundException e) { 7306 // Missing grants is okay 7307 } catch (IOException e) { 7308 Log.wtf(TAG, "Failed reading Uri grants", e); 7309 } catch (XmlPullParserException e) { 7310 Log.wtf(TAG, "Failed reading Uri grants", e); 7311 } finally { 7312 IoUtils.closeQuietly(fis); 7313 } 7314 } 7315 7316 @Override 7317 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7318 enforceNotIsolatedCaller("takePersistableUriPermission"); 7319 7320 Preconditions.checkFlagsArgument(modeFlags, 7321 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7322 7323 synchronized (this) { 7324 final int callingUid = Binder.getCallingUid(); 7325 boolean persistChanged = false; 7326 GrantUri grantUri = new GrantUri(userId, uri, false); 7327 7328 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7329 new GrantUri(userId, uri, false)); 7330 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7331 new GrantUri(userId, uri, true)); 7332 7333 final boolean exactValid = (exactPerm != null) 7334 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7335 final boolean prefixValid = (prefixPerm != null) 7336 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7337 7338 if (!(exactValid || prefixValid)) { 7339 throw new SecurityException("No persistable permission grants found for UID " 7340 + callingUid + " and Uri " + grantUri.toSafeString()); 7341 } 7342 7343 if (exactValid) { 7344 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7345 } 7346 if (prefixValid) { 7347 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7348 } 7349 7350 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7351 7352 if (persistChanged) { 7353 schedulePersistUriGrants(); 7354 } 7355 } 7356 } 7357 7358 @Override 7359 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7360 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7361 7362 Preconditions.checkFlagsArgument(modeFlags, 7363 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7364 7365 synchronized (this) { 7366 final int callingUid = Binder.getCallingUid(); 7367 boolean persistChanged = false; 7368 7369 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7370 new GrantUri(userId, uri, false)); 7371 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7372 new GrantUri(userId, uri, true)); 7373 if (exactPerm == null && prefixPerm == null) { 7374 throw new SecurityException("No permission grants found for UID " + callingUid 7375 + " and Uri " + uri.toSafeString()); 7376 } 7377 7378 if (exactPerm != null) { 7379 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7380 removeUriPermissionIfNeededLocked(exactPerm); 7381 } 7382 if (prefixPerm != null) { 7383 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7384 removeUriPermissionIfNeededLocked(prefixPerm); 7385 } 7386 7387 if (persistChanged) { 7388 schedulePersistUriGrants(); 7389 } 7390 } 7391 } 7392 7393 /** 7394 * Prune any older {@link UriPermission} for the given UID until outstanding 7395 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7396 * 7397 * @return if any mutations occured that require persisting. 7398 */ 7399 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7400 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7401 if (perms == null) return false; 7402 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7403 7404 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7405 for (UriPermission perm : perms.values()) { 7406 if (perm.persistedModeFlags != 0) { 7407 persisted.add(perm); 7408 } 7409 } 7410 7411 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7412 if (trimCount <= 0) return false; 7413 7414 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7415 for (int i = 0; i < trimCount; i++) { 7416 final UriPermission perm = persisted.get(i); 7417 7418 if (DEBUG_URI_PERMISSION) { 7419 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7420 } 7421 7422 perm.releasePersistableModes(~0); 7423 removeUriPermissionIfNeededLocked(perm); 7424 } 7425 7426 return true; 7427 } 7428 7429 @Override 7430 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7431 String packageName, boolean incoming) { 7432 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7433 Preconditions.checkNotNull(packageName, "packageName"); 7434 7435 final int callingUid = Binder.getCallingUid(); 7436 final IPackageManager pm = AppGlobals.getPackageManager(); 7437 try { 7438 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7439 if (packageUid != callingUid) { 7440 throw new SecurityException( 7441 "Package " + packageName + " does not belong to calling UID " + callingUid); 7442 } 7443 } catch (RemoteException e) { 7444 throw new SecurityException("Failed to verify package name ownership"); 7445 } 7446 7447 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7448 synchronized (this) { 7449 if (incoming) { 7450 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7451 callingUid); 7452 if (perms == null) { 7453 Slog.w(TAG, "No permission grants found for " + packageName); 7454 } else { 7455 for (UriPermission perm : perms.values()) { 7456 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7457 result.add(perm.buildPersistedPublicApiObject()); 7458 } 7459 } 7460 } 7461 } else { 7462 final int size = mGrantedUriPermissions.size(); 7463 for (int i = 0; i < size; i++) { 7464 final ArrayMap<GrantUri, UriPermission> perms = 7465 mGrantedUriPermissions.valueAt(i); 7466 for (UriPermission perm : perms.values()) { 7467 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7468 result.add(perm.buildPersistedPublicApiObject()); 7469 } 7470 } 7471 } 7472 } 7473 } 7474 return new ParceledListSlice<android.content.UriPermission>(result); 7475 } 7476 7477 @Override 7478 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7479 synchronized (this) { 7480 ProcessRecord app = 7481 who != null ? getRecordForAppLocked(who) : null; 7482 if (app == null) return; 7483 7484 Message msg = Message.obtain(); 7485 msg.what = WAIT_FOR_DEBUGGER_MSG; 7486 msg.obj = app; 7487 msg.arg1 = waiting ? 1 : 0; 7488 mHandler.sendMessage(msg); 7489 } 7490 } 7491 7492 @Override 7493 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7494 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7495 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7496 outInfo.availMem = Process.getFreeMemory(); 7497 outInfo.totalMem = Process.getTotalMemory(); 7498 outInfo.threshold = homeAppMem; 7499 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7500 outInfo.hiddenAppThreshold = cachedAppMem; 7501 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7502 ProcessList.SERVICE_ADJ); 7503 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7504 ProcessList.VISIBLE_APP_ADJ); 7505 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7506 ProcessList.FOREGROUND_APP_ADJ); 7507 } 7508 7509 // ========================================================= 7510 // TASK MANAGEMENT 7511 // ========================================================= 7512 7513 @Override 7514 public List<IAppTask> getAppTasks() { 7515 final PackageManager pm = mContext.getPackageManager(); 7516 int callingUid = Binder.getCallingUid(); 7517 long ident = Binder.clearCallingIdentity(); 7518 7519 // Compose the list of packages for this id to test against 7520 HashSet<String> packages = new HashSet<String>(); 7521 String[] uidPackages = pm.getPackagesForUid(callingUid); 7522 for (int i = 0; i < uidPackages.length; i++) { 7523 packages.add(uidPackages[i]); 7524 } 7525 7526 synchronized(this) { 7527 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7528 try { 7529 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7530 7531 final int N = mRecentTasks.size(); 7532 for (int i = 0; i < N; i++) { 7533 TaskRecord tr = mRecentTasks.get(i); 7534 // Skip tasks that do not match the package name 7535 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7536 ActivityManager.RecentTaskInfo taskInfo = 7537 createRecentTaskInfoFromTaskRecord(tr); 7538 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7539 list.add(taskImpl); 7540 } 7541 } 7542 } finally { 7543 Binder.restoreCallingIdentity(ident); 7544 } 7545 return list; 7546 } 7547 } 7548 7549 @Override 7550 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7551 final int callingUid = Binder.getCallingUid(); 7552 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7553 7554 synchronized(this) { 7555 if (localLOGV) Slog.v( 7556 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7557 7558 final boolean allowed = checkCallingPermission( 7559 android.Manifest.permission.GET_TASKS) 7560 == PackageManager.PERMISSION_GRANTED; 7561 if (!allowed) { 7562 Slog.w(TAG, "getTasks: caller " + callingUid 7563 + " does not hold GET_TASKS; limiting output"); 7564 } 7565 7566 // TODO: Improve with MRU list from all ActivityStacks. 7567 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7568 } 7569 7570 return list; 7571 } 7572 7573 TaskRecord getMostRecentTask() { 7574 return mRecentTasks.get(0); 7575 } 7576 7577 /** 7578 * Creates a new RecentTaskInfo from a TaskRecord. 7579 */ 7580 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7581 // Update the task description to reflect any changes in the task stack 7582 tr.updateTaskDescription(); 7583 7584 // Compose the recent task info 7585 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7586 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7587 rti.persistentId = tr.taskId; 7588 rti.baseIntent = new Intent(tr.getBaseIntent()); 7589 rti.origActivity = tr.origActivity; 7590 rti.description = tr.lastDescription; 7591 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7592 rti.userId = tr.userId; 7593 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7594 rti.firstActiveTime = tr.firstActiveTime; 7595 rti.lastActiveTime = tr.lastActiveTime; 7596 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7597 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 7598 return rti; 7599 } 7600 7601 @Override 7602 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7603 final int callingUid = Binder.getCallingUid(); 7604 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7605 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7606 7607 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7608 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7609 synchronized (this) { 7610 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7611 == PackageManager.PERMISSION_GRANTED; 7612 if (!allowed) { 7613 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7614 + " does not hold GET_TASKS; limiting output"); 7615 } 7616 final boolean detailed = checkCallingPermission( 7617 android.Manifest.permission.GET_DETAILED_TASKS) 7618 == PackageManager.PERMISSION_GRANTED; 7619 7620 IPackageManager pm = AppGlobals.getPackageManager(); 7621 7622 final int N = mRecentTasks.size(); 7623 ArrayList<ActivityManager.RecentTaskInfo> res 7624 = new ArrayList<ActivityManager.RecentTaskInfo>( 7625 maxNum < N ? maxNum : N); 7626 7627 final Set<Integer> includedUsers; 7628 if (includeProfiles) { 7629 includedUsers = getProfileIdsLocked(userId); 7630 } else { 7631 includedUsers = new HashSet<Integer>(); 7632 } 7633 includedUsers.add(Integer.valueOf(userId)); 7634 7635 // Regroup affiliated tasks together. 7636 for (int i = 0; i < N; ) { 7637 TaskRecord task = mRecentTasks.remove(i); 7638 if (mTmpRecents.contains(task)) { 7639 continue; 7640 } 7641 int affiliatedTaskId = task.mAffiliatedTaskId; 7642 while (true) { 7643 TaskRecord next = task.mNextAffiliate; 7644 if (next == null) { 7645 break; 7646 } 7647 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7648 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7649 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7650 task.setNextAffiliate(null); 7651 if (next.mPrevAffiliate == task) { 7652 next.setPrevAffiliate(null); 7653 } 7654 break; 7655 } 7656 if (next.mPrevAffiliate != task) { 7657 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7658 next.mPrevAffiliate + " task=" + task); 7659 next.setPrevAffiliate(null); 7660 break; 7661 } 7662 if (!mRecentTasks.contains(next)) { 7663 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7664 task.setNextAffiliate(null); 7665 if (next.mPrevAffiliate == task) { 7666 next.setPrevAffiliate(null); 7667 } 7668 break; 7669 } 7670 task = next; 7671 } 7672 // task is now the end of the list 7673 do { 7674 mRecentTasks.remove(task); 7675 mRecentTasks.add(i++, task); 7676 mTmpRecents.add(task); 7677 } while ((task = task.mPrevAffiliate) != null); 7678 } 7679 mTmpRecents.clear(); 7680 // mRecentTasks is now in sorted, affiliated order. 7681 7682 for (int i=0; i<N && maxNum > 0; i++) { 7683 TaskRecord tr = mRecentTasks.get(i); 7684 // Only add calling user or related users recent tasks 7685 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 7686 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 7687 continue; 7688 } 7689 7690 // Return the entry if desired by the caller. We always return 7691 // the first entry, because callers always expect this to be the 7692 // foreground app. We may filter others if the caller has 7693 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7694 // we should exclude the entry. 7695 7696 if (i == 0 7697 || withExcluded 7698 || (tr.intent == null) 7699 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7700 == 0)) { 7701 if (!allowed) { 7702 // If the caller doesn't have the GET_TASKS permission, then only 7703 // allow them to see a small subset of tasks -- their own and home. 7704 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7705 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 7706 continue; 7707 } 7708 } 7709 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 7710 if (tr.stack != null && tr.stack.isHomeStack()) { 7711 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 7712 continue; 7713 } 7714 } 7715 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7716 // Don't include auto remove tasks that are finished or finishing. 7717 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 7718 + tr); 7719 continue; 7720 } 7721 7722 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7723 if (!detailed) { 7724 rti.baseIntent.replaceExtras((Bundle)null); 7725 } 7726 7727 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7728 // Check whether this activity is currently available. 7729 try { 7730 if (rti.origActivity != null) { 7731 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7732 == null) { 7733 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: " 7734 + tr); 7735 continue; 7736 } 7737 } else if (rti.baseIntent != null) { 7738 if (pm.queryIntentActivities(rti.baseIntent, 7739 null, 0, userId) == null) { 7740 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: " 7741 + tr); 7742 continue; 7743 } 7744 } 7745 } catch (RemoteException e) { 7746 // Will never happen. 7747 } 7748 } 7749 7750 res.add(rti); 7751 maxNum--; 7752 } 7753 } 7754 return res; 7755 } 7756 } 7757 7758 private TaskRecord recentTaskForIdLocked(int id) { 7759 final int N = mRecentTasks.size(); 7760 for (int i=0; i<N; i++) { 7761 TaskRecord tr = mRecentTasks.get(i); 7762 if (tr.taskId == id) { 7763 return tr; 7764 } 7765 } 7766 return null; 7767 } 7768 7769 @Override 7770 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7771 synchronized (this) { 7772 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7773 "getTaskThumbnail()"); 7774 TaskRecord tr = recentTaskForIdLocked(id); 7775 if (tr != null) { 7776 return tr.getTaskThumbnailLocked(); 7777 } 7778 } 7779 return null; 7780 } 7781 7782 @Override 7783 public int addAppTask(IBinder activityToken, Intent intent, 7784 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 7785 final int callingUid = Binder.getCallingUid(); 7786 final long callingIdent = Binder.clearCallingIdentity(); 7787 7788 try { 7789 synchronized (this) { 7790 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 7791 if (r == null) { 7792 throw new IllegalArgumentException("Activity does not exist; token=" 7793 + activityToken); 7794 } 7795 ComponentName comp = intent.getComponent(); 7796 if (comp == null) { 7797 throw new IllegalArgumentException("Intent " + intent 7798 + " must specify explicit component"); 7799 } 7800 if (thumbnail.getWidth() != mThumbnailWidth 7801 || thumbnail.getHeight() != mThumbnailHeight) { 7802 throw new IllegalArgumentException("Bad thumbnail size: got " 7803 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 7804 + mThumbnailWidth + "x" + mThumbnailHeight); 7805 } 7806 if (intent.getSelector() != null) { 7807 intent.setSelector(null); 7808 } 7809 if (intent.getSourceBounds() != null) { 7810 intent.setSourceBounds(null); 7811 } 7812 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 7813 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 7814 // The caller has added this as an auto-remove task... that makes no 7815 // sense, so turn off auto-remove. 7816 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 7817 } 7818 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 7819 // Must be a new task. 7820 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7821 } 7822 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 7823 mLastAddedTaskActivity = null; 7824 } 7825 ActivityInfo ainfo = mLastAddedTaskActivity; 7826 if (ainfo == null) { 7827 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 7828 comp, 0, UserHandle.getUserId(callingUid)); 7829 if (ainfo.applicationInfo.uid != callingUid) { 7830 throw new SecurityException( 7831 "Can't add task for another application: target uid=" 7832 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 7833 } 7834 } 7835 7836 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 7837 intent, description); 7838 7839 int trimIdx = trimRecentsForTask(task, false); 7840 if (trimIdx >= 0) { 7841 // If this would have caused a trim, then we'll abort because that 7842 // means it would be added at the end of the list but then just removed. 7843 return -1; 7844 } 7845 7846 final int N = mRecentTasks.size(); 7847 if (N >= (MAX_RECENT_TASKS-1)) { 7848 final TaskRecord tr = mRecentTasks.remove(N - 1); 7849 tr.disposeThumbnail(); 7850 tr.closeRecentsChain(); 7851 } 7852 7853 mRecentTasks.add(task); 7854 r.task.stack.addTask(task, false, false); 7855 7856 task.setLastThumbnail(thumbnail); 7857 task.freeLastThumbnail(); 7858 7859 return task.taskId; 7860 } 7861 } finally { 7862 Binder.restoreCallingIdentity(callingIdent); 7863 } 7864 } 7865 7866 @Override 7867 public Point getAppTaskThumbnailSize() { 7868 synchronized (this) { 7869 return new Point(mThumbnailWidth, mThumbnailHeight); 7870 } 7871 } 7872 7873 @Override 7874 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7875 synchronized (this) { 7876 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7877 if (r != null) { 7878 r.taskDescription = td; 7879 r.task.updateTaskDescription(); 7880 } 7881 } 7882 } 7883 7884 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7885 if (!pr.killedByAm) { 7886 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7887 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7888 pr.processName, pr.setAdj, reason); 7889 pr.killedByAm = true; 7890 Process.killProcessQuiet(pr.pid); 7891 Process.killProcessGroup(pr.info.uid, pr.pid); 7892 } 7893 } 7894 7895 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7896 tr.disposeThumbnail(); 7897 mRecentTasks.remove(tr); 7898 tr.closeRecentsChain(); 7899 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7900 Intent baseIntent = new Intent( 7901 tr.intent != null ? tr.intent : tr.affinityIntent); 7902 ComponentName component = baseIntent.getComponent(); 7903 if (component == null) { 7904 Slog.w(TAG, "Now component for base intent of task: " + tr); 7905 return; 7906 } 7907 7908 // Find any running services associated with this app. 7909 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7910 7911 if (killProcesses) { 7912 // Find any running processes associated with this app. 7913 final String pkg = component.getPackageName(); 7914 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7915 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7916 for (int i=0; i<pmap.size(); i++) { 7917 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7918 for (int j=0; j<uids.size(); j++) { 7919 ProcessRecord proc = uids.valueAt(j); 7920 if (proc.userId != tr.userId) { 7921 continue; 7922 } 7923 if (!proc.pkgList.containsKey(pkg)) { 7924 continue; 7925 } 7926 procs.add(proc); 7927 } 7928 } 7929 7930 // Kill the running processes. 7931 for (int i=0; i<procs.size(); i++) { 7932 ProcessRecord pr = procs.get(i); 7933 if (pr == mHomeProcess) { 7934 // Don't kill the home process along with tasks from the same package. 7935 continue; 7936 } 7937 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7938 killUnneededProcessLocked(pr, "remove task"); 7939 } else { 7940 pr.waitingToKill = "remove task"; 7941 } 7942 } 7943 } 7944 } 7945 7946 /** 7947 * Removes the task with the specified task id. 7948 * 7949 * @param taskId Identifier of the task to be removed. 7950 * @param flags Additional operational flags. May be 0 or 7951 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7952 * @return Returns true if the given task was found and removed. 7953 */ 7954 private boolean removeTaskByIdLocked(int taskId, int flags) { 7955 TaskRecord tr = recentTaskForIdLocked(taskId); 7956 if (tr != null) { 7957 tr.removeTaskActivitiesLocked(); 7958 cleanUpRemovedTaskLocked(tr, flags); 7959 if (tr.isPersistable) { 7960 notifyTaskPersisterLocked(null, true); 7961 } 7962 return true; 7963 } 7964 return false; 7965 } 7966 7967 @Override 7968 public boolean removeTask(int taskId, int flags) { 7969 synchronized (this) { 7970 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7971 "removeTask()"); 7972 long ident = Binder.clearCallingIdentity(); 7973 try { 7974 return removeTaskByIdLocked(taskId, flags); 7975 } finally { 7976 Binder.restoreCallingIdentity(ident); 7977 } 7978 } 7979 } 7980 7981 /** 7982 * TODO: Add mController hook 7983 */ 7984 @Override 7985 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7986 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7987 "moveTaskToFront()"); 7988 7989 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7990 synchronized(this) { 7991 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7992 Binder.getCallingUid(), "Task to front")) { 7993 ActivityOptions.abort(options); 7994 return; 7995 } 7996 final long origId = Binder.clearCallingIdentity(); 7997 try { 7998 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7999 if (task == null) { 8000 return; 8001 } 8002 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8003 mStackSupervisor.showLockTaskToast(); 8004 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8005 return; 8006 } 8007 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8008 if (prev != null && prev.isRecentsActivity()) { 8009 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8010 } 8011 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8012 } finally { 8013 Binder.restoreCallingIdentity(origId); 8014 } 8015 ActivityOptions.abort(options); 8016 } 8017 } 8018 8019 @Override 8020 public void moveTaskToBack(int taskId) { 8021 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8022 "moveTaskToBack()"); 8023 8024 synchronized(this) { 8025 TaskRecord tr = recentTaskForIdLocked(taskId); 8026 if (tr != null) { 8027 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8028 ActivityStack stack = tr.stack; 8029 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8030 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8031 Binder.getCallingUid(), "Task to back")) { 8032 return; 8033 } 8034 } 8035 final long origId = Binder.clearCallingIdentity(); 8036 try { 8037 stack.moveTaskToBackLocked(taskId, null); 8038 } finally { 8039 Binder.restoreCallingIdentity(origId); 8040 } 8041 } 8042 } 8043 } 8044 8045 /** 8046 * Moves an activity, and all of the other activities within the same task, to the bottom 8047 * of the history stack. The activity's order within the task is unchanged. 8048 * 8049 * @param token A reference to the activity we wish to move 8050 * @param nonRoot If false then this only works if the activity is the root 8051 * of a task; if true it will work for any activity in a task. 8052 * @return Returns true if the move completed, false if not. 8053 */ 8054 @Override 8055 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8056 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8057 synchronized(this) { 8058 final long origId = Binder.clearCallingIdentity(); 8059 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8060 if (taskId >= 0) { 8061 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8062 } 8063 Binder.restoreCallingIdentity(origId); 8064 } 8065 return false; 8066 } 8067 8068 @Override 8069 public void moveTaskBackwards(int task) { 8070 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8071 "moveTaskBackwards()"); 8072 8073 synchronized(this) { 8074 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8075 Binder.getCallingUid(), "Task backwards")) { 8076 return; 8077 } 8078 final long origId = Binder.clearCallingIdentity(); 8079 moveTaskBackwardsLocked(task); 8080 Binder.restoreCallingIdentity(origId); 8081 } 8082 } 8083 8084 private final void moveTaskBackwardsLocked(int task) { 8085 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8086 } 8087 8088 @Override 8089 public IBinder getHomeActivityToken() throws RemoteException { 8090 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8091 "getHomeActivityToken()"); 8092 synchronized (this) { 8093 return mStackSupervisor.getHomeActivityToken(); 8094 } 8095 } 8096 8097 @Override 8098 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8099 IActivityContainerCallback callback) throws RemoteException { 8100 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8101 "createActivityContainer()"); 8102 synchronized (this) { 8103 if (parentActivityToken == null) { 8104 throw new IllegalArgumentException("parent token must not be null"); 8105 } 8106 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8107 if (r == null) { 8108 return null; 8109 } 8110 if (callback == null) { 8111 throw new IllegalArgumentException("callback must not be null"); 8112 } 8113 return mStackSupervisor.createActivityContainer(r, callback); 8114 } 8115 } 8116 8117 @Override 8118 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8119 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8120 "deleteActivityContainer()"); 8121 synchronized (this) { 8122 mStackSupervisor.deleteActivityContainer(container); 8123 } 8124 } 8125 8126 @Override 8127 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8128 throws RemoteException { 8129 synchronized (this) { 8130 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8131 if (stack != null) { 8132 return stack.mActivityContainer; 8133 } 8134 return null; 8135 } 8136 } 8137 8138 @Override 8139 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8140 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8141 "moveTaskToStack()"); 8142 if (stackId == HOME_STACK_ID) { 8143 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8144 new RuntimeException("here").fillInStackTrace()); 8145 } 8146 synchronized (this) { 8147 long ident = Binder.clearCallingIdentity(); 8148 try { 8149 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8150 + stackId + " toTop=" + toTop); 8151 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8152 } finally { 8153 Binder.restoreCallingIdentity(ident); 8154 } 8155 } 8156 } 8157 8158 @Override 8159 public void resizeStack(int stackBoxId, Rect bounds) { 8160 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8161 "resizeStackBox()"); 8162 long ident = Binder.clearCallingIdentity(); 8163 try { 8164 mWindowManager.resizeStack(stackBoxId, bounds); 8165 } finally { 8166 Binder.restoreCallingIdentity(ident); 8167 } 8168 } 8169 8170 @Override 8171 public List<StackInfo> getAllStackInfos() { 8172 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8173 "getAllStackInfos()"); 8174 long ident = Binder.clearCallingIdentity(); 8175 try { 8176 synchronized (this) { 8177 return mStackSupervisor.getAllStackInfosLocked(); 8178 } 8179 } finally { 8180 Binder.restoreCallingIdentity(ident); 8181 } 8182 } 8183 8184 @Override 8185 public StackInfo getStackInfo(int stackId) { 8186 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8187 "getStackInfo()"); 8188 long ident = Binder.clearCallingIdentity(); 8189 try { 8190 synchronized (this) { 8191 return mStackSupervisor.getStackInfoLocked(stackId); 8192 } 8193 } finally { 8194 Binder.restoreCallingIdentity(ident); 8195 } 8196 } 8197 8198 @Override 8199 public boolean isInHomeStack(int taskId) { 8200 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8201 "getStackInfo()"); 8202 long ident = Binder.clearCallingIdentity(); 8203 try { 8204 synchronized (this) { 8205 TaskRecord tr = recentTaskForIdLocked(taskId); 8206 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8207 } 8208 } finally { 8209 Binder.restoreCallingIdentity(ident); 8210 } 8211 } 8212 8213 @Override 8214 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8215 synchronized(this) { 8216 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8217 } 8218 } 8219 8220 private boolean isLockTaskAuthorized(String pkg) { 8221 final DevicePolicyManager dpm = (DevicePolicyManager) 8222 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8223 try { 8224 int uid = mContext.getPackageManager().getPackageUid(pkg, 8225 Binder.getCallingUserHandle().getIdentifier()); 8226 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8227 } catch (NameNotFoundException e) { 8228 return false; 8229 } 8230 } 8231 8232 void startLockTaskMode(TaskRecord task) { 8233 final String pkg; 8234 synchronized (this) { 8235 pkg = task.intent.getComponent().getPackageName(); 8236 } 8237 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8238 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8239 final TaskRecord taskRecord = task; 8240 mHandler.post(new Runnable() { 8241 @Override 8242 public void run() { 8243 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8244 } 8245 }); 8246 return; 8247 } 8248 long ident = Binder.clearCallingIdentity(); 8249 try { 8250 synchronized (this) { 8251 // Since we lost lock on task, make sure it is still there. 8252 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8253 if (task != null) { 8254 if (!isSystemInitiated 8255 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8256 throw new IllegalArgumentException("Invalid task, not in foreground"); 8257 } 8258 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8259 } 8260 } 8261 } finally { 8262 Binder.restoreCallingIdentity(ident); 8263 } 8264 } 8265 8266 @Override 8267 public void startLockTaskMode(int taskId) { 8268 final TaskRecord task; 8269 long ident = Binder.clearCallingIdentity(); 8270 try { 8271 synchronized (this) { 8272 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8273 } 8274 } finally { 8275 Binder.restoreCallingIdentity(ident); 8276 } 8277 if (task != null) { 8278 startLockTaskMode(task); 8279 } 8280 } 8281 8282 @Override 8283 public void startLockTaskMode(IBinder token) { 8284 final TaskRecord task; 8285 long ident = Binder.clearCallingIdentity(); 8286 try { 8287 synchronized (this) { 8288 final ActivityRecord r = ActivityRecord.forToken(token); 8289 if (r == null) { 8290 return; 8291 } 8292 task = r.task; 8293 } 8294 } finally { 8295 Binder.restoreCallingIdentity(ident); 8296 } 8297 if (task != null) { 8298 startLockTaskMode(task); 8299 } 8300 } 8301 8302 @Override 8303 public void startLockTaskModeOnCurrent() throws RemoteException { 8304 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8305 ActivityRecord r = null; 8306 synchronized (this) { 8307 r = mStackSupervisor.topRunningActivityLocked(); 8308 } 8309 startLockTaskMode(r.task); 8310 } 8311 8312 @Override 8313 public void stopLockTaskMode() { 8314 // Verify that the user matches the package of the intent for the TaskRecord 8315 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8316 // and stopLockTaskMode. 8317 final int callingUid = Binder.getCallingUid(); 8318 if (callingUid != Process.SYSTEM_UID) { 8319 try { 8320 String pkg = 8321 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8322 int uid = mContext.getPackageManager().getPackageUid(pkg, 8323 Binder.getCallingUserHandle().getIdentifier()); 8324 if (uid != callingUid) { 8325 throw new SecurityException("Invalid uid, expected " + uid); 8326 } 8327 } catch (NameNotFoundException e) { 8328 Log.d(TAG, "stopLockTaskMode " + e); 8329 return; 8330 } 8331 } 8332 long ident = Binder.clearCallingIdentity(); 8333 try { 8334 Log.d(TAG, "stopLockTaskMode"); 8335 // Stop lock task 8336 synchronized (this) { 8337 mStackSupervisor.setLockTaskModeLocked(null, false); 8338 } 8339 } finally { 8340 Binder.restoreCallingIdentity(ident); 8341 } 8342 } 8343 8344 @Override 8345 public void stopLockTaskModeOnCurrent() throws RemoteException { 8346 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8347 long ident = Binder.clearCallingIdentity(); 8348 try { 8349 stopLockTaskMode(); 8350 } finally { 8351 Binder.restoreCallingIdentity(ident); 8352 } 8353 } 8354 8355 @Override 8356 public boolean isInLockTaskMode() { 8357 synchronized (this) { 8358 return mStackSupervisor.isInLockTaskMode(); 8359 } 8360 } 8361 8362 // ========================================================= 8363 // CONTENT PROVIDERS 8364 // ========================================================= 8365 8366 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8367 List<ProviderInfo> providers = null; 8368 try { 8369 providers = AppGlobals.getPackageManager(). 8370 queryContentProviders(app.processName, app.uid, 8371 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8372 } catch (RemoteException ex) { 8373 } 8374 if (DEBUG_MU) 8375 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8376 int userId = app.userId; 8377 if (providers != null) { 8378 int N = providers.size(); 8379 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8380 for (int i=0; i<N; i++) { 8381 ProviderInfo cpi = 8382 (ProviderInfo)providers.get(i); 8383 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8384 cpi.name, cpi.flags); 8385 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8386 // This is a singleton provider, but a user besides the 8387 // default user is asking to initialize a process it runs 8388 // in... well, no, it doesn't actually run in this process, 8389 // it runs in the process of the default user. Get rid of it. 8390 providers.remove(i); 8391 N--; 8392 i--; 8393 continue; 8394 } 8395 8396 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8397 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8398 if (cpr == null) { 8399 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8400 mProviderMap.putProviderByClass(comp, cpr); 8401 } 8402 if (DEBUG_MU) 8403 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8404 app.pubProviders.put(cpi.name, cpr); 8405 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8406 // Don't add this if it is a platform component that is marked 8407 // to run in multiple processes, because this is actually 8408 // part of the framework so doesn't make sense to track as a 8409 // separate apk in the process. 8410 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8411 mProcessStats); 8412 } 8413 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8414 } 8415 } 8416 return providers; 8417 } 8418 8419 /** 8420 * Check if {@link ProcessRecord} has a possible chance at accessing the 8421 * given {@link ProviderInfo}. Final permission checking is always done 8422 * in {@link ContentProvider}. 8423 */ 8424 private final String checkContentProviderPermissionLocked( 8425 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8426 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8427 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8428 boolean checkedGrants = false; 8429 if (checkUser) { 8430 // Looking for cross-user grants before enforcing the typical cross-users permissions 8431 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8432 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8433 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8434 return null; 8435 } 8436 checkedGrants = true; 8437 } 8438 userId = handleIncomingUser(callingPid, callingUid, userId, 8439 false, ALLOW_NON_FULL, 8440 "checkContentProviderPermissionLocked " + cpi.authority, null); 8441 if (userId != tmpTargetUserId) { 8442 // When we actually went to determine the final targer user ID, this ended 8443 // up different than our initial check for the authority. This is because 8444 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8445 // SELF. So we need to re-check the grants again. 8446 checkedGrants = false; 8447 } 8448 } 8449 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8450 cpi.applicationInfo.uid, cpi.exported) 8451 == PackageManager.PERMISSION_GRANTED) { 8452 return null; 8453 } 8454 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8455 cpi.applicationInfo.uid, cpi.exported) 8456 == PackageManager.PERMISSION_GRANTED) { 8457 return null; 8458 } 8459 8460 PathPermission[] pps = cpi.pathPermissions; 8461 if (pps != null) { 8462 int i = pps.length; 8463 while (i > 0) { 8464 i--; 8465 PathPermission pp = pps[i]; 8466 String pprperm = pp.getReadPermission(); 8467 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8468 cpi.applicationInfo.uid, cpi.exported) 8469 == PackageManager.PERMISSION_GRANTED) { 8470 return null; 8471 } 8472 String ppwperm = pp.getWritePermission(); 8473 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8474 cpi.applicationInfo.uid, cpi.exported) 8475 == PackageManager.PERMISSION_GRANTED) { 8476 return null; 8477 } 8478 } 8479 } 8480 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8481 return null; 8482 } 8483 8484 String msg; 8485 if (!cpi.exported) { 8486 msg = "Permission Denial: opening provider " + cpi.name 8487 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8488 + ", uid=" + callingUid + ") that is not exported from uid " 8489 + cpi.applicationInfo.uid; 8490 } else { 8491 msg = "Permission Denial: opening provider " + cpi.name 8492 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8493 + ", uid=" + callingUid + ") requires " 8494 + cpi.readPermission + " or " + cpi.writePermission; 8495 } 8496 Slog.w(TAG, msg); 8497 return msg; 8498 } 8499 8500 /** 8501 * Returns if the ContentProvider has granted a uri to callingUid 8502 */ 8503 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8504 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8505 if (perms != null) { 8506 for (int i=perms.size()-1; i>=0; i--) { 8507 GrantUri grantUri = perms.keyAt(i); 8508 if (grantUri.sourceUserId == userId || !checkUser) { 8509 if (matchesProvider(grantUri.uri, cpi)) { 8510 return true; 8511 } 8512 } 8513 } 8514 } 8515 return false; 8516 } 8517 8518 /** 8519 * Returns true if the uri authority is one of the authorities specified in the provider. 8520 */ 8521 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8522 String uriAuth = uri.getAuthority(); 8523 String cpiAuth = cpi.authority; 8524 if (cpiAuth.indexOf(';') == -1) { 8525 return cpiAuth.equals(uriAuth); 8526 } 8527 String[] cpiAuths = cpiAuth.split(";"); 8528 int length = cpiAuths.length; 8529 for (int i = 0; i < length; i++) { 8530 if (cpiAuths[i].equals(uriAuth)) return true; 8531 } 8532 return false; 8533 } 8534 8535 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8536 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8537 if (r != null) { 8538 for (int i=0; i<r.conProviders.size(); i++) { 8539 ContentProviderConnection conn = r.conProviders.get(i); 8540 if (conn.provider == cpr) { 8541 if (DEBUG_PROVIDER) Slog.v(TAG, 8542 "Adding provider requested by " 8543 + r.processName + " from process " 8544 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8545 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8546 if (stable) { 8547 conn.stableCount++; 8548 conn.numStableIncs++; 8549 } else { 8550 conn.unstableCount++; 8551 conn.numUnstableIncs++; 8552 } 8553 return conn; 8554 } 8555 } 8556 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8557 if (stable) { 8558 conn.stableCount = 1; 8559 conn.numStableIncs = 1; 8560 } else { 8561 conn.unstableCount = 1; 8562 conn.numUnstableIncs = 1; 8563 } 8564 cpr.connections.add(conn); 8565 r.conProviders.add(conn); 8566 return conn; 8567 } 8568 cpr.addExternalProcessHandleLocked(externalProcessToken); 8569 return null; 8570 } 8571 8572 boolean decProviderCountLocked(ContentProviderConnection conn, 8573 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8574 if (conn != null) { 8575 cpr = conn.provider; 8576 if (DEBUG_PROVIDER) Slog.v(TAG, 8577 "Removing provider requested by " 8578 + conn.client.processName + " from process " 8579 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8580 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8581 if (stable) { 8582 conn.stableCount--; 8583 } else { 8584 conn.unstableCount--; 8585 } 8586 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8587 cpr.connections.remove(conn); 8588 conn.client.conProviders.remove(conn); 8589 return true; 8590 } 8591 return false; 8592 } 8593 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8594 return false; 8595 } 8596 8597 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8598 String name, IBinder token, boolean stable, int userId) { 8599 ContentProviderRecord cpr; 8600 ContentProviderConnection conn = null; 8601 ProviderInfo cpi = null; 8602 8603 synchronized(this) { 8604 ProcessRecord r = null; 8605 if (caller != null) { 8606 r = getRecordForAppLocked(caller); 8607 if (r == null) { 8608 throw new SecurityException( 8609 "Unable to find app for caller " + caller 8610 + " (pid=" + Binder.getCallingPid() 8611 + ") when getting content provider " + name); 8612 } 8613 } 8614 8615 boolean checkCrossUser = true; 8616 8617 // First check if this content provider has been published... 8618 cpr = mProviderMap.getProviderByName(name, userId); 8619 // If that didn't work, check if it exists for user 0 and then 8620 // verify that it's a singleton provider before using it. 8621 if (cpr == null && userId != UserHandle.USER_OWNER) { 8622 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8623 if (cpr != null) { 8624 cpi = cpr.info; 8625 if (isSingleton(cpi.processName, cpi.applicationInfo, 8626 cpi.name, cpi.flags) 8627 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8628 userId = UserHandle.USER_OWNER; 8629 checkCrossUser = false; 8630 } else { 8631 cpr = null; 8632 cpi = null; 8633 } 8634 } 8635 } 8636 8637 boolean providerRunning = cpr != null; 8638 if (providerRunning) { 8639 cpi = cpr.info; 8640 String msg; 8641 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8642 != null) { 8643 throw new SecurityException(msg); 8644 } 8645 8646 if (r != null && cpr.canRunHere(r)) { 8647 // This provider has been published or is in the process 8648 // of being published... but it is also allowed to run 8649 // in the caller's process, so don't make a connection 8650 // and just let the caller instantiate its own instance. 8651 ContentProviderHolder holder = cpr.newHolder(null); 8652 // don't give caller the provider object, it needs 8653 // to make its own. 8654 holder.provider = null; 8655 return holder; 8656 } 8657 8658 final long origId = Binder.clearCallingIdentity(); 8659 8660 // In this case the provider instance already exists, so we can 8661 // return it right away. 8662 conn = incProviderCountLocked(r, cpr, token, stable); 8663 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8664 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8665 // If this is a perceptible app accessing the provider, 8666 // make sure to count it as being accessed and thus 8667 // back up on the LRU list. This is good because 8668 // content providers are often expensive to start. 8669 updateLruProcessLocked(cpr.proc, false, null); 8670 } 8671 } 8672 8673 if (cpr.proc != null) { 8674 if (false) { 8675 if (cpr.name.flattenToShortString().equals( 8676 "com.android.providers.calendar/.CalendarProvider2")) { 8677 Slog.v(TAG, "****************** KILLING " 8678 + cpr.name.flattenToShortString()); 8679 Process.killProcess(cpr.proc.pid); 8680 } 8681 } 8682 boolean success = updateOomAdjLocked(cpr.proc); 8683 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8684 // NOTE: there is still a race here where a signal could be 8685 // pending on the process even though we managed to update its 8686 // adj level. Not sure what to do about this, but at least 8687 // the race is now smaller. 8688 if (!success) { 8689 // Uh oh... it looks like the provider's process 8690 // has been killed on us. We need to wait for a new 8691 // process to be started, and make sure its death 8692 // doesn't kill our process. 8693 Slog.i(TAG, 8694 "Existing provider " + cpr.name.flattenToShortString() 8695 + " is crashing; detaching " + r); 8696 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8697 appDiedLocked(cpr.proc); 8698 if (!lastRef) { 8699 // This wasn't the last ref our process had on 8700 // the provider... we have now been killed, bail. 8701 return null; 8702 } 8703 providerRunning = false; 8704 conn = null; 8705 } 8706 } 8707 8708 Binder.restoreCallingIdentity(origId); 8709 } 8710 8711 boolean singleton; 8712 if (!providerRunning) { 8713 try { 8714 cpi = AppGlobals.getPackageManager(). 8715 resolveContentProvider(name, 8716 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8717 } catch (RemoteException ex) { 8718 } 8719 if (cpi == null) { 8720 return null; 8721 } 8722 // If the provider is a singleton AND 8723 // (it's a call within the same user || the provider is a 8724 // privileged app) 8725 // Then allow connecting to the singleton provider 8726 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8727 cpi.name, cpi.flags) 8728 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8729 if (singleton) { 8730 userId = UserHandle.USER_OWNER; 8731 } 8732 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8733 8734 String msg; 8735 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8736 != null) { 8737 throw new SecurityException(msg); 8738 } 8739 8740 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8741 && !cpi.processName.equals("system")) { 8742 // If this content provider does not run in the system 8743 // process, and the system is not yet ready to run other 8744 // processes, then fail fast instead of hanging. 8745 throw new IllegalArgumentException( 8746 "Attempt to launch content provider before system ready"); 8747 } 8748 8749 // Make sure that the user who owns this provider is started. If not, 8750 // we don't want to allow it to run. 8751 if (mStartedUsers.get(userId) == null) { 8752 Slog.w(TAG, "Unable to launch app " 8753 + cpi.applicationInfo.packageName + "/" 8754 + cpi.applicationInfo.uid + " for provider " 8755 + name + ": user " + userId + " is stopped"); 8756 return null; 8757 } 8758 8759 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8760 cpr = mProviderMap.getProviderByClass(comp, userId); 8761 final boolean firstClass = cpr == null; 8762 if (firstClass) { 8763 try { 8764 ApplicationInfo ai = 8765 AppGlobals.getPackageManager(). 8766 getApplicationInfo( 8767 cpi.applicationInfo.packageName, 8768 STOCK_PM_FLAGS, userId); 8769 if (ai == null) { 8770 Slog.w(TAG, "No package info for content provider " 8771 + cpi.name); 8772 return null; 8773 } 8774 ai = getAppInfoForUser(ai, userId); 8775 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8776 } catch (RemoteException ex) { 8777 // pm is in same process, this will never happen. 8778 } 8779 } 8780 8781 if (r != null && cpr.canRunHere(r)) { 8782 // If this is a multiprocess provider, then just return its 8783 // info and allow the caller to instantiate it. Only do 8784 // this if the provider is the same user as the caller's 8785 // process, or can run as root (so can be in any process). 8786 return cpr.newHolder(null); 8787 } 8788 8789 if (DEBUG_PROVIDER) { 8790 RuntimeException e = new RuntimeException("here"); 8791 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8792 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8793 } 8794 8795 // This is single process, and our app is now connecting to it. 8796 // See if we are already in the process of launching this 8797 // provider. 8798 final int N = mLaunchingProviders.size(); 8799 int i; 8800 for (i=0; i<N; i++) { 8801 if (mLaunchingProviders.get(i) == cpr) { 8802 break; 8803 } 8804 } 8805 8806 // If the provider is not already being launched, then get it 8807 // started. 8808 if (i >= N) { 8809 final long origId = Binder.clearCallingIdentity(); 8810 8811 try { 8812 // Content provider is now in use, its package can't be stopped. 8813 try { 8814 AppGlobals.getPackageManager().setPackageStoppedState( 8815 cpr.appInfo.packageName, false, userId); 8816 } catch (RemoteException e) { 8817 } catch (IllegalArgumentException e) { 8818 Slog.w(TAG, "Failed trying to unstop package " 8819 + cpr.appInfo.packageName + ": " + e); 8820 } 8821 8822 // Use existing process if already started 8823 ProcessRecord proc = getProcessRecordLocked( 8824 cpi.processName, cpr.appInfo.uid, false); 8825 if (proc != null && proc.thread != null) { 8826 if (DEBUG_PROVIDER) { 8827 Slog.d(TAG, "Installing in existing process " + proc); 8828 } 8829 proc.pubProviders.put(cpi.name, cpr); 8830 try { 8831 proc.thread.scheduleInstallProvider(cpi); 8832 } catch (RemoteException e) { 8833 } 8834 } else { 8835 proc = startProcessLocked(cpi.processName, 8836 cpr.appInfo, false, 0, "content provider", 8837 new ComponentName(cpi.applicationInfo.packageName, 8838 cpi.name), false, false, false); 8839 if (proc == null) { 8840 Slog.w(TAG, "Unable to launch app " 8841 + cpi.applicationInfo.packageName + "/" 8842 + cpi.applicationInfo.uid + " for provider " 8843 + name + ": process is bad"); 8844 return null; 8845 } 8846 } 8847 cpr.launchingApp = proc; 8848 mLaunchingProviders.add(cpr); 8849 } finally { 8850 Binder.restoreCallingIdentity(origId); 8851 } 8852 } 8853 8854 // Make sure the provider is published (the same provider class 8855 // may be published under multiple names). 8856 if (firstClass) { 8857 mProviderMap.putProviderByClass(comp, cpr); 8858 } 8859 8860 mProviderMap.putProviderByName(name, cpr); 8861 conn = incProviderCountLocked(r, cpr, token, stable); 8862 if (conn != null) { 8863 conn.waiting = true; 8864 } 8865 } 8866 } 8867 8868 // Wait for the provider to be published... 8869 synchronized (cpr) { 8870 while (cpr.provider == null) { 8871 if (cpr.launchingApp == null) { 8872 Slog.w(TAG, "Unable to launch app " 8873 + cpi.applicationInfo.packageName + "/" 8874 + cpi.applicationInfo.uid + " for provider " 8875 + name + ": launching app became null"); 8876 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8877 UserHandle.getUserId(cpi.applicationInfo.uid), 8878 cpi.applicationInfo.packageName, 8879 cpi.applicationInfo.uid, name); 8880 return null; 8881 } 8882 try { 8883 if (DEBUG_MU) { 8884 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8885 + cpr.launchingApp); 8886 } 8887 if (conn != null) { 8888 conn.waiting = true; 8889 } 8890 cpr.wait(); 8891 } catch (InterruptedException ex) { 8892 } finally { 8893 if (conn != null) { 8894 conn.waiting = false; 8895 } 8896 } 8897 } 8898 } 8899 return cpr != null ? cpr.newHolder(conn) : null; 8900 } 8901 8902 @Override 8903 public final ContentProviderHolder getContentProvider( 8904 IApplicationThread caller, String name, int userId, boolean stable) { 8905 enforceNotIsolatedCaller("getContentProvider"); 8906 if (caller == null) { 8907 String msg = "null IApplicationThread when getting content provider " 8908 + name; 8909 Slog.w(TAG, msg); 8910 throw new SecurityException(msg); 8911 } 8912 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8913 // with cross-user grant. 8914 return getContentProviderImpl(caller, name, null, stable, userId); 8915 } 8916 8917 public ContentProviderHolder getContentProviderExternal( 8918 String name, int userId, IBinder token) { 8919 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8920 "Do not have permission in call getContentProviderExternal()"); 8921 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8922 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8923 return getContentProviderExternalUnchecked(name, token, userId); 8924 } 8925 8926 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8927 IBinder token, int userId) { 8928 return getContentProviderImpl(null, name, token, true, userId); 8929 } 8930 8931 /** 8932 * Drop a content provider from a ProcessRecord's bookkeeping 8933 */ 8934 public void removeContentProvider(IBinder connection, boolean stable) { 8935 enforceNotIsolatedCaller("removeContentProvider"); 8936 long ident = Binder.clearCallingIdentity(); 8937 try { 8938 synchronized (this) { 8939 ContentProviderConnection conn; 8940 try { 8941 conn = (ContentProviderConnection)connection; 8942 } catch (ClassCastException e) { 8943 String msg ="removeContentProvider: " + connection 8944 + " not a ContentProviderConnection"; 8945 Slog.w(TAG, msg); 8946 throw new IllegalArgumentException(msg); 8947 } 8948 if (conn == null) { 8949 throw new NullPointerException("connection is null"); 8950 } 8951 if (decProviderCountLocked(conn, null, null, stable)) { 8952 updateOomAdjLocked(); 8953 } 8954 } 8955 } finally { 8956 Binder.restoreCallingIdentity(ident); 8957 } 8958 } 8959 8960 public void removeContentProviderExternal(String name, IBinder token) { 8961 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8962 "Do not have permission in call removeContentProviderExternal()"); 8963 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8964 } 8965 8966 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8967 synchronized (this) { 8968 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8969 if(cpr == null) { 8970 //remove from mProvidersByClass 8971 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8972 return; 8973 } 8974 8975 //update content provider record entry info 8976 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8977 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8978 if (localCpr.hasExternalProcessHandles()) { 8979 if (localCpr.removeExternalProcessHandleLocked(token)) { 8980 updateOomAdjLocked(); 8981 } else { 8982 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8983 + " with no external reference for token: " 8984 + token + "."); 8985 } 8986 } else { 8987 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8988 + " with no external references."); 8989 } 8990 } 8991 } 8992 8993 public final void publishContentProviders(IApplicationThread caller, 8994 List<ContentProviderHolder> providers) { 8995 if (providers == null) { 8996 return; 8997 } 8998 8999 enforceNotIsolatedCaller("publishContentProviders"); 9000 synchronized (this) { 9001 final ProcessRecord r = getRecordForAppLocked(caller); 9002 if (DEBUG_MU) 9003 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9004 if (r == null) { 9005 throw new SecurityException( 9006 "Unable to find app for caller " + caller 9007 + " (pid=" + Binder.getCallingPid() 9008 + ") when publishing content providers"); 9009 } 9010 9011 final long origId = Binder.clearCallingIdentity(); 9012 9013 final int N = providers.size(); 9014 for (int i=0; i<N; i++) { 9015 ContentProviderHolder src = providers.get(i); 9016 if (src == null || src.info == null || src.provider == null) { 9017 continue; 9018 } 9019 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9020 if (DEBUG_MU) 9021 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9022 if (dst != null) { 9023 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9024 mProviderMap.putProviderByClass(comp, dst); 9025 String names[] = dst.info.authority.split(";"); 9026 for (int j = 0; j < names.length; j++) { 9027 mProviderMap.putProviderByName(names[j], dst); 9028 } 9029 9030 int NL = mLaunchingProviders.size(); 9031 int j; 9032 for (j=0; j<NL; j++) { 9033 if (mLaunchingProviders.get(j) == dst) { 9034 mLaunchingProviders.remove(j); 9035 j--; 9036 NL--; 9037 } 9038 } 9039 synchronized (dst) { 9040 dst.provider = src.provider; 9041 dst.proc = r; 9042 dst.notifyAll(); 9043 } 9044 updateOomAdjLocked(r); 9045 } 9046 } 9047 9048 Binder.restoreCallingIdentity(origId); 9049 } 9050 } 9051 9052 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9053 ContentProviderConnection conn; 9054 try { 9055 conn = (ContentProviderConnection)connection; 9056 } catch (ClassCastException e) { 9057 String msg ="refContentProvider: " + connection 9058 + " not a ContentProviderConnection"; 9059 Slog.w(TAG, msg); 9060 throw new IllegalArgumentException(msg); 9061 } 9062 if (conn == null) { 9063 throw new NullPointerException("connection is null"); 9064 } 9065 9066 synchronized (this) { 9067 if (stable > 0) { 9068 conn.numStableIncs += stable; 9069 } 9070 stable = conn.stableCount + stable; 9071 if (stable < 0) { 9072 throw new IllegalStateException("stableCount < 0: " + stable); 9073 } 9074 9075 if (unstable > 0) { 9076 conn.numUnstableIncs += unstable; 9077 } 9078 unstable = conn.unstableCount + unstable; 9079 if (unstable < 0) { 9080 throw new IllegalStateException("unstableCount < 0: " + unstable); 9081 } 9082 9083 if ((stable+unstable) <= 0) { 9084 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9085 + stable + " unstable=" + unstable); 9086 } 9087 conn.stableCount = stable; 9088 conn.unstableCount = unstable; 9089 return !conn.dead; 9090 } 9091 } 9092 9093 public void unstableProviderDied(IBinder connection) { 9094 ContentProviderConnection conn; 9095 try { 9096 conn = (ContentProviderConnection)connection; 9097 } catch (ClassCastException e) { 9098 String msg ="refContentProvider: " + connection 9099 + " not a ContentProviderConnection"; 9100 Slog.w(TAG, msg); 9101 throw new IllegalArgumentException(msg); 9102 } 9103 if (conn == null) { 9104 throw new NullPointerException("connection is null"); 9105 } 9106 9107 // Safely retrieve the content provider associated with the connection. 9108 IContentProvider provider; 9109 synchronized (this) { 9110 provider = conn.provider.provider; 9111 } 9112 9113 if (provider == null) { 9114 // Um, yeah, we're way ahead of you. 9115 return; 9116 } 9117 9118 // Make sure the caller is being honest with us. 9119 if (provider.asBinder().pingBinder()) { 9120 // Er, no, still looks good to us. 9121 synchronized (this) { 9122 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9123 + " says " + conn + " died, but we don't agree"); 9124 return; 9125 } 9126 } 9127 9128 // Well look at that! It's dead! 9129 synchronized (this) { 9130 if (conn.provider.provider != provider) { 9131 // But something changed... good enough. 9132 return; 9133 } 9134 9135 ProcessRecord proc = conn.provider.proc; 9136 if (proc == null || proc.thread == null) { 9137 // Seems like the process is already cleaned up. 9138 return; 9139 } 9140 9141 // As far as we're concerned, this is just like receiving a 9142 // death notification... just a bit prematurely. 9143 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9144 + ") early provider death"); 9145 final long ident = Binder.clearCallingIdentity(); 9146 try { 9147 appDiedLocked(proc); 9148 } finally { 9149 Binder.restoreCallingIdentity(ident); 9150 } 9151 } 9152 } 9153 9154 @Override 9155 public void appNotRespondingViaProvider(IBinder connection) { 9156 enforceCallingPermission( 9157 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9158 9159 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9160 if (conn == null) { 9161 Slog.w(TAG, "ContentProviderConnection is null"); 9162 return; 9163 } 9164 9165 final ProcessRecord host = conn.provider.proc; 9166 if (host == null) { 9167 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9168 return; 9169 } 9170 9171 final long token = Binder.clearCallingIdentity(); 9172 try { 9173 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9174 } finally { 9175 Binder.restoreCallingIdentity(token); 9176 } 9177 } 9178 9179 public final void installSystemProviders() { 9180 List<ProviderInfo> providers; 9181 synchronized (this) { 9182 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9183 providers = generateApplicationProvidersLocked(app); 9184 if (providers != null) { 9185 for (int i=providers.size()-1; i>=0; i--) { 9186 ProviderInfo pi = (ProviderInfo)providers.get(i); 9187 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9188 Slog.w(TAG, "Not installing system proc provider " + pi.name 9189 + ": not system .apk"); 9190 providers.remove(i); 9191 } 9192 } 9193 } 9194 } 9195 if (providers != null) { 9196 mSystemThread.installSystemProviders(providers); 9197 } 9198 9199 mCoreSettingsObserver = new CoreSettingsObserver(this); 9200 9201 //mUsageStatsService.monitorPackages(); 9202 } 9203 9204 /** 9205 * Allows apps to retrieve the MIME type of a URI. 9206 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9207 * users, then it does not need permission to access the ContentProvider. 9208 * Either, it needs cross-user uri grants. 9209 * 9210 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9211 * 9212 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9213 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9214 */ 9215 public String getProviderMimeType(Uri uri, int userId) { 9216 enforceNotIsolatedCaller("getProviderMimeType"); 9217 final String name = uri.getAuthority(); 9218 int callingUid = Binder.getCallingUid(); 9219 int callingPid = Binder.getCallingPid(); 9220 long ident = 0; 9221 boolean clearedIdentity = false; 9222 userId = unsafeConvertIncomingUser(userId); 9223 if (UserHandle.getUserId(callingUid) != userId) { 9224 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9225 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9226 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9227 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9228 clearedIdentity = true; 9229 ident = Binder.clearCallingIdentity(); 9230 } 9231 } 9232 ContentProviderHolder holder = null; 9233 try { 9234 holder = getContentProviderExternalUnchecked(name, null, userId); 9235 if (holder != null) { 9236 return holder.provider.getType(uri); 9237 } 9238 } catch (RemoteException e) { 9239 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9240 return null; 9241 } finally { 9242 // We need to clear the identity to call removeContentProviderExternalUnchecked 9243 if (!clearedIdentity) { 9244 ident = Binder.clearCallingIdentity(); 9245 } 9246 try { 9247 if (holder != null) { 9248 removeContentProviderExternalUnchecked(name, null, userId); 9249 } 9250 } finally { 9251 Binder.restoreCallingIdentity(ident); 9252 } 9253 } 9254 9255 return null; 9256 } 9257 9258 // ========================================================= 9259 // GLOBAL MANAGEMENT 9260 // ========================================================= 9261 9262 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9263 boolean isolated, int isolatedUid) { 9264 String proc = customProcess != null ? customProcess : info.processName; 9265 BatteryStatsImpl.Uid.Proc ps = null; 9266 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9267 int uid = info.uid; 9268 if (isolated) { 9269 if (isolatedUid == 0) { 9270 int userId = UserHandle.getUserId(uid); 9271 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9272 while (true) { 9273 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9274 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9275 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9276 } 9277 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9278 mNextIsolatedProcessUid++; 9279 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9280 // No process for this uid, use it. 9281 break; 9282 } 9283 stepsLeft--; 9284 if (stepsLeft <= 0) { 9285 return null; 9286 } 9287 } 9288 } else { 9289 // Special case for startIsolatedProcess (internal only), where 9290 // the uid of the isolated process is specified by the caller. 9291 uid = isolatedUid; 9292 } 9293 } 9294 return new ProcessRecord(stats, info, proc, uid); 9295 } 9296 9297 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9298 String abiOverride) { 9299 ProcessRecord app; 9300 if (!isolated) { 9301 app = getProcessRecordLocked(info.processName, info.uid, true); 9302 } else { 9303 app = null; 9304 } 9305 9306 if (app == null) { 9307 app = newProcessRecordLocked(info, null, isolated, 0); 9308 mProcessNames.put(info.processName, app.uid, app); 9309 if (isolated) { 9310 mIsolatedProcesses.put(app.uid, app); 9311 } 9312 updateLruProcessLocked(app, false, null); 9313 updateOomAdjLocked(); 9314 } 9315 9316 // This package really, really can not be stopped. 9317 try { 9318 AppGlobals.getPackageManager().setPackageStoppedState( 9319 info.packageName, false, UserHandle.getUserId(app.uid)); 9320 } catch (RemoteException e) { 9321 } catch (IllegalArgumentException e) { 9322 Slog.w(TAG, "Failed trying to unstop package " 9323 + info.packageName + ": " + e); 9324 } 9325 9326 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9327 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9328 app.persistent = true; 9329 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9330 } 9331 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9332 mPersistentStartingProcesses.add(app); 9333 startProcessLocked(app, "added application", app.processName, abiOverride, 9334 null /* entryPoint */, null /* entryPointArgs */); 9335 } 9336 9337 return app; 9338 } 9339 9340 public void unhandledBack() { 9341 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9342 "unhandledBack()"); 9343 9344 synchronized(this) { 9345 final long origId = Binder.clearCallingIdentity(); 9346 try { 9347 getFocusedStack().unhandledBackLocked(); 9348 } finally { 9349 Binder.restoreCallingIdentity(origId); 9350 } 9351 } 9352 } 9353 9354 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9355 enforceNotIsolatedCaller("openContentUri"); 9356 final int userId = UserHandle.getCallingUserId(); 9357 String name = uri.getAuthority(); 9358 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9359 ParcelFileDescriptor pfd = null; 9360 if (cph != null) { 9361 // We record the binder invoker's uid in thread-local storage before 9362 // going to the content provider to open the file. Later, in the code 9363 // that handles all permissions checks, we look for this uid and use 9364 // that rather than the Activity Manager's own uid. The effect is that 9365 // we do the check against the caller's permissions even though it looks 9366 // to the content provider like the Activity Manager itself is making 9367 // the request. 9368 sCallerIdentity.set(new Identity( 9369 Binder.getCallingPid(), Binder.getCallingUid())); 9370 try { 9371 pfd = cph.provider.openFile(null, uri, "r", null); 9372 } catch (FileNotFoundException e) { 9373 // do nothing; pfd will be returned null 9374 } finally { 9375 // Ensure that whatever happens, we clean up the identity state 9376 sCallerIdentity.remove(); 9377 } 9378 9379 // We've got the fd now, so we're done with the provider. 9380 removeContentProviderExternalUnchecked(name, null, userId); 9381 } else { 9382 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9383 } 9384 return pfd; 9385 } 9386 9387 // Actually is sleeping or shutting down or whatever else in the future 9388 // is an inactive state. 9389 public boolean isSleepingOrShuttingDown() { 9390 return mSleeping || mShuttingDown; 9391 } 9392 9393 public boolean isSleeping() { 9394 return mSleeping; 9395 } 9396 9397 void goingToSleep() { 9398 synchronized(this) { 9399 mWentToSleep = true; 9400 updateEventDispatchingLocked(); 9401 goToSleepIfNeededLocked(); 9402 } 9403 } 9404 9405 void finishRunningVoiceLocked() { 9406 if (mRunningVoice) { 9407 mRunningVoice = false; 9408 goToSleepIfNeededLocked(); 9409 } 9410 } 9411 9412 void goToSleepIfNeededLocked() { 9413 if (mWentToSleep && !mRunningVoice) { 9414 if (!mSleeping) { 9415 mSleeping = true; 9416 mStackSupervisor.goingToSleepLocked(); 9417 9418 // Initialize the wake times of all processes. 9419 checkExcessivePowerUsageLocked(false); 9420 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9421 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9422 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9423 } 9424 } 9425 } 9426 9427 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9428 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9429 // Never persist the home stack. 9430 return; 9431 } 9432 mTaskPersister.wakeup(task, flush); 9433 } 9434 9435 @Override 9436 public boolean shutdown(int timeout) { 9437 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9438 != PackageManager.PERMISSION_GRANTED) { 9439 throw new SecurityException("Requires permission " 9440 + android.Manifest.permission.SHUTDOWN); 9441 } 9442 9443 boolean timedout = false; 9444 9445 synchronized(this) { 9446 mShuttingDown = true; 9447 updateEventDispatchingLocked(); 9448 timedout = mStackSupervisor.shutdownLocked(timeout); 9449 } 9450 9451 mAppOpsService.shutdown(); 9452 if (mUsageStatsService != null) { 9453 mUsageStatsService.prepareShutdown(); 9454 } 9455 mBatteryStatsService.shutdown(); 9456 synchronized (this) { 9457 mProcessStats.shutdownLocked(); 9458 } 9459 notifyTaskPersisterLocked(null, true); 9460 9461 return timedout; 9462 } 9463 9464 public final void activitySlept(IBinder token) { 9465 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9466 9467 final long origId = Binder.clearCallingIdentity(); 9468 9469 synchronized (this) { 9470 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9471 if (r != null) { 9472 mStackSupervisor.activitySleptLocked(r); 9473 } 9474 } 9475 9476 Binder.restoreCallingIdentity(origId); 9477 } 9478 9479 void logLockScreen(String msg) { 9480 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9481 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9482 mWentToSleep + " mSleeping=" + mSleeping); 9483 } 9484 9485 private void comeOutOfSleepIfNeededLocked() { 9486 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9487 if (mSleeping) { 9488 mSleeping = false; 9489 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9490 } 9491 } 9492 } 9493 9494 void wakingUp() { 9495 synchronized(this) { 9496 mWentToSleep = false; 9497 updateEventDispatchingLocked(); 9498 comeOutOfSleepIfNeededLocked(); 9499 } 9500 } 9501 9502 void startRunningVoiceLocked() { 9503 if (!mRunningVoice) { 9504 mRunningVoice = true; 9505 comeOutOfSleepIfNeededLocked(); 9506 } 9507 } 9508 9509 private void updateEventDispatchingLocked() { 9510 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9511 } 9512 9513 public void setLockScreenShown(boolean shown) { 9514 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9515 != PackageManager.PERMISSION_GRANTED) { 9516 throw new SecurityException("Requires permission " 9517 + android.Manifest.permission.DEVICE_POWER); 9518 } 9519 9520 synchronized(this) { 9521 long ident = Binder.clearCallingIdentity(); 9522 try { 9523 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9524 mLockScreenShown = shown; 9525 comeOutOfSleepIfNeededLocked(); 9526 } finally { 9527 Binder.restoreCallingIdentity(ident); 9528 } 9529 } 9530 } 9531 9532 @Override 9533 public void stopAppSwitches() { 9534 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9535 != PackageManager.PERMISSION_GRANTED) { 9536 throw new SecurityException("Requires permission " 9537 + android.Manifest.permission.STOP_APP_SWITCHES); 9538 } 9539 9540 synchronized(this) { 9541 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9542 + APP_SWITCH_DELAY_TIME; 9543 mDidAppSwitch = false; 9544 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9545 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9546 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9547 } 9548 } 9549 9550 public void resumeAppSwitches() { 9551 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9552 != PackageManager.PERMISSION_GRANTED) { 9553 throw new SecurityException("Requires permission " 9554 + android.Manifest.permission.STOP_APP_SWITCHES); 9555 } 9556 9557 synchronized(this) { 9558 // Note that we don't execute any pending app switches... we will 9559 // let those wait until either the timeout, or the next start 9560 // activity request. 9561 mAppSwitchesAllowedTime = 0; 9562 } 9563 } 9564 9565 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9566 String name) { 9567 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9568 return true; 9569 } 9570 9571 final int perm = checkComponentPermission( 9572 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9573 callingUid, -1, true); 9574 if (perm == PackageManager.PERMISSION_GRANTED) { 9575 return true; 9576 } 9577 9578 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9579 return false; 9580 } 9581 9582 public void setDebugApp(String packageName, boolean waitForDebugger, 9583 boolean persistent) { 9584 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9585 "setDebugApp()"); 9586 9587 long ident = Binder.clearCallingIdentity(); 9588 try { 9589 // Note that this is not really thread safe if there are multiple 9590 // callers into it at the same time, but that's not a situation we 9591 // care about. 9592 if (persistent) { 9593 final ContentResolver resolver = mContext.getContentResolver(); 9594 Settings.Global.putString( 9595 resolver, Settings.Global.DEBUG_APP, 9596 packageName); 9597 Settings.Global.putInt( 9598 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9599 waitForDebugger ? 1 : 0); 9600 } 9601 9602 synchronized (this) { 9603 if (!persistent) { 9604 mOrigDebugApp = mDebugApp; 9605 mOrigWaitForDebugger = mWaitForDebugger; 9606 } 9607 mDebugApp = packageName; 9608 mWaitForDebugger = waitForDebugger; 9609 mDebugTransient = !persistent; 9610 if (packageName != null) { 9611 forceStopPackageLocked(packageName, -1, false, false, true, true, 9612 false, UserHandle.USER_ALL, "set debug app"); 9613 } 9614 } 9615 } finally { 9616 Binder.restoreCallingIdentity(ident); 9617 } 9618 } 9619 9620 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9621 synchronized (this) { 9622 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9623 if (!isDebuggable) { 9624 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9625 throw new SecurityException("Process not debuggable: " + app.packageName); 9626 } 9627 } 9628 9629 mOpenGlTraceApp = processName; 9630 } 9631 } 9632 9633 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9634 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9635 synchronized (this) { 9636 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9637 if (!isDebuggable) { 9638 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9639 throw new SecurityException("Process not debuggable: " + app.packageName); 9640 } 9641 } 9642 mProfileApp = processName; 9643 mProfileFile = profileFile; 9644 if (mProfileFd != null) { 9645 try { 9646 mProfileFd.close(); 9647 } catch (IOException e) { 9648 } 9649 mProfileFd = null; 9650 } 9651 mProfileFd = profileFd; 9652 mProfileType = 0; 9653 mAutoStopProfiler = autoStopProfiler; 9654 } 9655 } 9656 9657 @Override 9658 public void setAlwaysFinish(boolean enabled) { 9659 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9660 "setAlwaysFinish()"); 9661 9662 Settings.Global.putInt( 9663 mContext.getContentResolver(), 9664 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9665 9666 synchronized (this) { 9667 mAlwaysFinishActivities = enabled; 9668 } 9669 } 9670 9671 @Override 9672 public void setActivityController(IActivityController controller) { 9673 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9674 "setActivityController()"); 9675 synchronized (this) { 9676 mController = controller; 9677 Watchdog.getInstance().setActivityController(controller); 9678 } 9679 } 9680 9681 @Override 9682 public void setUserIsMonkey(boolean userIsMonkey) { 9683 synchronized (this) { 9684 synchronized (mPidsSelfLocked) { 9685 final int callingPid = Binder.getCallingPid(); 9686 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9687 if (precessRecord == null) { 9688 throw new SecurityException("Unknown process: " + callingPid); 9689 } 9690 if (precessRecord.instrumentationUiAutomationConnection == null) { 9691 throw new SecurityException("Only an instrumentation process " 9692 + "with a UiAutomation can call setUserIsMonkey"); 9693 } 9694 } 9695 mUserIsMonkey = userIsMonkey; 9696 } 9697 } 9698 9699 @Override 9700 public boolean isUserAMonkey() { 9701 synchronized (this) { 9702 // If there is a controller also implies the user is a monkey. 9703 return (mUserIsMonkey || mController != null); 9704 } 9705 } 9706 9707 public void requestBugReport() { 9708 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9709 SystemProperties.set("ctl.start", "bugreport"); 9710 } 9711 9712 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9713 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9714 } 9715 9716 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9717 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9718 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9719 } 9720 return KEY_DISPATCHING_TIMEOUT; 9721 } 9722 9723 @Override 9724 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9725 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9726 != PackageManager.PERMISSION_GRANTED) { 9727 throw new SecurityException("Requires permission " 9728 + android.Manifest.permission.FILTER_EVENTS); 9729 } 9730 ProcessRecord proc; 9731 long timeout; 9732 synchronized (this) { 9733 synchronized (mPidsSelfLocked) { 9734 proc = mPidsSelfLocked.get(pid); 9735 } 9736 timeout = getInputDispatchingTimeoutLocked(proc); 9737 } 9738 9739 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9740 return -1; 9741 } 9742 9743 return timeout; 9744 } 9745 9746 /** 9747 * Handle input dispatching timeouts. 9748 * Returns whether input dispatching should be aborted or not. 9749 */ 9750 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9751 final ActivityRecord activity, final ActivityRecord parent, 9752 final boolean aboveSystem, String reason) { 9753 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9754 != PackageManager.PERMISSION_GRANTED) { 9755 throw new SecurityException("Requires permission " 9756 + android.Manifest.permission.FILTER_EVENTS); 9757 } 9758 9759 final String annotation; 9760 if (reason == null) { 9761 annotation = "Input dispatching timed out"; 9762 } else { 9763 annotation = "Input dispatching timed out (" + reason + ")"; 9764 } 9765 9766 if (proc != null) { 9767 synchronized (this) { 9768 if (proc.debugging) { 9769 return false; 9770 } 9771 9772 if (mDidDexOpt) { 9773 // Give more time since we were dexopting. 9774 mDidDexOpt = false; 9775 return false; 9776 } 9777 9778 if (proc.instrumentationClass != null) { 9779 Bundle info = new Bundle(); 9780 info.putString("shortMsg", "keyDispatchingTimedOut"); 9781 info.putString("longMsg", annotation); 9782 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9783 return true; 9784 } 9785 } 9786 mHandler.post(new Runnable() { 9787 @Override 9788 public void run() { 9789 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9790 } 9791 }); 9792 } 9793 9794 return true; 9795 } 9796 9797 public Bundle getAssistContextExtras(int requestType) { 9798 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9799 "getAssistContextExtras()"); 9800 PendingAssistExtras pae; 9801 Bundle extras = new Bundle(); 9802 synchronized (this) { 9803 ActivityRecord activity = getFocusedStack().mResumedActivity; 9804 if (activity == null) { 9805 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9806 return null; 9807 } 9808 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9809 if (activity.app == null || activity.app.thread == null) { 9810 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9811 return extras; 9812 } 9813 if (activity.app.pid == Binder.getCallingPid()) { 9814 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9815 return extras; 9816 } 9817 pae = new PendingAssistExtras(activity); 9818 try { 9819 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9820 requestType); 9821 mPendingAssistExtras.add(pae); 9822 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9823 } catch (RemoteException e) { 9824 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9825 return extras; 9826 } 9827 } 9828 synchronized (pae) { 9829 while (!pae.haveResult) { 9830 try { 9831 pae.wait(); 9832 } catch (InterruptedException e) { 9833 } 9834 } 9835 if (pae.result != null) { 9836 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9837 } 9838 } 9839 synchronized (this) { 9840 mPendingAssistExtras.remove(pae); 9841 mHandler.removeCallbacks(pae); 9842 } 9843 return extras; 9844 } 9845 9846 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9847 PendingAssistExtras pae = (PendingAssistExtras)token; 9848 synchronized (pae) { 9849 pae.result = extras; 9850 pae.haveResult = true; 9851 pae.notifyAll(); 9852 } 9853 } 9854 9855 public void registerProcessObserver(IProcessObserver observer) { 9856 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9857 "registerProcessObserver()"); 9858 synchronized (this) { 9859 mProcessObservers.register(observer); 9860 } 9861 } 9862 9863 @Override 9864 public void unregisterProcessObserver(IProcessObserver observer) { 9865 synchronized (this) { 9866 mProcessObservers.unregister(observer); 9867 } 9868 } 9869 9870 @Override 9871 public boolean convertFromTranslucent(IBinder token) { 9872 final long origId = Binder.clearCallingIdentity(); 9873 try { 9874 synchronized (this) { 9875 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9876 if (r == null) { 9877 return false; 9878 } 9879 if (r.changeWindowTranslucency(true)) { 9880 mWindowManager.setAppFullscreen(token, true); 9881 r.task.stack.releaseBackgroundResources(); 9882 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9883 return true; 9884 } 9885 return false; 9886 } 9887 } finally { 9888 Binder.restoreCallingIdentity(origId); 9889 } 9890 } 9891 9892 @Override 9893 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9894 final long origId = Binder.clearCallingIdentity(); 9895 try { 9896 synchronized (this) { 9897 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9898 if (r == null) { 9899 return false; 9900 } 9901 int index = r.task.mActivities.lastIndexOf(r); 9902 if (index > 0) { 9903 ActivityRecord under = r.task.mActivities.get(index - 1); 9904 under.returningOptions = options; 9905 } 9906 if (r.changeWindowTranslucency(false)) { 9907 r.task.stack.convertToTranslucent(r); 9908 mWindowManager.setAppFullscreen(token, false); 9909 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9910 return true; 9911 } else { 9912 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9913 return false; 9914 } 9915 } 9916 } finally { 9917 Binder.restoreCallingIdentity(origId); 9918 } 9919 } 9920 9921 @Override 9922 public boolean requestVisibleBehind(IBinder token, boolean visible) { 9923 final long origId = Binder.clearCallingIdentity(); 9924 try { 9925 synchronized (this) { 9926 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9927 if (r != null) { 9928 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 9929 } 9930 } 9931 return false; 9932 } finally { 9933 Binder.restoreCallingIdentity(origId); 9934 } 9935 } 9936 9937 @Override 9938 public boolean isBackgroundVisibleBehind(IBinder token) { 9939 final long origId = Binder.clearCallingIdentity(); 9940 try { 9941 synchronized (this) { 9942 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9943 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 9944 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 9945 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 9946 return visible; 9947 } 9948 } finally { 9949 Binder.restoreCallingIdentity(origId); 9950 } 9951 } 9952 9953 @Override 9954 public ActivityOptions getActivityOptions(IBinder token) { 9955 final long origId = Binder.clearCallingIdentity(); 9956 try { 9957 synchronized (this) { 9958 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9959 if (r != null) { 9960 final ActivityOptions activityOptions = r.pendingOptions; 9961 r.pendingOptions = null; 9962 return activityOptions; 9963 } 9964 return null; 9965 } 9966 } finally { 9967 Binder.restoreCallingIdentity(origId); 9968 } 9969 } 9970 9971 @Override 9972 public void setImmersive(IBinder token, boolean immersive) { 9973 synchronized(this) { 9974 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9975 if (r == null) { 9976 throw new IllegalArgumentException(); 9977 } 9978 r.immersive = immersive; 9979 9980 // update associated state if we're frontmost 9981 if (r == mFocusedActivity) { 9982 if (DEBUG_IMMERSIVE) { 9983 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9984 } 9985 applyUpdateLockStateLocked(r); 9986 } 9987 } 9988 } 9989 9990 @Override 9991 public boolean isImmersive(IBinder token) { 9992 synchronized (this) { 9993 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9994 if (r == null) { 9995 throw new IllegalArgumentException(); 9996 } 9997 return r.immersive; 9998 } 9999 } 10000 10001 public boolean isTopActivityImmersive() { 10002 enforceNotIsolatedCaller("startActivity"); 10003 synchronized (this) { 10004 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10005 return (r != null) ? r.immersive : false; 10006 } 10007 } 10008 10009 @Override 10010 public boolean isTopOfTask(IBinder token) { 10011 synchronized (this) { 10012 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10013 if (r == null) { 10014 throw new IllegalArgumentException(); 10015 } 10016 return r.task.getTopActivity() == r; 10017 } 10018 } 10019 10020 public final void enterSafeMode() { 10021 synchronized(this) { 10022 // It only makes sense to do this before the system is ready 10023 // and started launching other packages. 10024 if (!mSystemReady) { 10025 try { 10026 AppGlobals.getPackageManager().enterSafeMode(); 10027 } catch (RemoteException e) { 10028 } 10029 } 10030 10031 mSafeMode = true; 10032 } 10033 } 10034 10035 public final void showSafeModeOverlay() { 10036 View v = LayoutInflater.from(mContext).inflate( 10037 com.android.internal.R.layout.safe_mode, null); 10038 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10039 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10040 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10041 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10042 lp.gravity = Gravity.BOTTOM | Gravity.START; 10043 lp.format = v.getBackground().getOpacity(); 10044 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10045 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10046 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10047 ((WindowManager)mContext.getSystemService( 10048 Context.WINDOW_SERVICE)).addView(v, lp); 10049 } 10050 10051 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10052 if (!(sender instanceof PendingIntentRecord)) { 10053 return; 10054 } 10055 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10056 synchronized (stats) { 10057 if (mBatteryStatsService.isOnBattery()) { 10058 mBatteryStatsService.enforceCallingPermission(); 10059 PendingIntentRecord rec = (PendingIntentRecord)sender; 10060 int MY_UID = Binder.getCallingUid(); 10061 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10062 BatteryStatsImpl.Uid.Pkg pkg = 10063 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10064 sourcePkg != null ? sourcePkg : rec.key.packageName); 10065 pkg.incWakeupsLocked(); 10066 } 10067 } 10068 } 10069 10070 public boolean killPids(int[] pids, String pReason, boolean secure) { 10071 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10072 throw new SecurityException("killPids only available to the system"); 10073 } 10074 String reason = (pReason == null) ? "Unknown" : pReason; 10075 // XXX Note: don't acquire main activity lock here, because the window 10076 // manager calls in with its locks held. 10077 10078 boolean killed = false; 10079 synchronized (mPidsSelfLocked) { 10080 int[] types = new int[pids.length]; 10081 int worstType = 0; 10082 for (int i=0; i<pids.length; i++) { 10083 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10084 if (proc != null) { 10085 int type = proc.setAdj; 10086 types[i] = type; 10087 if (type > worstType) { 10088 worstType = type; 10089 } 10090 } 10091 } 10092 10093 // If the worst oom_adj is somewhere in the cached proc LRU range, 10094 // then constrain it so we will kill all cached procs. 10095 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10096 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10097 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10098 } 10099 10100 // If this is not a secure call, don't let it kill processes that 10101 // are important. 10102 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10103 worstType = ProcessList.SERVICE_ADJ; 10104 } 10105 10106 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10107 for (int i=0; i<pids.length; i++) { 10108 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10109 if (proc == null) { 10110 continue; 10111 } 10112 int adj = proc.setAdj; 10113 if (adj >= worstType && !proc.killedByAm) { 10114 killUnneededProcessLocked(proc, reason); 10115 killed = true; 10116 } 10117 } 10118 } 10119 return killed; 10120 } 10121 10122 @Override 10123 public void killUid(int uid, String reason) { 10124 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10125 throw new SecurityException("killUid only available to the system"); 10126 } 10127 synchronized (this) { 10128 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10129 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10130 reason != null ? reason : "kill uid"); 10131 } 10132 } 10133 10134 @Override 10135 public boolean killProcessesBelowForeground(String reason) { 10136 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10137 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10138 } 10139 10140 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10141 } 10142 10143 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10144 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10145 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10146 } 10147 10148 boolean killed = false; 10149 synchronized (mPidsSelfLocked) { 10150 final int size = mPidsSelfLocked.size(); 10151 for (int i = 0; i < size; i++) { 10152 final int pid = mPidsSelfLocked.keyAt(i); 10153 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10154 if (proc == null) continue; 10155 10156 final int adj = proc.setAdj; 10157 if (adj > belowAdj && !proc.killedByAm) { 10158 killUnneededProcessLocked(proc, reason); 10159 killed = true; 10160 } 10161 } 10162 } 10163 return killed; 10164 } 10165 10166 @Override 10167 public void hang(final IBinder who, boolean allowRestart) { 10168 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10169 != PackageManager.PERMISSION_GRANTED) { 10170 throw new SecurityException("Requires permission " 10171 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10172 } 10173 10174 final IBinder.DeathRecipient death = new DeathRecipient() { 10175 @Override 10176 public void binderDied() { 10177 synchronized (this) { 10178 notifyAll(); 10179 } 10180 } 10181 }; 10182 10183 try { 10184 who.linkToDeath(death, 0); 10185 } catch (RemoteException e) { 10186 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10187 return; 10188 } 10189 10190 synchronized (this) { 10191 Watchdog.getInstance().setAllowRestart(allowRestart); 10192 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10193 synchronized (death) { 10194 while (who.isBinderAlive()) { 10195 try { 10196 death.wait(); 10197 } catch (InterruptedException e) { 10198 } 10199 } 10200 } 10201 Watchdog.getInstance().setAllowRestart(true); 10202 } 10203 } 10204 10205 @Override 10206 public void restart() { 10207 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10208 != PackageManager.PERMISSION_GRANTED) { 10209 throw new SecurityException("Requires permission " 10210 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10211 } 10212 10213 Log.i(TAG, "Sending shutdown broadcast..."); 10214 10215 BroadcastReceiver br = new BroadcastReceiver() { 10216 @Override public void onReceive(Context context, Intent intent) { 10217 // Now the broadcast is done, finish up the low-level shutdown. 10218 Log.i(TAG, "Shutting down activity manager..."); 10219 shutdown(10000); 10220 Log.i(TAG, "Shutdown complete, restarting!"); 10221 Process.killProcess(Process.myPid()); 10222 System.exit(10); 10223 } 10224 }; 10225 10226 // First send the high-level shut down broadcast. 10227 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10228 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10229 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10230 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10231 mContext.sendOrderedBroadcastAsUser(intent, 10232 UserHandle.ALL, null, br, mHandler, 0, null, null); 10233 */ 10234 br.onReceive(mContext, intent); 10235 } 10236 10237 private long getLowRamTimeSinceIdle(long now) { 10238 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10239 } 10240 10241 @Override 10242 public void performIdleMaintenance() { 10243 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10244 != PackageManager.PERMISSION_GRANTED) { 10245 throw new SecurityException("Requires permission " 10246 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10247 } 10248 10249 synchronized (this) { 10250 final long now = SystemClock.uptimeMillis(); 10251 final long timeSinceLastIdle = now - mLastIdleTime; 10252 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10253 mLastIdleTime = now; 10254 mLowRamTimeSinceLastIdle = 0; 10255 if (mLowRamStartTime != 0) { 10256 mLowRamStartTime = now; 10257 } 10258 10259 StringBuilder sb = new StringBuilder(128); 10260 sb.append("Idle maintenance over "); 10261 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10262 sb.append(" low RAM for "); 10263 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10264 Slog.i(TAG, sb.toString()); 10265 10266 // If at least 1/3 of our time since the last idle period has been spent 10267 // with RAM low, then we want to kill processes. 10268 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10269 10270 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10271 ProcessRecord proc = mLruProcesses.get(i); 10272 if (proc.notCachedSinceIdle) { 10273 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10274 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10275 if (doKilling && proc.initialIdlePss != 0 10276 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10277 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 10278 + " from " + proc.initialIdlePss + ")"); 10279 } 10280 } 10281 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10282 proc.notCachedSinceIdle = true; 10283 proc.initialIdlePss = 0; 10284 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10285 isSleeping(), now); 10286 } 10287 } 10288 10289 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10290 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10291 } 10292 } 10293 10294 private void retrieveSettings() { 10295 final ContentResolver resolver = mContext.getContentResolver(); 10296 String debugApp = Settings.Global.getString( 10297 resolver, Settings.Global.DEBUG_APP); 10298 boolean waitForDebugger = Settings.Global.getInt( 10299 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10300 boolean alwaysFinishActivities = Settings.Global.getInt( 10301 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10302 boolean forceRtl = Settings.Global.getInt( 10303 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10304 // Transfer any global setting for forcing RTL layout, into a System Property 10305 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10306 10307 Configuration configuration = new Configuration(); 10308 Settings.System.getConfiguration(resolver, configuration); 10309 if (forceRtl) { 10310 // This will take care of setting the correct layout direction flags 10311 configuration.setLayoutDirection(configuration.locale); 10312 } 10313 10314 synchronized (this) { 10315 mDebugApp = mOrigDebugApp = debugApp; 10316 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10317 mAlwaysFinishActivities = alwaysFinishActivities; 10318 // This happens before any activities are started, so we can 10319 // change mConfiguration in-place. 10320 updateConfigurationLocked(configuration, null, false, true); 10321 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10322 } 10323 } 10324 10325 public boolean testIsSystemReady() { 10326 // no need to synchronize(this) just to read & return the value 10327 return mSystemReady; 10328 } 10329 10330 private static File getCalledPreBootReceiversFile() { 10331 File dataDir = Environment.getDataDirectory(); 10332 File systemDir = new File(dataDir, "system"); 10333 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10334 return fname; 10335 } 10336 10337 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10338 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10339 File file = getCalledPreBootReceiversFile(); 10340 FileInputStream fis = null; 10341 try { 10342 fis = new FileInputStream(file); 10343 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10344 int fvers = dis.readInt(); 10345 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10346 String vers = dis.readUTF(); 10347 String codename = dis.readUTF(); 10348 String build = dis.readUTF(); 10349 if (android.os.Build.VERSION.RELEASE.equals(vers) 10350 && android.os.Build.VERSION.CODENAME.equals(codename) 10351 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10352 int num = dis.readInt(); 10353 while (num > 0) { 10354 num--; 10355 String pkg = dis.readUTF(); 10356 String cls = dis.readUTF(); 10357 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10358 } 10359 } 10360 } 10361 } catch (FileNotFoundException e) { 10362 } catch (IOException e) { 10363 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10364 } finally { 10365 if (fis != null) { 10366 try { 10367 fis.close(); 10368 } catch (IOException e) { 10369 } 10370 } 10371 } 10372 return lastDoneReceivers; 10373 } 10374 10375 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10376 File file = getCalledPreBootReceiversFile(); 10377 FileOutputStream fos = null; 10378 DataOutputStream dos = null; 10379 try { 10380 fos = new FileOutputStream(file); 10381 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10382 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10383 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10384 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10385 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10386 dos.writeInt(list.size()); 10387 for (int i=0; i<list.size(); i++) { 10388 dos.writeUTF(list.get(i).getPackageName()); 10389 dos.writeUTF(list.get(i).getClassName()); 10390 } 10391 } catch (IOException e) { 10392 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10393 file.delete(); 10394 } finally { 10395 FileUtils.sync(fos); 10396 if (dos != null) { 10397 try { 10398 dos.close(); 10399 } catch (IOException e) { 10400 // TODO Auto-generated catch block 10401 e.printStackTrace(); 10402 } 10403 } 10404 } 10405 } 10406 10407 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10408 ArrayList<ComponentName> doneReceivers, int userId) { 10409 boolean waitingUpdate = false; 10410 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10411 List<ResolveInfo> ris = null; 10412 try { 10413 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10414 intent, null, 0, userId); 10415 } catch (RemoteException e) { 10416 } 10417 if (ris != null) { 10418 for (int i=ris.size()-1; i>=0; i--) { 10419 if ((ris.get(i).activityInfo.applicationInfo.flags 10420 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10421 ris.remove(i); 10422 } 10423 } 10424 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10425 10426 // For User 0, load the version number. When delivering to a new user, deliver 10427 // to all receivers. 10428 if (userId == UserHandle.USER_OWNER) { 10429 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10430 for (int i=0; i<ris.size(); i++) { 10431 ActivityInfo ai = ris.get(i).activityInfo; 10432 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10433 if (lastDoneReceivers.contains(comp)) { 10434 // We already did the pre boot receiver for this app with the current 10435 // platform version, so don't do it again... 10436 ris.remove(i); 10437 i--; 10438 // ...however, do keep it as one that has been done, so we don't 10439 // forget about it when rewriting the file of last done receivers. 10440 doneReceivers.add(comp); 10441 } 10442 } 10443 } 10444 10445 // If primary user, send broadcast to all available users, else just to userId 10446 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10447 : new int[] { userId }; 10448 for (int i = 0; i < ris.size(); i++) { 10449 ActivityInfo ai = ris.get(i).activityInfo; 10450 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10451 doneReceivers.add(comp); 10452 intent.setComponent(comp); 10453 for (int j=0; j<users.length; j++) { 10454 IIntentReceiver finisher = null; 10455 // On last receiver and user, set up a completion callback 10456 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10457 finisher = new IIntentReceiver.Stub() { 10458 public void performReceive(Intent intent, int resultCode, 10459 String data, Bundle extras, boolean ordered, 10460 boolean sticky, int sendingUser) { 10461 // The raw IIntentReceiver interface is called 10462 // with the AM lock held, so redispatch to 10463 // execute our code without the lock. 10464 mHandler.post(onFinishCallback); 10465 } 10466 }; 10467 } 10468 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10469 + " for user " + users[j]); 10470 broadcastIntentLocked(null, null, intent, null, finisher, 10471 0, null, null, null, AppOpsManager.OP_NONE, 10472 true, false, MY_PID, Process.SYSTEM_UID, 10473 users[j]); 10474 if (finisher != null) { 10475 waitingUpdate = true; 10476 } 10477 } 10478 } 10479 } 10480 10481 return waitingUpdate; 10482 } 10483 10484 public void systemReady(final Runnable goingCallback) { 10485 synchronized(this) { 10486 if (mSystemReady) { 10487 // If we're done calling all the receivers, run the next "boot phase" passed in 10488 // by the SystemServer 10489 if (goingCallback != null) { 10490 goingCallback.run(); 10491 } 10492 return; 10493 } 10494 10495 // Make sure we have the current profile info, since it is needed for 10496 // security checks. 10497 updateCurrentProfileIdsLocked(); 10498 10499 if (mRecentTasks == null) { 10500 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10501 if (!mRecentTasks.isEmpty()) { 10502 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10503 } 10504 mTaskPersister.startPersisting(); 10505 } 10506 10507 // Check to see if there are any update receivers to run. 10508 if (!mDidUpdate) { 10509 if (mWaitingUpdate) { 10510 return; 10511 } 10512 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10513 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10514 public void run() { 10515 synchronized (ActivityManagerService.this) { 10516 mDidUpdate = true; 10517 } 10518 writeLastDonePreBootReceivers(doneReceivers); 10519 showBootMessage(mContext.getText( 10520 R.string.android_upgrading_complete), 10521 false); 10522 systemReady(goingCallback); 10523 } 10524 }, doneReceivers, UserHandle.USER_OWNER); 10525 10526 if (mWaitingUpdate) { 10527 return; 10528 } 10529 mDidUpdate = true; 10530 } 10531 10532 mAppOpsService.systemReady(); 10533 mSystemReady = true; 10534 } 10535 10536 ArrayList<ProcessRecord> procsToKill = null; 10537 synchronized(mPidsSelfLocked) { 10538 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10539 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10540 if (!isAllowedWhileBooting(proc.info)){ 10541 if (procsToKill == null) { 10542 procsToKill = new ArrayList<ProcessRecord>(); 10543 } 10544 procsToKill.add(proc); 10545 } 10546 } 10547 } 10548 10549 synchronized(this) { 10550 if (procsToKill != null) { 10551 for (int i=procsToKill.size()-1; i>=0; i--) { 10552 ProcessRecord proc = procsToKill.get(i); 10553 Slog.i(TAG, "Removing system update proc: " + proc); 10554 removeProcessLocked(proc, true, false, "system update done"); 10555 } 10556 } 10557 10558 // Now that we have cleaned up any update processes, we 10559 // are ready to start launching real processes and know that 10560 // we won't trample on them any more. 10561 mProcessesReady = true; 10562 } 10563 10564 Slog.i(TAG, "System now ready"); 10565 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10566 SystemClock.uptimeMillis()); 10567 10568 synchronized(this) { 10569 // Make sure we have no pre-ready processes sitting around. 10570 10571 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10572 ResolveInfo ri = mContext.getPackageManager() 10573 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10574 STOCK_PM_FLAGS); 10575 CharSequence errorMsg = null; 10576 if (ri != null) { 10577 ActivityInfo ai = ri.activityInfo; 10578 ApplicationInfo app = ai.applicationInfo; 10579 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10580 mTopAction = Intent.ACTION_FACTORY_TEST; 10581 mTopData = null; 10582 mTopComponent = new ComponentName(app.packageName, 10583 ai.name); 10584 } else { 10585 errorMsg = mContext.getResources().getText( 10586 com.android.internal.R.string.factorytest_not_system); 10587 } 10588 } else { 10589 errorMsg = mContext.getResources().getText( 10590 com.android.internal.R.string.factorytest_no_action); 10591 } 10592 if (errorMsg != null) { 10593 mTopAction = null; 10594 mTopData = null; 10595 mTopComponent = null; 10596 Message msg = Message.obtain(); 10597 msg.what = SHOW_FACTORY_ERROR_MSG; 10598 msg.getData().putCharSequence("msg", errorMsg); 10599 mHandler.sendMessage(msg); 10600 } 10601 } 10602 } 10603 10604 retrieveSettings(); 10605 10606 synchronized (this) { 10607 readGrantedUriPermissionsLocked(); 10608 } 10609 10610 if (goingCallback != null) goingCallback.run(); 10611 10612 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10613 Integer.toString(mCurrentUserId), mCurrentUserId); 10614 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10615 Integer.toString(mCurrentUserId), mCurrentUserId); 10616 mSystemServiceManager.startUser(mCurrentUserId); 10617 10618 synchronized (this) { 10619 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10620 try { 10621 List apps = AppGlobals.getPackageManager(). 10622 getPersistentApplications(STOCK_PM_FLAGS); 10623 if (apps != null) { 10624 int N = apps.size(); 10625 int i; 10626 for (i=0; i<N; i++) { 10627 ApplicationInfo info 10628 = (ApplicationInfo)apps.get(i); 10629 if (info != null && 10630 !info.packageName.equals("android")) { 10631 addAppLocked(info, false, null /* ABI override */); 10632 } 10633 } 10634 } 10635 } catch (RemoteException ex) { 10636 // pm is in same process, this will never happen. 10637 } 10638 } 10639 10640 // Start up initial activity. 10641 mBooting = true; 10642 10643 try { 10644 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10645 Message msg = Message.obtain(); 10646 msg.what = SHOW_UID_ERROR_MSG; 10647 mHandler.sendMessage(msg); 10648 } 10649 } catch (RemoteException e) { 10650 } 10651 10652 long ident = Binder.clearCallingIdentity(); 10653 try { 10654 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10655 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10656 | Intent.FLAG_RECEIVER_FOREGROUND); 10657 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10658 broadcastIntentLocked(null, null, intent, 10659 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10660 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10661 intent = new Intent(Intent.ACTION_USER_STARTING); 10662 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10663 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10664 broadcastIntentLocked(null, null, intent, 10665 null, new IIntentReceiver.Stub() { 10666 @Override 10667 public void performReceive(Intent intent, int resultCode, String data, 10668 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10669 throws RemoteException { 10670 } 10671 }, 0, null, null, 10672 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10673 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10674 } catch (Throwable t) { 10675 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10676 } finally { 10677 Binder.restoreCallingIdentity(ident); 10678 } 10679 mStackSupervisor.resumeTopActivitiesLocked(); 10680 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10681 } 10682 } 10683 10684 private boolean makeAppCrashingLocked(ProcessRecord app, 10685 String shortMsg, String longMsg, String stackTrace) { 10686 app.crashing = true; 10687 app.crashingReport = generateProcessError(app, 10688 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10689 startAppProblemLocked(app); 10690 app.stopFreezingAllLocked(); 10691 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10692 } 10693 10694 private void makeAppNotRespondingLocked(ProcessRecord app, 10695 String activity, String shortMsg, String longMsg) { 10696 app.notResponding = true; 10697 app.notRespondingReport = generateProcessError(app, 10698 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10699 activity, shortMsg, longMsg, null); 10700 startAppProblemLocked(app); 10701 app.stopFreezingAllLocked(); 10702 } 10703 10704 /** 10705 * Generate a process error record, suitable for attachment to a ProcessRecord. 10706 * 10707 * @param app The ProcessRecord in which the error occurred. 10708 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10709 * ActivityManager.AppErrorStateInfo 10710 * @param activity The activity associated with the crash, if known. 10711 * @param shortMsg Short message describing the crash. 10712 * @param longMsg Long message describing the crash. 10713 * @param stackTrace Full crash stack trace, may be null. 10714 * 10715 * @return Returns a fully-formed AppErrorStateInfo record. 10716 */ 10717 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10718 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10719 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10720 10721 report.condition = condition; 10722 report.processName = app.processName; 10723 report.pid = app.pid; 10724 report.uid = app.info.uid; 10725 report.tag = activity; 10726 report.shortMsg = shortMsg; 10727 report.longMsg = longMsg; 10728 report.stackTrace = stackTrace; 10729 10730 return report; 10731 } 10732 10733 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10734 synchronized (this) { 10735 app.crashing = false; 10736 app.crashingReport = null; 10737 app.notResponding = false; 10738 app.notRespondingReport = null; 10739 if (app.anrDialog == fromDialog) { 10740 app.anrDialog = null; 10741 } 10742 if (app.waitDialog == fromDialog) { 10743 app.waitDialog = null; 10744 } 10745 if (app.pid > 0 && app.pid != MY_PID) { 10746 handleAppCrashLocked(app, null, null, null); 10747 killUnneededProcessLocked(app, "user request after error"); 10748 } 10749 } 10750 } 10751 10752 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10753 String stackTrace) { 10754 long now = SystemClock.uptimeMillis(); 10755 10756 Long crashTime; 10757 if (!app.isolated) { 10758 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10759 } else { 10760 crashTime = null; 10761 } 10762 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10763 // This process loses! 10764 Slog.w(TAG, "Process " + app.info.processName 10765 + " has crashed too many times: killing!"); 10766 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10767 app.userId, app.info.processName, app.uid); 10768 mStackSupervisor.handleAppCrashLocked(app); 10769 if (!app.persistent) { 10770 // We don't want to start this process again until the user 10771 // explicitly does so... but for persistent process, we really 10772 // need to keep it running. If a persistent process is actually 10773 // repeatedly crashing, then badness for everyone. 10774 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10775 app.info.processName); 10776 if (!app.isolated) { 10777 // XXX We don't have a way to mark isolated processes 10778 // as bad, since they don't have a peristent identity. 10779 mBadProcesses.put(app.info.processName, app.uid, 10780 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10781 mProcessCrashTimes.remove(app.info.processName, app.uid); 10782 } 10783 app.bad = true; 10784 app.removed = true; 10785 // Don't let services in this process be restarted and potentially 10786 // annoy the user repeatedly. Unless it is persistent, since those 10787 // processes run critical code. 10788 removeProcessLocked(app, false, false, "crash"); 10789 mStackSupervisor.resumeTopActivitiesLocked(); 10790 return false; 10791 } 10792 mStackSupervisor.resumeTopActivitiesLocked(); 10793 } else { 10794 mStackSupervisor.finishTopRunningActivityLocked(app); 10795 } 10796 10797 // Bump up the crash count of any services currently running in the proc. 10798 for (int i=app.services.size()-1; i>=0; i--) { 10799 // Any services running in the application need to be placed 10800 // back in the pending list. 10801 ServiceRecord sr = app.services.valueAt(i); 10802 sr.crashCount++; 10803 } 10804 10805 // If the crashing process is what we consider to be the "home process" and it has been 10806 // replaced by a third-party app, clear the package preferred activities from packages 10807 // with a home activity running in the process to prevent a repeatedly crashing app 10808 // from blocking the user to manually clear the list. 10809 final ArrayList<ActivityRecord> activities = app.activities; 10810 if (app == mHomeProcess && activities.size() > 0 10811 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10812 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10813 final ActivityRecord r = activities.get(activityNdx); 10814 if (r.isHomeActivity()) { 10815 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10816 try { 10817 ActivityThread.getPackageManager() 10818 .clearPackagePreferredActivities(r.packageName); 10819 } catch (RemoteException c) { 10820 // pm is in same process, this will never happen. 10821 } 10822 } 10823 } 10824 } 10825 10826 if (!app.isolated) { 10827 // XXX Can't keep track of crash times for isolated processes, 10828 // because they don't have a perisistent identity. 10829 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10830 } 10831 10832 if (app.crashHandler != null) mHandler.post(app.crashHandler); 10833 return true; 10834 } 10835 10836 void startAppProblemLocked(ProcessRecord app) { 10837 // If this app is not running under the current user, then we 10838 // can't give it a report button because that would require 10839 // launching the report UI under a different user. 10840 app.errorReportReceiver = null; 10841 10842 for (int userId : mCurrentProfileIds) { 10843 if (app.userId == userId) { 10844 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10845 mContext, app.info.packageName, app.info.flags); 10846 } 10847 } 10848 skipCurrentReceiverLocked(app); 10849 } 10850 10851 void skipCurrentReceiverLocked(ProcessRecord app) { 10852 for (BroadcastQueue queue : mBroadcastQueues) { 10853 queue.skipCurrentReceiverLocked(app); 10854 } 10855 } 10856 10857 /** 10858 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10859 * The application process will exit immediately after this call returns. 10860 * @param app object of the crashing app, null for the system server 10861 * @param crashInfo describing the exception 10862 */ 10863 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10864 ProcessRecord r = findAppProcess(app, "Crash"); 10865 final String processName = app == null ? "system_server" 10866 : (r == null ? "unknown" : r.processName); 10867 10868 handleApplicationCrashInner("crash", r, processName, crashInfo); 10869 } 10870 10871 /* Native crash reporting uses this inner version because it needs to be somewhat 10872 * decoupled from the AM-managed cleanup lifecycle 10873 */ 10874 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10875 ApplicationErrorReport.CrashInfo crashInfo) { 10876 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10877 UserHandle.getUserId(Binder.getCallingUid()), processName, 10878 r == null ? -1 : r.info.flags, 10879 crashInfo.exceptionClassName, 10880 crashInfo.exceptionMessage, 10881 crashInfo.throwFileName, 10882 crashInfo.throwLineNumber); 10883 10884 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10885 10886 crashApplication(r, crashInfo); 10887 } 10888 10889 public void handleApplicationStrictModeViolation( 10890 IBinder app, 10891 int violationMask, 10892 StrictMode.ViolationInfo info) { 10893 ProcessRecord r = findAppProcess(app, "StrictMode"); 10894 if (r == null) { 10895 return; 10896 } 10897 10898 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10899 Integer stackFingerprint = info.hashCode(); 10900 boolean logIt = true; 10901 synchronized (mAlreadyLoggedViolatedStacks) { 10902 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10903 logIt = false; 10904 // TODO: sub-sample into EventLog for these, with 10905 // the info.durationMillis? Then we'd get 10906 // the relative pain numbers, without logging all 10907 // the stack traces repeatedly. We'd want to do 10908 // likewise in the client code, which also does 10909 // dup suppression, before the Binder call. 10910 } else { 10911 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10912 mAlreadyLoggedViolatedStacks.clear(); 10913 } 10914 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10915 } 10916 } 10917 if (logIt) { 10918 logStrictModeViolationToDropBox(r, info); 10919 } 10920 } 10921 10922 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10923 AppErrorResult result = new AppErrorResult(); 10924 synchronized (this) { 10925 final long origId = Binder.clearCallingIdentity(); 10926 10927 Message msg = Message.obtain(); 10928 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10929 HashMap<String, Object> data = new HashMap<String, Object>(); 10930 data.put("result", result); 10931 data.put("app", r); 10932 data.put("violationMask", violationMask); 10933 data.put("info", info); 10934 msg.obj = data; 10935 mHandler.sendMessage(msg); 10936 10937 Binder.restoreCallingIdentity(origId); 10938 } 10939 int res = result.get(); 10940 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10941 } 10942 } 10943 10944 // Depending on the policy in effect, there could be a bunch of 10945 // these in quick succession so we try to batch these together to 10946 // minimize disk writes, number of dropbox entries, and maximize 10947 // compression, by having more fewer, larger records. 10948 private void logStrictModeViolationToDropBox( 10949 ProcessRecord process, 10950 StrictMode.ViolationInfo info) { 10951 if (info == null) { 10952 return; 10953 } 10954 final boolean isSystemApp = process == null || 10955 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10956 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10957 final String processName = process == null ? "unknown" : process.processName; 10958 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10959 final DropBoxManager dbox = (DropBoxManager) 10960 mContext.getSystemService(Context.DROPBOX_SERVICE); 10961 10962 // Exit early if the dropbox isn't configured to accept this report type. 10963 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10964 10965 boolean bufferWasEmpty; 10966 boolean needsFlush; 10967 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10968 synchronized (sb) { 10969 bufferWasEmpty = sb.length() == 0; 10970 appendDropBoxProcessHeaders(process, processName, sb); 10971 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10972 sb.append("System-App: ").append(isSystemApp).append("\n"); 10973 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10974 if (info.violationNumThisLoop != 0) { 10975 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10976 } 10977 if (info.numAnimationsRunning != 0) { 10978 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10979 } 10980 if (info.broadcastIntentAction != null) { 10981 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10982 } 10983 if (info.durationMillis != -1) { 10984 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10985 } 10986 if (info.numInstances != -1) { 10987 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10988 } 10989 if (info.tags != null) { 10990 for (String tag : info.tags) { 10991 sb.append("Span-Tag: ").append(tag).append("\n"); 10992 } 10993 } 10994 sb.append("\n"); 10995 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10996 sb.append(info.crashInfo.stackTrace); 10997 } 10998 sb.append("\n"); 10999 11000 // Only buffer up to ~64k. Various logging bits truncate 11001 // things at 128k. 11002 needsFlush = (sb.length() > 64 * 1024); 11003 } 11004 11005 // Flush immediately if the buffer's grown too large, or this 11006 // is a non-system app. Non-system apps are isolated with a 11007 // different tag & policy and not batched. 11008 // 11009 // Batching is useful during internal testing with 11010 // StrictMode settings turned up high. Without batching, 11011 // thousands of separate files could be created on boot. 11012 if (!isSystemApp || needsFlush) { 11013 new Thread("Error dump: " + dropboxTag) { 11014 @Override 11015 public void run() { 11016 String report; 11017 synchronized (sb) { 11018 report = sb.toString(); 11019 sb.delete(0, sb.length()); 11020 sb.trimToSize(); 11021 } 11022 if (report.length() != 0) { 11023 dbox.addText(dropboxTag, report); 11024 } 11025 } 11026 }.start(); 11027 return; 11028 } 11029 11030 // System app batching: 11031 if (!bufferWasEmpty) { 11032 // An existing dropbox-writing thread is outstanding, so 11033 // we don't need to start it up. The existing thread will 11034 // catch the buffer appends we just did. 11035 return; 11036 } 11037 11038 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11039 // (After this point, we shouldn't access AMS internal data structures.) 11040 new Thread("Error dump: " + dropboxTag) { 11041 @Override 11042 public void run() { 11043 // 5 second sleep to let stacks arrive and be batched together 11044 try { 11045 Thread.sleep(5000); // 5 seconds 11046 } catch (InterruptedException e) {} 11047 11048 String errorReport; 11049 synchronized (mStrictModeBuffer) { 11050 errorReport = mStrictModeBuffer.toString(); 11051 if (errorReport.length() == 0) { 11052 return; 11053 } 11054 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11055 mStrictModeBuffer.trimToSize(); 11056 } 11057 dbox.addText(dropboxTag, errorReport); 11058 } 11059 }.start(); 11060 } 11061 11062 /** 11063 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11064 * @param app object of the crashing app, null for the system server 11065 * @param tag reported by the caller 11066 * @param crashInfo describing the context of the error 11067 * @return true if the process should exit immediately (WTF is fatal) 11068 */ 11069 public boolean handleApplicationWtf(IBinder app, String tag, 11070 ApplicationErrorReport.CrashInfo crashInfo) { 11071 ProcessRecord r = findAppProcess(app, "WTF"); 11072 final String processName = app == null ? "system_server" 11073 : (r == null ? "unknown" : r.processName); 11074 11075 EventLog.writeEvent(EventLogTags.AM_WTF, 11076 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11077 processName, 11078 r == null ? -1 : r.info.flags, 11079 tag, crashInfo.exceptionMessage); 11080 11081 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11082 11083 if (r != null && r.pid != Process.myPid() && 11084 Settings.Global.getInt(mContext.getContentResolver(), 11085 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11086 crashApplication(r, crashInfo); 11087 return true; 11088 } else { 11089 return false; 11090 } 11091 } 11092 11093 /** 11094 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11095 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11096 */ 11097 private ProcessRecord findAppProcess(IBinder app, String reason) { 11098 if (app == null) { 11099 return null; 11100 } 11101 11102 synchronized (this) { 11103 final int NP = mProcessNames.getMap().size(); 11104 for (int ip=0; ip<NP; ip++) { 11105 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11106 final int NA = apps.size(); 11107 for (int ia=0; ia<NA; ia++) { 11108 ProcessRecord p = apps.valueAt(ia); 11109 if (p.thread != null && p.thread.asBinder() == app) { 11110 return p; 11111 } 11112 } 11113 } 11114 11115 Slog.w(TAG, "Can't find mystery application for " + reason 11116 + " from pid=" + Binder.getCallingPid() 11117 + " uid=" + Binder.getCallingUid() + ": " + app); 11118 return null; 11119 } 11120 } 11121 11122 /** 11123 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11124 * to append various headers to the dropbox log text. 11125 */ 11126 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11127 StringBuilder sb) { 11128 // Watchdog thread ends up invoking this function (with 11129 // a null ProcessRecord) to add the stack file to dropbox. 11130 // Do not acquire a lock on this (am) in such cases, as it 11131 // could cause a potential deadlock, if and when watchdog 11132 // is invoked due to unavailability of lock on am and it 11133 // would prevent watchdog from killing system_server. 11134 if (process == null) { 11135 sb.append("Process: ").append(processName).append("\n"); 11136 return; 11137 } 11138 // Note: ProcessRecord 'process' is guarded by the service 11139 // instance. (notably process.pkgList, which could otherwise change 11140 // concurrently during execution of this method) 11141 synchronized (this) { 11142 sb.append("Process: ").append(processName).append("\n"); 11143 int flags = process.info.flags; 11144 IPackageManager pm = AppGlobals.getPackageManager(); 11145 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11146 for (int ip=0; ip<process.pkgList.size(); ip++) { 11147 String pkg = process.pkgList.keyAt(ip); 11148 sb.append("Package: ").append(pkg); 11149 try { 11150 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11151 if (pi != null) { 11152 sb.append(" v").append(pi.versionCode); 11153 if (pi.versionName != null) { 11154 sb.append(" (").append(pi.versionName).append(")"); 11155 } 11156 } 11157 } catch (RemoteException e) { 11158 Slog.e(TAG, "Error getting package info: " + pkg, e); 11159 } 11160 sb.append("\n"); 11161 } 11162 } 11163 } 11164 11165 private static String processClass(ProcessRecord process) { 11166 if (process == null || process.pid == MY_PID) { 11167 return "system_server"; 11168 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11169 return "system_app"; 11170 } else { 11171 return "data_app"; 11172 } 11173 } 11174 11175 /** 11176 * Write a description of an error (crash, WTF, ANR) to the drop box. 11177 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11178 * @param process which caused the error, null means the system server 11179 * @param activity which triggered the error, null if unknown 11180 * @param parent activity related to the error, null if unknown 11181 * @param subject line related to the error, null if absent 11182 * @param report in long form describing the error, null if absent 11183 * @param logFile to include in the report, null if none 11184 * @param crashInfo giving an application stack trace, null if absent 11185 */ 11186 public void addErrorToDropBox(String eventType, 11187 ProcessRecord process, String processName, ActivityRecord activity, 11188 ActivityRecord parent, String subject, 11189 final String report, final File logFile, 11190 final ApplicationErrorReport.CrashInfo crashInfo) { 11191 // NOTE -- this must never acquire the ActivityManagerService lock, 11192 // otherwise the watchdog may be prevented from resetting the system. 11193 11194 final String dropboxTag = processClass(process) + "_" + eventType; 11195 final DropBoxManager dbox = (DropBoxManager) 11196 mContext.getSystemService(Context.DROPBOX_SERVICE); 11197 11198 // Exit early if the dropbox isn't configured to accept this report type. 11199 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11200 11201 final StringBuilder sb = new StringBuilder(1024); 11202 appendDropBoxProcessHeaders(process, processName, sb); 11203 if (activity != null) { 11204 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11205 } 11206 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11207 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11208 } 11209 if (parent != null && parent != activity) { 11210 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11211 } 11212 if (subject != null) { 11213 sb.append("Subject: ").append(subject).append("\n"); 11214 } 11215 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11216 if (Debug.isDebuggerConnected()) { 11217 sb.append("Debugger: Connected\n"); 11218 } 11219 sb.append("\n"); 11220 11221 // Do the rest in a worker thread to avoid blocking the caller on I/O 11222 // (After this point, we shouldn't access AMS internal data structures.) 11223 Thread worker = new Thread("Error dump: " + dropboxTag) { 11224 @Override 11225 public void run() { 11226 if (report != null) { 11227 sb.append(report); 11228 } 11229 if (logFile != null) { 11230 try { 11231 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11232 "\n\n[[TRUNCATED]]")); 11233 } catch (IOException e) { 11234 Slog.e(TAG, "Error reading " + logFile, e); 11235 } 11236 } 11237 if (crashInfo != null && crashInfo.stackTrace != null) { 11238 sb.append(crashInfo.stackTrace); 11239 } 11240 11241 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11242 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11243 if (lines > 0) { 11244 sb.append("\n"); 11245 11246 // Merge several logcat streams, and take the last N lines 11247 InputStreamReader input = null; 11248 try { 11249 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11250 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11251 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11252 11253 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11254 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11255 input = new InputStreamReader(logcat.getInputStream()); 11256 11257 int num; 11258 char[] buf = new char[8192]; 11259 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11260 } catch (IOException e) { 11261 Slog.e(TAG, "Error running logcat", e); 11262 } finally { 11263 if (input != null) try { input.close(); } catch (IOException e) {} 11264 } 11265 } 11266 11267 dbox.addText(dropboxTag, sb.toString()); 11268 } 11269 }; 11270 11271 if (process == null) { 11272 // If process is null, we are being called from some internal code 11273 // and may be about to die -- run this synchronously. 11274 worker.run(); 11275 } else { 11276 worker.start(); 11277 } 11278 } 11279 11280 /** 11281 * Bring up the "unexpected error" dialog box for a crashing app. 11282 * Deal with edge cases (intercepts from instrumented applications, 11283 * ActivityController, error intent receivers, that sort of thing). 11284 * @param r the application crashing 11285 * @param crashInfo describing the failure 11286 */ 11287 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11288 long timeMillis = System.currentTimeMillis(); 11289 String shortMsg = crashInfo.exceptionClassName; 11290 String longMsg = crashInfo.exceptionMessage; 11291 String stackTrace = crashInfo.stackTrace; 11292 if (shortMsg != null && longMsg != null) { 11293 longMsg = shortMsg + ": " + longMsg; 11294 } else if (shortMsg != null) { 11295 longMsg = shortMsg; 11296 } 11297 11298 AppErrorResult result = new AppErrorResult(); 11299 synchronized (this) { 11300 if (mController != null) { 11301 try { 11302 String name = r != null ? r.processName : null; 11303 int pid = r != null ? r.pid : Binder.getCallingPid(); 11304 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11305 if (!mController.appCrashed(name, pid, 11306 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11307 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11308 && "Native crash".equals(crashInfo.exceptionClassName)) { 11309 Slog.w(TAG, "Skip killing native crashed app " + name 11310 + "(" + pid + ") during testing"); 11311 } else { 11312 Slog.w(TAG, "Force-killing crashed app " + name 11313 + " at watcher's request"); 11314 Process.killProcess(pid); 11315 if (r != null) { 11316 Process.killProcessGroup(uid, pid); 11317 } 11318 } 11319 return; 11320 } 11321 } catch (RemoteException e) { 11322 mController = null; 11323 Watchdog.getInstance().setActivityController(null); 11324 } 11325 } 11326 11327 final long origId = Binder.clearCallingIdentity(); 11328 11329 // If this process is running instrumentation, finish it. 11330 if (r != null && r.instrumentationClass != null) { 11331 Slog.w(TAG, "Error in app " + r.processName 11332 + " running instrumentation " + r.instrumentationClass + ":"); 11333 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11334 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11335 Bundle info = new Bundle(); 11336 info.putString("shortMsg", shortMsg); 11337 info.putString("longMsg", longMsg); 11338 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11339 Binder.restoreCallingIdentity(origId); 11340 return; 11341 } 11342 11343 // If we can't identify the process or it's already exceeded its crash quota, 11344 // quit right away without showing a crash dialog. 11345 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11346 Binder.restoreCallingIdentity(origId); 11347 return; 11348 } 11349 11350 Message msg = Message.obtain(); 11351 msg.what = SHOW_ERROR_MSG; 11352 HashMap data = new HashMap(); 11353 data.put("result", result); 11354 data.put("app", r); 11355 msg.obj = data; 11356 mHandler.sendMessage(msg); 11357 11358 Binder.restoreCallingIdentity(origId); 11359 } 11360 11361 int res = result.get(); 11362 11363 Intent appErrorIntent = null; 11364 synchronized (this) { 11365 if (r != null && !r.isolated) { 11366 // XXX Can't keep track of crash time for isolated processes, 11367 // since they don't have a persistent identity. 11368 mProcessCrashTimes.put(r.info.processName, r.uid, 11369 SystemClock.uptimeMillis()); 11370 } 11371 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11372 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11373 } 11374 } 11375 11376 if (appErrorIntent != null) { 11377 try { 11378 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11379 } catch (ActivityNotFoundException e) { 11380 Slog.w(TAG, "bug report receiver dissappeared", e); 11381 } 11382 } 11383 } 11384 11385 Intent createAppErrorIntentLocked(ProcessRecord r, 11386 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11387 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11388 if (report == null) { 11389 return null; 11390 } 11391 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11392 result.setComponent(r.errorReportReceiver); 11393 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11394 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11395 return result; 11396 } 11397 11398 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11399 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11400 if (r.errorReportReceiver == null) { 11401 return null; 11402 } 11403 11404 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11405 return null; 11406 } 11407 11408 ApplicationErrorReport report = new ApplicationErrorReport(); 11409 report.packageName = r.info.packageName; 11410 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11411 report.processName = r.processName; 11412 report.time = timeMillis; 11413 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11414 11415 if (r.crashing || r.forceCrashReport) { 11416 report.type = ApplicationErrorReport.TYPE_CRASH; 11417 report.crashInfo = crashInfo; 11418 } else if (r.notResponding) { 11419 report.type = ApplicationErrorReport.TYPE_ANR; 11420 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11421 11422 report.anrInfo.activity = r.notRespondingReport.tag; 11423 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11424 report.anrInfo.info = r.notRespondingReport.longMsg; 11425 } 11426 11427 return report; 11428 } 11429 11430 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11431 enforceNotIsolatedCaller("getProcessesInErrorState"); 11432 // assume our apps are happy - lazy create the list 11433 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11434 11435 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11436 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11437 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11438 11439 synchronized (this) { 11440 11441 // iterate across all processes 11442 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11443 ProcessRecord app = mLruProcesses.get(i); 11444 if (!allUsers && app.userId != userId) { 11445 continue; 11446 } 11447 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11448 // This one's in trouble, so we'll generate a report for it 11449 // crashes are higher priority (in case there's a crash *and* an anr) 11450 ActivityManager.ProcessErrorStateInfo report = null; 11451 if (app.crashing) { 11452 report = app.crashingReport; 11453 } else if (app.notResponding) { 11454 report = app.notRespondingReport; 11455 } 11456 11457 if (report != null) { 11458 if (errList == null) { 11459 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11460 } 11461 errList.add(report); 11462 } else { 11463 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11464 " crashing = " + app.crashing + 11465 " notResponding = " + app.notResponding); 11466 } 11467 } 11468 } 11469 } 11470 11471 return errList; 11472 } 11473 11474 static int procStateToImportance(int procState, int memAdj, 11475 ActivityManager.RunningAppProcessInfo currApp) { 11476 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11477 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11478 currApp.lru = memAdj; 11479 } else { 11480 currApp.lru = 0; 11481 } 11482 return imp; 11483 } 11484 11485 private void fillInProcMemInfo(ProcessRecord app, 11486 ActivityManager.RunningAppProcessInfo outInfo) { 11487 outInfo.pid = app.pid; 11488 outInfo.uid = app.info.uid; 11489 if (mHeavyWeightProcess == app) { 11490 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11491 } 11492 if (app.persistent) { 11493 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11494 } 11495 if (app.activities.size() > 0) { 11496 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11497 } 11498 outInfo.lastTrimLevel = app.trimMemoryLevel; 11499 int adj = app.curAdj; 11500 int procState = app.curProcState; 11501 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11502 outInfo.importanceReasonCode = app.adjTypeCode; 11503 outInfo.processState = app.curProcState; 11504 } 11505 11506 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11507 enforceNotIsolatedCaller("getRunningAppProcesses"); 11508 // Lazy instantiation of list 11509 List<ActivityManager.RunningAppProcessInfo> runList = null; 11510 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11511 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11512 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11513 synchronized (this) { 11514 // Iterate across all processes 11515 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11516 ProcessRecord app = mLruProcesses.get(i); 11517 if (!allUsers && app.userId != userId) { 11518 continue; 11519 } 11520 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11521 // Generate process state info for running application 11522 ActivityManager.RunningAppProcessInfo currApp = 11523 new ActivityManager.RunningAppProcessInfo(app.processName, 11524 app.pid, app.getPackageList()); 11525 fillInProcMemInfo(app, currApp); 11526 if (app.adjSource instanceof ProcessRecord) { 11527 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11528 currApp.importanceReasonImportance = 11529 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11530 app.adjSourceProcState); 11531 } else if (app.adjSource instanceof ActivityRecord) { 11532 ActivityRecord r = (ActivityRecord)app.adjSource; 11533 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11534 } 11535 if (app.adjTarget instanceof ComponentName) { 11536 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11537 } 11538 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11539 // + " lru=" + currApp.lru); 11540 if (runList == null) { 11541 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11542 } 11543 runList.add(currApp); 11544 } 11545 } 11546 } 11547 return runList; 11548 } 11549 11550 public List<ApplicationInfo> getRunningExternalApplications() { 11551 enforceNotIsolatedCaller("getRunningExternalApplications"); 11552 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11553 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11554 if (runningApps != null && runningApps.size() > 0) { 11555 Set<String> extList = new HashSet<String>(); 11556 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11557 if (app.pkgList != null) { 11558 for (String pkg : app.pkgList) { 11559 extList.add(pkg); 11560 } 11561 } 11562 } 11563 IPackageManager pm = AppGlobals.getPackageManager(); 11564 for (String pkg : extList) { 11565 try { 11566 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11567 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11568 retList.add(info); 11569 } 11570 } catch (RemoteException e) { 11571 } 11572 } 11573 } 11574 return retList; 11575 } 11576 11577 @Override 11578 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11579 enforceNotIsolatedCaller("getMyMemoryState"); 11580 synchronized (this) { 11581 ProcessRecord proc; 11582 synchronized (mPidsSelfLocked) { 11583 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11584 } 11585 fillInProcMemInfo(proc, outInfo); 11586 } 11587 } 11588 11589 @Override 11590 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11591 if (checkCallingPermission(android.Manifest.permission.DUMP) 11592 != PackageManager.PERMISSION_GRANTED) { 11593 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11594 + Binder.getCallingPid() 11595 + ", uid=" + Binder.getCallingUid() 11596 + " without permission " 11597 + android.Manifest.permission.DUMP); 11598 return; 11599 } 11600 11601 boolean dumpAll = false; 11602 boolean dumpClient = false; 11603 String dumpPackage = null; 11604 11605 int opti = 0; 11606 while (opti < args.length) { 11607 String opt = args[opti]; 11608 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11609 break; 11610 } 11611 opti++; 11612 if ("-a".equals(opt)) { 11613 dumpAll = true; 11614 } else if ("-c".equals(opt)) { 11615 dumpClient = true; 11616 } else if ("-h".equals(opt)) { 11617 pw.println("Activity manager dump options:"); 11618 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11619 pw.println(" cmd may be one of:"); 11620 pw.println(" a[ctivities]: activity stack state"); 11621 pw.println(" r[recents]: recent activities state"); 11622 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11623 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11624 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11625 pw.println(" o[om]: out of memory management"); 11626 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11627 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11628 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11629 pw.println(" service [COMP_SPEC]: service client-side state"); 11630 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11631 pw.println(" all: dump all activities"); 11632 pw.println(" top: dump the top activity"); 11633 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11634 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11635 pw.println(" a partial substring in a component name, a"); 11636 pw.println(" hex object identifier."); 11637 pw.println(" -a: include all available server state."); 11638 pw.println(" -c: include client state."); 11639 return; 11640 } else { 11641 pw.println("Unknown argument: " + opt + "; use -h for help"); 11642 } 11643 } 11644 11645 long origId = Binder.clearCallingIdentity(); 11646 boolean more = false; 11647 // Is the caller requesting to dump a particular piece of data? 11648 if (opti < args.length) { 11649 String cmd = args[opti]; 11650 opti++; 11651 if ("activities".equals(cmd) || "a".equals(cmd)) { 11652 synchronized (this) { 11653 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11654 } 11655 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 11656 synchronized (this) { 11657 dumpRecentsLocked(fd, pw, args, opti, true, null); 11658 } 11659 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11660 String[] newArgs; 11661 String name; 11662 if (opti >= args.length) { 11663 name = null; 11664 newArgs = EMPTY_STRING_ARRAY; 11665 } else { 11666 name = args[opti]; 11667 opti++; 11668 newArgs = new String[args.length - opti]; 11669 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11670 args.length - opti); 11671 } 11672 synchronized (this) { 11673 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11674 } 11675 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11676 String[] newArgs; 11677 String name; 11678 if (opti >= args.length) { 11679 name = null; 11680 newArgs = EMPTY_STRING_ARRAY; 11681 } else { 11682 name = args[opti]; 11683 opti++; 11684 newArgs = new String[args.length - opti]; 11685 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11686 args.length - opti); 11687 } 11688 synchronized (this) { 11689 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11690 } 11691 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11692 String[] newArgs; 11693 String name; 11694 if (opti >= args.length) { 11695 name = null; 11696 newArgs = EMPTY_STRING_ARRAY; 11697 } else { 11698 name = args[opti]; 11699 opti++; 11700 newArgs = new String[args.length - opti]; 11701 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11702 args.length - opti); 11703 } 11704 synchronized (this) { 11705 dumpProcessesLocked(fd, pw, args, opti, true, name); 11706 } 11707 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11708 synchronized (this) { 11709 dumpOomLocked(fd, pw, args, opti, true); 11710 } 11711 } else if ("provider".equals(cmd)) { 11712 String[] newArgs; 11713 String name; 11714 if (opti >= args.length) { 11715 name = null; 11716 newArgs = EMPTY_STRING_ARRAY; 11717 } else { 11718 name = args[opti]; 11719 opti++; 11720 newArgs = new String[args.length - opti]; 11721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11722 } 11723 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11724 pw.println("No providers match: " + name); 11725 pw.println("Use -h for help."); 11726 } 11727 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11728 synchronized (this) { 11729 dumpProvidersLocked(fd, pw, args, opti, true, null); 11730 } 11731 } else if ("service".equals(cmd)) { 11732 String[] newArgs; 11733 String name; 11734 if (opti >= args.length) { 11735 name = null; 11736 newArgs = EMPTY_STRING_ARRAY; 11737 } else { 11738 name = args[opti]; 11739 opti++; 11740 newArgs = new String[args.length - opti]; 11741 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11742 args.length - opti); 11743 } 11744 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11745 pw.println("No services match: " + name); 11746 pw.println("Use -h for help."); 11747 } 11748 } else if ("package".equals(cmd)) { 11749 String[] newArgs; 11750 if (opti >= args.length) { 11751 pw.println("package: no package name specified"); 11752 pw.println("Use -h for help."); 11753 } else { 11754 dumpPackage = args[opti]; 11755 opti++; 11756 newArgs = new String[args.length - opti]; 11757 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11758 args.length - opti); 11759 args = newArgs; 11760 opti = 0; 11761 more = true; 11762 } 11763 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11764 synchronized (this) { 11765 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11766 } 11767 } else { 11768 // Dumping a single activity? 11769 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11770 pw.println("Bad activity command, or no activities match: " + cmd); 11771 pw.println("Use -h for help."); 11772 } 11773 } 11774 if (!more) { 11775 Binder.restoreCallingIdentity(origId); 11776 return; 11777 } 11778 } 11779 11780 // No piece of data specified, dump everything. 11781 synchronized (this) { 11782 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11783 pw.println(); 11784 if (dumpAll) { 11785 pw.println("-------------------------------------------------------------------------------"); 11786 } 11787 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11788 pw.println(); 11789 if (dumpAll) { 11790 pw.println("-------------------------------------------------------------------------------"); 11791 } 11792 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11793 pw.println(); 11794 if (dumpAll) { 11795 pw.println("-------------------------------------------------------------------------------"); 11796 } 11797 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11798 pw.println(); 11799 if (dumpAll) { 11800 pw.println("-------------------------------------------------------------------------------"); 11801 } 11802 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11803 pw.println(); 11804 if (dumpAll) { 11805 pw.println("-------------------------------------------------------------------------------"); 11806 } 11807 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11808 pw.println(); 11809 if (dumpAll) { 11810 pw.println("-------------------------------------------------------------------------------"); 11811 } 11812 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11813 } 11814 Binder.restoreCallingIdentity(origId); 11815 } 11816 11817 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11818 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11819 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11820 11821 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11822 dumpPackage); 11823 boolean needSep = printedAnything; 11824 11825 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11826 dumpPackage, needSep, " mFocusedActivity: "); 11827 if (printed) { 11828 printedAnything = true; 11829 needSep = false; 11830 } 11831 11832 if (dumpPackage == null) { 11833 if (needSep) { 11834 pw.println(); 11835 } 11836 needSep = true; 11837 printedAnything = true; 11838 mStackSupervisor.dump(pw, " "); 11839 } 11840 11841 if (!printedAnything) { 11842 pw.println(" (nothing)"); 11843 } 11844 } 11845 11846 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11847 int opti, boolean dumpAll, String dumpPackage) { 11848 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 11849 11850 boolean printedAnything = false; 11851 11852 if (mRecentTasks.size() > 0) { 11853 boolean printedHeader = false; 11854 11855 final int N = mRecentTasks.size(); 11856 for (int i=0; i<N; i++) { 11857 TaskRecord tr = mRecentTasks.get(i); 11858 if (dumpPackage != null) { 11859 if (tr.realActivity == null || 11860 !dumpPackage.equals(tr.realActivity)) { 11861 continue; 11862 } 11863 } 11864 if (!printedHeader) { 11865 pw.println(" Recent tasks:"); 11866 printedHeader = true; 11867 printedAnything = true; 11868 } 11869 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11870 pw.println(tr); 11871 if (dumpAll) { 11872 mRecentTasks.get(i).dump(pw, " "); 11873 } 11874 } 11875 } 11876 11877 if (!printedAnything) { 11878 pw.println(" (nothing)"); 11879 } 11880 } 11881 11882 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11883 int opti, boolean dumpAll, String dumpPackage) { 11884 boolean needSep = false; 11885 boolean printedAnything = false; 11886 int numPers = 0; 11887 11888 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11889 11890 if (dumpAll) { 11891 final int NP = mProcessNames.getMap().size(); 11892 for (int ip=0; ip<NP; ip++) { 11893 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11894 final int NA = procs.size(); 11895 for (int ia=0; ia<NA; ia++) { 11896 ProcessRecord r = procs.valueAt(ia); 11897 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11898 continue; 11899 } 11900 if (!needSep) { 11901 pw.println(" All known processes:"); 11902 needSep = true; 11903 printedAnything = true; 11904 } 11905 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11906 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11907 pw.print(" "); pw.println(r); 11908 r.dump(pw, " "); 11909 if (r.persistent) { 11910 numPers++; 11911 } 11912 } 11913 } 11914 } 11915 11916 if (mIsolatedProcesses.size() > 0) { 11917 boolean printed = false; 11918 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11919 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11920 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11921 continue; 11922 } 11923 if (!printed) { 11924 if (needSep) { 11925 pw.println(); 11926 } 11927 pw.println(" Isolated process list (sorted by uid):"); 11928 printedAnything = true; 11929 printed = true; 11930 needSep = true; 11931 } 11932 pw.println(String.format("%sIsolated #%2d: %s", 11933 " ", i, r.toString())); 11934 } 11935 } 11936 11937 if (mLruProcesses.size() > 0) { 11938 if (needSep) { 11939 pw.println(); 11940 } 11941 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11942 pw.print(" total, non-act at "); 11943 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11944 pw.print(", non-svc at "); 11945 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11946 pw.println("):"); 11947 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11948 needSep = true; 11949 printedAnything = true; 11950 } 11951 11952 if (dumpAll || dumpPackage != null) { 11953 synchronized (mPidsSelfLocked) { 11954 boolean printed = false; 11955 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11956 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11957 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11958 continue; 11959 } 11960 if (!printed) { 11961 if (needSep) pw.println(); 11962 needSep = true; 11963 pw.println(" PID mappings:"); 11964 printed = true; 11965 printedAnything = true; 11966 } 11967 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11968 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11969 } 11970 } 11971 } 11972 11973 if (mForegroundProcesses.size() > 0) { 11974 synchronized (mPidsSelfLocked) { 11975 boolean printed = false; 11976 for (int i=0; i<mForegroundProcesses.size(); i++) { 11977 ProcessRecord r = mPidsSelfLocked.get( 11978 mForegroundProcesses.valueAt(i).pid); 11979 if (dumpPackage != null && (r == null 11980 || !r.pkgList.containsKey(dumpPackage))) { 11981 continue; 11982 } 11983 if (!printed) { 11984 if (needSep) pw.println(); 11985 needSep = true; 11986 pw.println(" Foreground Processes:"); 11987 printed = true; 11988 printedAnything = true; 11989 } 11990 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11991 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11992 } 11993 } 11994 } 11995 11996 if (mPersistentStartingProcesses.size() > 0) { 11997 if (needSep) pw.println(); 11998 needSep = true; 11999 printedAnything = true; 12000 pw.println(" Persisent processes that are starting:"); 12001 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12002 "Starting Norm", "Restarting PERS", dumpPackage); 12003 } 12004 12005 if (mRemovedProcesses.size() > 0) { 12006 if (needSep) pw.println(); 12007 needSep = true; 12008 printedAnything = true; 12009 pw.println(" Processes that are being removed:"); 12010 dumpProcessList(pw, this, mRemovedProcesses, " ", 12011 "Removed Norm", "Removed PERS", dumpPackage); 12012 } 12013 12014 if (mProcessesOnHold.size() > 0) { 12015 if (needSep) pw.println(); 12016 needSep = true; 12017 printedAnything = true; 12018 pw.println(" Processes that are on old until the system is ready:"); 12019 dumpProcessList(pw, this, mProcessesOnHold, " ", 12020 "OnHold Norm", "OnHold PERS", dumpPackage); 12021 } 12022 12023 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12024 12025 if (mProcessCrashTimes.getMap().size() > 0) { 12026 boolean printed = false; 12027 long now = SystemClock.uptimeMillis(); 12028 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12029 final int NP = pmap.size(); 12030 for (int ip=0; ip<NP; ip++) { 12031 String pname = pmap.keyAt(ip); 12032 SparseArray<Long> uids = pmap.valueAt(ip); 12033 final int N = uids.size(); 12034 for (int i=0; i<N; i++) { 12035 int puid = uids.keyAt(i); 12036 ProcessRecord r = mProcessNames.get(pname, puid); 12037 if (dumpPackage != null && (r == null 12038 || !r.pkgList.containsKey(dumpPackage))) { 12039 continue; 12040 } 12041 if (!printed) { 12042 if (needSep) pw.println(); 12043 needSep = true; 12044 pw.println(" Time since processes crashed:"); 12045 printed = true; 12046 printedAnything = true; 12047 } 12048 pw.print(" Process "); pw.print(pname); 12049 pw.print(" uid "); pw.print(puid); 12050 pw.print(": last crashed "); 12051 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12052 pw.println(" ago"); 12053 } 12054 } 12055 } 12056 12057 if (mBadProcesses.getMap().size() > 0) { 12058 boolean printed = false; 12059 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12060 final int NP = pmap.size(); 12061 for (int ip=0; ip<NP; ip++) { 12062 String pname = pmap.keyAt(ip); 12063 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12064 final int N = uids.size(); 12065 for (int i=0; i<N; i++) { 12066 int puid = uids.keyAt(i); 12067 ProcessRecord r = mProcessNames.get(pname, puid); 12068 if (dumpPackage != null && (r == null 12069 || !r.pkgList.containsKey(dumpPackage))) { 12070 continue; 12071 } 12072 if (!printed) { 12073 if (needSep) pw.println(); 12074 needSep = true; 12075 pw.println(" Bad processes:"); 12076 printedAnything = true; 12077 } 12078 BadProcessInfo info = uids.valueAt(i); 12079 pw.print(" Bad process "); pw.print(pname); 12080 pw.print(" uid "); pw.print(puid); 12081 pw.print(": crashed at time "); pw.println(info.time); 12082 if (info.shortMsg != null) { 12083 pw.print(" Short msg: "); pw.println(info.shortMsg); 12084 } 12085 if (info.longMsg != null) { 12086 pw.print(" Long msg: "); pw.println(info.longMsg); 12087 } 12088 if (info.stack != null) { 12089 pw.println(" Stack:"); 12090 int lastPos = 0; 12091 for (int pos=0; pos<info.stack.length(); pos++) { 12092 if (info.stack.charAt(pos) == '\n') { 12093 pw.print(" "); 12094 pw.write(info.stack, lastPos, pos-lastPos); 12095 pw.println(); 12096 lastPos = pos+1; 12097 } 12098 } 12099 if (lastPos < info.stack.length()) { 12100 pw.print(" "); 12101 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12102 pw.println(); 12103 } 12104 } 12105 } 12106 } 12107 } 12108 12109 if (dumpPackage == null) { 12110 pw.println(); 12111 needSep = false; 12112 pw.println(" mStartedUsers:"); 12113 for (int i=0; i<mStartedUsers.size(); i++) { 12114 UserStartedState uss = mStartedUsers.valueAt(i); 12115 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12116 pw.print(": "); uss.dump("", pw); 12117 } 12118 pw.print(" mStartedUserArray: ["); 12119 for (int i=0; i<mStartedUserArray.length; i++) { 12120 if (i > 0) pw.print(", "); 12121 pw.print(mStartedUserArray[i]); 12122 } 12123 pw.println("]"); 12124 pw.print(" mUserLru: ["); 12125 for (int i=0; i<mUserLru.size(); i++) { 12126 if (i > 0) pw.print(", "); 12127 pw.print(mUserLru.get(i)); 12128 } 12129 pw.println("]"); 12130 if (dumpAll) { 12131 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12132 } 12133 synchronized (mUserProfileGroupIdsSelfLocked) { 12134 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12135 pw.println(" mUserProfileGroupIds:"); 12136 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12137 pw.print(" User #"); 12138 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12139 pw.print(" -> profile #"); 12140 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12141 } 12142 } 12143 } 12144 } 12145 if (mHomeProcess != null && (dumpPackage == null 12146 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12147 if (needSep) { 12148 pw.println(); 12149 needSep = false; 12150 } 12151 pw.println(" mHomeProcess: " + mHomeProcess); 12152 } 12153 if (mPreviousProcess != null && (dumpPackage == null 12154 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12155 if (needSep) { 12156 pw.println(); 12157 needSep = false; 12158 } 12159 pw.println(" mPreviousProcess: " + mPreviousProcess); 12160 } 12161 if (dumpAll) { 12162 StringBuilder sb = new StringBuilder(128); 12163 sb.append(" mPreviousProcessVisibleTime: "); 12164 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12165 pw.println(sb); 12166 } 12167 if (mHeavyWeightProcess != null && (dumpPackage == null 12168 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12169 if (needSep) { 12170 pw.println(); 12171 needSep = false; 12172 } 12173 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12174 } 12175 if (dumpPackage == null) { 12176 pw.println(" mConfiguration: " + mConfiguration); 12177 } 12178 if (dumpAll) { 12179 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12180 if (mCompatModePackages.getPackages().size() > 0) { 12181 boolean printed = false; 12182 for (Map.Entry<String, Integer> entry 12183 : mCompatModePackages.getPackages().entrySet()) { 12184 String pkg = entry.getKey(); 12185 int mode = entry.getValue(); 12186 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12187 continue; 12188 } 12189 if (!printed) { 12190 pw.println(" mScreenCompatPackages:"); 12191 printed = true; 12192 } 12193 pw.print(" "); pw.print(pkg); pw.print(": "); 12194 pw.print(mode); pw.println(); 12195 } 12196 } 12197 } 12198 if (dumpPackage == null) { 12199 if (mSleeping || mWentToSleep || mLockScreenShown) { 12200 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12201 + " mLockScreenShown " + mLockScreenShown); 12202 } 12203 if (mShuttingDown || mRunningVoice) { 12204 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12205 } 12206 } 12207 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12208 || mOrigWaitForDebugger) { 12209 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12210 || dumpPackage.equals(mOrigDebugApp)) { 12211 if (needSep) { 12212 pw.println(); 12213 needSep = false; 12214 } 12215 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12216 + " mDebugTransient=" + mDebugTransient 12217 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12218 } 12219 } 12220 if (mOpenGlTraceApp != null) { 12221 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12222 if (needSep) { 12223 pw.println(); 12224 needSep = false; 12225 } 12226 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12227 } 12228 } 12229 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12230 || mProfileFd != null) { 12231 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12232 if (needSep) { 12233 pw.println(); 12234 needSep = false; 12235 } 12236 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12237 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12238 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 12239 + mAutoStopProfiler); 12240 } 12241 } 12242 if (dumpPackage == null) { 12243 if (mAlwaysFinishActivities || mController != null) { 12244 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12245 + " mController=" + mController); 12246 } 12247 if (dumpAll) { 12248 pw.println(" Total persistent processes: " + numPers); 12249 pw.println(" mProcessesReady=" + mProcessesReady 12250 + " mSystemReady=" + mSystemReady); 12251 pw.println(" mBooting=" + mBooting 12252 + " mBooted=" + mBooted 12253 + " mFactoryTest=" + mFactoryTest); 12254 pw.print(" mLastPowerCheckRealtime="); 12255 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12256 pw.println(""); 12257 pw.print(" mLastPowerCheckUptime="); 12258 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12259 pw.println(""); 12260 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12261 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12262 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12263 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12264 + " (" + mLruProcesses.size() + " total)" 12265 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12266 + " mNumServiceProcs=" + mNumServiceProcs 12267 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12268 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12269 + " mLastMemoryLevel" + mLastMemoryLevel 12270 + " mLastNumProcesses" + mLastNumProcesses); 12271 long now = SystemClock.uptimeMillis(); 12272 pw.print(" mLastIdleTime="); 12273 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12274 pw.print(" mLowRamSinceLastIdle="); 12275 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12276 pw.println(); 12277 } 12278 } 12279 12280 if (!printedAnything) { 12281 pw.println(" (nothing)"); 12282 } 12283 } 12284 12285 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12286 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12287 if (mProcessesToGc.size() > 0) { 12288 boolean printed = false; 12289 long now = SystemClock.uptimeMillis(); 12290 for (int i=0; i<mProcessesToGc.size(); i++) { 12291 ProcessRecord proc = mProcessesToGc.get(i); 12292 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12293 continue; 12294 } 12295 if (!printed) { 12296 if (needSep) pw.println(); 12297 needSep = true; 12298 pw.println(" Processes that are waiting to GC:"); 12299 printed = true; 12300 } 12301 pw.print(" Process "); pw.println(proc); 12302 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12303 pw.print(", last gced="); 12304 pw.print(now-proc.lastRequestedGc); 12305 pw.print(" ms ago, last lowMem="); 12306 pw.print(now-proc.lastLowMemory); 12307 pw.println(" ms ago"); 12308 12309 } 12310 } 12311 return needSep; 12312 } 12313 12314 void printOomLevel(PrintWriter pw, String name, int adj) { 12315 pw.print(" "); 12316 if (adj >= 0) { 12317 pw.print(' '); 12318 if (adj < 10) pw.print(' '); 12319 } else { 12320 if (adj > -10) pw.print(' '); 12321 } 12322 pw.print(adj); 12323 pw.print(": "); 12324 pw.print(name); 12325 pw.print(" ("); 12326 pw.print(mProcessList.getMemLevel(adj)/1024); 12327 pw.println(" kB)"); 12328 } 12329 12330 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12331 int opti, boolean dumpAll) { 12332 boolean needSep = false; 12333 12334 if (mLruProcesses.size() > 0) { 12335 if (needSep) pw.println(); 12336 needSep = true; 12337 pw.println(" OOM levels:"); 12338 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12339 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12340 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12341 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12342 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12343 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12344 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12345 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12346 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12347 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12348 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12349 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12350 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12351 12352 if (needSep) pw.println(); 12353 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12354 pw.print(" total, non-act at "); 12355 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12356 pw.print(", non-svc at "); 12357 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12358 pw.println("):"); 12359 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12360 needSep = true; 12361 } 12362 12363 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12364 12365 pw.println(); 12366 pw.println(" mHomeProcess: " + mHomeProcess); 12367 pw.println(" mPreviousProcess: " + mPreviousProcess); 12368 if (mHeavyWeightProcess != null) { 12369 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12370 } 12371 12372 return true; 12373 } 12374 12375 /** 12376 * There are three ways to call this: 12377 * - no provider specified: dump all the providers 12378 * - a flattened component name that matched an existing provider was specified as the 12379 * first arg: dump that one provider 12380 * - the first arg isn't the flattened component name of an existing provider: 12381 * dump all providers whose component contains the first arg as a substring 12382 */ 12383 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12384 int opti, boolean dumpAll) { 12385 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12386 } 12387 12388 static class ItemMatcher { 12389 ArrayList<ComponentName> components; 12390 ArrayList<String> strings; 12391 ArrayList<Integer> objects; 12392 boolean all; 12393 12394 ItemMatcher() { 12395 all = true; 12396 } 12397 12398 void build(String name) { 12399 ComponentName componentName = ComponentName.unflattenFromString(name); 12400 if (componentName != null) { 12401 if (components == null) { 12402 components = new ArrayList<ComponentName>(); 12403 } 12404 components.add(componentName); 12405 all = false; 12406 } else { 12407 int objectId = 0; 12408 // Not a '/' separated full component name; maybe an object ID? 12409 try { 12410 objectId = Integer.parseInt(name, 16); 12411 if (objects == null) { 12412 objects = new ArrayList<Integer>(); 12413 } 12414 objects.add(objectId); 12415 all = false; 12416 } catch (RuntimeException e) { 12417 // Not an integer; just do string match. 12418 if (strings == null) { 12419 strings = new ArrayList<String>(); 12420 } 12421 strings.add(name); 12422 all = false; 12423 } 12424 } 12425 } 12426 12427 int build(String[] args, int opti) { 12428 for (; opti<args.length; opti++) { 12429 String name = args[opti]; 12430 if ("--".equals(name)) { 12431 return opti+1; 12432 } 12433 build(name); 12434 } 12435 return opti; 12436 } 12437 12438 boolean match(Object object, ComponentName comp) { 12439 if (all) { 12440 return true; 12441 } 12442 if (components != null) { 12443 for (int i=0; i<components.size(); i++) { 12444 if (components.get(i).equals(comp)) { 12445 return true; 12446 } 12447 } 12448 } 12449 if (objects != null) { 12450 for (int i=0; i<objects.size(); i++) { 12451 if (System.identityHashCode(object) == objects.get(i)) { 12452 return true; 12453 } 12454 } 12455 } 12456 if (strings != null) { 12457 String flat = comp.flattenToString(); 12458 for (int i=0; i<strings.size(); i++) { 12459 if (flat.contains(strings.get(i))) { 12460 return true; 12461 } 12462 } 12463 } 12464 return false; 12465 } 12466 } 12467 12468 /** 12469 * There are three things that cmd can be: 12470 * - a flattened component name that matches an existing activity 12471 * - the cmd arg isn't the flattened component name of an existing activity: 12472 * dump all activity whose component contains the cmd as a substring 12473 * - A hex number of the ActivityRecord object instance. 12474 */ 12475 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12476 int opti, boolean dumpAll) { 12477 ArrayList<ActivityRecord> activities; 12478 12479 synchronized (this) { 12480 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12481 } 12482 12483 if (activities.size() <= 0) { 12484 return false; 12485 } 12486 12487 String[] newArgs = new String[args.length - opti]; 12488 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12489 12490 TaskRecord lastTask = null; 12491 boolean needSep = false; 12492 for (int i=activities.size()-1; i>=0; i--) { 12493 ActivityRecord r = activities.get(i); 12494 if (needSep) { 12495 pw.println(); 12496 } 12497 needSep = true; 12498 synchronized (this) { 12499 if (lastTask != r.task) { 12500 lastTask = r.task; 12501 pw.print("TASK "); pw.print(lastTask.affinity); 12502 pw.print(" id="); pw.println(lastTask.taskId); 12503 if (dumpAll) { 12504 lastTask.dump(pw, " "); 12505 } 12506 } 12507 } 12508 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12509 } 12510 return true; 12511 } 12512 12513 /** 12514 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12515 * there is a thread associated with the activity. 12516 */ 12517 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12518 final ActivityRecord r, String[] args, boolean dumpAll) { 12519 String innerPrefix = prefix + " "; 12520 synchronized (this) { 12521 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12522 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12523 pw.print(" pid="); 12524 if (r.app != null) pw.println(r.app.pid); 12525 else pw.println("(not running)"); 12526 if (dumpAll) { 12527 r.dump(pw, innerPrefix); 12528 } 12529 } 12530 if (r.app != null && r.app.thread != null) { 12531 // flush anything that is already in the PrintWriter since the thread is going 12532 // to write to the file descriptor directly 12533 pw.flush(); 12534 try { 12535 TransferPipe tp = new TransferPipe(); 12536 try { 12537 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12538 r.appToken, innerPrefix, args); 12539 tp.go(fd); 12540 } finally { 12541 tp.kill(); 12542 } 12543 } catch (IOException e) { 12544 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12545 } catch (RemoteException e) { 12546 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12547 } 12548 } 12549 } 12550 12551 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12552 int opti, boolean dumpAll, String dumpPackage) { 12553 boolean needSep = false; 12554 boolean onlyHistory = false; 12555 boolean printedAnything = false; 12556 12557 if ("history".equals(dumpPackage)) { 12558 if (opti < args.length && "-s".equals(args[opti])) { 12559 dumpAll = false; 12560 } 12561 onlyHistory = true; 12562 dumpPackage = null; 12563 } 12564 12565 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12566 if (!onlyHistory && dumpAll) { 12567 if (mRegisteredReceivers.size() > 0) { 12568 boolean printed = false; 12569 Iterator it = mRegisteredReceivers.values().iterator(); 12570 while (it.hasNext()) { 12571 ReceiverList r = (ReceiverList)it.next(); 12572 if (dumpPackage != null && (r.app == null || 12573 !dumpPackage.equals(r.app.info.packageName))) { 12574 continue; 12575 } 12576 if (!printed) { 12577 pw.println(" Registered Receivers:"); 12578 needSep = true; 12579 printed = true; 12580 printedAnything = true; 12581 } 12582 pw.print(" * "); pw.println(r); 12583 r.dump(pw, " "); 12584 } 12585 } 12586 12587 if (mReceiverResolver.dump(pw, needSep ? 12588 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12589 " ", dumpPackage, false)) { 12590 needSep = true; 12591 printedAnything = true; 12592 } 12593 } 12594 12595 for (BroadcastQueue q : mBroadcastQueues) { 12596 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12597 printedAnything |= needSep; 12598 } 12599 12600 needSep = true; 12601 12602 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12603 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12604 if (needSep) { 12605 pw.println(); 12606 } 12607 needSep = true; 12608 printedAnything = true; 12609 pw.print(" Sticky broadcasts for user "); 12610 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12611 StringBuilder sb = new StringBuilder(128); 12612 for (Map.Entry<String, ArrayList<Intent>> ent 12613 : mStickyBroadcasts.valueAt(user).entrySet()) { 12614 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12615 if (dumpAll) { 12616 pw.println(":"); 12617 ArrayList<Intent> intents = ent.getValue(); 12618 final int N = intents.size(); 12619 for (int i=0; i<N; i++) { 12620 sb.setLength(0); 12621 sb.append(" Intent: "); 12622 intents.get(i).toShortString(sb, false, true, false, false); 12623 pw.println(sb.toString()); 12624 Bundle bundle = intents.get(i).getExtras(); 12625 if (bundle != null) { 12626 pw.print(" "); 12627 pw.println(bundle.toString()); 12628 } 12629 } 12630 } else { 12631 pw.println(""); 12632 } 12633 } 12634 } 12635 } 12636 12637 if (!onlyHistory && dumpAll) { 12638 pw.println(); 12639 for (BroadcastQueue queue : mBroadcastQueues) { 12640 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12641 + queue.mBroadcastsScheduled); 12642 } 12643 pw.println(" mHandler:"); 12644 mHandler.dump(new PrintWriterPrinter(pw), " "); 12645 needSep = true; 12646 printedAnything = true; 12647 } 12648 12649 if (!printedAnything) { 12650 pw.println(" (nothing)"); 12651 } 12652 } 12653 12654 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12655 int opti, boolean dumpAll, String dumpPackage) { 12656 boolean needSep; 12657 boolean printedAnything = false; 12658 12659 ItemMatcher matcher = new ItemMatcher(); 12660 matcher.build(args, opti); 12661 12662 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12663 12664 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12665 printedAnything |= needSep; 12666 12667 if (mLaunchingProviders.size() > 0) { 12668 boolean printed = false; 12669 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12670 ContentProviderRecord r = mLaunchingProviders.get(i); 12671 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12672 continue; 12673 } 12674 if (!printed) { 12675 if (needSep) pw.println(); 12676 needSep = true; 12677 pw.println(" Launching content providers:"); 12678 printed = true; 12679 printedAnything = true; 12680 } 12681 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12682 pw.println(r); 12683 } 12684 } 12685 12686 if (mGrantedUriPermissions.size() > 0) { 12687 boolean printed = false; 12688 int dumpUid = -2; 12689 if (dumpPackage != null) { 12690 try { 12691 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12692 } catch (NameNotFoundException e) { 12693 dumpUid = -1; 12694 } 12695 } 12696 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12697 int uid = mGrantedUriPermissions.keyAt(i); 12698 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12699 continue; 12700 } 12701 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12702 if (!printed) { 12703 if (needSep) pw.println(); 12704 needSep = true; 12705 pw.println(" Granted Uri Permissions:"); 12706 printed = true; 12707 printedAnything = true; 12708 } 12709 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12710 for (UriPermission perm : perms.values()) { 12711 pw.print(" "); pw.println(perm); 12712 if (dumpAll) { 12713 perm.dump(pw, " "); 12714 } 12715 } 12716 } 12717 } 12718 12719 if (!printedAnything) { 12720 pw.println(" (nothing)"); 12721 } 12722 } 12723 12724 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12725 int opti, boolean dumpAll, String dumpPackage) { 12726 boolean printed = false; 12727 12728 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12729 12730 if (mIntentSenderRecords.size() > 0) { 12731 Iterator<WeakReference<PendingIntentRecord>> it 12732 = mIntentSenderRecords.values().iterator(); 12733 while (it.hasNext()) { 12734 WeakReference<PendingIntentRecord> ref = it.next(); 12735 PendingIntentRecord rec = ref != null ? ref.get(): null; 12736 if (dumpPackage != null && (rec == null 12737 || !dumpPackage.equals(rec.key.packageName))) { 12738 continue; 12739 } 12740 printed = true; 12741 if (rec != null) { 12742 pw.print(" * "); pw.println(rec); 12743 if (dumpAll) { 12744 rec.dump(pw, " "); 12745 } 12746 } else { 12747 pw.print(" * "); pw.println(ref); 12748 } 12749 } 12750 } 12751 12752 if (!printed) { 12753 pw.println(" (nothing)"); 12754 } 12755 } 12756 12757 private static final int dumpProcessList(PrintWriter pw, 12758 ActivityManagerService service, List list, 12759 String prefix, String normalLabel, String persistentLabel, 12760 String dumpPackage) { 12761 int numPers = 0; 12762 final int N = list.size()-1; 12763 for (int i=N; i>=0; i--) { 12764 ProcessRecord r = (ProcessRecord)list.get(i); 12765 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12766 continue; 12767 } 12768 pw.println(String.format("%s%s #%2d: %s", 12769 prefix, (r.persistent ? persistentLabel : normalLabel), 12770 i, r.toString())); 12771 if (r.persistent) { 12772 numPers++; 12773 } 12774 } 12775 return numPers; 12776 } 12777 12778 private static final boolean dumpProcessOomList(PrintWriter pw, 12779 ActivityManagerService service, List<ProcessRecord> origList, 12780 String prefix, String normalLabel, String persistentLabel, 12781 boolean inclDetails, String dumpPackage) { 12782 12783 ArrayList<Pair<ProcessRecord, Integer>> list 12784 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12785 for (int i=0; i<origList.size(); i++) { 12786 ProcessRecord r = origList.get(i); 12787 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12788 continue; 12789 } 12790 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12791 } 12792 12793 if (list.size() <= 0) { 12794 return false; 12795 } 12796 12797 Comparator<Pair<ProcessRecord, Integer>> comparator 12798 = new Comparator<Pair<ProcessRecord, Integer>>() { 12799 @Override 12800 public int compare(Pair<ProcessRecord, Integer> object1, 12801 Pair<ProcessRecord, Integer> object2) { 12802 if (object1.first.setAdj != object2.first.setAdj) { 12803 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12804 } 12805 if (object1.second.intValue() != object2.second.intValue()) { 12806 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12807 } 12808 return 0; 12809 } 12810 }; 12811 12812 Collections.sort(list, comparator); 12813 12814 final long curRealtime = SystemClock.elapsedRealtime(); 12815 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12816 final long curUptime = SystemClock.uptimeMillis(); 12817 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12818 12819 for (int i=list.size()-1; i>=0; i--) { 12820 ProcessRecord r = list.get(i).first; 12821 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12822 char schedGroup; 12823 switch (r.setSchedGroup) { 12824 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12825 schedGroup = 'B'; 12826 break; 12827 case Process.THREAD_GROUP_DEFAULT: 12828 schedGroup = 'F'; 12829 break; 12830 default: 12831 schedGroup = '?'; 12832 break; 12833 } 12834 char foreground; 12835 if (r.foregroundActivities) { 12836 foreground = 'A'; 12837 } else if (r.foregroundServices) { 12838 foreground = 'S'; 12839 } else { 12840 foreground = ' '; 12841 } 12842 String procState = ProcessList.makeProcStateString(r.curProcState); 12843 pw.print(prefix); 12844 pw.print(r.persistent ? persistentLabel : normalLabel); 12845 pw.print(" #"); 12846 int num = (origList.size()-1)-list.get(i).second; 12847 if (num < 10) pw.print(' '); 12848 pw.print(num); 12849 pw.print(": "); 12850 pw.print(oomAdj); 12851 pw.print(' '); 12852 pw.print(schedGroup); 12853 pw.print('/'); 12854 pw.print(foreground); 12855 pw.print('/'); 12856 pw.print(procState); 12857 pw.print(" trm:"); 12858 if (r.trimMemoryLevel < 10) pw.print(' '); 12859 pw.print(r.trimMemoryLevel); 12860 pw.print(' '); 12861 pw.print(r.toShortString()); 12862 pw.print(" ("); 12863 pw.print(r.adjType); 12864 pw.println(')'); 12865 if (r.adjSource != null || r.adjTarget != null) { 12866 pw.print(prefix); 12867 pw.print(" "); 12868 if (r.adjTarget instanceof ComponentName) { 12869 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12870 } else if (r.adjTarget != null) { 12871 pw.print(r.adjTarget.toString()); 12872 } else { 12873 pw.print("{null}"); 12874 } 12875 pw.print("<="); 12876 if (r.adjSource instanceof ProcessRecord) { 12877 pw.print("Proc{"); 12878 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12879 pw.println("}"); 12880 } else if (r.adjSource != null) { 12881 pw.println(r.adjSource.toString()); 12882 } else { 12883 pw.println("{null}"); 12884 } 12885 } 12886 if (inclDetails) { 12887 pw.print(prefix); 12888 pw.print(" "); 12889 pw.print("oom: max="); pw.print(r.maxAdj); 12890 pw.print(" curRaw="); pw.print(r.curRawAdj); 12891 pw.print(" setRaw="); pw.print(r.setRawAdj); 12892 pw.print(" cur="); pw.print(r.curAdj); 12893 pw.print(" set="); pw.println(r.setAdj); 12894 pw.print(prefix); 12895 pw.print(" "); 12896 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12897 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12898 pw.print(" lastPss="); pw.print(r.lastPss); 12899 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12900 pw.print(prefix); 12901 pw.print(" "); 12902 pw.print("cached="); pw.print(r.cached); 12903 pw.print(" empty="); pw.print(r.empty); 12904 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12905 12906 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12907 if (r.lastWakeTime != 0) { 12908 long wtime; 12909 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12910 synchronized (stats) { 12911 wtime = stats.getProcessWakeTime(r.info.uid, 12912 r.pid, curRealtime); 12913 } 12914 long timeUsed = wtime - r.lastWakeTime; 12915 pw.print(prefix); 12916 pw.print(" "); 12917 pw.print("keep awake over "); 12918 TimeUtils.formatDuration(realtimeSince, pw); 12919 pw.print(" used "); 12920 TimeUtils.formatDuration(timeUsed, pw); 12921 pw.print(" ("); 12922 pw.print((timeUsed*100)/realtimeSince); 12923 pw.println("%)"); 12924 } 12925 if (r.lastCpuTime != 0) { 12926 long timeUsed = r.curCpuTime - r.lastCpuTime; 12927 pw.print(prefix); 12928 pw.print(" "); 12929 pw.print("run cpu over "); 12930 TimeUtils.formatDuration(uptimeSince, pw); 12931 pw.print(" used "); 12932 TimeUtils.formatDuration(timeUsed, pw); 12933 pw.print(" ("); 12934 pw.print((timeUsed*100)/uptimeSince); 12935 pw.println("%)"); 12936 } 12937 } 12938 } 12939 } 12940 return true; 12941 } 12942 12943 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12944 ArrayList<ProcessRecord> procs; 12945 synchronized (this) { 12946 if (args != null && args.length > start 12947 && args[start].charAt(0) != '-') { 12948 procs = new ArrayList<ProcessRecord>(); 12949 int pid = -1; 12950 try { 12951 pid = Integer.parseInt(args[start]); 12952 } catch (NumberFormatException e) { 12953 } 12954 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12955 ProcessRecord proc = mLruProcesses.get(i); 12956 if (proc.pid == pid) { 12957 procs.add(proc); 12958 } else if (proc.processName.equals(args[start])) { 12959 procs.add(proc); 12960 } 12961 } 12962 if (procs.size() <= 0) { 12963 return null; 12964 } 12965 } else { 12966 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12967 } 12968 } 12969 return procs; 12970 } 12971 12972 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12973 PrintWriter pw, String[] args) { 12974 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12975 if (procs == null) { 12976 pw.println("No process found for: " + args[0]); 12977 return; 12978 } 12979 12980 long uptime = SystemClock.uptimeMillis(); 12981 long realtime = SystemClock.elapsedRealtime(); 12982 pw.println("Applications Graphics Acceleration Info:"); 12983 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12984 12985 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12986 ProcessRecord r = procs.get(i); 12987 if (r.thread != null) { 12988 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12989 pw.flush(); 12990 try { 12991 TransferPipe tp = new TransferPipe(); 12992 try { 12993 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12994 tp.go(fd); 12995 } finally { 12996 tp.kill(); 12997 } 12998 } catch (IOException e) { 12999 pw.println("Failure while dumping the app: " + r); 13000 pw.flush(); 13001 } catch (RemoteException e) { 13002 pw.println("Got a RemoteException while dumping the app " + r); 13003 pw.flush(); 13004 } 13005 } 13006 } 13007 } 13008 13009 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13010 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13011 if (procs == null) { 13012 pw.println("No process found for: " + args[0]); 13013 return; 13014 } 13015 13016 pw.println("Applications Database Info:"); 13017 13018 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13019 ProcessRecord r = procs.get(i); 13020 if (r.thread != null) { 13021 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13022 pw.flush(); 13023 try { 13024 TransferPipe tp = new TransferPipe(); 13025 try { 13026 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13027 tp.go(fd); 13028 } finally { 13029 tp.kill(); 13030 } 13031 } catch (IOException e) { 13032 pw.println("Failure while dumping the app: " + r); 13033 pw.flush(); 13034 } catch (RemoteException e) { 13035 pw.println("Got a RemoteException while dumping the app " + r); 13036 pw.flush(); 13037 } 13038 } 13039 } 13040 } 13041 13042 final static class MemItem { 13043 final boolean isProc; 13044 final String label; 13045 final String shortLabel; 13046 final long pss; 13047 final int id; 13048 final boolean hasActivities; 13049 ArrayList<MemItem> subitems; 13050 13051 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13052 boolean _hasActivities) { 13053 isProc = true; 13054 label = _label; 13055 shortLabel = _shortLabel; 13056 pss = _pss; 13057 id = _id; 13058 hasActivities = _hasActivities; 13059 } 13060 13061 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13062 isProc = false; 13063 label = _label; 13064 shortLabel = _shortLabel; 13065 pss = _pss; 13066 id = _id; 13067 hasActivities = false; 13068 } 13069 } 13070 13071 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13072 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13073 if (sort && !isCompact) { 13074 Collections.sort(items, new Comparator<MemItem>() { 13075 @Override 13076 public int compare(MemItem lhs, MemItem rhs) { 13077 if (lhs.pss < rhs.pss) { 13078 return 1; 13079 } else if (lhs.pss > rhs.pss) { 13080 return -1; 13081 } 13082 return 0; 13083 } 13084 }); 13085 } 13086 13087 for (int i=0; i<items.size(); i++) { 13088 MemItem mi = items.get(i); 13089 if (!isCompact) { 13090 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13091 } else if (mi.isProc) { 13092 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13093 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13094 pw.println(mi.hasActivities ? ",a" : ",e"); 13095 } else { 13096 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13097 pw.println(mi.pss); 13098 } 13099 if (mi.subitems != null) { 13100 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13101 true, isCompact); 13102 } 13103 } 13104 } 13105 13106 // These are in KB. 13107 static final long[] DUMP_MEM_BUCKETS = new long[] { 13108 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13109 120*1024, 160*1024, 200*1024, 13110 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13111 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13112 }; 13113 13114 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13115 boolean stackLike) { 13116 int start = label.lastIndexOf('.'); 13117 if (start >= 0) start++; 13118 else start = 0; 13119 int end = label.length(); 13120 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13121 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13122 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13123 out.append(bucket); 13124 out.append(stackLike ? "MB." : "MB "); 13125 out.append(label, start, end); 13126 return; 13127 } 13128 } 13129 out.append(memKB/1024); 13130 out.append(stackLike ? "MB." : "MB "); 13131 out.append(label, start, end); 13132 } 13133 13134 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13135 ProcessList.NATIVE_ADJ, 13136 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13137 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13138 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13139 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13140 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13141 }; 13142 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13143 "Native", 13144 "System", "Persistent", "Foreground", 13145 "Visible", "Perceptible", 13146 "Heavy Weight", "Backup", 13147 "A Services", "Home", 13148 "Previous", "B Services", "Cached" 13149 }; 13150 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13151 "native", 13152 "sys", "pers", "fore", 13153 "vis", "percept", 13154 "heavy", "backup", 13155 "servicea", "home", 13156 "prev", "serviceb", "cached" 13157 }; 13158 13159 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13160 long realtime, boolean isCheckinRequest, boolean isCompact) { 13161 if (isCheckinRequest || isCompact) { 13162 // short checkin version 13163 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13164 } else { 13165 pw.println("Applications Memory Usage (kB):"); 13166 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13167 } 13168 } 13169 13170 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13171 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13172 boolean dumpDetails = false; 13173 boolean dumpFullDetails = false; 13174 boolean dumpDalvik = false; 13175 boolean oomOnly = false; 13176 boolean isCompact = false; 13177 boolean localOnly = false; 13178 13179 int opti = 0; 13180 while (opti < args.length) { 13181 String opt = args[opti]; 13182 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13183 break; 13184 } 13185 opti++; 13186 if ("-a".equals(opt)) { 13187 dumpDetails = true; 13188 dumpFullDetails = true; 13189 dumpDalvik = true; 13190 } else if ("-d".equals(opt)) { 13191 dumpDalvik = true; 13192 } else if ("-c".equals(opt)) { 13193 isCompact = true; 13194 } else if ("--oom".equals(opt)) { 13195 oomOnly = true; 13196 } else if ("--local".equals(opt)) { 13197 localOnly = true; 13198 } else if ("-h".equals(opt)) { 13199 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13200 pw.println(" -a: include all available information for each process."); 13201 pw.println(" -d: include dalvik details when dumping process details."); 13202 pw.println(" -c: dump in a compact machine-parseable representation."); 13203 pw.println(" --oom: only show processes organized by oom adj."); 13204 pw.println(" --local: only collect details locally, don't call process."); 13205 pw.println("If [process] is specified it can be the name or "); 13206 pw.println("pid of a specific process to dump."); 13207 return; 13208 } else { 13209 pw.println("Unknown argument: " + opt + "; use -h for help"); 13210 } 13211 } 13212 13213 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13214 long uptime = SystemClock.uptimeMillis(); 13215 long realtime = SystemClock.elapsedRealtime(); 13216 final long[] tmpLong = new long[1]; 13217 13218 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13219 if (procs == null) { 13220 // No Java processes. Maybe they want to print a native process. 13221 if (args != null && args.length > opti 13222 && args[opti].charAt(0) != '-') { 13223 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13224 = new ArrayList<ProcessCpuTracker.Stats>(); 13225 updateCpuStatsNow(); 13226 int findPid = -1; 13227 try { 13228 findPid = Integer.parseInt(args[opti]); 13229 } catch (NumberFormatException e) { 13230 } 13231 synchronized (mProcessCpuThread) { 13232 final int N = mProcessCpuTracker.countStats(); 13233 for (int i=0; i<N; i++) { 13234 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13235 if (st.pid == findPid || (st.baseName != null 13236 && st.baseName.equals(args[opti]))) { 13237 nativeProcs.add(st); 13238 } 13239 } 13240 } 13241 if (nativeProcs.size() > 0) { 13242 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13243 isCompact); 13244 Debug.MemoryInfo mi = null; 13245 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13246 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13247 final int pid = r.pid; 13248 if (!isCheckinRequest && dumpDetails) { 13249 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13250 } 13251 if (mi == null) { 13252 mi = new Debug.MemoryInfo(); 13253 } 13254 if (dumpDetails || (!brief && !oomOnly)) { 13255 Debug.getMemoryInfo(pid, mi); 13256 } else { 13257 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13258 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13259 } 13260 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13261 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13262 if (isCheckinRequest) { 13263 pw.println(); 13264 } 13265 } 13266 return; 13267 } 13268 } 13269 pw.println("No process found for: " + args[opti]); 13270 return; 13271 } 13272 13273 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13274 dumpDetails = true; 13275 } 13276 13277 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13278 13279 String[] innerArgs = new String[args.length-opti]; 13280 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13281 13282 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13283 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13284 long nativePss=0, dalvikPss=0, otherPss=0; 13285 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13286 13287 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13288 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13289 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13290 13291 long totalPss = 0; 13292 long cachedPss = 0; 13293 13294 Debug.MemoryInfo mi = null; 13295 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13296 final ProcessRecord r = procs.get(i); 13297 final IApplicationThread thread; 13298 final int pid; 13299 final int oomAdj; 13300 final boolean hasActivities; 13301 synchronized (this) { 13302 thread = r.thread; 13303 pid = r.pid; 13304 oomAdj = r.getSetAdjWithServices(); 13305 hasActivities = r.activities.size() > 0; 13306 } 13307 if (thread != null) { 13308 if (!isCheckinRequest && dumpDetails) { 13309 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13310 } 13311 if (mi == null) { 13312 mi = new Debug.MemoryInfo(); 13313 } 13314 if (dumpDetails || (!brief && !oomOnly)) { 13315 Debug.getMemoryInfo(pid, mi); 13316 } else { 13317 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13318 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13319 } 13320 if (dumpDetails) { 13321 if (localOnly) { 13322 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13323 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13324 if (isCheckinRequest) { 13325 pw.println(); 13326 } 13327 } else { 13328 try { 13329 pw.flush(); 13330 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13331 dumpDalvik, innerArgs); 13332 } catch (RemoteException e) { 13333 if (!isCheckinRequest) { 13334 pw.println("Got RemoteException!"); 13335 pw.flush(); 13336 } 13337 } 13338 } 13339 } 13340 13341 final long myTotalPss = mi.getTotalPss(); 13342 final long myTotalUss = mi.getTotalUss(); 13343 13344 synchronized (this) { 13345 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13346 // Record this for posterity if the process has been stable. 13347 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13348 } 13349 } 13350 13351 if (!isCheckinRequest && mi != null) { 13352 totalPss += myTotalPss; 13353 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13354 (hasActivities ? " / activities)" : ")"), 13355 r.processName, myTotalPss, pid, hasActivities); 13356 procMems.add(pssItem); 13357 procMemsMap.put(pid, pssItem); 13358 13359 nativePss += mi.nativePss; 13360 dalvikPss += mi.dalvikPss; 13361 otherPss += mi.otherPss; 13362 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13363 long mem = mi.getOtherPss(j); 13364 miscPss[j] += mem; 13365 otherPss -= mem; 13366 } 13367 13368 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13369 cachedPss += myTotalPss; 13370 } 13371 13372 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13373 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13374 || oomIndex == (oomPss.length-1)) { 13375 oomPss[oomIndex] += myTotalPss; 13376 if (oomProcs[oomIndex] == null) { 13377 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13378 } 13379 oomProcs[oomIndex].add(pssItem); 13380 break; 13381 } 13382 } 13383 } 13384 } 13385 } 13386 13387 long nativeProcTotalPss = 0; 13388 13389 if (!isCheckinRequest && procs.size() > 1) { 13390 // If we are showing aggregations, also look for native processes to 13391 // include so that our aggregations are more accurate. 13392 updateCpuStatsNow(); 13393 synchronized (mProcessCpuThread) { 13394 final int N = mProcessCpuTracker.countStats(); 13395 for (int i=0; i<N; i++) { 13396 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13397 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13398 if (mi == null) { 13399 mi = new Debug.MemoryInfo(); 13400 } 13401 if (!brief && !oomOnly) { 13402 Debug.getMemoryInfo(st.pid, mi); 13403 } else { 13404 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13405 mi.nativePrivateDirty = (int)tmpLong[0]; 13406 } 13407 13408 final long myTotalPss = mi.getTotalPss(); 13409 totalPss += myTotalPss; 13410 nativeProcTotalPss += myTotalPss; 13411 13412 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13413 st.name, myTotalPss, st.pid, false); 13414 procMems.add(pssItem); 13415 13416 nativePss += mi.nativePss; 13417 dalvikPss += mi.dalvikPss; 13418 otherPss += mi.otherPss; 13419 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13420 long mem = mi.getOtherPss(j); 13421 miscPss[j] += mem; 13422 otherPss -= mem; 13423 } 13424 oomPss[0] += myTotalPss; 13425 if (oomProcs[0] == null) { 13426 oomProcs[0] = new ArrayList<MemItem>(); 13427 } 13428 oomProcs[0].add(pssItem); 13429 } 13430 } 13431 } 13432 13433 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13434 13435 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13436 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13437 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13438 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13439 String label = Debug.MemoryInfo.getOtherLabel(j); 13440 catMems.add(new MemItem(label, label, miscPss[j], j)); 13441 } 13442 13443 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13444 for (int j=0; j<oomPss.length; j++) { 13445 if (oomPss[j] != 0) { 13446 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13447 : DUMP_MEM_OOM_LABEL[j]; 13448 MemItem item = new MemItem(label, label, oomPss[j], 13449 DUMP_MEM_OOM_ADJ[j]); 13450 item.subitems = oomProcs[j]; 13451 oomMems.add(item); 13452 } 13453 } 13454 13455 if (!brief && !oomOnly && !isCompact) { 13456 pw.println(); 13457 pw.println("Total PSS by process:"); 13458 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13459 pw.println(); 13460 } 13461 if (!isCompact) { 13462 pw.println("Total PSS by OOM adjustment:"); 13463 } 13464 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13465 if (!brief && !oomOnly) { 13466 PrintWriter out = categoryPw != null ? categoryPw : pw; 13467 if (!isCompact) { 13468 out.println(); 13469 out.println("Total PSS by category:"); 13470 } 13471 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13472 } 13473 if (!isCompact) { 13474 pw.println(); 13475 } 13476 MemInfoReader memInfo = new MemInfoReader(); 13477 memInfo.readMemInfo(); 13478 if (nativeProcTotalPss > 0) { 13479 synchronized (this) { 13480 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13481 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13482 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13483 nativeProcTotalPss); 13484 } 13485 } 13486 if (!brief) { 13487 if (!isCompact) { 13488 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13489 pw.print(" kB (status "); 13490 switch (mLastMemoryLevel) { 13491 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13492 pw.println("normal)"); 13493 break; 13494 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13495 pw.println("moderate)"); 13496 break; 13497 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13498 pw.println("low)"); 13499 break; 13500 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13501 pw.println("critical)"); 13502 break; 13503 default: 13504 pw.print(mLastMemoryLevel); 13505 pw.println(")"); 13506 break; 13507 } 13508 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13509 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13510 pw.print(cachedPss); pw.print(" cached pss + "); 13511 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13512 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13513 } else { 13514 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13515 pw.print(cachedPss + memInfo.getCachedSizeKb() 13516 + memInfo.getFreeSizeKb()); pw.print(","); 13517 pw.println(totalPss - cachedPss); 13518 } 13519 } 13520 if (!isCompact) { 13521 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13522 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13523 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13524 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13525 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13526 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13527 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13528 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13529 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13530 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13531 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13532 } 13533 if (!brief) { 13534 if (memInfo.getZramTotalSizeKb() != 0) { 13535 if (!isCompact) { 13536 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13537 pw.print(" kB physical used for "); 13538 pw.print(memInfo.getSwapTotalSizeKb() 13539 - memInfo.getSwapFreeSizeKb()); 13540 pw.print(" kB in swap ("); 13541 pw.print(memInfo.getSwapTotalSizeKb()); 13542 pw.println(" kB total swap)"); 13543 } else { 13544 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13545 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13546 pw.println(memInfo.getSwapFreeSizeKb()); 13547 } 13548 } 13549 final int[] SINGLE_LONG_FORMAT = new int[] { 13550 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13551 }; 13552 long[] longOut = new long[1]; 13553 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13554 SINGLE_LONG_FORMAT, null, longOut, null); 13555 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13556 longOut[0] = 0; 13557 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13558 SINGLE_LONG_FORMAT, null, longOut, null); 13559 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13560 longOut[0] = 0; 13561 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13562 SINGLE_LONG_FORMAT, null, longOut, null); 13563 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13564 longOut[0] = 0; 13565 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13566 SINGLE_LONG_FORMAT, null, longOut, null); 13567 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13568 if (!isCompact) { 13569 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13570 pw.print(" KSM: "); pw.print(sharing); 13571 pw.print(" kB saved from shared "); 13572 pw.print(shared); pw.println(" kB"); 13573 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13574 pw.print(voltile); pw.println(" kB volatile"); 13575 } 13576 pw.print(" Tuning: "); 13577 pw.print(ActivityManager.staticGetMemoryClass()); 13578 pw.print(" (large "); 13579 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13580 pw.print("), oom "); 13581 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13582 pw.print(" kB"); 13583 pw.print(", restore limit "); 13584 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13585 pw.print(" kB"); 13586 if (ActivityManager.isLowRamDeviceStatic()) { 13587 pw.print(" (low-ram)"); 13588 } 13589 if (ActivityManager.isHighEndGfx()) { 13590 pw.print(" (high-end-gfx)"); 13591 } 13592 pw.println(); 13593 } else { 13594 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13595 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13596 pw.println(voltile); 13597 pw.print("tuning,"); 13598 pw.print(ActivityManager.staticGetMemoryClass()); 13599 pw.print(','); 13600 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13601 pw.print(','); 13602 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13603 if (ActivityManager.isLowRamDeviceStatic()) { 13604 pw.print(",low-ram"); 13605 } 13606 if (ActivityManager.isHighEndGfx()) { 13607 pw.print(",high-end-gfx"); 13608 } 13609 pw.println(); 13610 } 13611 } 13612 } 13613 } 13614 13615 /** 13616 * Searches array of arguments for the specified string 13617 * @param args array of argument strings 13618 * @param value value to search for 13619 * @return true if the value is contained in the array 13620 */ 13621 private static boolean scanArgs(String[] args, String value) { 13622 if (args != null) { 13623 for (String arg : args) { 13624 if (value.equals(arg)) { 13625 return true; 13626 } 13627 } 13628 } 13629 return false; 13630 } 13631 13632 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13633 ContentProviderRecord cpr, boolean always) { 13634 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13635 13636 if (!inLaunching || always) { 13637 synchronized (cpr) { 13638 cpr.launchingApp = null; 13639 cpr.notifyAll(); 13640 } 13641 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13642 String names[] = cpr.info.authority.split(";"); 13643 for (int j = 0; j < names.length; j++) { 13644 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13645 } 13646 } 13647 13648 for (int i=0; i<cpr.connections.size(); i++) { 13649 ContentProviderConnection conn = cpr.connections.get(i); 13650 if (conn.waiting) { 13651 // If this connection is waiting for the provider, then we don't 13652 // need to mess with its process unless we are always removing 13653 // or for some reason the provider is not currently launching. 13654 if (inLaunching && !always) { 13655 continue; 13656 } 13657 } 13658 ProcessRecord capp = conn.client; 13659 conn.dead = true; 13660 if (conn.stableCount > 0) { 13661 if (!capp.persistent && capp.thread != null 13662 && capp.pid != 0 13663 && capp.pid != MY_PID) { 13664 killUnneededProcessLocked(capp, "depends on provider " 13665 + cpr.name.flattenToShortString() 13666 + " in dying proc " + (proc != null ? proc.processName : "??")); 13667 } 13668 } else if (capp.thread != null && conn.provider.provider != null) { 13669 try { 13670 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13671 } catch (RemoteException e) { 13672 } 13673 // In the protocol here, we don't expect the client to correctly 13674 // clean up this connection, we'll just remove it. 13675 cpr.connections.remove(i); 13676 conn.client.conProviders.remove(conn); 13677 } 13678 } 13679 13680 if (inLaunching && always) { 13681 mLaunchingProviders.remove(cpr); 13682 } 13683 return inLaunching; 13684 } 13685 13686 /** 13687 * Main code for cleaning up a process when it has gone away. This is 13688 * called both as a result of the process dying, or directly when stopping 13689 * a process when running in single process mode. 13690 */ 13691 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13692 boolean restarting, boolean allowRestart, int index) { 13693 if (index >= 0) { 13694 removeLruProcessLocked(app); 13695 ProcessList.remove(app.pid); 13696 } 13697 13698 mProcessesToGc.remove(app); 13699 mPendingPssProcesses.remove(app); 13700 13701 // Dismiss any open dialogs. 13702 if (app.crashDialog != null && !app.forceCrashReport) { 13703 app.crashDialog.dismiss(); 13704 app.crashDialog = null; 13705 } 13706 if (app.anrDialog != null) { 13707 app.anrDialog.dismiss(); 13708 app.anrDialog = null; 13709 } 13710 if (app.waitDialog != null) { 13711 app.waitDialog.dismiss(); 13712 app.waitDialog = null; 13713 } 13714 13715 app.crashing = false; 13716 app.notResponding = false; 13717 13718 app.resetPackageList(mProcessStats); 13719 app.unlinkDeathRecipient(); 13720 app.makeInactive(mProcessStats); 13721 app.waitingToKill = null; 13722 app.forcingToForeground = null; 13723 updateProcessForegroundLocked(app, false, false); 13724 app.foregroundActivities = false; 13725 app.hasShownUi = false; 13726 app.treatLikeActivity = false; 13727 app.hasAboveClient = false; 13728 app.hasClientActivities = false; 13729 13730 mServices.killServicesLocked(app, allowRestart); 13731 13732 boolean restart = false; 13733 13734 // Remove published content providers. 13735 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13736 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13737 final boolean always = app.bad || !allowRestart; 13738 if (removeDyingProviderLocked(app, cpr, always) || always) { 13739 // We left the provider in the launching list, need to 13740 // restart it. 13741 restart = true; 13742 } 13743 13744 cpr.provider = null; 13745 cpr.proc = null; 13746 } 13747 app.pubProviders.clear(); 13748 13749 // Take care of any launching providers waiting for this process. 13750 if (checkAppInLaunchingProvidersLocked(app, false)) { 13751 restart = true; 13752 } 13753 13754 // Unregister from connected content providers. 13755 if (!app.conProviders.isEmpty()) { 13756 for (int i=0; i<app.conProviders.size(); i++) { 13757 ContentProviderConnection conn = app.conProviders.get(i); 13758 conn.provider.connections.remove(conn); 13759 } 13760 app.conProviders.clear(); 13761 } 13762 13763 // At this point there may be remaining entries in mLaunchingProviders 13764 // where we were the only one waiting, so they are no longer of use. 13765 // Look for these and clean up if found. 13766 // XXX Commented out for now. Trying to figure out a way to reproduce 13767 // the actual situation to identify what is actually going on. 13768 if (false) { 13769 for (int i=0; i<mLaunchingProviders.size(); i++) { 13770 ContentProviderRecord cpr = (ContentProviderRecord) 13771 mLaunchingProviders.get(i); 13772 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13773 synchronized (cpr) { 13774 cpr.launchingApp = null; 13775 cpr.notifyAll(); 13776 } 13777 } 13778 } 13779 } 13780 13781 skipCurrentReceiverLocked(app); 13782 13783 // Unregister any receivers. 13784 for (int i=app.receivers.size()-1; i>=0; i--) { 13785 removeReceiverLocked(app.receivers.valueAt(i)); 13786 } 13787 app.receivers.clear(); 13788 13789 // If the app is undergoing backup, tell the backup manager about it 13790 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13791 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13792 + mBackupTarget.appInfo + " died during backup"); 13793 try { 13794 IBackupManager bm = IBackupManager.Stub.asInterface( 13795 ServiceManager.getService(Context.BACKUP_SERVICE)); 13796 bm.agentDisconnected(app.info.packageName); 13797 } catch (RemoteException e) { 13798 // can't happen; backup manager is local 13799 } 13800 } 13801 13802 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13803 ProcessChangeItem item = mPendingProcessChanges.get(i); 13804 if (item.pid == app.pid) { 13805 mPendingProcessChanges.remove(i); 13806 mAvailProcessChanges.add(item); 13807 } 13808 } 13809 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13810 13811 // If the caller is restarting this app, then leave it in its 13812 // current lists and let the caller take care of it. 13813 if (restarting) { 13814 return; 13815 } 13816 13817 if (!app.persistent || app.isolated) { 13818 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13819 "Removing non-persistent process during cleanup: " + app); 13820 mProcessNames.remove(app.processName, app.uid); 13821 mIsolatedProcesses.remove(app.uid); 13822 if (mHeavyWeightProcess == app) { 13823 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13824 mHeavyWeightProcess.userId, 0)); 13825 mHeavyWeightProcess = null; 13826 } 13827 } else if (!app.removed) { 13828 // This app is persistent, so we need to keep its record around. 13829 // If it is not already on the pending app list, add it there 13830 // and start a new process for it. 13831 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13832 mPersistentStartingProcesses.add(app); 13833 restart = true; 13834 } 13835 } 13836 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13837 "Clean-up removing on hold: " + app); 13838 mProcessesOnHold.remove(app); 13839 13840 if (app == mHomeProcess) { 13841 mHomeProcess = null; 13842 } 13843 if (app == mPreviousProcess) { 13844 mPreviousProcess = null; 13845 } 13846 13847 if (restart && !app.isolated) { 13848 // We have components that still need to be running in the 13849 // process, so re-launch it. 13850 mProcessNames.put(app.processName, app.uid, app); 13851 startProcessLocked(app, "restart", app.processName); 13852 } else if (app.pid > 0 && app.pid != MY_PID) { 13853 // Goodbye! 13854 boolean removed; 13855 synchronized (mPidsSelfLocked) { 13856 mPidsSelfLocked.remove(app.pid); 13857 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13858 } 13859 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13860 if (app.isolated) { 13861 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13862 } 13863 app.setPid(0); 13864 } 13865 } 13866 13867 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13868 // Look through the content providers we are waiting to have launched, 13869 // and if any run in this process then either schedule a restart of 13870 // the process or kill the client waiting for it if this process has 13871 // gone bad. 13872 int NL = mLaunchingProviders.size(); 13873 boolean restart = false; 13874 for (int i=0; i<NL; i++) { 13875 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13876 if (cpr.launchingApp == app) { 13877 if (!alwaysBad && !app.bad) { 13878 restart = true; 13879 } else { 13880 removeDyingProviderLocked(app, cpr, true); 13881 // cpr should have been removed from mLaunchingProviders 13882 NL = mLaunchingProviders.size(); 13883 i--; 13884 } 13885 } 13886 } 13887 return restart; 13888 } 13889 13890 // ========================================================= 13891 // SERVICES 13892 // ========================================================= 13893 13894 @Override 13895 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13896 int flags) { 13897 enforceNotIsolatedCaller("getServices"); 13898 synchronized (this) { 13899 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13900 } 13901 } 13902 13903 @Override 13904 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13905 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13906 synchronized (this) { 13907 return mServices.getRunningServiceControlPanelLocked(name); 13908 } 13909 } 13910 13911 @Override 13912 public ComponentName startService(IApplicationThread caller, Intent service, 13913 String resolvedType, int userId) { 13914 enforceNotIsolatedCaller("startService"); 13915 // Refuse possible leaked file descriptors 13916 if (service != null && service.hasFileDescriptors() == true) { 13917 throw new IllegalArgumentException("File descriptors passed in Intent"); 13918 } 13919 13920 if (DEBUG_SERVICE) 13921 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13922 synchronized(this) { 13923 final int callingPid = Binder.getCallingPid(); 13924 final int callingUid = Binder.getCallingUid(); 13925 final long origId = Binder.clearCallingIdentity(); 13926 ComponentName res = mServices.startServiceLocked(caller, service, 13927 resolvedType, callingPid, callingUid, userId); 13928 Binder.restoreCallingIdentity(origId); 13929 return res; 13930 } 13931 } 13932 13933 ComponentName startServiceInPackage(int uid, 13934 Intent service, String resolvedType, int userId) { 13935 synchronized(this) { 13936 if (DEBUG_SERVICE) 13937 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13938 final long origId = Binder.clearCallingIdentity(); 13939 ComponentName res = mServices.startServiceLocked(null, service, 13940 resolvedType, -1, uid, userId); 13941 Binder.restoreCallingIdentity(origId); 13942 return res; 13943 } 13944 } 13945 13946 @Override 13947 public int stopService(IApplicationThread caller, Intent service, 13948 String resolvedType, int userId) { 13949 enforceNotIsolatedCaller("stopService"); 13950 // Refuse possible leaked file descriptors 13951 if (service != null && service.hasFileDescriptors() == true) { 13952 throw new IllegalArgumentException("File descriptors passed in Intent"); 13953 } 13954 13955 synchronized(this) { 13956 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13957 } 13958 } 13959 13960 @Override 13961 public IBinder peekService(Intent service, String resolvedType) { 13962 enforceNotIsolatedCaller("peekService"); 13963 // Refuse possible leaked file descriptors 13964 if (service != null && service.hasFileDescriptors() == true) { 13965 throw new IllegalArgumentException("File descriptors passed in Intent"); 13966 } 13967 synchronized(this) { 13968 return mServices.peekServiceLocked(service, resolvedType); 13969 } 13970 } 13971 13972 @Override 13973 public boolean stopServiceToken(ComponentName className, IBinder token, 13974 int startId) { 13975 synchronized(this) { 13976 return mServices.stopServiceTokenLocked(className, token, startId); 13977 } 13978 } 13979 13980 @Override 13981 public void setServiceForeground(ComponentName className, IBinder token, 13982 int id, Notification notification, boolean removeNotification) { 13983 synchronized(this) { 13984 mServices.setServiceForegroundLocked(className, token, id, notification, 13985 removeNotification); 13986 } 13987 } 13988 13989 @Override 13990 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13991 boolean requireFull, String name, String callerPackage) { 13992 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13993 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13994 } 13995 13996 int unsafeConvertIncomingUser(int userId) { 13997 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13998 ? mCurrentUserId : userId; 13999 } 14000 14001 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14002 int allowMode, String name, String callerPackage) { 14003 final int callingUserId = UserHandle.getUserId(callingUid); 14004 if (callingUserId == userId) { 14005 return userId; 14006 } 14007 14008 // Note that we may be accessing mCurrentUserId outside of a lock... 14009 // shouldn't be a big deal, if this is being called outside 14010 // of a locked context there is intrinsically a race with 14011 // the value the caller will receive and someone else changing it. 14012 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14013 // we will switch to the calling user if access to the current user fails. 14014 int targetUserId = unsafeConvertIncomingUser(userId); 14015 14016 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14017 final boolean allow; 14018 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14019 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14020 // If the caller has this permission, they always pass go. And collect $200. 14021 allow = true; 14022 } else if (allowMode == ALLOW_FULL_ONLY) { 14023 // We require full access, sucks to be you. 14024 allow = false; 14025 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14026 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14027 // If the caller does not have either permission, they are always doomed. 14028 allow = false; 14029 } else if (allowMode == ALLOW_NON_FULL) { 14030 // We are blanket allowing non-full access, you lucky caller! 14031 allow = true; 14032 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14033 // We may or may not allow this depending on whether the two users are 14034 // in the same profile. 14035 synchronized (mUserProfileGroupIdsSelfLocked) { 14036 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14037 UserInfo.NO_PROFILE_GROUP_ID); 14038 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14039 UserInfo.NO_PROFILE_GROUP_ID); 14040 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14041 && callingProfile == targetProfile; 14042 } 14043 } else { 14044 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14045 } 14046 if (!allow) { 14047 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14048 // In this case, they would like to just execute as their 14049 // owner user instead of failing. 14050 targetUserId = callingUserId; 14051 } else { 14052 StringBuilder builder = new StringBuilder(128); 14053 builder.append("Permission Denial: "); 14054 builder.append(name); 14055 if (callerPackage != null) { 14056 builder.append(" from "); 14057 builder.append(callerPackage); 14058 } 14059 builder.append(" asks to run as user "); 14060 builder.append(userId); 14061 builder.append(" but is calling from user "); 14062 builder.append(UserHandle.getUserId(callingUid)); 14063 builder.append("; this requires "); 14064 builder.append(INTERACT_ACROSS_USERS_FULL); 14065 if (allowMode != ALLOW_FULL_ONLY) { 14066 builder.append(" or "); 14067 builder.append(INTERACT_ACROSS_USERS); 14068 } 14069 String msg = builder.toString(); 14070 Slog.w(TAG, msg); 14071 throw new SecurityException(msg); 14072 } 14073 } 14074 } 14075 if (!allowAll && targetUserId < 0) { 14076 throw new IllegalArgumentException( 14077 "Call does not support special user #" + targetUserId); 14078 } 14079 return targetUserId; 14080 } 14081 14082 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14083 String className, int flags) { 14084 boolean result = false; 14085 // For apps that don't have pre-defined UIDs, check for permission 14086 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14087 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14088 if (ActivityManager.checkUidPermission( 14089 INTERACT_ACROSS_USERS, 14090 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14091 ComponentName comp = new ComponentName(aInfo.packageName, className); 14092 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14093 + " requests FLAG_SINGLE_USER, but app does not hold " 14094 + INTERACT_ACROSS_USERS; 14095 Slog.w(TAG, msg); 14096 throw new SecurityException(msg); 14097 } 14098 // Permission passed 14099 result = true; 14100 } 14101 } else if ("system".equals(componentProcessName)) { 14102 result = true; 14103 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14104 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14105 // Phone app is allowed to export singleuser providers. 14106 result = true; 14107 } else { 14108 // App with pre-defined UID, check if it's a persistent app 14109 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14110 } 14111 if (DEBUG_MU) { 14112 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14113 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14114 } 14115 return result; 14116 } 14117 14118 /** 14119 * Checks to see if the caller is in the same app as the singleton 14120 * component, or the component is in a special app. It allows special apps 14121 * to export singleton components but prevents exporting singleton 14122 * components for regular apps. 14123 */ 14124 boolean isValidSingletonCall(int callingUid, int componentUid) { 14125 int componentAppId = UserHandle.getAppId(componentUid); 14126 return UserHandle.isSameApp(callingUid, componentUid) 14127 || componentAppId == Process.SYSTEM_UID 14128 || componentAppId == Process.PHONE_UID 14129 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14130 == PackageManager.PERMISSION_GRANTED; 14131 } 14132 14133 public int bindService(IApplicationThread caller, IBinder token, 14134 Intent service, String resolvedType, 14135 IServiceConnection connection, int flags, int userId) { 14136 enforceNotIsolatedCaller("bindService"); 14137 // Refuse possible leaked file descriptors 14138 if (service != null && service.hasFileDescriptors() == true) { 14139 throw new IllegalArgumentException("File descriptors passed in Intent"); 14140 } 14141 14142 synchronized(this) { 14143 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14144 connection, flags, userId); 14145 } 14146 } 14147 14148 public boolean unbindService(IServiceConnection connection) { 14149 synchronized (this) { 14150 return mServices.unbindServiceLocked(connection); 14151 } 14152 } 14153 14154 public void publishService(IBinder token, Intent intent, IBinder service) { 14155 // Refuse possible leaked file descriptors 14156 if (intent != null && intent.hasFileDescriptors() == true) { 14157 throw new IllegalArgumentException("File descriptors passed in Intent"); 14158 } 14159 14160 synchronized(this) { 14161 if (!(token instanceof ServiceRecord)) { 14162 throw new IllegalArgumentException("Invalid service token"); 14163 } 14164 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14165 } 14166 } 14167 14168 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14169 // Refuse possible leaked file descriptors 14170 if (intent != null && intent.hasFileDescriptors() == true) { 14171 throw new IllegalArgumentException("File descriptors passed in Intent"); 14172 } 14173 14174 synchronized(this) { 14175 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14176 } 14177 } 14178 14179 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14180 synchronized(this) { 14181 if (!(token instanceof ServiceRecord)) { 14182 throw new IllegalArgumentException("Invalid service token"); 14183 } 14184 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14185 } 14186 } 14187 14188 // ========================================================= 14189 // BACKUP AND RESTORE 14190 // ========================================================= 14191 14192 // Cause the target app to be launched if necessary and its backup agent 14193 // instantiated. The backup agent will invoke backupAgentCreated() on the 14194 // activity manager to announce its creation. 14195 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14196 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14197 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14198 14199 synchronized(this) { 14200 // !!! TODO: currently no check here that we're already bound 14201 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14202 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14203 synchronized (stats) { 14204 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14205 } 14206 14207 // Backup agent is now in use, its package can't be stopped. 14208 try { 14209 AppGlobals.getPackageManager().setPackageStoppedState( 14210 app.packageName, false, UserHandle.getUserId(app.uid)); 14211 } catch (RemoteException e) { 14212 } catch (IllegalArgumentException e) { 14213 Slog.w(TAG, "Failed trying to unstop package " 14214 + app.packageName + ": " + e); 14215 } 14216 14217 BackupRecord r = new BackupRecord(ss, app, backupMode); 14218 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14219 ? new ComponentName(app.packageName, app.backupAgentName) 14220 : new ComponentName("android", "FullBackupAgent"); 14221 // startProcessLocked() returns existing proc's record if it's already running 14222 ProcessRecord proc = startProcessLocked(app.processName, app, 14223 false, 0, "backup", hostingName, false, false, false); 14224 if (proc == null) { 14225 Slog.e(TAG, "Unable to start backup agent process " + r); 14226 return false; 14227 } 14228 14229 r.app = proc; 14230 mBackupTarget = r; 14231 mBackupAppName = app.packageName; 14232 14233 // Try not to kill the process during backup 14234 updateOomAdjLocked(proc); 14235 14236 // If the process is already attached, schedule the creation of the backup agent now. 14237 // If it is not yet live, this will be done when it attaches to the framework. 14238 if (proc.thread != null) { 14239 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14240 try { 14241 proc.thread.scheduleCreateBackupAgent(app, 14242 compatibilityInfoForPackageLocked(app), backupMode); 14243 } catch (RemoteException e) { 14244 // Will time out on the backup manager side 14245 } 14246 } else { 14247 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14248 } 14249 // Invariants: at this point, the target app process exists and the application 14250 // is either already running or in the process of coming up. mBackupTarget and 14251 // mBackupAppName describe the app, so that when it binds back to the AM we 14252 // know that it's scheduled for a backup-agent operation. 14253 } 14254 14255 return true; 14256 } 14257 14258 @Override 14259 public void clearPendingBackup() { 14260 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14261 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14262 14263 synchronized (this) { 14264 mBackupTarget = null; 14265 mBackupAppName = null; 14266 } 14267 } 14268 14269 // A backup agent has just come up 14270 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14271 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14272 + " = " + agent); 14273 14274 synchronized(this) { 14275 if (!agentPackageName.equals(mBackupAppName)) { 14276 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14277 return; 14278 } 14279 } 14280 14281 long oldIdent = Binder.clearCallingIdentity(); 14282 try { 14283 IBackupManager bm = IBackupManager.Stub.asInterface( 14284 ServiceManager.getService(Context.BACKUP_SERVICE)); 14285 bm.agentConnected(agentPackageName, agent); 14286 } catch (RemoteException e) { 14287 // can't happen; the backup manager service is local 14288 } catch (Exception e) { 14289 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14290 e.printStackTrace(); 14291 } finally { 14292 Binder.restoreCallingIdentity(oldIdent); 14293 } 14294 } 14295 14296 // done with this agent 14297 public void unbindBackupAgent(ApplicationInfo appInfo) { 14298 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14299 if (appInfo == null) { 14300 Slog.w(TAG, "unbind backup agent for null app"); 14301 return; 14302 } 14303 14304 synchronized(this) { 14305 try { 14306 if (mBackupAppName == null) { 14307 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14308 return; 14309 } 14310 14311 if (!mBackupAppName.equals(appInfo.packageName)) { 14312 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14313 return; 14314 } 14315 14316 // Not backing this app up any more; reset its OOM adjustment 14317 final ProcessRecord proc = mBackupTarget.app; 14318 updateOomAdjLocked(proc); 14319 14320 // If the app crashed during backup, 'thread' will be null here 14321 if (proc.thread != null) { 14322 try { 14323 proc.thread.scheduleDestroyBackupAgent(appInfo, 14324 compatibilityInfoForPackageLocked(appInfo)); 14325 } catch (Exception e) { 14326 Slog.e(TAG, "Exception when unbinding backup agent:"); 14327 e.printStackTrace(); 14328 } 14329 } 14330 } finally { 14331 mBackupTarget = null; 14332 mBackupAppName = null; 14333 } 14334 } 14335 } 14336 // ========================================================= 14337 // BROADCASTS 14338 // ========================================================= 14339 14340 private final List getStickiesLocked(String action, IntentFilter filter, 14341 List cur, int userId) { 14342 final ContentResolver resolver = mContext.getContentResolver(); 14343 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14344 if (stickies == null) { 14345 return cur; 14346 } 14347 final ArrayList<Intent> list = stickies.get(action); 14348 if (list == null) { 14349 return cur; 14350 } 14351 int N = list.size(); 14352 for (int i=0; i<N; i++) { 14353 Intent intent = list.get(i); 14354 if (filter.match(resolver, intent, true, TAG) >= 0) { 14355 if (cur == null) { 14356 cur = new ArrayList<Intent>(); 14357 } 14358 cur.add(intent); 14359 } 14360 } 14361 return cur; 14362 } 14363 14364 boolean isPendingBroadcastProcessLocked(int pid) { 14365 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14366 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14367 } 14368 14369 void skipPendingBroadcastLocked(int pid) { 14370 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14371 for (BroadcastQueue queue : mBroadcastQueues) { 14372 queue.skipPendingBroadcastLocked(pid); 14373 } 14374 } 14375 14376 // The app just attached; send any pending broadcasts that it should receive 14377 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14378 boolean didSomething = false; 14379 for (BroadcastQueue queue : mBroadcastQueues) { 14380 didSomething |= queue.sendPendingBroadcastsLocked(app); 14381 } 14382 return didSomething; 14383 } 14384 14385 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14386 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14387 enforceNotIsolatedCaller("registerReceiver"); 14388 int callingUid; 14389 int callingPid; 14390 synchronized(this) { 14391 ProcessRecord callerApp = null; 14392 if (caller != null) { 14393 callerApp = getRecordForAppLocked(caller); 14394 if (callerApp == null) { 14395 throw new SecurityException( 14396 "Unable to find app for caller " + caller 14397 + " (pid=" + Binder.getCallingPid() 14398 + ") when registering receiver " + receiver); 14399 } 14400 if (callerApp.info.uid != Process.SYSTEM_UID && 14401 !callerApp.pkgList.containsKey(callerPackage) && 14402 !"android".equals(callerPackage)) { 14403 throw new SecurityException("Given caller package " + callerPackage 14404 + " is not running in process " + callerApp); 14405 } 14406 callingUid = callerApp.info.uid; 14407 callingPid = callerApp.pid; 14408 } else { 14409 callerPackage = null; 14410 callingUid = Binder.getCallingUid(); 14411 callingPid = Binder.getCallingPid(); 14412 } 14413 14414 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14415 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14416 14417 List allSticky = null; 14418 14419 // Look for any matching sticky broadcasts... 14420 Iterator actions = filter.actionsIterator(); 14421 if (actions != null) { 14422 while (actions.hasNext()) { 14423 String action = (String)actions.next(); 14424 allSticky = getStickiesLocked(action, filter, allSticky, 14425 UserHandle.USER_ALL); 14426 allSticky = getStickiesLocked(action, filter, allSticky, 14427 UserHandle.getUserId(callingUid)); 14428 } 14429 } else { 14430 allSticky = getStickiesLocked(null, filter, allSticky, 14431 UserHandle.USER_ALL); 14432 allSticky = getStickiesLocked(null, filter, allSticky, 14433 UserHandle.getUserId(callingUid)); 14434 } 14435 14436 // The first sticky in the list is returned directly back to 14437 // the client. 14438 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14439 14440 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14441 + ": " + sticky); 14442 14443 if (receiver == null) { 14444 return sticky; 14445 } 14446 14447 ReceiverList rl 14448 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14449 if (rl == null) { 14450 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14451 userId, receiver); 14452 if (rl.app != null) { 14453 rl.app.receivers.add(rl); 14454 } else { 14455 try { 14456 receiver.asBinder().linkToDeath(rl, 0); 14457 } catch (RemoteException e) { 14458 return sticky; 14459 } 14460 rl.linkedToDeath = true; 14461 } 14462 mRegisteredReceivers.put(receiver.asBinder(), rl); 14463 } else if (rl.uid != callingUid) { 14464 throw new IllegalArgumentException( 14465 "Receiver requested to register for uid " + callingUid 14466 + " was previously registered for uid " + rl.uid); 14467 } else if (rl.pid != callingPid) { 14468 throw new IllegalArgumentException( 14469 "Receiver requested to register for pid " + callingPid 14470 + " was previously registered for pid " + rl.pid); 14471 } else if (rl.userId != userId) { 14472 throw new IllegalArgumentException( 14473 "Receiver requested to register for user " + userId 14474 + " was previously registered for user " + rl.userId); 14475 } 14476 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14477 permission, callingUid, userId); 14478 rl.add(bf); 14479 if (!bf.debugCheck()) { 14480 Slog.w(TAG, "==> For Dynamic broadast"); 14481 } 14482 mReceiverResolver.addFilter(bf); 14483 14484 // Enqueue broadcasts for all existing stickies that match 14485 // this filter. 14486 if (allSticky != null) { 14487 ArrayList receivers = new ArrayList(); 14488 receivers.add(bf); 14489 14490 int N = allSticky.size(); 14491 for (int i=0; i<N; i++) { 14492 Intent intent = (Intent)allSticky.get(i); 14493 BroadcastQueue queue = broadcastQueueForIntent(intent); 14494 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14495 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14496 null, null, false, true, true, -1); 14497 queue.enqueueParallelBroadcastLocked(r); 14498 queue.scheduleBroadcastsLocked(); 14499 } 14500 } 14501 14502 return sticky; 14503 } 14504 } 14505 14506 public void unregisterReceiver(IIntentReceiver receiver) { 14507 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14508 14509 final long origId = Binder.clearCallingIdentity(); 14510 try { 14511 boolean doTrim = false; 14512 14513 synchronized(this) { 14514 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14515 if (rl != null) { 14516 if (rl.curBroadcast != null) { 14517 BroadcastRecord r = rl.curBroadcast; 14518 final boolean doNext = finishReceiverLocked( 14519 receiver.asBinder(), r.resultCode, r.resultData, 14520 r.resultExtras, r.resultAbort); 14521 if (doNext) { 14522 doTrim = true; 14523 r.queue.processNextBroadcast(false); 14524 } 14525 } 14526 14527 if (rl.app != null) { 14528 rl.app.receivers.remove(rl); 14529 } 14530 removeReceiverLocked(rl); 14531 if (rl.linkedToDeath) { 14532 rl.linkedToDeath = false; 14533 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14534 } 14535 } 14536 } 14537 14538 // If we actually concluded any broadcasts, we might now be able 14539 // to trim the recipients' apps from our working set 14540 if (doTrim) { 14541 trimApplications(); 14542 return; 14543 } 14544 14545 } finally { 14546 Binder.restoreCallingIdentity(origId); 14547 } 14548 } 14549 14550 void removeReceiverLocked(ReceiverList rl) { 14551 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14552 int N = rl.size(); 14553 for (int i=0; i<N; i++) { 14554 mReceiverResolver.removeFilter(rl.get(i)); 14555 } 14556 } 14557 14558 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14559 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14560 ProcessRecord r = mLruProcesses.get(i); 14561 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14562 try { 14563 r.thread.dispatchPackageBroadcast(cmd, packages); 14564 } catch (RemoteException ex) { 14565 } 14566 } 14567 } 14568 } 14569 14570 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14571 int[] users) { 14572 List<ResolveInfo> receivers = null; 14573 try { 14574 HashSet<ComponentName> singleUserReceivers = null; 14575 boolean scannedFirstReceivers = false; 14576 for (int user : users) { 14577 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14578 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14579 if (user != 0 && newReceivers != null) { 14580 // If this is not the primary user, we need to check for 14581 // any receivers that should be filtered out. 14582 for (int i=0; i<newReceivers.size(); i++) { 14583 ResolveInfo ri = newReceivers.get(i); 14584 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14585 newReceivers.remove(i); 14586 i--; 14587 } 14588 } 14589 } 14590 if (newReceivers != null && newReceivers.size() == 0) { 14591 newReceivers = null; 14592 } 14593 if (receivers == null) { 14594 receivers = newReceivers; 14595 } else if (newReceivers != null) { 14596 // We need to concatenate the additional receivers 14597 // found with what we have do far. This would be easy, 14598 // but we also need to de-dup any receivers that are 14599 // singleUser. 14600 if (!scannedFirstReceivers) { 14601 // Collect any single user receivers we had already retrieved. 14602 scannedFirstReceivers = true; 14603 for (int i=0; i<receivers.size(); i++) { 14604 ResolveInfo ri = receivers.get(i); 14605 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14606 ComponentName cn = new ComponentName( 14607 ri.activityInfo.packageName, ri.activityInfo.name); 14608 if (singleUserReceivers == null) { 14609 singleUserReceivers = new HashSet<ComponentName>(); 14610 } 14611 singleUserReceivers.add(cn); 14612 } 14613 } 14614 } 14615 // Add the new results to the existing results, tracking 14616 // and de-dupping single user receivers. 14617 for (int i=0; i<newReceivers.size(); i++) { 14618 ResolveInfo ri = newReceivers.get(i); 14619 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14620 ComponentName cn = new ComponentName( 14621 ri.activityInfo.packageName, ri.activityInfo.name); 14622 if (singleUserReceivers == null) { 14623 singleUserReceivers = new HashSet<ComponentName>(); 14624 } 14625 if (!singleUserReceivers.contains(cn)) { 14626 singleUserReceivers.add(cn); 14627 receivers.add(ri); 14628 } 14629 } else { 14630 receivers.add(ri); 14631 } 14632 } 14633 } 14634 } 14635 } catch (RemoteException ex) { 14636 // pm is in same process, this will never happen. 14637 } 14638 return receivers; 14639 } 14640 14641 private final int broadcastIntentLocked(ProcessRecord callerApp, 14642 String callerPackage, Intent intent, String resolvedType, 14643 IIntentReceiver resultTo, int resultCode, String resultData, 14644 Bundle map, String requiredPermission, int appOp, 14645 boolean ordered, boolean sticky, int callingPid, int callingUid, 14646 int userId) { 14647 intent = new Intent(intent); 14648 14649 // By default broadcasts do not go to stopped apps. 14650 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14651 14652 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14653 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14654 + " ordered=" + ordered + " userid=" + userId); 14655 if ((resultTo != null) && !ordered) { 14656 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14657 } 14658 14659 userId = handleIncomingUser(callingPid, callingUid, userId, 14660 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14661 14662 // Make sure that the user who is receiving this broadcast is started. 14663 // If not, we will just skip it. 14664 14665 14666 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14667 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14668 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14669 Slog.w(TAG, "Skipping broadcast of " + intent 14670 + ": user " + userId + " is stopped"); 14671 return ActivityManager.BROADCAST_SUCCESS; 14672 } 14673 } 14674 14675 /* 14676 * Prevent non-system code (defined here to be non-persistent 14677 * processes) from sending protected broadcasts. 14678 */ 14679 int callingAppId = UserHandle.getAppId(callingUid); 14680 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14681 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14682 || callingAppId == Process.NFC_UID || callingUid == 0) { 14683 // Always okay. 14684 } else if (callerApp == null || !callerApp.persistent) { 14685 try { 14686 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14687 intent.getAction())) { 14688 String msg = "Permission Denial: not allowed to send broadcast " 14689 + intent.getAction() + " from pid=" 14690 + callingPid + ", uid=" + callingUid; 14691 Slog.w(TAG, msg); 14692 throw new SecurityException(msg); 14693 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14694 // Special case for compatibility: we don't want apps to send this, 14695 // but historically it has not been protected and apps may be using it 14696 // to poke their own app widget. So, instead of making it protected, 14697 // just limit it to the caller. 14698 if (callerApp == null) { 14699 String msg = "Permission Denial: not allowed to send broadcast " 14700 + intent.getAction() + " from unknown caller."; 14701 Slog.w(TAG, msg); 14702 throw new SecurityException(msg); 14703 } else if (intent.getComponent() != null) { 14704 // They are good enough to send to an explicit component... verify 14705 // it is being sent to the calling app. 14706 if (!intent.getComponent().getPackageName().equals( 14707 callerApp.info.packageName)) { 14708 String msg = "Permission Denial: not allowed to send broadcast " 14709 + intent.getAction() + " to " 14710 + intent.getComponent().getPackageName() + " from " 14711 + callerApp.info.packageName; 14712 Slog.w(TAG, msg); 14713 throw new SecurityException(msg); 14714 } 14715 } else { 14716 // Limit broadcast to their own package. 14717 intent.setPackage(callerApp.info.packageName); 14718 } 14719 } 14720 } catch (RemoteException e) { 14721 Slog.w(TAG, "Remote exception", e); 14722 return ActivityManager.BROADCAST_SUCCESS; 14723 } 14724 } 14725 14726 // Handle special intents: if this broadcast is from the package 14727 // manager about a package being removed, we need to remove all of 14728 // its activities from the history stack. 14729 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14730 intent.getAction()); 14731 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14732 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14733 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14734 || uidRemoved) { 14735 if (checkComponentPermission( 14736 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14737 callingPid, callingUid, -1, true) 14738 == PackageManager.PERMISSION_GRANTED) { 14739 if (uidRemoved) { 14740 final Bundle intentExtras = intent.getExtras(); 14741 final int uid = intentExtras != null 14742 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14743 if (uid >= 0) { 14744 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14745 synchronized (bs) { 14746 bs.removeUidStatsLocked(uid); 14747 } 14748 mAppOpsService.uidRemoved(uid); 14749 } 14750 } else { 14751 // If resources are unavailable just force stop all 14752 // those packages and flush the attribute cache as well. 14753 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14754 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14755 if (list != null && (list.length > 0)) { 14756 for (String pkg : list) { 14757 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14758 "storage unmount"); 14759 } 14760 sendPackageBroadcastLocked( 14761 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14762 } 14763 } else { 14764 Uri data = intent.getData(); 14765 String ssp; 14766 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14767 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14768 intent.getAction()); 14769 boolean fullUninstall = removed && 14770 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14771 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14772 forceStopPackageLocked(ssp, UserHandle.getAppId( 14773 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14774 false, fullUninstall, userId, 14775 removed ? "pkg removed" : "pkg changed"); 14776 } 14777 if (removed) { 14778 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14779 new String[] {ssp}, userId); 14780 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14781 mAppOpsService.packageRemoved( 14782 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14783 14784 // Remove all permissions granted from/to this package 14785 removeUriPermissionsForPackageLocked(ssp, userId, true); 14786 } 14787 } 14788 } 14789 } 14790 } 14791 } else { 14792 String msg = "Permission Denial: " + intent.getAction() 14793 + " broadcast from " + callerPackage + " (pid=" + callingPid 14794 + ", uid=" + callingUid + ")" 14795 + " requires " 14796 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14797 Slog.w(TAG, msg); 14798 throw new SecurityException(msg); 14799 } 14800 14801 // Special case for adding a package: by default turn on compatibility 14802 // mode. 14803 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14804 Uri data = intent.getData(); 14805 String ssp; 14806 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14807 mCompatModePackages.handlePackageAddedLocked(ssp, 14808 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14809 } 14810 } 14811 14812 /* 14813 * If this is the time zone changed action, queue up a message that will reset the timezone 14814 * of all currently running processes. This message will get queued up before the broadcast 14815 * happens. 14816 */ 14817 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14818 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14819 } 14820 14821 /* 14822 * If the user set the time, let all running processes know. 14823 */ 14824 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14825 final int is24Hour = intent.getBooleanExtra( 14826 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14827 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14828 } 14829 14830 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14831 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14832 } 14833 14834 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14835 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14836 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14837 } 14838 14839 // Add to the sticky list if requested. 14840 if (sticky) { 14841 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14842 callingPid, callingUid) 14843 != PackageManager.PERMISSION_GRANTED) { 14844 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14845 + callingPid + ", uid=" + callingUid 14846 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14847 Slog.w(TAG, msg); 14848 throw new SecurityException(msg); 14849 } 14850 if (requiredPermission != null) { 14851 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14852 + " and enforce permission " + requiredPermission); 14853 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14854 } 14855 if (intent.getComponent() != null) { 14856 throw new SecurityException( 14857 "Sticky broadcasts can't target a specific component"); 14858 } 14859 // We use userId directly here, since the "all" target is maintained 14860 // as a separate set of sticky broadcasts. 14861 if (userId != UserHandle.USER_ALL) { 14862 // But first, if this is not a broadcast to all users, then 14863 // make sure it doesn't conflict with an existing broadcast to 14864 // all users. 14865 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14866 UserHandle.USER_ALL); 14867 if (stickies != null) { 14868 ArrayList<Intent> list = stickies.get(intent.getAction()); 14869 if (list != null) { 14870 int N = list.size(); 14871 int i; 14872 for (i=0; i<N; i++) { 14873 if (intent.filterEquals(list.get(i))) { 14874 throw new IllegalArgumentException( 14875 "Sticky broadcast " + intent + " for user " 14876 + userId + " conflicts with existing global broadcast"); 14877 } 14878 } 14879 } 14880 } 14881 } 14882 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14883 if (stickies == null) { 14884 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14885 mStickyBroadcasts.put(userId, stickies); 14886 } 14887 ArrayList<Intent> list = stickies.get(intent.getAction()); 14888 if (list == null) { 14889 list = new ArrayList<Intent>(); 14890 stickies.put(intent.getAction(), list); 14891 } 14892 int N = list.size(); 14893 int i; 14894 for (i=0; i<N; i++) { 14895 if (intent.filterEquals(list.get(i))) { 14896 // This sticky already exists, replace it. 14897 list.set(i, new Intent(intent)); 14898 break; 14899 } 14900 } 14901 if (i >= N) { 14902 list.add(new Intent(intent)); 14903 } 14904 } 14905 14906 int[] users; 14907 if (userId == UserHandle.USER_ALL) { 14908 // Caller wants broadcast to go to all started users. 14909 users = mStartedUserArray; 14910 } else { 14911 // Caller wants broadcast to go to one specific user. 14912 users = new int[] {userId}; 14913 } 14914 14915 // Figure out who all will receive this broadcast. 14916 List receivers = null; 14917 List<BroadcastFilter> registeredReceivers = null; 14918 // Need to resolve the intent to interested receivers... 14919 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14920 == 0) { 14921 receivers = collectReceiverComponents(intent, resolvedType, users); 14922 } 14923 if (intent.getComponent() == null) { 14924 registeredReceivers = mReceiverResolver.queryIntent(intent, 14925 resolvedType, false, userId); 14926 } 14927 14928 final boolean replacePending = 14929 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14930 14931 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14932 + " replacePending=" + replacePending); 14933 14934 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14935 if (!ordered && NR > 0) { 14936 // If we are not serializing this broadcast, then send the 14937 // registered receivers separately so they don't wait for the 14938 // components to be launched. 14939 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14940 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14941 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14942 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14943 ordered, sticky, false, userId); 14944 if (DEBUG_BROADCAST) Slog.v( 14945 TAG, "Enqueueing parallel broadcast " + r); 14946 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14947 if (!replaced) { 14948 queue.enqueueParallelBroadcastLocked(r); 14949 queue.scheduleBroadcastsLocked(); 14950 } 14951 registeredReceivers = null; 14952 NR = 0; 14953 } 14954 14955 // Merge into one list. 14956 int ir = 0; 14957 if (receivers != null) { 14958 // A special case for PACKAGE_ADDED: do not allow the package 14959 // being added to see this broadcast. This prevents them from 14960 // using this as a back door to get run as soon as they are 14961 // installed. Maybe in the future we want to have a special install 14962 // broadcast or such for apps, but we'd like to deliberately make 14963 // this decision. 14964 String skipPackages[] = null; 14965 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14966 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14967 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14968 Uri data = intent.getData(); 14969 if (data != null) { 14970 String pkgName = data.getSchemeSpecificPart(); 14971 if (pkgName != null) { 14972 skipPackages = new String[] { pkgName }; 14973 } 14974 } 14975 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14976 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14977 } 14978 if (skipPackages != null && (skipPackages.length > 0)) { 14979 for (String skipPackage : skipPackages) { 14980 if (skipPackage != null) { 14981 int NT = receivers.size(); 14982 for (int it=0; it<NT; it++) { 14983 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14984 if (curt.activityInfo.packageName.equals(skipPackage)) { 14985 receivers.remove(it); 14986 it--; 14987 NT--; 14988 } 14989 } 14990 } 14991 } 14992 } 14993 14994 int NT = receivers != null ? receivers.size() : 0; 14995 int it = 0; 14996 ResolveInfo curt = null; 14997 BroadcastFilter curr = null; 14998 while (it < NT && ir < NR) { 14999 if (curt == null) { 15000 curt = (ResolveInfo)receivers.get(it); 15001 } 15002 if (curr == null) { 15003 curr = registeredReceivers.get(ir); 15004 } 15005 if (curr.getPriority() >= curt.priority) { 15006 // Insert this broadcast record into the final list. 15007 receivers.add(it, curr); 15008 ir++; 15009 curr = null; 15010 it++; 15011 NT++; 15012 } else { 15013 // Skip to the next ResolveInfo in the final list. 15014 it++; 15015 curt = null; 15016 } 15017 } 15018 } 15019 while (ir < NR) { 15020 if (receivers == null) { 15021 receivers = new ArrayList(); 15022 } 15023 receivers.add(registeredReceivers.get(ir)); 15024 ir++; 15025 } 15026 15027 if ((receivers != null && receivers.size() > 0) 15028 || resultTo != null) { 15029 BroadcastQueue queue = broadcastQueueForIntent(intent); 15030 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15031 callerPackage, callingPid, callingUid, resolvedType, 15032 requiredPermission, appOp, receivers, resultTo, resultCode, 15033 resultData, map, ordered, sticky, false, userId); 15034 if (DEBUG_BROADCAST) Slog.v( 15035 TAG, "Enqueueing ordered broadcast " + r 15036 + ": prev had " + queue.mOrderedBroadcasts.size()); 15037 if (DEBUG_BROADCAST) { 15038 int seq = r.intent.getIntExtra("seq", -1); 15039 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15040 } 15041 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15042 if (!replaced) { 15043 queue.enqueueOrderedBroadcastLocked(r); 15044 queue.scheduleBroadcastsLocked(); 15045 } 15046 } 15047 15048 return ActivityManager.BROADCAST_SUCCESS; 15049 } 15050 15051 final Intent verifyBroadcastLocked(Intent intent) { 15052 // Refuse possible leaked file descriptors 15053 if (intent != null && intent.hasFileDescriptors() == true) { 15054 throw new IllegalArgumentException("File descriptors passed in Intent"); 15055 } 15056 15057 int flags = intent.getFlags(); 15058 15059 if (!mProcessesReady) { 15060 // if the caller really truly claims to know what they're doing, go 15061 // ahead and allow the broadcast without launching any receivers 15062 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15063 intent = new Intent(intent); 15064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15065 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15066 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15067 + " before boot completion"); 15068 throw new IllegalStateException("Cannot broadcast before boot completed"); 15069 } 15070 } 15071 15072 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15073 throw new IllegalArgumentException( 15074 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15075 } 15076 15077 return intent; 15078 } 15079 15080 public final int broadcastIntent(IApplicationThread caller, 15081 Intent intent, String resolvedType, IIntentReceiver resultTo, 15082 int resultCode, String resultData, Bundle map, 15083 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15084 enforceNotIsolatedCaller("broadcastIntent"); 15085 synchronized(this) { 15086 intent = verifyBroadcastLocked(intent); 15087 15088 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15089 final int callingPid = Binder.getCallingPid(); 15090 final int callingUid = Binder.getCallingUid(); 15091 final long origId = Binder.clearCallingIdentity(); 15092 int res = broadcastIntentLocked(callerApp, 15093 callerApp != null ? callerApp.info.packageName : null, 15094 intent, resolvedType, resultTo, 15095 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15096 callingPid, callingUid, userId); 15097 Binder.restoreCallingIdentity(origId); 15098 return res; 15099 } 15100 } 15101 15102 int broadcastIntentInPackage(String packageName, int uid, 15103 Intent intent, String resolvedType, IIntentReceiver resultTo, 15104 int resultCode, String resultData, Bundle map, 15105 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15106 synchronized(this) { 15107 intent = verifyBroadcastLocked(intent); 15108 15109 final long origId = Binder.clearCallingIdentity(); 15110 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15111 resultTo, resultCode, resultData, map, requiredPermission, 15112 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15113 Binder.restoreCallingIdentity(origId); 15114 return res; 15115 } 15116 } 15117 15118 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15119 // Refuse possible leaked file descriptors 15120 if (intent != null && intent.hasFileDescriptors() == true) { 15121 throw new IllegalArgumentException("File descriptors passed in Intent"); 15122 } 15123 15124 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15125 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15126 15127 synchronized(this) { 15128 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15129 != PackageManager.PERMISSION_GRANTED) { 15130 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15131 + Binder.getCallingPid() 15132 + ", uid=" + Binder.getCallingUid() 15133 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15134 Slog.w(TAG, msg); 15135 throw new SecurityException(msg); 15136 } 15137 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15138 if (stickies != null) { 15139 ArrayList<Intent> list = stickies.get(intent.getAction()); 15140 if (list != null) { 15141 int N = list.size(); 15142 int i; 15143 for (i=0; i<N; i++) { 15144 if (intent.filterEquals(list.get(i))) { 15145 list.remove(i); 15146 break; 15147 } 15148 } 15149 if (list.size() <= 0) { 15150 stickies.remove(intent.getAction()); 15151 } 15152 } 15153 if (stickies.size() <= 0) { 15154 mStickyBroadcasts.remove(userId); 15155 } 15156 } 15157 } 15158 } 15159 15160 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15161 String resultData, Bundle resultExtras, boolean resultAbort) { 15162 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15163 if (r == null) { 15164 Slog.w(TAG, "finishReceiver called but not found on queue"); 15165 return false; 15166 } 15167 15168 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15169 } 15170 15171 void backgroundServicesFinishedLocked(int userId) { 15172 for (BroadcastQueue queue : mBroadcastQueues) { 15173 queue.backgroundServicesFinishedLocked(userId); 15174 } 15175 } 15176 15177 public void finishReceiver(IBinder who, int resultCode, String resultData, 15178 Bundle resultExtras, boolean resultAbort) { 15179 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15180 15181 // Refuse possible leaked file descriptors 15182 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15183 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15184 } 15185 15186 final long origId = Binder.clearCallingIdentity(); 15187 try { 15188 boolean doNext = false; 15189 BroadcastRecord r; 15190 15191 synchronized(this) { 15192 r = broadcastRecordForReceiverLocked(who); 15193 if (r != null) { 15194 doNext = r.queue.finishReceiverLocked(r, resultCode, 15195 resultData, resultExtras, resultAbort, true); 15196 } 15197 } 15198 15199 if (doNext) { 15200 r.queue.processNextBroadcast(false); 15201 } 15202 trimApplications(); 15203 } finally { 15204 Binder.restoreCallingIdentity(origId); 15205 } 15206 } 15207 15208 // ========================================================= 15209 // INSTRUMENTATION 15210 // ========================================================= 15211 15212 public boolean startInstrumentation(ComponentName className, 15213 String profileFile, int flags, Bundle arguments, 15214 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15215 int userId, String abiOverride) { 15216 enforceNotIsolatedCaller("startInstrumentation"); 15217 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15218 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15219 // Refuse possible leaked file descriptors 15220 if (arguments != null && arguments.hasFileDescriptors()) { 15221 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15222 } 15223 15224 synchronized(this) { 15225 InstrumentationInfo ii = null; 15226 ApplicationInfo ai = null; 15227 try { 15228 ii = mContext.getPackageManager().getInstrumentationInfo( 15229 className, STOCK_PM_FLAGS); 15230 ai = AppGlobals.getPackageManager().getApplicationInfo( 15231 ii.targetPackage, STOCK_PM_FLAGS, userId); 15232 } catch (PackageManager.NameNotFoundException e) { 15233 } catch (RemoteException e) { 15234 } 15235 if (ii == null) { 15236 reportStartInstrumentationFailure(watcher, className, 15237 "Unable to find instrumentation info for: " + className); 15238 return false; 15239 } 15240 if (ai == null) { 15241 reportStartInstrumentationFailure(watcher, className, 15242 "Unable to find instrumentation target package: " + ii.targetPackage); 15243 return false; 15244 } 15245 15246 int match = mContext.getPackageManager().checkSignatures( 15247 ii.targetPackage, ii.packageName); 15248 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15249 String msg = "Permission Denial: starting instrumentation " 15250 + className + " from pid=" 15251 + Binder.getCallingPid() 15252 + ", uid=" + Binder.getCallingPid() 15253 + " not allowed because package " + ii.packageName 15254 + " does not have a signature matching the target " 15255 + ii.targetPackage; 15256 reportStartInstrumentationFailure(watcher, className, msg); 15257 throw new SecurityException(msg); 15258 } 15259 15260 final long origId = Binder.clearCallingIdentity(); 15261 // Instrumentation can kill and relaunch even persistent processes 15262 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15263 "start instr"); 15264 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15265 app.instrumentationClass = className; 15266 app.instrumentationInfo = ai; 15267 app.instrumentationProfileFile = profileFile; 15268 app.instrumentationArguments = arguments; 15269 app.instrumentationWatcher = watcher; 15270 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15271 app.instrumentationResultClass = className; 15272 Binder.restoreCallingIdentity(origId); 15273 } 15274 15275 return true; 15276 } 15277 15278 /** 15279 * Report errors that occur while attempting to start Instrumentation. Always writes the 15280 * error to the logs, but if somebody is watching, send the report there too. This enables 15281 * the "am" command to report errors with more information. 15282 * 15283 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15284 * @param cn The component name of the instrumentation. 15285 * @param report The error report. 15286 */ 15287 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15288 ComponentName cn, String report) { 15289 Slog.w(TAG, report); 15290 try { 15291 if (watcher != null) { 15292 Bundle results = new Bundle(); 15293 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15294 results.putString("Error", report); 15295 watcher.instrumentationStatus(cn, -1, results); 15296 } 15297 } catch (RemoteException e) { 15298 Slog.w(TAG, e); 15299 } 15300 } 15301 15302 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15303 if (app.instrumentationWatcher != null) { 15304 try { 15305 // NOTE: IInstrumentationWatcher *must* be oneway here 15306 app.instrumentationWatcher.instrumentationFinished( 15307 app.instrumentationClass, 15308 resultCode, 15309 results); 15310 } catch (RemoteException e) { 15311 } 15312 } 15313 if (app.instrumentationUiAutomationConnection != null) { 15314 try { 15315 app.instrumentationUiAutomationConnection.shutdown(); 15316 } catch (RemoteException re) { 15317 /* ignore */ 15318 } 15319 // Only a UiAutomation can set this flag and now that 15320 // it is finished we make sure it is reset to its default. 15321 mUserIsMonkey = false; 15322 } 15323 app.instrumentationWatcher = null; 15324 app.instrumentationUiAutomationConnection = null; 15325 app.instrumentationClass = null; 15326 app.instrumentationInfo = null; 15327 app.instrumentationProfileFile = null; 15328 app.instrumentationArguments = null; 15329 15330 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15331 "finished inst"); 15332 } 15333 15334 public void finishInstrumentation(IApplicationThread target, 15335 int resultCode, Bundle results) { 15336 int userId = UserHandle.getCallingUserId(); 15337 // Refuse possible leaked file descriptors 15338 if (results != null && results.hasFileDescriptors()) { 15339 throw new IllegalArgumentException("File descriptors passed in Intent"); 15340 } 15341 15342 synchronized(this) { 15343 ProcessRecord app = getRecordForAppLocked(target); 15344 if (app == null) { 15345 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15346 return; 15347 } 15348 final long origId = Binder.clearCallingIdentity(); 15349 finishInstrumentationLocked(app, resultCode, results); 15350 Binder.restoreCallingIdentity(origId); 15351 } 15352 } 15353 15354 // ========================================================= 15355 // CONFIGURATION 15356 // ========================================================= 15357 15358 public ConfigurationInfo getDeviceConfigurationInfo() { 15359 ConfigurationInfo config = new ConfigurationInfo(); 15360 synchronized (this) { 15361 config.reqTouchScreen = mConfiguration.touchscreen; 15362 config.reqKeyboardType = mConfiguration.keyboard; 15363 config.reqNavigation = mConfiguration.navigation; 15364 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15365 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15366 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15367 } 15368 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15369 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15370 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15371 } 15372 config.reqGlEsVersion = GL_ES_VERSION; 15373 } 15374 return config; 15375 } 15376 15377 ActivityStack getFocusedStack() { 15378 return mStackSupervisor.getFocusedStack(); 15379 } 15380 15381 public Configuration getConfiguration() { 15382 Configuration ci; 15383 synchronized(this) { 15384 ci = new Configuration(mConfiguration); 15385 } 15386 return ci; 15387 } 15388 15389 public void updatePersistentConfiguration(Configuration values) { 15390 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15391 "updateConfiguration()"); 15392 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15393 "updateConfiguration()"); 15394 if (values == null) { 15395 throw new NullPointerException("Configuration must not be null"); 15396 } 15397 15398 synchronized(this) { 15399 final long origId = Binder.clearCallingIdentity(); 15400 updateConfigurationLocked(values, null, true, false); 15401 Binder.restoreCallingIdentity(origId); 15402 } 15403 } 15404 15405 public void updateConfiguration(Configuration values) { 15406 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15407 "updateConfiguration()"); 15408 15409 synchronized(this) { 15410 if (values == null && mWindowManager != null) { 15411 // sentinel: fetch the current configuration from the window manager 15412 values = mWindowManager.computeNewConfiguration(); 15413 } 15414 15415 if (mWindowManager != null) { 15416 mProcessList.applyDisplaySize(mWindowManager); 15417 } 15418 15419 final long origId = Binder.clearCallingIdentity(); 15420 if (values != null) { 15421 Settings.System.clearConfiguration(values); 15422 } 15423 updateConfigurationLocked(values, null, false, false); 15424 Binder.restoreCallingIdentity(origId); 15425 } 15426 } 15427 15428 /** 15429 * Do either or both things: (1) change the current configuration, and (2) 15430 * make sure the given activity is running with the (now) current 15431 * configuration. Returns true if the activity has been left running, or 15432 * false if <var>starting</var> is being destroyed to match the new 15433 * configuration. 15434 * @param persistent TODO 15435 */ 15436 boolean updateConfigurationLocked(Configuration values, 15437 ActivityRecord starting, boolean persistent, boolean initLocale) { 15438 int changes = 0; 15439 15440 if (values != null) { 15441 Configuration newConfig = new Configuration(mConfiguration); 15442 changes = newConfig.updateFrom(values); 15443 if (changes != 0) { 15444 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15445 Slog.i(TAG, "Updating configuration to: " + values); 15446 } 15447 15448 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15449 15450 if (values.locale != null && !initLocale) { 15451 saveLocaleLocked(values.locale, 15452 !values.locale.equals(mConfiguration.locale), 15453 values.userSetLocale); 15454 } 15455 15456 mConfigurationSeq++; 15457 if (mConfigurationSeq <= 0) { 15458 mConfigurationSeq = 1; 15459 } 15460 newConfig.seq = mConfigurationSeq; 15461 mConfiguration = newConfig; 15462 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15463 //mUsageStatsService.noteStartConfig(newConfig); 15464 15465 final Configuration configCopy = new Configuration(mConfiguration); 15466 15467 // TODO: If our config changes, should we auto dismiss any currently 15468 // showing dialogs? 15469 mShowDialogs = shouldShowDialogs(newConfig); 15470 15471 AttributeCache ac = AttributeCache.instance(); 15472 if (ac != null) { 15473 ac.updateConfiguration(configCopy); 15474 } 15475 15476 // Make sure all resources in our process are updated 15477 // right now, so that anyone who is going to retrieve 15478 // resource values after we return will be sure to get 15479 // the new ones. This is especially important during 15480 // boot, where the first config change needs to guarantee 15481 // all resources have that config before following boot 15482 // code is executed. 15483 mSystemThread.applyConfigurationToResources(configCopy); 15484 15485 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15486 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15487 msg.obj = new Configuration(configCopy); 15488 mHandler.sendMessage(msg); 15489 } 15490 15491 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15492 ProcessRecord app = mLruProcesses.get(i); 15493 try { 15494 if (app.thread != null) { 15495 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15496 + app.processName + " new config " + mConfiguration); 15497 app.thread.scheduleConfigurationChanged(configCopy); 15498 } 15499 } catch (Exception e) { 15500 } 15501 } 15502 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15504 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15505 | Intent.FLAG_RECEIVER_FOREGROUND); 15506 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15507 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15508 Process.SYSTEM_UID, UserHandle.USER_ALL); 15509 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15510 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15511 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15512 broadcastIntentLocked(null, null, intent, 15513 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15514 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15515 } 15516 } 15517 } 15518 15519 boolean kept = true; 15520 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15521 // mainStack is null during startup. 15522 if (mainStack != null) { 15523 if (changes != 0 && starting == null) { 15524 // If the configuration changed, and the caller is not already 15525 // in the process of starting an activity, then find the top 15526 // activity to check if its configuration needs to change. 15527 starting = mainStack.topRunningActivityLocked(null); 15528 } 15529 15530 if (starting != null) { 15531 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15532 // And we need to make sure at this point that all other activities 15533 // are made visible with the correct configuration. 15534 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15535 } 15536 } 15537 15538 if (values != null && mWindowManager != null) { 15539 mWindowManager.setNewConfiguration(mConfiguration); 15540 } 15541 15542 return kept; 15543 } 15544 15545 /** 15546 * Decide based on the configuration whether we should shouw the ANR, 15547 * crash, etc dialogs. The idea is that if there is no affordnace to 15548 * press the on-screen buttons, we shouldn't show the dialog. 15549 * 15550 * A thought: SystemUI might also want to get told about this, the Power 15551 * dialog / global actions also might want different behaviors. 15552 */ 15553 private static final boolean shouldShowDialogs(Configuration config) { 15554 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15555 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15556 } 15557 15558 /** 15559 * Save the locale. You must be inside a synchronized (this) block. 15560 */ 15561 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15562 if(isDiff) { 15563 SystemProperties.set("user.language", l.getLanguage()); 15564 SystemProperties.set("user.region", l.getCountry()); 15565 } 15566 15567 if(isPersist) { 15568 SystemProperties.set("persist.sys.language", l.getLanguage()); 15569 SystemProperties.set("persist.sys.country", l.getCountry()); 15570 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15571 } 15572 } 15573 15574 @Override 15575 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15576 ActivityRecord srec = ActivityRecord.forToken(token); 15577 return srec != null && srec.task.affinity != null && 15578 srec.task.affinity.equals(destAffinity); 15579 } 15580 15581 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15582 Intent resultData) { 15583 15584 synchronized (this) { 15585 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15586 if (stack != null) { 15587 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15588 } 15589 return false; 15590 } 15591 } 15592 15593 public int getLaunchedFromUid(IBinder activityToken) { 15594 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15595 if (srec == null) { 15596 return -1; 15597 } 15598 return srec.launchedFromUid; 15599 } 15600 15601 public String getLaunchedFromPackage(IBinder activityToken) { 15602 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15603 if (srec == null) { 15604 return null; 15605 } 15606 return srec.launchedFromPackage; 15607 } 15608 15609 // ========================================================= 15610 // LIFETIME MANAGEMENT 15611 // ========================================================= 15612 15613 // Returns which broadcast queue the app is the current [or imminent] receiver 15614 // on, or 'null' if the app is not an active broadcast recipient. 15615 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15616 BroadcastRecord r = app.curReceiver; 15617 if (r != null) { 15618 return r.queue; 15619 } 15620 15621 // It's not the current receiver, but it might be starting up to become one 15622 synchronized (this) { 15623 for (BroadcastQueue queue : mBroadcastQueues) { 15624 r = queue.mPendingBroadcast; 15625 if (r != null && r.curApp == app) { 15626 // found it; report which queue it's in 15627 return queue; 15628 } 15629 } 15630 } 15631 15632 return null; 15633 } 15634 15635 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15636 boolean doingAll, long now) { 15637 if (mAdjSeq == app.adjSeq) { 15638 // This adjustment has already been computed. 15639 return app.curRawAdj; 15640 } 15641 15642 if (app.thread == null) { 15643 app.adjSeq = mAdjSeq; 15644 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15645 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15646 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15647 } 15648 15649 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15650 app.adjSource = null; 15651 app.adjTarget = null; 15652 app.empty = false; 15653 app.cached = false; 15654 15655 final int activitiesSize = app.activities.size(); 15656 15657 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15658 // The max adjustment doesn't allow this app to be anything 15659 // below foreground, so it is not worth doing work for it. 15660 app.adjType = "fixed"; 15661 app.adjSeq = mAdjSeq; 15662 app.curRawAdj = app.maxAdj; 15663 app.foregroundActivities = false; 15664 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15665 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15666 // System processes can do UI, and when they do we want to have 15667 // them trim their memory after the user leaves the UI. To 15668 // facilitate this, here we need to determine whether or not it 15669 // is currently showing UI. 15670 app.systemNoUi = true; 15671 if (app == TOP_APP) { 15672 app.systemNoUi = false; 15673 } else if (activitiesSize > 0) { 15674 for (int j = 0; j < activitiesSize; j++) { 15675 final ActivityRecord r = app.activities.get(j); 15676 if (r.visible) { 15677 app.systemNoUi = false; 15678 } 15679 } 15680 } 15681 if (!app.systemNoUi) { 15682 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15683 } 15684 return (app.curAdj=app.maxAdj); 15685 } 15686 15687 app.systemNoUi = false; 15688 15689 // Determine the importance of the process, starting with most 15690 // important to least, and assign an appropriate OOM adjustment. 15691 int adj; 15692 int schedGroup; 15693 int procState; 15694 boolean foregroundActivities = false; 15695 BroadcastQueue queue; 15696 if (app == TOP_APP) { 15697 // The last app on the list is the foreground app. 15698 adj = ProcessList.FOREGROUND_APP_ADJ; 15699 schedGroup = Process.THREAD_GROUP_DEFAULT; 15700 app.adjType = "top-activity"; 15701 foregroundActivities = true; 15702 procState = ActivityManager.PROCESS_STATE_TOP; 15703 } else if (app.instrumentationClass != null) { 15704 // Don't want to kill running instrumentation. 15705 adj = ProcessList.FOREGROUND_APP_ADJ; 15706 schedGroup = Process.THREAD_GROUP_DEFAULT; 15707 app.adjType = "instrumentation"; 15708 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15709 } else if ((queue = isReceivingBroadcast(app)) != null) { 15710 // An app that is currently receiving a broadcast also 15711 // counts as being in the foreground for OOM killer purposes. 15712 // It's placed in a sched group based on the nature of the 15713 // broadcast as reflected by which queue it's active in. 15714 adj = ProcessList.FOREGROUND_APP_ADJ; 15715 schedGroup = (queue == mFgBroadcastQueue) 15716 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15717 app.adjType = "broadcast"; 15718 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15719 } else if (app.executingServices.size() > 0) { 15720 // An app that is currently executing a service callback also 15721 // counts as being in the foreground. 15722 adj = ProcessList.FOREGROUND_APP_ADJ; 15723 schedGroup = app.execServicesFg ? 15724 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15725 app.adjType = "exec-service"; 15726 procState = ActivityManager.PROCESS_STATE_SERVICE; 15727 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15728 } else { 15729 // As far as we know the process is empty. We may change our mind later. 15730 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15731 // At this point we don't actually know the adjustment. Use the cached adj 15732 // value that the caller wants us to. 15733 adj = cachedAdj; 15734 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15735 app.cached = true; 15736 app.empty = true; 15737 app.adjType = "cch-empty"; 15738 } 15739 15740 // Examine all activities if not already foreground. 15741 if (!foregroundActivities && activitiesSize > 0) { 15742 for (int j = 0; j < activitiesSize; j++) { 15743 final ActivityRecord r = app.activities.get(j); 15744 if (r.app != app) { 15745 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15746 + app + "?!?"); 15747 continue; 15748 } 15749 if (r.visible) { 15750 // App has a visible activity; only upgrade adjustment. 15751 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15752 adj = ProcessList.VISIBLE_APP_ADJ; 15753 app.adjType = "visible"; 15754 } 15755 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15756 procState = ActivityManager.PROCESS_STATE_TOP; 15757 } 15758 schedGroup = Process.THREAD_GROUP_DEFAULT; 15759 app.cached = false; 15760 app.empty = false; 15761 foregroundActivities = true; 15762 break; 15763 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15764 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15765 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15766 app.adjType = "pausing"; 15767 } 15768 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15769 procState = ActivityManager.PROCESS_STATE_TOP; 15770 } 15771 schedGroup = Process.THREAD_GROUP_DEFAULT; 15772 app.cached = false; 15773 app.empty = false; 15774 foregroundActivities = true; 15775 } else if (r.state == ActivityState.STOPPING) { 15776 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15777 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15778 app.adjType = "stopping"; 15779 } 15780 // For the process state, we will at this point consider the 15781 // process to be cached. It will be cached either as an activity 15782 // or empty depending on whether the activity is finishing. We do 15783 // this so that we can treat the process as cached for purposes of 15784 // memory trimming (determing current memory level, trim command to 15785 // send to process) since there can be an arbitrary number of stopping 15786 // processes and they should soon all go into the cached state. 15787 if (!r.finishing) { 15788 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15789 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15790 } 15791 } 15792 app.cached = false; 15793 app.empty = false; 15794 foregroundActivities = true; 15795 } else { 15796 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15797 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15798 app.adjType = "cch-act"; 15799 } 15800 } 15801 } 15802 } 15803 15804 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15805 if (app.foregroundServices) { 15806 // The user is aware of this app, so make it visible. 15807 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15808 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15809 app.cached = false; 15810 app.adjType = "fg-service"; 15811 schedGroup = Process.THREAD_GROUP_DEFAULT; 15812 } else if (app.forcingToForeground != null) { 15813 // The user is aware of this app, so make it visible. 15814 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15815 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15816 app.cached = false; 15817 app.adjType = "force-fg"; 15818 app.adjSource = app.forcingToForeground; 15819 schedGroup = Process.THREAD_GROUP_DEFAULT; 15820 } 15821 } 15822 15823 if (app == mHeavyWeightProcess) { 15824 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15825 // We don't want to kill the current heavy-weight process. 15826 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15827 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15828 app.cached = false; 15829 app.adjType = "heavy"; 15830 } 15831 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15832 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15833 } 15834 } 15835 15836 if (app == mHomeProcess) { 15837 if (adj > ProcessList.HOME_APP_ADJ) { 15838 // This process is hosting what we currently consider to be the 15839 // home app, so we don't want to let it go into the background. 15840 adj = ProcessList.HOME_APP_ADJ; 15841 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15842 app.cached = false; 15843 app.adjType = "home"; 15844 } 15845 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15846 procState = ActivityManager.PROCESS_STATE_HOME; 15847 } 15848 } 15849 15850 if (app == mPreviousProcess && app.activities.size() > 0) { 15851 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15852 // This was the previous process that showed UI to the user. 15853 // We want to try to keep it around more aggressively, to give 15854 // a good experience around switching between two apps. 15855 adj = ProcessList.PREVIOUS_APP_ADJ; 15856 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15857 app.cached = false; 15858 app.adjType = "previous"; 15859 } 15860 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15861 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15862 } 15863 } 15864 15865 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15866 + " reason=" + app.adjType); 15867 15868 // By default, we use the computed adjustment. It may be changed if 15869 // there are applications dependent on our services or providers, but 15870 // this gives us a baseline and makes sure we don't get into an 15871 // infinite recursion. 15872 app.adjSeq = mAdjSeq; 15873 app.curRawAdj = adj; 15874 app.hasStartedServices = false; 15875 15876 if (mBackupTarget != null && app == mBackupTarget.app) { 15877 // If possible we want to avoid killing apps while they're being backed up 15878 if (adj > ProcessList.BACKUP_APP_ADJ) { 15879 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15880 adj = ProcessList.BACKUP_APP_ADJ; 15881 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15882 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15883 } 15884 app.adjType = "backup"; 15885 app.cached = false; 15886 } 15887 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15888 procState = ActivityManager.PROCESS_STATE_BACKUP; 15889 } 15890 } 15891 15892 boolean mayBeTop = false; 15893 15894 for (int is = app.services.size()-1; 15895 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15896 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15897 || procState > ActivityManager.PROCESS_STATE_TOP); 15898 is--) { 15899 ServiceRecord s = app.services.valueAt(is); 15900 if (s.startRequested) { 15901 app.hasStartedServices = true; 15902 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15903 procState = ActivityManager.PROCESS_STATE_SERVICE; 15904 } 15905 if (app.hasShownUi && app != mHomeProcess) { 15906 // If this process has shown some UI, let it immediately 15907 // go to the LRU list because it may be pretty heavy with 15908 // UI stuff. We'll tag it with a label just to help 15909 // debug and understand what is going on. 15910 if (adj > ProcessList.SERVICE_ADJ) { 15911 app.adjType = "cch-started-ui-services"; 15912 } 15913 } else { 15914 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15915 // This service has seen some activity within 15916 // recent memory, so we will keep its process ahead 15917 // of the background processes. 15918 if (adj > ProcessList.SERVICE_ADJ) { 15919 adj = ProcessList.SERVICE_ADJ; 15920 app.adjType = "started-services"; 15921 app.cached = false; 15922 } 15923 } 15924 // If we have let the service slide into the background 15925 // state, still have some text describing what it is doing 15926 // even though the service no longer has an impact. 15927 if (adj > ProcessList.SERVICE_ADJ) { 15928 app.adjType = "cch-started-services"; 15929 } 15930 } 15931 } 15932 for (int conni = s.connections.size()-1; 15933 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15934 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15935 || procState > ActivityManager.PROCESS_STATE_TOP); 15936 conni--) { 15937 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15938 for (int i = 0; 15939 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15940 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15941 || procState > ActivityManager.PROCESS_STATE_TOP); 15942 i++) { 15943 // XXX should compute this based on the max of 15944 // all connected clients. 15945 ConnectionRecord cr = clist.get(i); 15946 if (cr.binding.client == app) { 15947 // Binding to ourself is not interesting. 15948 continue; 15949 } 15950 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15951 ProcessRecord client = cr.binding.client; 15952 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15953 TOP_APP, doingAll, now); 15954 int clientProcState = client.curProcState; 15955 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15956 // If the other app is cached for any reason, for purposes here 15957 // we are going to consider it empty. The specific cached state 15958 // doesn't propagate except under certain conditions. 15959 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15960 } 15961 String adjType = null; 15962 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15963 // Not doing bind OOM management, so treat 15964 // this guy more like a started service. 15965 if (app.hasShownUi && app != mHomeProcess) { 15966 // If this process has shown some UI, let it immediately 15967 // go to the LRU list because it may be pretty heavy with 15968 // UI stuff. We'll tag it with a label just to help 15969 // debug and understand what is going on. 15970 if (adj > clientAdj) { 15971 adjType = "cch-bound-ui-services"; 15972 } 15973 app.cached = false; 15974 clientAdj = adj; 15975 clientProcState = procState; 15976 } else { 15977 if (now >= (s.lastActivity 15978 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15979 // This service has not seen activity within 15980 // recent memory, so allow it to drop to the 15981 // LRU list if there is no other reason to keep 15982 // it around. We'll also tag it with a label just 15983 // to help debug and undertand what is going on. 15984 if (adj > clientAdj) { 15985 adjType = "cch-bound-services"; 15986 } 15987 clientAdj = adj; 15988 } 15989 } 15990 } 15991 if (adj > clientAdj) { 15992 // If this process has recently shown UI, and 15993 // the process that is binding to it is less 15994 // important than being visible, then we don't 15995 // care about the binding as much as we care 15996 // about letting this process get into the LRU 15997 // list to be killed and restarted if needed for 15998 // memory. 15999 if (app.hasShownUi && app != mHomeProcess 16000 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16001 adjType = "cch-bound-ui-services"; 16002 } else { 16003 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16004 |Context.BIND_IMPORTANT)) != 0) { 16005 adj = clientAdj; 16006 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16007 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16008 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16009 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16010 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16011 adj = clientAdj; 16012 } else { 16013 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16014 adj = ProcessList.VISIBLE_APP_ADJ; 16015 } 16016 } 16017 if (!client.cached) { 16018 app.cached = false; 16019 } 16020 adjType = "service"; 16021 } 16022 } 16023 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16024 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16025 schedGroup = Process.THREAD_GROUP_DEFAULT; 16026 } 16027 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16028 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16029 // Special handling of clients who are in the top state. 16030 // We *may* want to consider this process to be in the 16031 // top state as well, but only if there is not another 16032 // reason for it to be running. Being on the top is a 16033 // special state, meaning you are specifically running 16034 // for the current top app. If the process is already 16035 // running in the background for some other reason, it 16036 // is more important to continue considering it to be 16037 // in the background state. 16038 mayBeTop = true; 16039 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16040 } else { 16041 // Special handling for above-top states (persistent 16042 // processes). These should not bring the current process 16043 // into the top state, since they are not on top. Instead 16044 // give them the best state after that. 16045 clientProcState = 16046 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16047 } 16048 } 16049 } else { 16050 if (clientProcState < 16051 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16052 clientProcState = 16053 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16054 } 16055 } 16056 if (procState > clientProcState) { 16057 procState = clientProcState; 16058 } 16059 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16060 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16061 app.pendingUiClean = true; 16062 } 16063 if (adjType != null) { 16064 app.adjType = adjType; 16065 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16066 .REASON_SERVICE_IN_USE; 16067 app.adjSource = cr.binding.client; 16068 app.adjSourceProcState = clientProcState; 16069 app.adjTarget = s.name; 16070 } 16071 } 16072 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16073 app.treatLikeActivity = true; 16074 } 16075 final ActivityRecord a = cr.activity; 16076 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16077 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16078 (a.visible || a.state == ActivityState.RESUMED 16079 || a.state == ActivityState.PAUSING)) { 16080 adj = ProcessList.FOREGROUND_APP_ADJ; 16081 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16082 schedGroup = Process.THREAD_GROUP_DEFAULT; 16083 } 16084 app.cached = false; 16085 app.adjType = "service"; 16086 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16087 .REASON_SERVICE_IN_USE; 16088 app.adjSource = a; 16089 app.adjSourceProcState = procState; 16090 app.adjTarget = s.name; 16091 } 16092 } 16093 } 16094 } 16095 } 16096 16097 for (int provi = app.pubProviders.size()-1; 16098 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16099 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16100 || procState > ActivityManager.PROCESS_STATE_TOP); 16101 provi--) { 16102 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16103 for (int i = cpr.connections.size()-1; 16104 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16105 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16106 || procState > ActivityManager.PROCESS_STATE_TOP); 16107 i--) { 16108 ContentProviderConnection conn = cpr.connections.get(i); 16109 ProcessRecord client = conn.client; 16110 if (client == app) { 16111 // Being our own client is not interesting. 16112 continue; 16113 } 16114 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16115 int clientProcState = client.curProcState; 16116 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16117 // If the other app is cached for any reason, for purposes here 16118 // we are going to consider it empty. 16119 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16120 } 16121 if (adj > clientAdj) { 16122 if (app.hasShownUi && app != mHomeProcess 16123 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16124 app.adjType = "cch-ui-provider"; 16125 } else { 16126 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16127 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16128 app.adjType = "provider"; 16129 } 16130 app.cached &= client.cached; 16131 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16132 .REASON_PROVIDER_IN_USE; 16133 app.adjSource = client; 16134 app.adjSourceProcState = clientProcState; 16135 app.adjTarget = cpr.name; 16136 } 16137 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16138 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16139 // Special handling of clients who are in the top state. 16140 // We *may* want to consider this process to be in the 16141 // top state as well, but only if there is not another 16142 // reason for it to be running. Being on the top is a 16143 // special state, meaning you are specifically running 16144 // for the current top app. If the process is already 16145 // running in the background for some other reason, it 16146 // is more important to continue considering it to be 16147 // in the background state. 16148 mayBeTop = true; 16149 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16150 } else { 16151 // Special handling for above-top states (persistent 16152 // processes). These should not bring the current process 16153 // into the top state, since they are not on top. Instead 16154 // give them the best state after that. 16155 clientProcState = 16156 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16157 } 16158 } 16159 if (procState > clientProcState) { 16160 procState = clientProcState; 16161 } 16162 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16163 schedGroup = Process.THREAD_GROUP_DEFAULT; 16164 } 16165 } 16166 // If the provider has external (non-framework) process 16167 // dependencies, ensure that its adjustment is at least 16168 // FOREGROUND_APP_ADJ. 16169 if (cpr.hasExternalProcessHandles()) { 16170 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16171 adj = ProcessList.FOREGROUND_APP_ADJ; 16172 schedGroup = Process.THREAD_GROUP_DEFAULT; 16173 app.cached = false; 16174 app.adjType = "provider"; 16175 app.adjTarget = cpr.name; 16176 } 16177 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16178 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16179 } 16180 } 16181 } 16182 16183 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16184 // A client of one of our services or providers is in the top state. We 16185 // *may* want to be in the top state, but not if we are already running in 16186 // the background for some other reason. For the decision here, we are going 16187 // to pick out a few specific states that we want to remain in when a client 16188 // is top (states that tend to be longer-term) and otherwise allow it to go 16189 // to the top state. 16190 switch (procState) { 16191 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16192 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16193 case ActivityManager.PROCESS_STATE_SERVICE: 16194 // These all are longer-term states, so pull them up to the top 16195 // of the background states, but not all the way to the top state. 16196 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16197 break; 16198 default: 16199 // Otherwise, top is a better choice, so take it. 16200 procState = ActivityManager.PROCESS_STATE_TOP; 16201 break; 16202 } 16203 } 16204 16205 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16206 if (app.hasClientActivities) { 16207 // This is a cached process, but with client activities. Mark it so. 16208 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16209 app.adjType = "cch-client-act"; 16210 } else if (app.treatLikeActivity) { 16211 // This is a cached process, but somebody wants us to treat it like it has 16212 // an activity, okay! 16213 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16214 app.adjType = "cch-as-act"; 16215 } 16216 } 16217 16218 if (adj == ProcessList.SERVICE_ADJ) { 16219 if (doingAll) { 16220 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16221 mNewNumServiceProcs++; 16222 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16223 if (!app.serviceb) { 16224 // This service isn't far enough down on the LRU list to 16225 // normally be a B service, but if we are low on RAM and it 16226 // is large we want to force it down since we would prefer to 16227 // keep launcher over it. 16228 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16229 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16230 app.serviceHighRam = true; 16231 app.serviceb = true; 16232 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16233 } else { 16234 mNewNumAServiceProcs++; 16235 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16236 } 16237 } else { 16238 app.serviceHighRam = false; 16239 } 16240 } 16241 if (app.serviceb) { 16242 adj = ProcessList.SERVICE_B_ADJ; 16243 } 16244 } 16245 16246 app.curRawAdj = adj; 16247 16248 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16249 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16250 if (adj > app.maxAdj) { 16251 adj = app.maxAdj; 16252 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16253 schedGroup = Process.THREAD_GROUP_DEFAULT; 16254 } 16255 } 16256 16257 // Do final modification to adj. Everything we do between here and applying 16258 // the final setAdj must be done in this function, because we will also use 16259 // it when computing the final cached adj later. Note that we don't need to 16260 // worry about this for max adj above, since max adj will always be used to 16261 // keep it out of the cached vaues. 16262 app.curAdj = app.modifyRawOomAdj(adj); 16263 app.curSchedGroup = schedGroup; 16264 app.curProcState = procState; 16265 app.foregroundActivities = foregroundActivities; 16266 16267 return app.curRawAdj; 16268 } 16269 16270 /** 16271 * Schedule PSS collection of a process. 16272 */ 16273 void requestPssLocked(ProcessRecord proc, int procState) { 16274 if (mPendingPssProcesses.contains(proc)) { 16275 return; 16276 } 16277 if (mPendingPssProcesses.size() == 0) { 16278 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16279 } 16280 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16281 proc.pssProcState = procState; 16282 mPendingPssProcesses.add(proc); 16283 } 16284 16285 /** 16286 * Schedule PSS collection of all processes. 16287 */ 16288 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16289 if (!always) { 16290 if (now < (mLastFullPssTime + 16291 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16292 return; 16293 } 16294 } 16295 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16296 mLastFullPssTime = now; 16297 mFullPssPending = true; 16298 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16299 mPendingPssProcesses.clear(); 16300 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16301 ProcessRecord app = mLruProcesses.get(i); 16302 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16303 app.pssProcState = app.setProcState; 16304 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16305 isSleeping(), now); 16306 mPendingPssProcesses.add(app); 16307 } 16308 } 16309 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16310 } 16311 16312 /** 16313 * Ask a given process to GC right now. 16314 */ 16315 final void performAppGcLocked(ProcessRecord app) { 16316 try { 16317 app.lastRequestedGc = SystemClock.uptimeMillis(); 16318 if (app.thread != null) { 16319 if (app.reportLowMemory) { 16320 app.reportLowMemory = false; 16321 app.thread.scheduleLowMemory(); 16322 } else { 16323 app.thread.processInBackground(); 16324 } 16325 } 16326 } catch (Exception e) { 16327 // whatever. 16328 } 16329 } 16330 16331 /** 16332 * Returns true if things are idle enough to perform GCs. 16333 */ 16334 private final boolean canGcNowLocked() { 16335 boolean processingBroadcasts = false; 16336 for (BroadcastQueue q : mBroadcastQueues) { 16337 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16338 processingBroadcasts = true; 16339 } 16340 } 16341 return !processingBroadcasts 16342 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16343 } 16344 16345 /** 16346 * Perform GCs on all processes that are waiting for it, but only 16347 * if things are idle. 16348 */ 16349 final void performAppGcsLocked() { 16350 final int N = mProcessesToGc.size(); 16351 if (N <= 0) { 16352 return; 16353 } 16354 if (canGcNowLocked()) { 16355 while (mProcessesToGc.size() > 0) { 16356 ProcessRecord proc = mProcessesToGc.remove(0); 16357 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16358 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16359 <= SystemClock.uptimeMillis()) { 16360 // To avoid spamming the system, we will GC processes one 16361 // at a time, waiting a few seconds between each. 16362 performAppGcLocked(proc); 16363 scheduleAppGcsLocked(); 16364 return; 16365 } else { 16366 // It hasn't been long enough since we last GCed this 16367 // process... put it in the list to wait for its time. 16368 addProcessToGcListLocked(proc); 16369 break; 16370 } 16371 } 16372 } 16373 16374 scheduleAppGcsLocked(); 16375 } 16376 } 16377 16378 /** 16379 * If all looks good, perform GCs on all processes waiting for them. 16380 */ 16381 final void performAppGcsIfAppropriateLocked() { 16382 if (canGcNowLocked()) { 16383 performAppGcsLocked(); 16384 return; 16385 } 16386 // Still not idle, wait some more. 16387 scheduleAppGcsLocked(); 16388 } 16389 16390 /** 16391 * Schedule the execution of all pending app GCs. 16392 */ 16393 final void scheduleAppGcsLocked() { 16394 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16395 16396 if (mProcessesToGc.size() > 0) { 16397 // Schedule a GC for the time to the next process. 16398 ProcessRecord proc = mProcessesToGc.get(0); 16399 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16400 16401 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16402 long now = SystemClock.uptimeMillis(); 16403 if (when < (now+GC_TIMEOUT)) { 16404 when = now + GC_TIMEOUT; 16405 } 16406 mHandler.sendMessageAtTime(msg, when); 16407 } 16408 } 16409 16410 /** 16411 * Add a process to the array of processes waiting to be GCed. Keeps the 16412 * list in sorted order by the last GC time. The process can't already be 16413 * on the list. 16414 */ 16415 final void addProcessToGcListLocked(ProcessRecord proc) { 16416 boolean added = false; 16417 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16418 if (mProcessesToGc.get(i).lastRequestedGc < 16419 proc.lastRequestedGc) { 16420 added = true; 16421 mProcessesToGc.add(i+1, proc); 16422 break; 16423 } 16424 } 16425 if (!added) { 16426 mProcessesToGc.add(0, proc); 16427 } 16428 } 16429 16430 /** 16431 * Set up to ask a process to GC itself. This will either do it 16432 * immediately, or put it on the list of processes to gc the next 16433 * time things are idle. 16434 */ 16435 final void scheduleAppGcLocked(ProcessRecord app) { 16436 long now = SystemClock.uptimeMillis(); 16437 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16438 return; 16439 } 16440 if (!mProcessesToGc.contains(app)) { 16441 addProcessToGcListLocked(app); 16442 scheduleAppGcsLocked(); 16443 } 16444 } 16445 16446 final void checkExcessivePowerUsageLocked(boolean doKills) { 16447 updateCpuStatsNow(); 16448 16449 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16450 boolean doWakeKills = doKills; 16451 boolean doCpuKills = doKills; 16452 if (mLastPowerCheckRealtime == 0) { 16453 doWakeKills = false; 16454 } 16455 if (mLastPowerCheckUptime == 0) { 16456 doCpuKills = false; 16457 } 16458 if (stats.isScreenOn()) { 16459 doWakeKills = false; 16460 } 16461 final long curRealtime = SystemClock.elapsedRealtime(); 16462 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16463 final long curUptime = SystemClock.uptimeMillis(); 16464 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16465 mLastPowerCheckRealtime = curRealtime; 16466 mLastPowerCheckUptime = curUptime; 16467 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16468 doWakeKills = false; 16469 } 16470 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16471 doCpuKills = false; 16472 } 16473 int i = mLruProcesses.size(); 16474 while (i > 0) { 16475 i--; 16476 ProcessRecord app = mLruProcesses.get(i); 16477 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16478 long wtime; 16479 synchronized (stats) { 16480 wtime = stats.getProcessWakeTime(app.info.uid, 16481 app.pid, curRealtime); 16482 } 16483 long wtimeUsed = wtime - app.lastWakeTime; 16484 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16485 if (DEBUG_POWER) { 16486 StringBuilder sb = new StringBuilder(128); 16487 sb.append("Wake for "); 16488 app.toShortString(sb); 16489 sb.append(": over "); 16490 TimeUtils.formatDuration(realtimeSince, sb); 16491 sb.append(" used "); 16492 TimeUtils.formatDuration(wtimeUsed, sb); 16493 sb.append(" ("); 16494 sb.append((wtimeUsed*100)/realtimeSince); 16495 sb.append("%)"); 16496 Slog.i(TAG, sb.toString()); 16497 sb.setLength(0); 16498 sb.append("CPU for "); 16499 app.toShortString(sb); 16500 sb.append(": over "); 16501 TimeUtils.formatDuration(uptimeSince, sb); 16502 sb.append(" used "); 16503 TimeUtils.formatDuration(cputimeUsed, sb); 16504 sb.append(" ("); 16505 sb.append((cputimeUsed*100)/uptimeSince); 16506 sb.append("%)"); 16507 Slog.i(TAG, sb.toString()); 16508 } 16509 // If a process has held a wake lock for more 16510 // than 50% of the time during this period, 16511 // that sounds bad. Kill! 16512 if (doWakeKills && realtimeSince > 0 16513 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16514 synchronized (stats) { 16515 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16516 realtimeSince, wtimeUsed); 16517 } 16518 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16519 + " during " + realtimeSince); 16520 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16521 } else if (doCpuKills && uptimeSince > 0 16522 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16523 synchronized (stats) { 16524 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16525 uptimeSince, cputimeUsed); 16526 } 16527 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16528 + " during " + uptimeSince); 16529 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16530 } else { 16531 app.lastWakeTime = wtime; 16532 app.lastCpuTime = app.curCpuTime; 16533 } 16534 } 16535 } 16536 } 16537 16538 private final boolean applyOomAdjLocked(ProcessRecord app, 16539 ProcessRecord TOP_APP, boolean doingAll, long now) { 16540 boolean success = true; 16541 16542 if (app.curRawAdj != app.setRawAdj) { 16543 app.setRawAdj = app.curRawAdj; 16544 } 16545 16546 int changes = 0; 16547 16548 if (app.curAdj != app.setAdj) { 16549 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16550 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16551 TAG, "Set " + app.pid + " " + app.processName + 16552 " adj " + app.curAdj + ": " + app.adjType); 16553 app.setAdj = app.curAdj; 16554 } 16555 16556 if (app.setSchedGroup != app.curSchedGroup) { 16557 app.setSchedGroup = app.curSchedGroup; 16558 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16559 "Setting process group of " + app.processName 16560 + " to " + app.curSchedGroup); 16561 if (app.waitingToKill != null && 16562 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16563 killUnneededProcessLocked(app, app.waitingToKill); 16564 success = false; 16565 } else { 16566 if (true) { 16567 long oldId = Binder.clearCallingIdentity(); 16568 try { 16569 Process.setProcessGroup(app.pid, app.curSchedGroup); 16570 } catch (Exception e) { 16571 Slog.w(TAG, "Failed setting process group of " + app.pid 16572 + " to " + app.curSchedGroup); 16573 e.printStackTrace(); 16574 } finally { 16575 Binder.restoreCallingIdentity(oldId); 16576 } 16577 } else { 16578 if (app.thread != null) { 16579 try { 16580 app.thread.setSchedulingGroup(app.curSchedGroup); 16581 } catch (RemoteException e) { 16582 } 16583 } 16584 } 16585 Process.setSwappiness(app.pid, 16586 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16587 } 16588 } 16589 if (app.repForegroundActivities != app.foregroundActivities) { 16590 app.repForegroundActivities = app.foregroundActivities; 16591 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16592 } 16593 if (app.repProcState != app.curProcState) { 16594 app.repProcState = app.curProcState; 16595 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16596 if (app.thread != null) { 16597 try { 16598 if (false) { 16599 //RuntimeException h = new RuntimeException("here"); 16600 Slog.i(TAG, "Sending new process state " + app.repProcState 16601 + " to " + app /*, h*/); 16602 } 16603 app.thread.setProcessState(app.repProcState); 16604 } catch (RemoteException e) { 16605 } 16606 } 16607 } 16608 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16609 app.setProcState)) { 16610 app.lastStateTime = now; 16611 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16612 isSleeping(), now); 16613 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16614 + ProcessList.makeProcStateString(app.setProcState) + " to " 16615 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16616 + (app.nextPssTime-now) + ": " + app); 16617 } else { 16618 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16619 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16620 requestPssLocked(app, app.setProcState); 16621 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16622 isSleeping(), now); 16623 } else if (false && DEBUG_PSS) { 16624 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16625 } 16626 } 16627 if (app.setProcState != app.curProcState) { 16628 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16629 "Proc state change of " + app.processName 16630 + " to " + app.curProcState); 16631 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16632 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16633 if (setImportant && !curImportant) { 16634 // This app is no longer something we consider important enough to allow to 16635 // use arbitrary amounts of battery power. Note 16636 // its current wake lock time to later know to kill it if 16637 // it is not behaving well. 16638 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16639 synchronized (stats) { 16640 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16641 app.pid, SystemClock.elapsedRealtime()); 16642 } 16643 app.lastCpuTime = app.curCpuTime; 16644 16645 } 16646 app.setProcState = app.curProcState; 16647 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16648 app.notCachedSinceIdle = false; 16649 } 16650 if (!doingAll) { 16651 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16652 } else { 16653 app.procStateChanged = true; 16654 } 16655 } 16656 16657 if (changes != 0) { 16658 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16659 int i = mPendingProcessChanges.size()-1; 16660 ProcessChangeItem item = null; 16661 while (i >= 0) { 16662 item = mPendingProcessChanges.get(i); 16663 if (item.pid == app.pid) { 16664 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16665 break; 16666 } 16667 i--; 16668 } 16669 if (i < 0) { 16670 // No existing item in pending changes; need a new one. 16671 final int NA = mAvailProcessChanges.size(); 16672 if (NA > 0) { 16673 item = mAvailProcessChanges.remove(NA-1); 16674 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16675 } else { 16676 item = new ProcessChangeItem(); 16677 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16678 } 16679 item.changes = 0; 16680 item.pid = app.pid; 16681 item.uid = app.info.uid; 16682 if (mPendingProcessChanges.size() == 0) { 16683 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16684 "*** Enqueueing dispatch processes changed!"); 16685 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16686 } 16687 mPendingProcessChanges.add(item); 16688 } 16689 item.changes |= changes; 16690 item.processState = app.repProcState; 16691 item.foregroundActivities = app.repForegroundActivities; 16692 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16693 + Integer.toHexString(System.identityHashCode(item)) 16694 + " " + app.toShortString() + ": changes=" + item.changes 16695 + " procState=" + item.processState 16696 + " foreground=" + item.foregroundActivities 16697 + " type=" + app.adjType + " source=" + app.adjSource 16698 + " target=" + app.adjTarget); 16699 } 16700 16701 return success; 16702 } 16703 16704 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16705 if (proc.thread != null) { 16706 if (proc.baseProcessTracker != null) { 16707 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16708 } 16709 if (proc.repProcState >= 0) { 16710 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16711 proc.repProcState); 16712 } 16713 } 16714 } 16715 16716 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16717 ProcessRecord TOP_APP, boolean doingAll, long now) { 16718 if (app.thread == null) { 16719 return false; 16720 } 16721 16722 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16723 16724 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16725 } 16726 16727 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16728 boolean oomAdj) { 16729 if (isForeground != proc.foregroundServices) { 16730 proc.foregroundServices = isForeground; 16731 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16732 proc.info.uid); 16733 if (isForeground) { 16734 if (curProcs == null) { 16735 curProcs = new ArrayList<ProcessRecord>(); 16736 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16737 } 16738 if (!curProcs.contains(proc)) { 16739 curProcs.add(proc); 16740 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16741 proc.info.packageName, proc.info.uid); 16742 } 16743 } else { 16744 if (curProcs != null) { 16745 if (curProcs.remove(proc)) { 16746 mBatteryStatsService.noteEvent( 16747 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16748 proc.info.packageName, proc.info.uid); 16749 if (curProcs.size() <= 0) { 16750 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16751 } 16752 } 16753 } 16754 } 16755 if (oomAdj) { 16756 updateOomAdjLocked(); 16757 } 16758 } 16759 } 16760 16761 private final ActivityRecord resumedAppLocked() { 16762 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16763 String pkg; 16764 int uid; 16765 if (act != null) { 16766 pkg = act.packageName; 16767 uid = act.info.applicationInfo.uid; 16768 } else { 16769 pkg = null; 16770 uid = -1; 16771 } 16772 // Has the UID or resumed package name changed? 16773 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16774 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16775 if (mCurResumedPackage != null) { 16776 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16777 mCurResumedPackage, mCurResumedUid); 16778 } 16779 mCurResumedPackage = pkg; 16780 mCurResumedUid = uid; 16781 if (mCurResumedPackage != null) { 16782 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16783 mCurResumedPackage, mCurResumedUid); 16784 } 16785 } 16786 return act; 16787 } 16788 16789 final boolean updateOomAdjLocked(ProcessRecord app) { 16790 final ActivityRecord TOP_ACT = resumedAppLocked(); 16791 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16792 final boolean wasCached = app.cached; 16793 16794 mAdjSeq++; 16795 16796 // This is the desired cached adjusment we want to tell it to use. 16797 // If our app is currently cached, we know it, and that is it. Otherwise, 16798 // we don't know it yet, and it needs to now be cached we will then 16799 // need to do a complete oom adj. 16800 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16801 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16802 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16803 SystemClock.uptimeMillis()); 16804 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16805 // Changed to/from cached state, so apps after it in the LRU 16806 // list may also be changed. 16807 updateOomAdjLocked(); 16808 } 16809 return success; 16810 } 16811 16812 final void updateOomAdjLocked() { 16813 final ActivityRecord TOP_ACT = resumedAppLocked(); 16814 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16815 final long now = SystemClock.uptimeMillis(); 16816 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16817 final int N = mLruProcesses.size(); 16818 16819 if (false) { 16820 RuntimeException e = new RuntimeException(); 16821 e.fillInStackTrace(); 16822 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16823 } 16824 16825 mAdjSeq++; 16826 mNewNumServiceProcs = 0; 16827 mNewNumAServiceProcs = 0; 16828 16829 final int emptyProcessLimit; 16830 final int cachedProcessLimit; 16831 if (mProcessLimit <= 0) { 16832 emptyProcessLimit = cachedProcessLimit = 0; 16833 } else if (mProcessLimit == 1) { 16834 emptyProcessLimit = 1; 16835 cachedProcessLimit = 0; 16836 } else { 16837 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16838 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16839 } 16840 16841 // Let's determine how many processes we have running vs. 16842 // how many slots we have for background processes; we may want 16843 // to put multiple processes in a slot of there are enough of 16844 // them. 16845 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16846 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16847 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16848 if (numEmptyProcs > cachedProcessLimit) { 16849 // If there are more empty processes than our limit on cached 16850 // processes, then use the cached process limit for the factor. 16851 // This ensures that the really old empty processes get pushed 16852 // down to the bottom, so if we are running low on memory we will 16853 // have a better chance at keeping around more cached processes 16854 // instead of a gazillion empty processes. 16855 numEmptyProcs = cachedProcessLimit; 16856 } 16857 int emptyFactor = numEmptyProcs/numSlots; 16858 if (emptyFactor < 1) emptyFactor = 1; 16859 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16860 if (cachedFactor < 1) cachedFactor = 1; 16861 int stepCached = 0; 16862 int stepEmpty = 0; 16863 int numCached = 0; 16864 int numEmpty = 0; 16865 int numTrimming = 0; 16866 16867 mNumNonCachedProcs = 0; 16868 mNumCachedHiddenProcs = 0; 16869 16870 // First update the OOM adjustment for each of the 16871 // application processes based on their current state. 16872 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16873 int nextCachedAdj = curCachedAdj+1; 16874 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16875 int nextEmptyAdj = curEmptyAdj+2; 16876 for (int i=N-1; i>=0; i--) { 16877 ProcessRecord app = mLruProcesses.get(i); 16878 if (!app.killedByAm && app.thread != null) { 16879 app.procStateChanged = false; 16880 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16881 16882 // If we haven't yet assigned the final cached adj 16883 // to the process, do that now. 16884 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16885 switch (app.curProcState) { 16886 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16887 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16888 // This process is a cached process holding activities... 16889 // assign it the next cached value for that type, and then 16890 // step that cached level. 16891 app.curRawAdj = curCachedAdj; 16892 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16893 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16894 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16895 + ")"); 16896 if (curCachedAdj != nextCachedAdj) { 16897 stepCached++; 16898 if (stepCached >= cachedFactor) { 16899 stepCached = 0; 16900 curCachedAdj = nextCachedAdj; 16901 nextCachedAdj += 2; 16902 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16903 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16904 } 16905 } 16906 } 16907 break; 16908 default: 16909 // For everything else, assign next empty cached process 16910 // level and bump that up. Note that this means that 16911 // long-running services that have dropped down to the 16912 // cached level will be treated as empty (since their process 16913 // state is still as a service), which is what we want. 16914 app.curRawAdj = curEmptyAdj; 16915 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16916 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16917 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16918 + ")"); 16919 if (curEmptyAdj != nextEmptyAdj) { 16920 stepEmpty++; 16921 if (stepEmpty >= emptyFactor) { 16922 stepEmpty = 0; 16923 curEmptyAdj = nextEmptyAdj; 16924 nextEmptyAdj += 2; 16925 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16926 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16927 } 16928 } 16929 } 16930 break; 16931 } 16932 } 16933 16934 applyOomAdjLocked(app, TOP_APP, true, now); 16935 16936 // Count the number of process types. 16937 switch (app.curProcState) { 16938 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16939 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16940 mNumCachedHiddenProcs++; 16941 numCached++; 16942 if (numCached > cachedProcessLimit) { 16943 killUnneededProcessLocked(app, "cached #" + numCached); 16944 } 16945 break; 16946 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16947 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16948 && app.lastActivityTime < oldTime) { 16949 killUnneededProcessLocked(app, "empty for " 16950 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16951 / 1000) + "s"); 16952 } else { 16953 numEmpty++; 16954 if (numEmpty > emptyProcessLimit) { 16955 killUnneededProcessLocked(app, "empty #" + numEmpty); 16956 } 16957 } 16958 break; 16959 default: 16960 mNumNonCachedProcs++; 16961 break; 16962 } 16963 16964 if (app.isolated && app.services.size() <= 0) { 16965 // If this is an isolated process, and there are no 16966 // services running in it, then the process is no longer 16967 // needed. We agressively kill these because we can by 16968 // definition not re-use the same process again, and it is 16969 // good to avoid having whatever code was running in them 16970 // left sitting around after no longer needed. 16971 killUnneededProcessLocked(app, "isolated not needed"); 16972 } 16973 16974 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16975 && !app.killedByAm) { 16976 numTrimming++; 16977 } 16978 } 16979 } 16980 16981 mNumServiceProcs = mNewNumServiceProcs; 16982 16983 // Now determine the memory trimming level of background processes. 16984 // Unfortunately we need to start at the back of the list to do this 16985 // properly. We only do this if the number of background apps we 16986 // are managing to keep around is less than half the maximum we desire; 16987 // if we are keeping a good number around, we'll let them use whatever 16988 // memory they want. 16989 final int numCachedAndEmpty = numCached + numEmpty; 16990 int memFactor; 16991 if (numCached <= ProcessList.TRIM_CACHED_APPS 16992 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16993 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16994 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16995 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16996 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16997 } else { 16998 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16999 } 17000 } else { 17001 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17002 } 17003 // We always allow the memory level to go up (better). We only allow it to go 17004 // down if we are in a state where that is allowed, *and* the total number of processes 17005 // has gone down since last time. 17006 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17007 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17008 + " last=" + mLastNumProcesses); 17009 if (memFactor > mLastMemoryLevel) { 17010 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17011 memFactor = mLastMemoryLevel; 17012 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17013 } 17014 } 17015 mLastMemoryLevel = memFactor; 17016 mLastNumProcesses = mLruProcesses.size(); 17017 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17018 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17019 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17020 if (mLowRamStartTime == 0) { 17021 mLowRamStartTime = now; 17022 } 17023 int step = 0; 17024 int fgTrimLevel; 17025 switch (memFactor) { 17026 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17027 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17028 break; 17029 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17030 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17031 break; 17032 default: 17033 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17034 break; 17035 } 17036 int factor = numTrimming/3; 17037 int minFactor = 2; 17038 if (mHomeProcess != null) minFactor++; 17039 if (mPreviousProcess != null) minFactor++; 17040 if (factor < minFactor) factor = minFactor; 17041 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17042 for (int i=N-1; i>=0; i--) { 17043 ProcessRecord app = mLruProcesses.get(i); 17044 if (allChanged || app.procStateChanged) { 17045 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17046 app.procStateChanged = false; 17047 } 17048 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17049 && !app.killedByAm) { 17050 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17051 try { 17052 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17053 "Trimming memory of " + app.processName 17054 + " to " + curLevel); 17055 app.thread.scheduleTrimMemory(curLevel); 17056 } catch (RemoteException e) { 17057 } 17058 if (false) { 17059 // For now we won't do this; our memory trimming seems 17060 // to be good enough at this point that destroying 17061 // activities causes more harm than good. 17062 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17063 && app != mHomeProcess && app != mPreviousProcess) { 17064 // Need to do this on its own message because the stack may not 17065 // be in a consistent state at this point. 17066 // For these apps we will also finish their activities 17067 // to help them free memory. 17068 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17069 } 17070 } 17071 } 17072 app.trimMemoryLevel = curLevel; 17073 step++; 17074 if (step >= factor) { 17075 step = 0; 17076 switch (curLevel) { 17077 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17078 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17079 break; 17080 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17081 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17082 break; 17083 } 17084 } 17085 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17086 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17087 && app.thread != null) { 17088 try { 17089 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17090 "Trimming memory of heavy-weight " + app.processName 17091 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17092 app.thread.scheduleTrimMemory( 17093 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17094 } catch (RemoteException e) { 17095 } 17096 } 17097 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17098 } else { 17099 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17100 || app.systemNoUi) && app.pendingUiClean) { 17101 // If this application is now in the background and it 17102 // had done UI, then give it the special trim level to 17103 // have it free UI resources. 17104 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17105 if (app.trimMemoryLevel < level && app.thread != null) { 17106 try { 17107 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17108 "Trimming memory of bg-ui " + app.processName 17109 + " to " + level); 17110 app.thread.scheduleTrimMemory(level); 17111 } catch (RemoteException e) { 17112 } 17113 } 17114 app.pendingUiClean = false; 17115 } 17116 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17117 try { 17118 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17119 "Trimming memory of fg " + app.processName 17120 + " to " + fgTrimLevel); 17121 app.thread.scheduleTrimMemory(fgTrimLevel); 17122 } catch (RemoteException e) { 17123 } 17124 } 17125 app.trimMemoryLevel = fgTrimLevel; 17126 } 17127 } 17128 } else { 17129 if (mLowRamStartTime != 0) { 17130 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17131 mLowRamStartTime = 0; 17132 } 17133 for (int i=N-1; i>=0; i--) { 17134 ProcessRecord app = mLruProcesses.get(i); 17135 if (allChanged || app.procStateChanged) { 17136 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17137 app.procStateChanged = false; 17138 } 17139 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17140 || app.systemNoUi) && app.pendingUiClean) { 17141 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17142 && app.thread != null) { 17143 try { 17144 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17145 "Trimming memory of ui hidden " + app.processName 17146 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17147 app.thread.scheduleTrimMemory( 17148 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17149 } catch (RemoteException e) { 17150 } 17151 } 17152 app.pendingUiClean = false; 17153 } 17154 app.trimMemoryLevel = 0; 17155 } 17156 } 17157 17158 if (mAlwaysFinishActivities) { 17159 // Need to do this on its own message because the stack may not 17160 // be in a consistent state at this point. 17161 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17162 } 17163 17164 if (allChanged) { 17165 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17166 } 17167 17168 if (mProcessStats.shouldWriteNowLocked(now)) { 17169 mHandler.post(new Runnable() { 17170 @Override public void run() { 17171 synchronized (ActivityManagerService.this) { 17172 mProcessStats.writeStateAsyncLocked(); 17173 } 17174 } 17175 }); 17176 } 17177 17178 if (DEBUG_OOM_ADJ) { 17179 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17180 } 17181 } 17182 17183 final void trimApplications() { 17184 synchronized (this) { 17185 int i; 17186 17187 // First remove any unused application processes whose package 17188 // has been removed. 17189 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17190 final ProcessRecord app = mRemovedProcesses.get(i); 17191 if (app.activities.size() == 0 17192 && app.curReceiver == null && app.services.size() == 0) { 17193 Slog.i( 17194 TAG, "Exiting empty application process " 17195 + app.processName + " (" 17196 + (app.thread != null ? app.thread.asBinder() : null) 17197 + ")\n"); 17198 if (app.pid > 0 && app.pid != MY_PID) { 17199 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 17200 app.processName, app.setAdj, "empty"); 17201 app.killedByAm = true; 17202 Process.killProcessQuiet(app.pid); 17203 Process.killProcessGroup(app.info.uid, app.pid); 17204 } else { 17205 try { 17206 app.thread.scheduleExit(); 17207 } catch (Exception e) { 17208 // Ignore exceptions. 17209 } 17210 } 17211 cleanUpApplicationRecordLocked(app, false, true, -1); 17212 mRemovedProcesses.remove(i); 17213 17214 if (app.persistent) { 17215 addAppLocked(app.info, false, null /* ABI override */); 17216 } 17217 } 17218 } 17219 17220 // Now update the oom adj for all processes. 17221 updateOomAdjLocked(); 17222 } 17223 } 17224 17225 /** This method sends the specified signal to each of the persistent apps */ 17226 public void signalPersistentProcesses(int sig) throws RemoteException { 17227 if (sig != Process.SIGNAL_USR1) { 17228 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17229 } 17230 17231 synchronized (this) { 17232 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17233 != PackageManager.PERMISSION_GRANTED) { 17234 throw new SecurityException("Requires permission " 17235 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17236 } 17237 17238 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17239 ProcessRecord r = mLruProcesses.get(i); 17240 if (r.thread != null && r.persistent) { 17241 Process.sendSignal(r.pid, sig); 17242 } 17243 } 17244 } 17245 } 17246 17247 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 17248 if (proc == null || proc == mProfileProc) { 17249 proc = mProfileProc; 17250 path = mProfileFile; 17251 profileType = mProfileType; 17252 clearProfilerLocked(); 17253 } 17254 if (proc == null) { 17255 return; 17256 } 17257 try { 17258 proc.thread.profilerControl(false, path, null, profileType); 17259 } catch (RemoteException e) { 17260 throw new IllegalStateException("Process disappeared"); 17261 } 17262 } 17263 17264 private void clearProfilerLocked() { 17265 if (mProfileFd != null) { 17266 try { 17267 mProfileFd.close(); 17268 } catch (IOException e) { 17269 } 17270 } 17271 mProfileApp = null; 17272 mProfileProc = null; 17273 mProfileFile = null; 17274 mProfileType = 0; 17275 mAutoStopProfiler = false; 17276 } 17277 17278 public boolean profileControl(String process, int userId, boolean start, 17279 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 17280 17281 try { 17282 synchronized (this) { 17283 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17284 // its own permission. 17285 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17286 != PackageManager.PERMISSION_GRANTED) { 17287 throw new SecurityException("Requires permission " 17288 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17289 } 17290 17291 if (start && fd == null) { 17292 throw new IllegalArgumentException("null fd"); 17293 } 17294 17295 ProcessRecord proc = null; 17296 if (process != null) { 17297 proc = findProcessLocked(process, userId, "profileControl"); 17298 } 17299 17300 if (start && (proc == null || proc.thread == null)) { 17301 throw new IllegalArgumentException("Unknown process: " + process); 17302 } 17303 17304 if (start) { 17305 stopProfilerLocked(null, null, 0); 17306 setProfileApp(proc.info, proc.processName, path, fd, false); 17307 mProfileProc = proc; 17308 mProfileType = profileType; 17309 try { 17310 fd = fd.dup(); 17311 } catch (IOException e) { 17312 fd = null; 17313 } 17314 proc.thread.profilerControl(start, path, fd, profileType); 17315 fd = null; 17316 mProfileFd = null; 17317 } else { 17318 stopProfilerLocked(proc, path, profileType); 17319 if (fd != null) { 17320 try { 17321 fd.close(); 17322 } catch (IOException e) { 17323 } 17324 } 17325 } 17326 17327 return true; 17328 } 17329 } catch (RemoteException e) { 17330 throw new IllegalStateException("Process disappeared"); 17331 } finally { 17332 if (fd != null) { 17333 try { 17334 fd.close(); 17335 } catch (IOException e) { 17336 } 17337 } 17338 } 17339 } 17340 17341 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17342 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17343 userId, true, ALLOW_FULL_ONLY, callName, null); 17344 ProcessRecord proc = null; 17345 try { 17346 int pid = Integer.parseInt(process); 17347 synchronized (mPidsSelfLocked) { 17348 proc = mPidsSelfLocked.get(pid); 17349 } 17350 } catch (NumberFormatException e) { 17351 } 17352 17353 if (proc == null) { 17354 ArrayMap<String, SparseArray<ProcessRecord>> all 17355 = mProcessNames.getMap(); 17356 SparseArray<ProcessRecord> procs = all.get(process); 17357 if (procs != null && procs.size() > 0) { 17358 proc = procs.valueAt(0); 17359 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17360 for (int i=1; i<procs.size(); i++) { 17361 ProcessRecord thisProc = procs.valueAt(i); 17362 if (thisProc.userId == userId) { 17363 proc = thisProc; 17364 break; 17365 } 17366 } 17367 } 17368 } 17369 } 17370 17371 return proc; 17372 } 17373 17374 public boolean dumpHeap(String process, int userId, boolean managed, 17375 String path, ParcelFileDescriptor fd) throws RemoteException { 17376 17377 try { 17378 synchronized (this) { 17379 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17380 // its own permission (same as profileControl). 17381 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17382 != PackageManager.PERMISSION_GRANTED) { 17383 throw new SecurityException("Requires permission " 17384 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17385 } 17386 17387 if (fd == null) { 17388 throw new IllegalArgumentException("null fd"); 17389 } 17390 17391 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17392 if (proc == null || proc.thread == null) { 17393 throw new IllegalArgumentException("Unknown process: " + process); 17394 } 17395 17396 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17397 if (!isDebuggable) { 17398 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17399 throw new SecurityException("Process not debuggable: " + proc); 17400 } 17401 } 17402 17403 proc.thread.dumpHeap(managed, path, fd); 17404 fd = null; 17405 return true; 17406 } 17407 } catch (RemoteException e) { 17408 throw new IllegalStateException("Process disappeared"); 17409 } finally { 17410 if (fd != null) { 17411 try { 17412 fd.close(); 17413 } catch (IOException e) { 17414 } 17415 } 17416 } 17417 } 17418 17419 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17420 public void monitor() { 17421 synchronized (this) { } 17422 } 17423 17424 void onCoreSettingsChange(Bundle settings) { 17425 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17426 ProcessRecord processRecord = mLruProcesses.get(i); 17427 try { 17428 if (processRecord.thread != null) { 17429 processRecord.thread.setCoreSettings(settings); 17430 } 17431 } catch (RemoteException re) { 17432 /* ignore */ 17433 } 17434 } 17435 } 17436 17437 // Multi-user methods 17438 17439 /** 17440 * Start user, if its not already running, but don't bring it to foreground. 17441 */ 17442 @Override 17443 public boolean startUserInBackground(final int userId) { 17444 return startUser(userId, /* foreground */ false); 17445 } 17446 17447 /** 17448 * Refreshes the list of users related to the current user when either a 17449 * user switch happens or when a new related user is started in the 17450 * background. 17451 */ 17452 private void updateCurrentProfileIdsLocked() { 17453 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17454 mCurrentUserId, false /* enabledOnly */); 17455 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17456 for (int i = 0; i < currentProfileIds.length; i++) { 17457 currentProfileIds[i] = profiles.get(i).id; 17458 } 17459 mCurrentProfileIds = currentProfileIds; 17460 17461 synchronized (mUserProfileGroupIdsSelfLocked) { 17462 mUserProfileGroupIdsSelfLocked.clear(); 17463 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17464 for (int i = 0; i < users.size(); i++) { 17465 UserInfo user = users.get(i); 17466 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17467 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17468 } 17469 } 17470 } 17471 } 17472 17473 private Set getProfileIdsLocked(int userId) { 17474 Set userIds = new HashSet<Integer>(); 17475 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17476 userId, false /* enabledOnly */); 17477 for (UserInfo user : profiles) { 17478 userIds.add(Integer.valueOf(user.id)); 17479 } 17480 return userIds; 17481 } 17482 17483 @Override 17484 public boolean switchUser(final int userId) { 17485 return startUser(userId, /* foregound */ true); 17486 } 17487 17488 private boolean startUser(final int userId, boolean foreground) { 17489 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17490 != PackageManager.PERMISSION_GRANTED) { 17491 String msg = "Permission Denial: switchUser() from pid=" 17492 + Binder.getCallingPid() 17493 + ", uid=" + Binder.getCallingUid() 17494 + " requires " + INTERACT_ACROSS_USERS_FULL; 17495 Slog.w(TAG, msg); 17496 throw new SecurityException(msg); 17497 } 17498 17499 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17500 17501 final long ident = Binder.clearCallingIdentity(); 17502 try { 17503 synchronized (this) { 17504 final int oldUserId = mCurrentUserId; 17505 if (oldUserId == userId) { 17506 return true; 17507 } 17508 17509 mStackSupervisor.setLockTaskModeLocked(null, false); 17510 17511 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17512 if (userInfo == null) { 17513 Slog.w(TAG, "No user info for user #" + userId); 17514 return false; 17515 } 17516 if (foreground && userInfo.isManagedProfile()) { 17517 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17518 return false; 17519 } 17520 17521 if (foreground) { 17522 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17523 R.anim.screen_user_enter); 17524 } 17525 17526 boolean needStart = false; 17527 17528 // If the user we are switching to is not currently started, then 17529 // we need to start it now. 17530 if (mStartedUsers.get(userId) == null) { 17531 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17532 updateStartedUserArrayLocked(); 17533 needStart = true; 17534 } 17535 17536 final Integer userIdInt = Integer.valueOf(userId); 17537 mUserLru.remove(userIdInt); 17538 mUserLru.add(userIdInt); 17539 17540 if (foreground) { 17541 mCurrentUserId = userId; 17542 updateCurrentProfileIdsLocked(); 17543 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17544 // Once the internal notion of the active user has switched, we lock the device 17545 // with the option to show the user switcher on the keyguard. 17546 mWindowManager.lockNow(null); 17547 } else { 17548 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17549 updateCurrentProfileIdsLocked(); 17550 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17551 mUserLru.remove(currentUserIdInt); 17552 mUserLru.add(currentUserIdInt); 17553 } 17554 17555 final UserStartedState uss = mStartedUsers.get(userId); 17556 17557 // Make sure user is in the started state. If it is currently 17558 // stopping, we need to knock that off. 17559 if (uss.mState == UserStartedState.STATE_STOPPING) { 17560 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17561 // so we can just fairly silently bring the user back from 17562 // the almost-dead. 17563 uss.mState = UserStartedState.STATE_RUNNING; 17564 updateStartedUserArrayLocked(); 17565 needStart = true; 17566 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17567 // This means ACTION_SHUTDOWN has been sent, so we will 17568 // need to treat this as a new boot of the user. 17569 uss.mState = UserStartedState.STATE_BOOTING; 17570 updateStartedUserArrayLocked(); 17571 needStart = true; 17572 } 17573 17574 if (uss.mState == UserStartedState.STATE_BOOTING) { 17575 // Booting up a new user, need to tell system services about it. 17576 // Note that this is on the same handler as scheduling of broadcasts, 17577 // which is important because it needs to go first. 17578 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 17579 } 17580 17581 if (foreground) { 17582 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17583 oldUserId)); 17584 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17585 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17586 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17587 oldUserId, userId, uss)); 17588 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17589 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17590 } 17591 17592 if (needStart) { 17593 // Send USER_STARTED broadcast 17594 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17595 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17596 | Intent.FLAG_RECEIVER_FOREGROUND); 17597 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17598 broadcastIntentLocked(null, null, intent, 17599 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17600 false, false, MY_PID, Process.SYSTEM_UID, userId); 17601 } 17602 17603 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17604 if (userId != UserHandle.USER_OWNER) { 17605 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17606 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17607 broadcastIntentLocked(null, null, intent, null, 17608 new IIntentReceiver.Stub() { 17609 public void performReceive(Intent intent, int resultCode, 17610 String data, Bundle extras, boolean ordered, 17611 boolean sticky, int sendingUser) { 17612 userInitialized(uss, userId); 17613 } 17614 }, 0, null, null, null, AppOpsManager.OP_NONE, 17615 true, false, MY_PID, Process.SYSTEM_UID, 17616 userId); 17617 uss.initializing = true; 17618 } else { 17619 getUserManagerLocked().makeInitialized(userInfo.id); 17620 } 17621 } 17622 17623 if (foreground) { 17624 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17625 if (homeInFront) { 17626 startHomeActivityLocked(userId); 17627 } else { 17628 mStackSupervisor.resumeTopActivitiesLocked(); 17629 } 17630 EventLogTags.writeAmSwitchUser(userId); 17631 getUserManagerLocked().userForeground(userId); 17632 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17633 } else { 17634 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17635 } 17636 17637 if (needStart) { 17638 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17639 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17640 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17641 broadcastIntentLocked(null, null, intent, 17642 null, new IIntentReceiver.Stub() { 17643 @Override 17644 public void performReceive(Intent intent, int resultCode, String data, 17645 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17646 throws RemoteException { 17647 } 17648 }, 0, null, null, 17649 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17650 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17651 } 17652 } 17653 } finally { 17654 Binder.restoreCallingIdentity(ident); 17655 } 17656 17657 return true; 17658 } 17659 17660 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17661 long ident = Binder.clearCallingIdentity(); 17662 try { 17663 Intent intent; 17664 if (oldUserId >= 0) { 17665 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17666 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17667 int count = profiles.size(); 17668 for (int i = 0; i < count; i++) { 17669 int profileUserId = profiles.get(i).id; 17670 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17671 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17672 | Intent.FLAG_RECEIVER_FOREGROUND); 17673 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17674 broadcastIntentLocked(null, null, intent, 17675 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17676 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17677 } 17678 } 17679 if (newUserId >= 0) { 17680 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17681 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17682 int count = profiles.size(); 17683 for (int i = 0; i < count; i++) { 17684 int profileUserId = profiles.get(i).id; 17685 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17686 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17687 | Intent.FLAG_RECEIVER_FOREGROUND); 17688 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17689 broadcastIntentLocked(null, null, intent, 17690 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17691 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17692 } 17693 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17694 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17695 | Intent.FLAG_RECEIVER_FOREGROUND); 17696 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17697 broadcastIntentLocked(null, null, intent, 17698 null, null, 0, null, null, 17699 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17700 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17701 } 17702 } finally { 17703 Binder.restoreCallingIdentity(ident); 17704 } 17705 } 17706 17707 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17708 final int newUserId) { 17709 final int N = mUserSwitchObservers.beginBroadcast(); 17710 if (N > 0) { 17711 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17712 int mCount = 0; 17713 @Override 17714 public void sendResult(Bundle data) throws RemoteException { 17715 synchronized (ActivityManagerService.this) { 17716 if (mCurUserSwitchCallback == this) { 17717 mCount++; 17718 if (mCount == N) { 17719 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17720 } 17721 } 17722 } 17723 } 17724 }; 17725 synchronized (this) { 17726 uss.switching = true; 17727 mCurUserSwitchCallback = callback; 17728 } 17729 for (int i=0; i<N; i++) { 17730 try { 17731 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17732 newUserId, callback); 17733 } catch (RemoteException e) { 17734 } 17735 } 17736 } else { 17737 synchronized (this) { 17738 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17739 } 17740 } 17741 mUserSwitchObservers.finishBroadcast(); 17742 } 17743 17744 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17745 synchronized (this) { 17746 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17747 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17748 } 17749 } 17750 17751 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17752 mCurUserSwitchCallback = null; 17753 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17754 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17755 oldUserId, newUserId, uss)); 17756 } 17757 17758 void userInitialized(UserStartedState uss, int newUserId) { 17759 completeSwitchAndInitalize(uss, newUserId, true, false); 17760 } 17761 17762 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17763 completeSwitchAndInitalize(uss, newUserId, false, true); 17764 } 17765 17766 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17767 boolean clearInitializing, boolean clearSwitching) { 17768 boolean unfrozen = false; 17769 synchronized (this) { 17770 if (clearInitializing) { 17771 uss.initializing = false; 17772 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17773 } 17774 if (clearSwitching) { 17775 uss.switching = false; 17776 } 17777 if (!uss.switching && !uss.initializing) { 17778 mWindowManager.stopFreezingScreen(); 17779 unfrozen = true; 17780 } 17781 } 17782 if (unfrozen) { 17783 final int N = mUserSwitchObservers.beginBroadcast(); 17784 for (int i=0; i<N; i++) { 17785 try { 17786 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17787 } catch (RemoteException e) { 17788 } 17789 } 17790 mUserSwitchObservers.finishBroadcast(); 17791 } 17792 } 17793 17794 void scheduleStartProfilesLocked() { 17795 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17796 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17797 DateUtils.SECOND_IN_MILLIS); 17798 } 17799 } 17800 17801 void startProfilesLocked() { 17802 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17803 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17804 mCurrentUserId, false /* enabledOnly */); 17805 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17806 for (UserInfo user : profiles) { 17807 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17808 && user.id != mCurrentUserId) { 17809 toStart.add(user); 17810 } 17811 } 17812 final int n = toStart.size(); 17813 int i = 0; 17814 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17815 startUserInBackground(toStart.get(i).id); 17816 } 17817 if (i < n) { 17818 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17819 } 17820 } 17821 17822 void finishUserBoot(UserStartedState uss) { 17823 synchronized (this) { 17824 if (uss.mState == UserStartedState.STATE_BOOTING 17825 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17826 uss.mState = UserStartedState.STATE_RUNNING; 17827 final int userId = uss.mHandle.getIdentifier(); 17828 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17829 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17830 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17831 broadcastIntentLocked(null, null, intent, 17832 null, null, 0, null, null, 17833 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17834 true, false, MY_PID, Process.SYSTEM_UID, userId); 17835 } 17836 } 17837 } 17838 17839 void finishUserSwitch(UserStartedState uss) { 17840 synchronized (this) { 17841 finishUserBoot(uss); 17842 17843 startProfilesLocked(); 17844 17845 int num = mUserLru.size(); 17846 int i = 0; 17847 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17848 Integer oldUserId = mUserLru.get(i); 17849 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17850 if (oldUss == null) { 17851 // Shouldn't happen, but be sane if it does. 17852 mUserLru.remove(i); 17853 num--; 17854 continue; 17855 } 17856 if (oldUss.mState == UserStartedState.STATE_STOPPING 17857 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17858 // This user is already stopping, doesn't count. 17859 num--; 17860 i++; 17861 continue; 17862 } 17863 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17864 // Owner and current can't be stopped, but count as running. 17865 i++; 17866 continue; 17867 } 17868 // This is a user to be stopped. 17869 stopUserLocked(oldUserId, null); 17870 num--; 17871 i++; 17872 } 17873 } 17874 } 17875 17876 @Override 17877 public int stopUser(final int userId, final IStopUserCallback callback) { 17878 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17879 != PackageManager.PERMISSION_GRANTED) { 17880 String msg = "Permission Denial: switchUser() from pid=" 17881 + Binder.getCallingPid() 17882 + ", uid=" + Binder.getCallingUid() 17883 + " requires " + INTERACT_ACROSS_USERS_FULL; 17884 Slog.w(TAG, msg); 17885 throw new SecurityException(msg); 17886 } 17887 if (userId <= 0) { 17888 throw new IllegalArgumentException("Can't stop primary user " + userId); 17889 } 17890 synchronized (this) { 17891 return stopUserLocked(userId, callback); 17892 } 17893 } 17894 17895 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17896 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17897 if (mCurrentUserId == userId) { 17898 return ActivityManager.USER_OP_IS_CURRENT; 17899 } 17900 17901 final UserStartedState uss = mStartedUsers.get(userId); 17902 if (uss == null) { 17903 // User is not started, nothing to do... but we do need to 17904 // callback if requested. 17905 if (callback != null) { 17906 mHandler.post(new Runnable() { 17907 @Override 17908 public void run() { 17909 try { 17910 callback.userStopped(userId); 17911 } catch (RemoteException e) { 17912 } 17913 } 17914 }); 17915 } 17916 return ActivityManager.USER_OP_SUCCESS; 17917 } 17918 17919 if (callback != null) { 17920 uss.mStopCallbacks.add(callback); 17921 } 17922 17923 if (uss.mState != UserStartedState.STATE_STOPPING 17924 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17925 uss.mState = UserStartedState.STATE_STOPPING; 17926 updateStartedUserArrayLocked(); 17927 17928 long ident = Binder.clearCallingIdentity(); 17929 try { 17930 // We are going to broadcast ACTION_USER_STOPPING and then 17931 // once that is done send a final ACTION_SHUTDOWN and then 17932 // stop the user. 17933 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17934 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17935 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17936 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17937 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17938 // This is the result receiver for the final shutdown broadcast. 17939 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17940 @Override 17941 public void performReceive(Intent intent, int resultCode, String data, 17942 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17943 finishUserStop(uss); 17944 } 17945 }; 17946 // This is the result receiver for the initial stopping broadcast. 17947 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17948 @Override 17949 public void performReceive(Intent intent, int resultCode, String data, 17950 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17951 // On to the next. 17952 synchronized (ActivityManagerService.this) { 17953 if (uss.mState != UserStartedState.STATE_STOPPING) { 17954 // Whoops, we are being started back up. Abort, abort! 17955 return; 17956 } 17957 uss.mState = UserStartedState.STATE_SHUTDOWN; 17958 } 17959 mBatteryStatsService.noteEvent( 17960 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17961 Integer.toString(userId), userId); 17962 mSystemServiceManager.stopUser(userId); 17963 broadcastIntentLocked(null, null, shutdownIntent, 17964 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17965 true, false, MY_PID, Process.SYSTEM_UID, userId); 17966 } 17967 }; 17968 // Kick things off. 17969 broadcastIntentLocked(null, null, stoppingIntent, 17970 null, stoppingReceiver, 0, null, null, 17971 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17972 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17973 } finally { 17974 Binder.restoreCallingIdentity(ident); 17975 } 17976 } 17977 17978 return ActivityManager.USER_OP_SUCCESS; 17979 } 17980 17981 void finishUserStop(UserStartedState uss) { 17982 final int userId = uss.mHandle.getIdentifier(); 17983 boolean stopped; 17984 ArrayList<IStopUserCallback> callbacks; 17985 synchronized (this) { 17986 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17987 if (mStartedUsers.get(userId) != uss) { 17988 stopped = false; 17989 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17990 stopped = false; 17991 } else { 17992 stopped = true; 17993 // User can no longer run. 17994 mStartedUsers.remove(userId); 17995 mUserLru.remove(Integer.valueOf(userId)); 17996 updateStartedUserArrayLocked(); 17997 17998 // Clean up all state and processes associated with the user. 17999 // Kill all the processes for the user. 18000 forceStopUserLocked(userId, "finish user"); 18001 } 18002 18003 // Explicitly remove the old information in mRecentTasks. 18004 removeRecentTasksForUserLocked(userId); 18005 } 18006 18007 for (int i=0; i<callbacks.size(); i++) { 18008 try { 18009 if (stopped) callbacks.get(i).userStopped(userId); 18010 else callbacks.get(i).userStopAborted(userId); 18011 } catch (RemoteException e) { 18012 } 18013 } 18014 18015 if (stopped) { 18016 mSystemServiceManager.cleanupUser(userId); 18017 synchronized (this) { 18018 mStackSupervisor.removeUserLocked(userId); 18019 } 18020 } 18021 } 18022 18023 @Override 18024 public UserInfo getCurrentUser() { 18025 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18026 != PackageManager.PERMISSION_GRANTED) && ( 18027 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18028 != PackageManager.PERMISSION_GRANTED)) { 18029 String msg = "Permission Denial: getCurrentUser() from pid=" 18030 + Binder.getCallingPid() 18031 + ", uid=" + Binder.getCallingUid() 18032 + " requires " + INTERACT_ACROSS_USERS; 18033 Slog.w(TAG, msg); 18034 throw new SecurityException(msg); 18035 } 18036 synchronized (this) { 18037 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18038 } 18039 } 18040 18041 int getCurrentUserIdLocked() { 18042 return mCurrentUserId; 18043 } 18044 18045 @Override 18046 public boolean isUserRunning(int userId, boolean orStopped) { 18047 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18048 != PackageManager.PERMISSION_GRANTED) { 18049 String msg = "Permission Denial: isUserRunning() from pid=" 18050 + Binder.getCallingPid() 18051 + ", uid=" + Binder.getCallingUid() 18052 + " requires " + INTERACT_ACROSS_USERS; 18053 Slog.w(TAG, msg); 18054 throw new SecurityException(msg); 18055 } 18056 synchronized (this) { 18057 return isUserRunningLocked(userId, orStopped); 18058 } 18059 } 18060 18061 boolean isUserRunningLocked(int userId, boolean orStopped) { 18062 UserStartedState state = mStartedUsers.get(userId); 18063 if (state == null) { 18064 return false; 18065 } 18066 if (orStopped) { 18067 return true; 18068 } 18069 return state.mState != UserStartedState.STATE_STOPPING 18070 && state.mState != UserStartedState.STATE_SHUTDOWN; 18071 } 18072 18073 @Override 18074 public int[] getRunningUserIds() { 18075 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18076 != PackageManager.PERMISSION_GRANTED) { 18077 String msg = "Permission Denial: isUserRunning() from pid=" 18078 + Binder.getCallingPid() 18079 + ", uid=" + Binder.getCallingUid() 18080 + " requires " + INTERACT_ACROSS_USERS; 18081 Slog.w(TAG, msg); 18082 throw new SecurityException(msg); 18083 } 18084 synchronized (this) { 18085 return mStartedUserArray; 18086 } 18087 } 18088 18089 private void updateStartedUserArrayLocked() { 18090 int num = 0; 18091 for (int i=0; i<mStartedUsers.size(); i++) { 18092 UserStartedState uss = mStartedUsers.valueAt(i); 18093 // This list does not include stopping users. 18094 if (uss.mState != UserStartedState.STATE_STOPPING 18095 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18096 num++; 18097 } 18098 } 18099 mStartedUserArray = new int[num]; 18100 num = 0; 18101 for (int i=0; i<mStartedUsers.size(); i++) { 18102 UserStartedState uss = mStartedUsers.valueAt(i); 18103 if (uss.mState != UserStartedState.STATE_STOPPING 18104 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18105 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18106 num++; 18107 } 18108 } 18109 } 18110 18111 @Override 18112 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18113 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18114 != PackageManager.PERMISSION_GRANTED) { 18115 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18116 + Binder.getCallingPid() 18117 + ", uid=" + Binder.getCallingUid() 18118 + " requires " + INTERACT_ACROSS_USERS_FULL; 18119 Slog.w(TAG, msg); 18120 throw new SecurityException(msg); 18121 } 18122 18123 mUserSwitchObservers.register(observer); 18124 } 18125 18126 @Override 18127 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18128 mUserSwitchObservers.unregister(observer); 18129 } 18130 18131 private boolean userExists(int userId) { 18132 if (userId == 0) { 18133 return true; 18134 } 18135 UserManagerService ums = getUserManagerLocked(); 18136 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18137 } 18138 18139 int[] getUsersLocked() { 18140 UserManagerService ums = getUserManagerLocked(); 18141 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18142 } 18143 18144 UserManagerService getUserManagerLocked() { 18145 if (mUserManager == null) { 18146 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18147 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18148 } 18149 return mUserManager; 18150 } 18151 18152 private int applyUserId(int uid, int userId) { 18153 return UserHandle.getUid(userId, uid); 18154 } 18155 18156 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18157 if (info == null) return null; 18158 ApplicationInfo newInfo = new ApplicationInfo(info); 18159 newInfo.uid = applyUserId(info.uid, userId); 18160 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18161 + info.packageName; 18162 return newInfo; 18163 } 18164 18165 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18166 if (aInfo == null 18167 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18168 return aInfo; 18169 } 18170 18171 ActivityInfo info = new ActivityInfo(aInfo); 18172 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18173 return info; 18174 } 18175 18176 private final class LocalService extends ActivityManagerInternal { 18177 @Override 18178 public void goingToSleep() { 18179 ActivityManagerService.this.goingToSleep(); 18180 } 18181 18182 @Override 18183 public void wakingUp() { 18184 ActivityManagerService.this.wakingUp(); 18185 } 18186 18187 @Override 18188 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18189 String processName, String abiOverride, int uid, Runnable crashHandler) { 18190 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18191 processName, abiOverride, uid, crashHandler); 18192 } 18193 } 18194 18195 /** 18196 * An implementation of IAppTask, that allows an app to manage its own tasks via 18197 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18198 * only the process that calls getAppTasks() can call the AppTask methods. 18199 */ 18200 class AppTaskImpl extends IAppTask.Stub { 18201 private int mTaskId; 18202 private int mCallingUid; 18203 18204 public AppTaskImpl(int taskId, int callingUid) { 18205 mTaskId = taskId; 18206 mCallingUid = callingUid; 18207 } 18208 18209 private void checkCaller() { 18210 if (mCallingUid != Binder.getCallingUid()) { 18211 throw new SecurityException("Caller " + mCallingUid 18212 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18213 } 18214 } 18215 18216 @Override 18217 public void finishAndRemoveTask() { 18218 checkCaller(); 18219 18220 synchronized (ActivityManagerService.this) { 18221 long origId = Binder.clearCallingIdentity(); 18222 try { 18223 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18224 if (tr != null) { 18225 // Only kill the process if we are not a new document 18226 int flags = tr.getBaseIntent().getFlags(); 18227 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18228 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18229 removeTaskByIdLocked(mTaskId, 18230 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18231 } 18232 } finally { 18233 Binder.restoreCallingIdentity(origId); 18234 } 18235 } 18236 } 18237 18238 @Override 18239 public ActivityManager.RecentTaskInfo getTaskInfo() { 18240 checkCaller(); 18241 18242 synchronized (ActivityManagerService.this) { 18243 long origId = Binder.clearCallingIdentity(); 18244 try { 18245 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18246 if (tr != null) { 18247 return createRecentTaskInfoFromTaskRecord(tr); 18248 } 18249 } finally { 18250 Binder.restoreCallingIdentity(origId); 18251 } 18252 return null; 18253 } 18254 } 18255 18256 @Override 18257 public void setExcludeFromRecents(boolean exclude) { 18258 checkCaller(); 18259 18260 synchronized (ActivityManagerService.this) { 18261 long origId = Binder.clearCallingIdentity(); 18262 try { 18263 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18264 if (tr != null) { 18265 Intent intent = tr.getBaseIntent(); 18266 if (exclude) { 18267 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18268 } else { 18269 intent.setFlags(intent.getFlags() 18270 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18271 } 18272 } 18273 } finally { 18274 Binder.restoreCallingIdentity(origId); 18275 } 18276 } 18277 } 18278 } 18279} 18280