ActivityManagerService.java revision 828bd38a074ae62e9363267ad62214796d94e0de
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a Recents UI */ 1202 boolean mHasRecents; 1203 1204 /** The dimensions of the thumbnails in the Recents UI. */ 1205 int mThumbnailWidth; 1206 int mThumbnailHeight; 1207 1208 final ServiceThread mHandlerThread; 1209 final MainHandler mHandler; 1210 1211 final class MainHandler extends Handler { 1212 public MainHandler(Looper looper) { 1213 super(looper, null, true); 1214 } 1215 1216 @Override 1217 public void handleMessage(Message msg) { 1218 switch (msg.what) { 1219 case SHOW_ERROR_MSG: { 1220 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1221 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1222 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1223 synchronized (ActivityManagerService.this) { 1224 ProcessRecord proc = (ProcessRecord)data.get("app"); 1225 AppErrorResult res = (AppErrorResult) data.get("result"); 1226 if (proc != null && proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has crash dialog: " + proc); 1228 if (res != null) { 1229 res.set(0); 1230 } 1231 return; 1232 } 1233 boolean isBackground = (UserHandle.getAppId(proc.uid) 1234 >= Process.FIRST_APPLICATION_UID 1235 && proc.pid != MY_PID); 1236 for (int userId : mCurrentProfileIds) { 1237 isBackground &= (proc.userId != userId); 1238 } 1239 if (isBackground && !showBackground) { 1240 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1241 if (res != null) { 1242 res.set(0); 1243 } 1244 return; 1245 } 1246 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1247 Dialog d = new AppErrorDialog(mContext, 1248 ActivityManagerService.this, res, proc); 1249 d.show(); 1250 proc.crashDialog = d; 1251 } else { 1252 // The device is asleep, so just pretend that the user 1253 // saw a crash dialog and hit "force quit". 1254 if (res != null) { 1255 res.set(0); 1256 } 1257 } 1258 } 1259 1260 ensureBootCompleted(); 1261 } break; 1262 case SHOW_NOT_RESPONDING_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1265 ProcessRecord proc = (ProcessRecord)data.get("app"); 1266 if (proc != null && proc.anrDialog != null) { 1267 Slog.e(TAG, "App already has anr dialog: " + proc); 1268 return; 1269 } 1270 1271 Intent intent = new Intent("android.intent.action.ANR"); 1272 if (!mProcessesReady) { 1273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1274 | Intent.FLAG_RECEIVER_FOREGROUND); 1275 } 1276 broadcastIntentLocked(null, null, intent, 1277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1278 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1279 1280 if (mShowDialogs) { 1281 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1282 mContext, proc, (ActivityRecord)data.get("activity"), 1283 msg.arg1 != 0); 1284 d.show(); 1285 proc.anrDialog = d; 1286 } else { 1287 // Just kill the app if there is no dialog to be shown. 1288 killAppAtUsersRequest(proc, null); 1289 } 1290 } 1291 1292 ensureBootCompleted(); 1293 } break; 1294 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1295 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1296 synchronized (ActivityManagerService.this) { 1297 ProcessRecord proc = (ProcessRecord) data.get("app"); 1298 if (proc == null) { 1299 Slog.e(TAG, "App not found when showing strict mode dialog."); 1300 break; 1301 } 1302 if (proc.crashDialog != null) { 1303 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1304 return; 1305 } 1306 AppErrorResult res = (AppErrorResult) data.get("result"); 1307 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1308 Dialog d = new StrictModeViolationDialog(mContext, 1309 ActivityManagerService.this, res, proc); 1310 d.show(); 1311 proc.crashDialog = d; 1312 } else { 1313 // The device is asleep, so just pretend that the user 1314 // saw a crash dialog and hit "force quit". 1315 res.set(0); 1316 } 1317 } 1318 ensureBootCompleted(); 1319 } break; 1320 case SHOW_FACTORY_ERROR_MSG: { 1321 Dialog d = new FactoryErrorDialog( 1322 mContext, msg.getData().getCharSequence("msg")); 1323 d.show(); 1324 ensureBootCompleted(); 1325 } break; 1326 case UPDATE_CONFIGURATION_MSG: { 1327 final ContentResolver resolver = mContext.getContentResolver(); 1328 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1329 } break; 1330 case GC_BACKGROUND_PROCESSES_MSG: { 1331 synchronized (ActivityManagerService.this) { 1332 performAppGcsIfAppropriateLocked(); 1333 } 1334 } break; 1335 case WAIT_FOR_DEBUGGER_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 ProcessRecord app = (ProcessRecord)msg.obj; 1338 if (msg.arg1 != 0) { 1339 if (!app.waitedForDebugger) { 1340 Dialog d = new AppWaitingForDebuggerDialog( 1341 ActivityManagerService.this, 1342 mContext, app); 1343 app.waitDialog = d; 1344 app.waitedForDebugger = true; 1345 d.show(); 1346 } 1347 } else { 1348 if (app.waitDialog != null) { 1349 app.waitDialog.dismiss(); 1350 app.waitDialog = null; 1351 } 1352 } 1353 } 1354 } break; 1355 case SERVICE_TIMEOUT_MSG: { 1356 if (mDidDexOpt) { 1357 mDidDexOpt = false; 1358 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1359 nmsg.obj = msg.obj; 1360 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1361 return; 1362 } 1363 mServices.serviceTimeout((ProcessRecord)msg.obj); 1364 } break; 1365 case UPDATE_TIME_ZONE: { 1366 synchronized (ActivityManagerService.this) { 1367 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1368 ProcessRecord r = mLruProcesses.get(i); 1369 if (r.thread != null) { 1370 try { 1371 r.thread.updateTimeZone(); 1372 } catch (RemoteException ex) { 1373 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1374 } 1375 } 1376 } 1377 } 1378 } break; 1379 case CLEAR_DNS_CACHE_MSG: { 1380 synchronized (ActivityManagerService.this) { 1381 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1382 ProcessRecord r = mLruProcesses.get(i); 1383 if (r.thread != null) { 1384 try { 1385 r.thread.clearDnsCache(); 1386 } catch (RemoteException ex) { 1387 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1388 } 1389 } 1390 } 1391 } 1392 } break; 1393 case UPDATE_HTTP_PROXY_MSG: { 1394 ProxyInfo proxy = (ProxyInfo)msg.obj; 1395 String host = ""; 1396 String port = ""; 1397 String exclList = ""; 1398 Uri pacFileUrl = Uri.EMPTY; 1399 if (proxy != null) { 1400 host = proxy.getHost(); 1401 port = Integer.toString(proxy.getPort()); 1402 exclList = proxy.getExclusionListAsString(); 1403 pacFileUrl = proxy.getPacFileUrl(); 1404 } 1405 synchronized (ActivityManagerService.this) { 1406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1407 ProcessRecord r = mLruProcesses.get(i); 1408 if (r.thread != null) { 1409 try { 1410 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1411 } catch (RemoteException ex) { 1412 Slog.w(TAG, "Failed to update http proxy for: " + 1413 r.info.processName); 1414 } 1415 } 1416 } 1417 } 1418 } break; 1419 case SHOW_UID_ERROR_MSG: { 1420 String title = "System UIDs Inconsistent"; 1421 String text = "UIDs on the system are inconsistent, you need to wipe your" 1422 + " data partition or your device will be unstable."; 1423 Log.e(TAG, title + ": " + text); 1424 if (mShowDialogs) { 1425 // XXX This is a temporary dialog, no need to localize. 1426 AlertDialog d = new BaseErrorDialog(mContext); 1427 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1428 d.setCancelable(false); 1429 d.setTitle(title); 1430 d.setMessage(text); 1431 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1432 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1433 mUidAlert = d; 1434 d.show(); 1435 } 1436 } break; 1437 case IM_FEELING_LUCKY_MSG: { 1438 if (mUidAlert != null) { 1439 mUidAlert.dismiss(); 1440 mUidAlert = null; 1441 } 1442 } break; 1443 case PROC_START_TIMEOUT_MSG: { 1444 if (mDidDexOpt) { 1445 mDidDexOpt = false; 1446 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1447 nmsg.obj = msg.obj; 1448 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1449 return; 1450 } 1451 ProcessRecord app = (ProcessRecord)msg.obj; 1452 synchronized (ActivityManagerService.this) { 1453 processStartTimedOutLocked(app); 1454 } 1455 } break; 1456 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1457 synchronized (ActivityManagerService.this) { 1458 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1459 } 1460 } break; 1461 case KILL_APPLICATION_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 int appid = msg.arg1; 1464 boolean restart = (msg.arg2 == 1); 1465 Bundle bundle = (Bundle)msg.obj; 1466 String pkg = bundle.getString("pkg"); 1467 String reason = bundle.getString("reason"); 1468 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1469 false, UserHandle.USER_ALL, reason); 1470 } 1471 } break; 1472 case FINALIZE_PENDING_INTENT_MSG: { 1473 ((PendingIntentRecord)msg.obj).completeFinalize(); 1474 } break; 1475 case POST_HEAVY_NOTIFICATION_MSG: { 1476 INotificationManager inm = NotificationManager.getService(); 1477 if (inm == null) { 1478 return; 1479 } 1480 1481 ActivityRecord root = (ActivityRecord)msg.obj; 1482 ProcessRecord process = root.app; 1483 if (process == null) { 1484 return; 1485 } 1486 1487 try { 1488 Context context = mContext.createPackageContext(process.info.packageName, 0); 1489 String text = mContext.getString(R.string.heavy_weight_notification, 1490 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1491 Notification notification = new Notification(); 1492 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1493 notification.when = 0; 1494 notification.flags = Notification.FLAG_ONGOING_EVENT; 1495 notification.tickerText = text; 1496 notification.defaults = 0; // please be quiet 1497 notification.sound = null; 1498 notification.vibrate = null; 1499 notification.color = mContext.getResources().getColor( 1500 com.android.internal.R.color.system_notification_accent_color); 1501 notification.setLatestEventInfo(context, text, 1502 mContext.getText(R.string.heavy_weight_notification_detail), 1503 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1504 PendingIntent.FLAG_CANCEL_CURRENT, null, 1505 new UserHandle(root.userId))); 1506 1507 try { 1508 int[] outId = new int[1]; 1509 inm.enqueueNotificationWithTag("android", "android", null, 1510 R.string.heavy_weight_notification, 1511 notification, outId, root.userId); 1512 } catch (RuntimeException e) { 1513 Slog.w(ActivityManagerService.TAG, 1514 "Error showing notification for heavy-weight app", e); 1515 } catch (RemoteException e) { 1516 } 1517 } catch (NameNotFoundException e) { 1518 Slog.w(TAG, "Unable to create context for heavy notification", e); 1519 } 1520 } break; 1521 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 try { 1527 inm.cancelNotificationWithTag("android", null, 1528 R.string.heavy_weight_notification, msg.arg1); 1529 } catch (RuntimeException e) { 1530 Slog.w(ActivityManagerService.TAG, 1531 "Error canceling notification for service", e); 1532 } catch (RemoteException e) { 1533 } 1534 } break; 1535 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 checkExcessivePowerUsageLocked(true); 1538 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1540 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1541 } 1542 } break; 1543 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 ActivityRecord ar = (ActivityRecord)msg.obj; 1546 if (mCompatModeDialog != null) { 1547 if (mCompatModeDialog.mAppInfo.packageName.equals( 1548 ar.info.applicationInfo.packageName)) { 1549 return; 1550 } 1551 mCompatModeDialog.dismiss(); 1552 mCompatModeDialog = null; 1553 } 1554 if (ar != null && false) { 1555 if (mCompatModePackages.getPackageAskCompatModeLocked( 1556 ar.packageName)) { 1557 int mode = mCompatModePackages.computeCompatModeLocked( 1558 ar.info.applicationInfo); 1559 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1560 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1561 mCompatModeDialog = new CompatModeDialog( 1562 ActivityManagerService.this, mContext, 1563 ar.info.applicationInfo); 1564 mCompatModeDialog.show(); 1565 } 1566 } 1567 } 1568 } 1569 break; 1570 } 1571 case DISPATCH_PROCESSES_CHANGED: { 1572 dispatchProcessesChanged(); 1573 break; 1574 } 1575 case DISPATCH_PROCESS_DIED: { 1576 final int pid = msg.arg1; 1577 final int uid = msg.arg2; 1578 dispatchProcessDied(pid, uid); 1579 break; 1580 } 1581 case REPORT_MEM_USAGE_MSG: { 1582 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1583 Thread thread = new Thread() { 1584 @Override public void run() { 1585 final SparseArray<ProcessMemInfo> infoMap 1586 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 infoMap.put(mi.pid, mi); 1590 } 1591 updateCpuStatsNow(); 1592 synchronized (mProcessCpuThread) { 1593 final int N = mProcessCpuTracker.countStats(); 1594 for (int i=0; i<N; i++) { 1595 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1596 if (st.vsize > 0) { 1597 long pss = Debug.getPss(st.pid, null); 1598 if (pss > 0) { 1599 if (infoMap.indexOfKey(st.pid) < 0) { 1600 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1601 ProcessList.NATIVE_ADJ, -1, "native", null); 1602 mi.pss = pss; 1603 memInfos.add(mi); 1604 } 1605 } 1606 } 1607 } 1608 } 1609 1610 long totalPss = 0; 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 if (mi.pss == 0) { 1614 mi.pss = Debug.getPss(mi.pid, null); 1615 } 1616 totalPss += mi.pss; 1617 } 1618 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1619 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1620 if (lhs.oomAdj != rhs.oomAdj) { 1621 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1622 } 1623 if (lhs.pss != rhs.pss) { 1624 return lhs.pss < rhs.pss ? 1 : -1; 1625 } 1626 return 0; 1627 } 1628 }); 1629 1630 StringBuilder tag = new StringBuilder(128); 1631 StringBuilder stack = new StringBuilder(128); 1632 tag.append("Low on memory -- "); 1633 appendMemBucket(tag, totalPss, "total", false); 1634 appendMemBucket(stack, totalPss, "total", true); 1635 1636 StringBuilder logBuilder = new StringBuilder(1024); 1637 logBuilder.append("Low on memory:\n"); 1638 1639 boolean firstLine = true; 1640 int lastOomAdj = Integer.MIN_VALUE; 1641 for (int i=0, N=memInfos.size(); i<N; i++) { 1642 ProcessMemInfo mi = memInfos.get(i); 1643 1644 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1645 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1646 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1647 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1648 if (lastOomAdj != mi.oomAdj) { 1649 lastOomAdj = mi.oomAdj; 1650 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1651 tag.append(" / "); 1652 } 1653 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1654 if (firstLine) { 1655 stack.append(":"); 1656 firstLine = false; 1657 } 1658 stack.append("\n\t at "); 1659 } else { 1660 stack.append("$"); 1661 } 1662 } else { 1663 tag.append(" "); 1664 stack.append("$"); 1665 } 1666 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1667 appendMemBucket(tag, mi.pss, mi.name, false); 1668 } 1669 appendMemBucket(stack, mi.pss, mi.name, true); 1670 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1671 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1672 stack.append("("); 1673 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1674 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1675 stack.append(DUMP_MEM_OOM_LABEL[k]); 1676 stack.append(":"); 1677 stack.append(DUMP_MEM_OOM_ADJ[k]); 1678 } 1679 } 1680 stack.append(")"); 1681 } 1682 } 1683 1684 logBuilder.append(" "); 1685 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1686 logBuilder.append(' '); 1687 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1688 logBuilder.append(' '); 1689 ProcessList.appendRamKb(logBuilder, mi.pss); 1690 logBuilder.append(" kB: "); 1691 logBuilder.append(mi.name); 1692 logBuilder.append(" ("); 1693 logBuilder.append(mi.pid); 1694 logBuilder.append(") "); 1695 logBuilder.append(mi.adjType); 1696 logBuilder.append('\n'); 1697 if (mi.adjReason != null) { 1698 logBuilder.append(" "); 1699 logBuilder.append(mi.adjReason); 1700 logBuilder.append('\n'); 1701 } 1702 } 1703 1704 logBuilder.append(" "); 1705 ProcessList.appendRamKb(logBuilder, totalPss); 1706 logBuilder.append(" kB: TOTAL\n"); 1707 1708 long[] infos = new long[Debug.MEMINFO_COUNT]; 1709 Debug.getMemInfo(infos); 1710 logBuilder.append(" MemInfo: "); 1711 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1712 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1713 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1714 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1715 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1716 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1717 logBuilder.append(" ZRAM: "); 1718 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1719 logBuilder.append(" kB RAM, "); 1720 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1721 logBuilder.append(" kB swap total, "); 1722 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1723 logBuilder.append(" kB swap free\n"); 1724 } 1725 Slog.i(TAG, logBuilder.toString()); 1726 1727 StringBuilder dropBuilder = new StringBuilder(1024); 1728 /* 1729 StringWriter oomSw = new StringWriter(); 1730 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1731 StringWriter catSw = new StringWriter(); 1732 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1733 String[] emptyArgs = new String[] { }; 1734 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1735 oomPw.flush(); 1736 String oomString = oomSw.toString(); 1737 */ 1738 dropBuilder.append(stack); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append('\n'); 1741 dropBuilder.append(logBuilder); 1742 dropBuilder.append('\n'); 1743 /* 1744 dropBuilder.append(oomString); 1745 dropBuilder.append('\n'); 1746 */ 1747 StringWriter catSw = new StringWriter(); 1748 synchronized (ActivityManagerService.this) { 1749 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1750 String[] emptyArgs = new String[] { }; 1751 catPw.println(); 1752 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1753 catPw.println(); 1754 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1755 false, false, null); 1756 catPw.println(); 1757 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1758 catPw.flush(); 1759 } 1760 dropBuilder.append(catSw.toString()); 1761 addErrorToDropBox("lowmem", null, "system_server", null, 1762 null, tag.toString(), dropBuilder.toString(), null, null); 1763 //Slog.i(TAG, "Sent to dropbox:"); 1764 //Slog.i(TAG, dropBuilder.toString()); 1765 synchronized (ActivityManagerService.this) { 1766 long now = SystemClock.uptimeMillis(); 1767 if (mLastMemUsageReportTime < now) { 1768 mLastMemUsageReportTime = now; 1769 } 1770 } 1771 } 1772 }; 1773 thread.start(); 1774 break; 1775 } 1776 case START_USER_SWITCH_MSG: { 1777 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1778 break; 1779 } 1780 case REPORT_USER_SWITCH_MSG: { 1781 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1782 break; 1783 } 1784 case CONTINUE_USER_SWITCH_MSG: { 1785 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1786 break; 1787 } 1788 case USER_SWITCH_TIMEOUT_MSG: { 1789 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1790 break; 1791 } 1792 case IMMERSIVE_MODE_LOCK_MSG: { 1793 final boolean nextState = (msg.arg1 != 0); 1794 if (mUpdateLock.isHeld() != nextState) { 1795 if (DEBUG_IMMERSIVE) { 1796 final ActivityRecord r = (ActivityRecord) msg.obj; 1797 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1798 } 1799 if (nextState) { 1800 mUpdateLock.acquire(); 1801 } else { 1802 mUpdateLock.release(); 1803 } 1804 } 1805 break; 1806 } 1807 case PERSIST_URI_GRANTS_MSG: { 1808 writeGrantedUriPermissions(); 1809 break; 1810 } 1811 case REQUEST_ALL_PSS_MSG: { 1812 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1813 break; 1814 } 1815 case START_PROFILES_MSG: { 1816 synchronized (ActivityManagerService.this) { 1817 startProfilesLocked(); 1818 } 1819 break; 1820 } 1821 case UPDATE_TIME: { 1822 synchronized (ActivityManagerService.this) { 1823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1824 ProcessRecord r = mLruProcesses.get(i); 1825 if (r.thread != null) { 1826 try { 1827 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1828 } catch (RemoteException ex) { 1829 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1830 } 1831 } 1832 } 1833 } 1834 break; 1835 } 1836 case SYSTEM_USER_START_MSG: { 1837 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1838 Integer.toString(msg.arg1), msg.arg1); 1839 mSystemServiceManager.startUser(msg.arg1); 1840 break; 1841 } 1842 case SYSTEM_USER_CURRENT_MSG: { 1843 mBatteryStatsService.noteEvent( 1844 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1845 Integer.toString(msg.arg2), msg.arg2); 1846 mBatteryStatsService.noteEvent( 1847 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1848 Integer.toString(msg.arg1), msg.arg1); 1849 mSystemServiceManager.switchUser(msg.arg1); 1850 mLockToAppRequest.clearPrompt(); 1851 break; 1852 } 1853 case ENTER_ANIMATION_COMPLETE_MSG: { 1854 synchronized (ActivityManagerService.this) { 1855 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1856 if (r != null && r.app != null && r.app.thread != null) { 1857 try { 1858 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1859 } catch (RemoteException e) { 1860 } 1861 } 1862 } 1863 break; 1864 } 1865 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1866 enableScreenAfterBoot(); 1867 break; 1868 } 1869 } 1870 } 1871 }; 1872 1873 static final int COLLECT_PSS_BG_MSG = 1; 1874 1875 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1876 @Override 1877 public void handleMessage(Message msg) { 1878 switch (msg.what) { 1879 case COLLECT_PSS_BG_MSG: { 1880 long start = SystemClock.uptimeMillis(); 1881 MemInfoReader memInfo = null; 1882 synchronized (ActivityManagerService.this) { 1883 if (mFullPssPending) { 1884 mFullPssPending = false; 1885 memInfo = new MemInfoReader(); 1886 } 1887 } 1888 if (memInfo != null) { 1889 updateCpuStatsNow(); 1890 long nativeTotalPss = 0; 1891 synchronized (mProcessCpuThread) { 1892 final int N = mProcessCpuTracker.countStats(); 1893 for (int j=0; j<N; j++) { 1894 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1895 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1896 // This is definitely an application process; skip it. 1897 continue; 1898 } 1899 synchronized (mPidsSelfLocked) { 1900 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1901 // This is one of our own processes; skip it. 1902 continue; 1903 } 1904 } 1905 nativeTotalPss += Debug.getPss(st.pid, null); 1906 } 1907 } 1908 memInfo.readMemInfo(); 1909 synchronized (this) { 1910 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1911 + (SystemClock.uptimeMillis()-start) + "ms"); 1912 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1913 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1914 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1915 +memInfo.getSlabSizeKb(), 1916 nativeTotalPss); 1917 } 1918 } 1919 1920 int i=0, num=0; 1921 long[] tmp = new long[1]; 1922 do { 1923 ProcessRecord proc; 1924 int procState; 1925 int pid; 1926 synchronized (ActivityManagerService.this) { 1927 if (i >= mPendingPssProcesses.size()) { 1928 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1929 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1930 mPendingPssProcesses.clear(); 1931 return; 1932 } 1933 proc = mPendingPssProcesses.get(i); 1934 procState = proc.pssProcState; 1935 if (proc.thread != null && procState == proc.setProcState) { 1936 pid = proc.pid; 1937 } else { 1938 proc = null; 1939 pid = 0; 1940 } 1941 i++; 1942 } 1943 if (proc != null) { 1944 long pss = Debug.getPss(pid, tmp); 1945 synchronized (ActivityManagerService.this) { 1946 if (proc.thread != null && proc.setProcState == procState 1947 && proc.pid == pid) { 1948 num++; 1949 proc.lastPssTime = SystemClock.uptimeMillis(); 1950 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1951 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1952 + ": " + pss + " lastPss=" + proc.lastPss 1953 + " state=" + ProcessList.makeProcStateString(procState)); 1954 if (proc.initialIdlePss == 0) { 1955 proc.initialIdlePss = pss; 1956 } 1957 proc.lastPss = pss; 1958 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1959 proc.lastCachedPss = pss; 1960 } 1961 } 1962 } 1963 } 1964 } while (true); 1965 } 1966 } 1967 } 1968 }; 1969 1970 /** 1971 * Monitor for package changes and update our internal state. 1972 */ 1973 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1974 @Override 1975 public void onPackageRemoved(String packageName, int uid) { 1976 // Remove all tasks with activities in the specified package from the list of recent tasks 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1979 TaskRecord tr = mRecentTasks.get(i); 1980 ComponentName cn = tr.intent.getComponent(); 1981 if (cn != null && cn.getPackageName().equals(packageName)) { 1982 // If the package name matches, remove the task and kill the process 1983 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1984 } 1985 } 1986 } 1987 } 1988 1989 @Override 1990 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1991 onPackageModified(packageName); 1992 return true; 1993 } 1994 1995 @Override 1996 public void onPackageModified(String packageName) { 1997 final PackageManager pm = mContext.getPackageManager(); 1998 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1999 new ArrayList<Pair<Intent, Integer>>(); 2000 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2001 // Copy the list of recent tasks so that we don't hold onto the lock on 2002 // ActivityManagerService for long periods while checking if components exist. 2003 synchronized (ActivityManagerService.this) { 2004 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2005 TaskRecord tr = mRecentTasks.get(i); 2006 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2007 } 2008 } 2009 // Check the recent tasks and filter out all tasks with components that no longer exist. 2010 Intent tmpI = new Intent(); 2011 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2012 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2013 ComponentName cn = p.first.getComponent(); 2014 if (cn != null && cn.getPackageName().equals(packageName)) { 2015 try { 2016 // Add the task to the list to remove if the component no longer exists 2017 tmpI.setComponent(cn); 2018 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2019 tasksToRemove.add(p.second); 2020 } 2021 } catch (Exception e) {} 2022 } 2023 } 2024 // Prune all the tasks with removed components from the list of recent tasks 2025 synchronized (ActivityManagerService.this) { 2026 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2027 // Remove the task but don't kill the process (since other components in that 2028 // package may still be running and in the background) 2029 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2030 } 2031 } 2032 } 2033 2034 @Override 2035 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2036 // Force stop the specified packages 2037 if (packages != null) { 2038 for (String pkg : packages) { 2039 synchronized (ActivityManagerService.this) { 2040 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2041 "finished booting")) { 2042 return true; 2043 } 2044 } 2045 } 2046 } 2047 return false; 2048 } 2049 }; 2050 2051 public void setSystemProcess() { 2052 try { 2053 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2054 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2055 ServiceManager.addService("meminfo", new MemBinder(this)); 2056 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2057 ServiceManager.addService("dbinfo", new DbBinder(this)); 2058 if (MONITOR_CPU_USAGE) { 2059 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2060 } 2061 ServiceManager.addService("permission", new PermissionController(this)); 2062 2063 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2064 "android", STOCK_PM_FLAGS); 2065 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2066 2067 synchronized (this) { 2068 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2069 app.persistent = true; 2070 app.pid = MY_PID; 2071 app.maxAdj = ProcessList.SYSTEM_ADJ; 2072 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2073 mProcessNames.put(app.processName, app.uid, app); 2074 synchronized (mPidsSelfLocked) { 2075 mPidsSelfLocked.put(app.pid, app); 2076 } 2077 updateLruProcessLocked(app, false, null); 2078 updateOomAdjLocked(); 2079 } 2080 } catch (PackageManager.NameNotFoundException e) { 2081 throw new RuntimeException( 2082 "Unable to find android system package", e); 2083 } 2084 } 2085 2086 public void setWindowManager(WindowManagerService wm) { 2087 mWindowManager = wm; 2088 mStackSupervisor.setWindowManager(wm); 2089 } 2090 2091 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2092 mUsageStatsService = usageStatsManager; 2093 } 2094 2095 public void startObservingNativeCrashes() { 2096 final NativeCrashListener ncl = new NativeCrashListener(this); 2097 ncl.start(); 2098 } 2099 2100 public IAppOpsService getAppOpsService() { 2101 return mAppOpsService; 2102 } 2103 2104 static class MemBinder extends Binder { 2105 ActivityManagerService mActivityManagerService; 2106 MemBinder(ActivityManagerService activityManagerService) { 2107 mActivityManagerService = activityManagerService; 2108 } 2109 2110 @Override 2111 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2112 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2113 != PackageManager.PERMISSION_GRANTED) { 2114 pw.println("Permission Denial: can't dump meminfo from from pid=" 2115 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2116 + " without permission " + android.Manifest.permission.DUMP); 2117 return; 2118 } 2119 2120 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2121 } 2122 } 2123 2124 static class GraphicsBinder extends Binder { 2125 ActivityManagerService mActivityManagerService; 2126 GraphicsBinder(ActivityManagerService activityManagerService) { 2127 mActivityManagerService = activityManagerService; 2128 } 2129 2130 @Override 2131 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2132 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2133 != PackageManager.PERMISSION_GRANTED) { 2134 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2135 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2136 + " without permission " + android.Manifest.permission.DUMP); 2137 return; 2138 } 2139 2140 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2141 } 2142 } 2143 2144 static class DbBinder extends Binder { 2145 ActivityManagerService mActivityManagerService; 2146 DbBinder(ActivityManagerService activityManagerService) { 2147 mActivityManagerService = activityManagerService; 2148 } 2149 2150 @Override 2151 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2152 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2153 != PackageManager.PERMISSION_GRANTED) { 2154 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2155 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2156 + " without permission " + android.Manifest.permission.DUMP); 2157 return; 2158 } 2159 2160 mActivityManagerService.dumpDbInfo(fd, pw, args); 2161 } 2162 } 2163 2164 static class CpuBinder extends Binder { 2165 ActivityManagerService mActivityManagerService; 2166 CpuBinder(ActivityManagerService activityManagerService) { 2167 mActivityManagerService = activityManagerService; 2168 } 2169 2170 @Override 2171 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2172 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2173 != PackageManager.PERMISSION_GRANTED) { 2174 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2175 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2176 + " without permission " + android.Manifest.permission.DUMP); 2177 return; 2178 } 2179 2180 synchronized (mActivityManagerService.mProcessCpuThread) { 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2182 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2183 SystemClock.uptimeMillis())); 2184 } 2185 } 2186 } 2187 2188 public static final class Lifecycle extends SystemService { 2189 private final ActivityManagerService mService; 2190 2191 public Lifecycle(Context context) { 2192 super(context); 2193 mService = new ActivityManagerService(context); 2194 } 2195 2196 @Override 2197 public void onStart() { 2198 mService.start(); 2199 } 2200 2201 public ActivityManagerService getService() { 2202 return mService; 2203 } 2204 } 2205 2206 // Note: This method is invoked on the main thread but may need to attach various 2207 // handlers to other threads. So take care to be explicit about the looper. 2208 public ActivityManagerService(Context systemContext) { 2209 mContext = systemContext; 2210 mFactoryTest = FactoryTest.getMode(); 2211 mSystemThread = ActivityThread.currentActivityThread(); 2212 2213 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2214 2215 mHandlerThread = new ServiceThread(TAG, 2216 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2217 mHandlerThread.start(); 2218 mHandler = new MainHandler(mHandlerThread.getLooper()); 2219 2220 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2221 "foreground", BROADCAST_FG_TIMEOUT, false); 2222 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2223 "background", BROADCAST_BG_TIMEOUT, true); 2224 mBroadcastQueues[0] = mFgBroadcastQueue; 2225 mBroadcastQueues[1] = mBgBroadcastQueue; 2226 2227 mServices = new ActiveServices(this); 2228 mProviderMap = new ProviderMap(this); 2229 2230 // TODO: Move creation of battery stats service outside of activity manager service. 2231 File dataDir = Environment.getDataDirectory(); 2232 File systemDir = new File(dataDir, "system"); 2233 systemDir.mkdirs(); 2234 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2235 mBatteryStatsService.getActiveStatistics().readLocked(); 2236 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2237 mOnBattery = DEBUG_POWER ? true 2238 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2239 mBatteryStatsService.getActiveStatistics().setCallback(this); 2240 2241 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2242 2243 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2244 2245 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2246 2247 // User 0 is the first and only user that runs at boot. 2248 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2249 mUserLru.add(Integer.valueOf(0)); 2250 updateStartedUserArrayLocked(); 2251 2252 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2253 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2254 2255 mConfiguration.setToDefaults(); 2256 mConfiguration.setLocale(Locale.getDefault()); 2257 2258 mConfigurationSeq = mConfiguration.seq = 1; 2259 mProcessCpuTracker.init(); 2260 2261 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2262 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2263 mStackSupervisor = new ActivityStackSupervisor(this); 2264 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2265 2266 mProcessCpuThread = new Thread("CpuTracker") { 2267 @Override 2268 public void run() { 2269 while (true) { 2270 try { 2271 try { 2272 synchronized(this) { 2273 final long now = SystemClock.uptimeMillis(); 2274 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2275 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2276 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2277 // + ", write delay=" + nextWriteDelay); 2278 if (nextWriteDelay < nextCpuDelay) { 2279 nextCpuDelay = nextWriteDelay; 2280 } 2281 if (nextCpuDelay > 0) { 2282 mProcessCpuMutexFree.set(true); 2283 this.wait(nextCpuDelay); 2284 } 2285 } 2286 } catch (InterruptedException e) { 2287 } 2288 updateCpuStatsNow(); 2289 } catch (Exception e) { 2290 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2291 } 2292 } 2293 } 2294 }; 2295 2296 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2297 2298 Watchdog.getInstance().addMonitor(this); 2299 Watchdog.getInstance().addThread(mHandler); 2300 } 2301 2302 public void setSystemServiceManager(SystemServiceManager mgr) { 2303 mSystemServiceManager = mgr; 2304 } 2305 2306 private void start() { 2307 Process.removeAllProcessGroups(); 2308 mProcessCpuThread.start(); 2309 2310 mBatteryStatsService.publish(mContext); 2311 mAppOpsService.publish(mContext); 2312 Slog.d("AppOps", "AppOpsService published"); 2313 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2314 } 2315 2316 public void initPowerManagement() { 2317 mStackSupervisor.initPowerManagement(); 2318 mBatteryStatsService.initPowerManagement(); 2319 } 2320 2321 @Override 2322 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2323 throws RemoteException { 2324 if (code == SYSPROPS_TRANSACTION) { 2325 // We need to tell all apps about the system property change. 2326 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2327 synchronized(this) { 2328 final int NP = mProcessNames.getMap().size(); 2329 for (int ip=0; ip<NP; ip++) { 2330 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2331 final int NA = apps.size(); 2332 for (int ia=0; ia<NA; ia++) { 2333 ProcessRecord app = apps.valueAt(ia); 2334 if (app.thread != null) { 2335 procs.add(app.thread.asBinder()); 2336 } 2337 } 2338 } 2339 } 2340 2341 int N = procs.size(); 2342 for (int i=0; i<N; i++) { 2343 Parcel data2 = Parcel.obtain(); 2344 try { 2345 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2346 } catch (RemoteException e) { 2347 } 2348 data2.recycle(); 2349 } 2350 } 2351 try { 2352 return super.onTransact(code, data, reply, flags); 2353 } catch (RuntimeException e) { 2354 // The activity manager only throws security exceptions, so let's 2355 // log all others. 2356 if (!(e instanceof SecurityException)) { 2357 Slog.wtf(TAG, "Activity Manager Crash", e); 2358 } 2359 throw e; 2360 } 2361 } 2362 2363 void updateCpuStats() { 2364 final long now = SystemClock.uptimeMillis(); 2365 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2366 return; 2367 } 2368 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2369 synchronized (mProcessCpuThread) { 2370 mProcessCpuThread.notify(); 2371 } 2372 } 2373 } 2374 2375 void updateCpuStatsNow() { 2376 synchronized (mProcessCpuThread) { 2377 mProcessCpuMutexFree.set(false); 2378 final long now = SystemClock.uptimeMillis(); 2379 boolean haveNewCpuStats = false; 2380 2381 if (MONITOR_CPU_USAGE && 2382 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2383 mLastCpuTime.set(now); 2384 haveNewCpuStats = true; 2385 mProcessCpuTracker.update(); 2386 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2387 //Slog.i(TAG, "Total CPU usage: " 2388 // + mProcessCpu.getTotalCpuPercent() + "%"); 2389 2390 // Slog the cpu usage if the property is set. 2391 if ("true".equals(SystemProperties.get("events.cpu"))) { 2392 int user = mProcessCpuTracker.getLastUserTime(); 2393 int system = mProcessCpuTracker.getLastSystemTime(); 2394 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2395 int irq = mProcessCpuTracker.getLastIrqTime(); 2396 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2397 int idle = mProcessCpuTracker.getLastIdleTime(); 2398 2399 int total = user + system + iowait + irq + softIrq + idle; 2400 if (total == 0) total = 1; 2401 2402 EventLog.writeEvent(EventLogTags.CPU, 2403 ((user+system+iowait+irq+softIrq) * 100) / total, 2404 (user * 100) / total, 2405 (system * 100) / total, 2406 (iowait * 100) / total, 2407 (irq * 100) / total, 2408 (softIrq * 100) / total); 2409 } 2410 } 2411 2412 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2413 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2414 synchronized(bstats) { 2415 synchronized(mPidsSelfLocked) { 2416 if (haveNewCpuStats) { 2417 if (mOnBattery) { 2418 int perc = bstats.startAddingCpuLocked(); 2419 int totalUTime = 0; 2420 int totalSTime = 0; 2421 final int N = mProcessCpuTracker.countStats(); 2422 for (int i=0; i<N; i++) { 2423 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2424 if (!st.working) { 2425 continue; 2426 } 2427 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2428 int otherUTime = (st.rel_utime*perc)/100; 2429 int otherSTime = (st.rel_stime*perc)/100; 2430 totalUTime += otherUTime; 2431 totalSTime += otherSTime; 2432 if (pr != null) { 2433 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2434 if (ps == null || !ps.isActive()) { 2435 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2436 pr.info.uid, pr.processName); 2437 } 2438 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2439 st.rel_stime-otherSTime); 2440 ps.addSpeedStepTimes(cpuSpeedTimes); 2441 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2442 } else { 2443 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2444 if (ps == null || !ps.isActive()) { 2445 st.batteryStats = ps = bstats.getProcessStatsLocked( 2446 bstats.mapUid(st.uid), st.name); 2447 } 2448 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2449 st.rel_stime-otherSTime); 2450 ps.addSpeedStepTimes(cpuSpeedTimes); 2451 } 2452 } 2453 bstats.finishAddingCpuLocked(perc, totalUTime, 2454 totalSTime, cpuSpeedTimes); 2455 } 2456 } 2457 } 2458 2459 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2460 mLastWriteTime = now; 2461 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2462 } 2463 } 2464 } 2465 } 2466 2467 @Override 2468 public void batteryNeedsCpuUpdate() { 2469 updateCpuStatsNow(); 2470 } 2471 2472 @Override 2473 public void batteryPowerChanged(boolean onBattery) { 2474 // When plugging in, update the CPU stats first before changing 2475 // the plug state. 2476 updateCpuStatsNow(); 2477 synchronized (this) { 2478 synchronized(mPidsSelfLocked) { 2479 mOnBattery = DEBUG_POWER ? true : onBattery; 2480 } 2481 } 2482 } 2483 2484 /** 2485 * Initialize the application bind args. These are passed to each 2486 * process when the bindApplication() IPC is sent to the process. They're 2487 * lazily setup to make sure the services are running when they're asked for. 2488 */ 2489 private HashMap<String, IBinder> getCommonServicesLocked() { 2490 if (mAppBindArgs == null) { 2491 mAppBindArgs = new HashMap<String, IBinder>(); 2492 2493 // Setup the application init args 2494 mAppBindArgs.put("package", ServiceManager.getService("package")); 2495 mAppBindArgs.put("window", ServiceManager.getService("window")); 2496 mAppBindArgs.put(Context.ALARM_SERVICE, 2497 ServiceManager.getService(Context.ALARM_SERVICE)); 2498 } 2499 return mAppBindArgs; 2500 } 2501 2502 final void setFocusedActivityLocked(ActivityRecord r) { 2503 if (mFocusedActivity != r) { 2504 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2505 mFocusedActivity = r; 2506 if (r.task != null && r.task.voiceInteractor != null) { 2507 startRunningVoiceLocked(); 2508 } else { 2509 finishRunningVoiceLocked(); 2510 } 2511 mStackSupervisor.setFocusedStack(r); 2512 if (r != null) { 2513 mWindowManager.setFocusedApp(r.appToken, true); 2514 } 2515 applyUpdateLockStateLocked(r); 2516 } 2517 } 2518 2519 final void clearFocusedActivity(ActivityRecord r) { 2520 if (mFocusedActivity == r) { 2521 mFocusedActivity = null; 2522 } 2523 } 2524 2525 @Override 2526 public void setFocusedStack(int stackId) { 2527 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2528 synchronized (ActivityManagerService.this) { 2529 ActivityStack stack = mStackSupervisor.getStack(stackId); 2530 if (stack != null) { 2531 ActivityRecord r = stack.topRunningActivityLocked(null); 2532 if (r != null) { 2533 setFocusedActivityLocked(r); 2534 } 2535 } 2536 } 2537 } 2538 2539 @Override 2540 public void notifyActivityDrawn(IBinder token) { 2541 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2542 synchronized (this) { 2543 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2544 if (r != null) { 2545 r.task.stack.notifyActivityDrawnLocked(r); 2546 } 2547 } 2548 } 2549 2550 final void applyUpdateLockStateLocked(ActivityRecord r) { 2551 // Modifications to the UpdateLock state are done on our handler, outside 2552 // the activity manager's locks. The new state is determined based on the 2553 // state *now* of the relevant activity record. The object is passed to 2554 // the handler solely for logging detail, not to be consulted/modified. 2555 final boolean nextState = r != null && r.immersive; 2556 mHandler.sendMessage( 2557 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2558 } 2559 2560 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2561 Message msg = Message.obtain(); 2562 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2563 msg.obj = r.task.askedCompatMode ? null : r; 2564 mHandler.sendMessage(msg); 2565 } 2566 2567 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2568 String what, Object obj, ProcessRecord srcApp) { 2569 app.lastActivityTime = now; 2570 2571 if (app.activities.size() > 0) { 2572 // Don't want to touch dependent processes that are hosting activities. 2573 return index; 2574 } 2575 2576 int lrui = mLruProcesses.lastIndexOf(app); 2577 if (lrui < 0) { 2578 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2579 + what + " " + obj + " from " + srcApp); 2580 return index; 2581 } 2582 2583 if (lrui >= index) { 2584 // Don't want to cause this to move dependent processes *back* in the 2585 // list as if they were less frequently used. 2586 return index; 2587 } 2588 2589 if (lrui >= mLruProcessActivityStart) { 2590 // Don't want to touch dependent processes that are hosting activities. 2591 return index; 2592 } 2593 2594 mLruProcesses.remove(lrui); 2595 if (index > 0) { 2596 index--; 2597 } 2598 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2599 + " in LRU list: " + app); 2600 mLruProcesses.add(index, app); 2601 return index; 2602 } 2603 2604 final void removeLruProcessLocked(ProcessRecord app) { 2605 int lrui = mLruProcesses.lastIndexOf(app); 2606 if (lrui >= 0) { 2607 if (lrui <= mLruProcessActivityStart) { 2608 mLruProcessActivityStart--; 2609 } 2610 if (lrui <= mLruProcessServiceStart) { 2611 mLruProcessServiceStart--; 2612 } 2613 mLruProcesses.remove(lrui); 2614 } 2615 } 2616 2617 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2618 ProcessRecord client) { 2619 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2620 || app.treatLikeActivity; 2621 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2622 if (!activityChange && hasActivity) { 2623 // The process has activities, so we are only allowing activity-based adjustments 2624 // to move it. It should be kept in the front of the list with other 2625 // processes that have activities, and we don't want those to change their 2626 // order except due to activity operations. 2627 return; 2628 } 2629 2630 mLruSeq++; 2631 final long now = SystemClock.uptimeMillis(); 2632 app.lastActivityTime = now; 2633 2634 // First a quick reject: if the app is already at the position we will 2635 // put it, then there is nothing to do. 2636 if (hasActivity) { 2637 final int N = mLruProcesses.size(); 2638 if (N > 0 && mLruProcesses.get(N-1) == app) { 2639 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2640 return; 2641 } 2642 } else { 2643 if (mLruProcessServiceStart > 0 2644 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2646 return; 2647 } 2648 } 2649 2650 int lrui = mLruProcesses.lastIndexOf(app); 2651 2652 if (app.persistent && lrui >= 0) { 2653 // We don't care about the position of persistent processes, as long as 2654 // they are in the list. 2655 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2656 return; 2657 } 2658 2659 /* In progress: compute new position first, so we can avoid doing work 2660 if the process is not actually going to move. Not yet working. 2661 int addIndex; 2662 int nextIndex; 2663 boolean inActivity = false, inService = false; 2664 if (hasActivity) { 2665 // Process has activities, put it at the very tipsy-top. 2666 addIndex = mLruProcesses.size(); 2667 nextIndex = mLruProcessServiceStart; 2668 inActivity = true; 2669 } else if (hasService) { 2670 // Process has services, put it at the top of the service list. 2671 addIndex = mLruProcessActivityStart; 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 inService = true; 2675 } else { 2676 // Process not otherwise of interest, it goes to the top of the non-service area. 2677 addIndex = mLruProcessServiceStart; 2678 if (client != null) { 2679 int clientIndex = mLruProcesses.lastIndexOf(client); 2680 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2681 + app); 2682 if (clientIndex >= 0 && addIndex > clientIndex) { 2683 addIndex = clientIndex; 2684 } 2685 } 2686 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2687 } 2688 2689 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2690 + mLruProcessActivityStart + "): " + app); 2691 */ 2692 2693 if (lrui >= 0) { 2694 if (lrui < mLruProcessActivityStart) { 2695 mLruProcessActivityStart--; 2696 } 2697 if (lrui < mLruProcessServiceStart) { 2698 mLruProcessServiceStart--; 2699 } 2700 /* 2701 if (addIndex > lrui) { 2702 addIndex--; 2703 } 2704 if (nextIndex > lrui) { 2705 nextIndex--; 2706 } 2707 */ 2708 mLruProcesses.remove(lrui); 2709 } 2710 2711 /* 2712 mLruProcesses.add(addIndex, app); 2713 if (inActivity) { 2714 mLruProcessActivityStart++; 2715 } 2716 if (inService) { 2717 mLruProcessActivityStart++; 2718 } 2719 */ 2720 2721 int nextIndex; 2722 if (hasActivity) { 2723 final int N = mLruProcesses.size(); 2724 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2725 // Process doesn't have activities, but has clients with 2726 // activities... move it up, but one below the top (the top 2727 // should always have a real activity). 2728 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2729 mLruProcesses.add(N-1, app); 2730 // To keep it from spamming the LRU list (by making a bunch of clients), 2731 // we will push down any other entries owned by the app. 2732 final int uid = app.info.uid; 2733 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2734 ProcessRecord subProc = mLruProcesses.get(i); 2735 if (subProc.info.uid == uid) { 2736 // We want to push this one down the list. If the process after 2737 // it is for the same uid, however, don't do so, because we don't 2738 // want them internally to be re-ordered. 2739 if (mLruProcesses.get(i-1).info.uid != uid) { 2740 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2741 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2742 ProcessRecord tmp = mLruProcesses.get(i); 2743 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2744 mLruProcesses.set(i-1, tmp); 2745 i--; 2746 } 2747 } else { 2748 // A gap, we can stop here. 2749 break; 2750 } 2751 } 2752 } else { 2753 // Process has activities, put it at the very tipsy-top. 2754 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2755 mLruProcesses.add(app); 2756 } 2757 nextIndex = mLruProcessServiceStart; 2758 } else if (hasService) { 2759 // Process has services, put it at the top of the service list. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2761 mLruProcesses.add(mLruProcessActivityStart, app); 2762 nextIndex = mLruProcessServiceStart; 2763 mLruProcessActivityStart++; 2764 } else { 2765 // Process not otherwise of interest, it goes to the top of the non-service area. 2766 int index = mLruProcessServiceStart; 2767 if (client != null) { 2768 // If there is a client, don't allow the process to be moved up higher 2769 // in the list than that client. 2770 int clientIndex = mLruProcesses.lastIndexOf(client); 2771 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2772 + " when updating " + app); 2773 if (clientIndex <= lrui) { 2774 // Don't allow the client index restriction to push it down farther in the 2775 // list than it already is. 2776 clientIndex = lrui; 2777 } 2778 if (clientIndex >= 0 && index > clientIndex) { 2779 index = clientIndex; 2780 } 2781 } 2782 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2783 mLruProcesses.add(index, app); 2784 nextIndex = index-1; 2785 mLruProcessActivityStart++; 2786 mLruProcessServiceStart++; 2787 } 2788 2789 // If the app is currently using a content provider or service, 2790 // bump those processes as well. 2791 for (int j=app.connections.size()-1; j>=0; j--) { 2792 ConnectionRecord cr = app.connections.valueAt(j); 2793 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2794 && cr.binding.service.app != null 2795 && cr.binding.service.app.lruSeq != mLruSeq 2796 && !cr.binding.service.app.persistent) { 2797 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2798 "service connection", cr, app); 2799 } 2800 } 2801 for (int j=app.conProviders.size()-1; j>=0; j--) { 2802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2804 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2805 "provider reference", cpr, app); 2806 } 2807 } 2808 } 2809 2810 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2811 if (uid == Process.SYSTEM_UID) { 2812 // The system gets to run in any process. If there are multiple 2813 // processes with the same uid, just pick the first (this 2814 // should never happen). 2815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2816 if (procs == null) return null; 2817 final int N = procs.size(); 2818 for (int i = 0; i < N; i++) { 2819 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2820 } 2821 } 2822 ProcessRecord proc = mProcessNames.get(processName, uid); 2823 if (false && proc != null && !keepIfLarge 2824 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2825 && proc.lastCachedPss >= 4000) { 2826 // Turn this condition on to cause killing to happen regularly, for testing. 2827 if (proc.baseProcessTracker != null) { 2828 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2829 } 2830 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 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 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2840 } 2841 } 2842 return proc; 2843 } 2844 2845 void ensurePackageDexOpt(String packageName) { 2846 IPackageManager pm = AppGlobals.getPackageManager(); 2847 try { 2848 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2849 mDidDexOpt = true; 2850 } 2851 } catch (RemoteException e) { 2852 } 2853 } 2854 2855 boolean isNextTransitionForward() { 2856 int transit = mWindowManager.getPendingAppTransition(); 2857 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2858 || transit == AppTransition.TRANSIT_TASK_OPEN 2859 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2860 } 2861 2862 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2863 String processName, String abiOverride, int uid, Runnable crashHandler) { 2864 synchronized(this) { 2865 ApplicationInfo info = new ApplicationInfo(); 2866 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2867 // For isolated processes, the former contains the parent's uid and the latter the 2868 // actual uid of the isolated process. 2869 // In the special case introduced by this method (which is, starting an isolated 2870 // process directly from the SystemServer without an actual parent app process) the 2871 // closest thing to a parent's uid is SYSTEM_UID. 2872 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2873 // the |isolated| logic in the ProcessRecord constructor. 2874 info.uid = Process.SYSTEM_UID; 2875 info.processName = processName; 2876 info.className = entryPoint; 2877 info.packageName = "android"; 2878 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2879 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2880 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2881 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2882 crashHandler); 2883 return proc != null ? proc.pid : 0; 2884 } 2885 } 2886 2887 final ProcessRecord startProcessLocked(String processName, 2888 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2889 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2890 boolean isolated, boolean keepIfLarge) { 2891 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2892 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2893 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2894 null /* crashHandler */); 2895 } 2896 2897 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2898 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2899 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2900 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2901 ProcessRecord app; 2902 if (!isolated) { 2903 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2904 } else { 2905 // If this is an isolated process, it can't re-use an existing process. 2906 app = null; 2907 } 2908 // We don't have to do anything more if: 2909 // (1) There is an existing application record; and 2910 // (2) The caller doesn't think it is dead, OR there is no thread 2911 // object attached to it so we know it couldn't have crashed; and 2912 // (3) There is a pid assigned to it, so it is either starting or 2913 // already running. 2914 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2915 + " app=" + app + " knownToBeDead=" + knownToBeDead 2916 + " thread=" + (app != null ? app.thread : null) 2917 + " pid=" + (app != null ? app.pid : -1)); 2918 if (app != null && app.pid > 0) { 2919 if (!knownToBeDead || app.thread == null) { 2920 // We already have the app running, or are waiting for it to 2921 // come up (we have a pid but not yet its thread), so keep it. 2922 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2923 // If this is a new package in the process, add the package to the list 2924 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2925 return app; 2926 } 2927 2928 // An application record is attached to a previous process, 2929 // clean it up now. 2930 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2931 Process.killProcessGroup(app.info.uid, app.pid); 2932 handleAppDiedLocked(app, true, true); 2933 } 2934 2935 String hostingNameStr = hostingName != null 2936 ? hostingName.flattenToShortString() : null; 2937 2938 if (!isolated) { 2939 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2940 // If we are in the background, then check to see if this process 2941 // is bad. If so, we will just silently fail. 2942 if (mBadProcesses.get(info.processName, info.uid) != null) { 2943 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2944 + "/" + info.processName); 2945 return null; 2946 } 2947 } else { 2948 // When the user is explicitly starting a process, then clear its 2949 // crash count so that we won't make it bad until they see at 2950 // least one crash dialog again, and make the process good again 2951 // if it had been bad. 2952 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2953 + "/" + info.processName); 2954 mProcessCrashTimes.remove(info.processName, info.uid); 2955 if (mBadProcesses.get(info.processName, info.uid) != null) { 2956 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2957 UserHandle.getUserId(info.uid), info.uid, 2958 info.processName); 2959 mBadProcesses.remove(info.processName, info.uid); 2960 if (app != null) { 2961 app.bad = false; 2962 } 2963 } 2964 } 2965 } 2966 2967 if (app == null) { 2968 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2969 app.crashHandler = crashHandler; 2970 if (app == null) { 2971 Slog.w(TAG, "Failed making new process record for " 2972 + processName + "/" + info.uid + " isolated=" + isolated); 2973 return null; 2974 } 2975 mProcessNames.put(processName, app.uid, app); 2976 if (isolated) { 2977 mIsolatedProcesses.put(app.uid, app); 2978 } 2979 } else { 2980 // If this is a new package in the process, add the package to the list 2981 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2982 } 2983 2984 // If the system is not ready yet, then hold off on starting this 2985 // process until it is. 2986 if (!mProcessesReady 2987 && !isAllowedWhileBooting(info) 2988 && !allowWhileBooting) { 2989 if (!mProcessesOnHold.contains(app)) { 2990 mProcessesOnHold.add(app); 2991 } 2992 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2993 return app; 2994 } 2995 2996 startProcessLocked( 2997 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2998 return (app.pid != 0) ? app : null; 2999 } 3000 3001 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3002 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3003 } 3004 3005 private final void startProcessLocked(ProcessRecord app, 3006 String hostingType, String hostingNameStr) { 3007 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3008 null /* entryPoint */, null /* entryPointArgs */); 3009 } 3010 3011 private final void startProcessLocked(ProcessRecord app, String hostingType, 3012 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3013 if (app.pid > 0 && app.pid != MY_PID) { 3014 synchronized (mPidsSelfLocked) { 3015 mPidsSelfLocked.remove(app.pid); 3016 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3017 } 3018 app.setPid(0); 3019 } 3020 3021 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3022 "startProcessLocked removing on hold: " + app); 3023 mProcessesOnHold.remove(app); 3024 3025 updateCpuStats(); 3026 3027 try { 3028 int uid = app.uid; 3029 3030 int[] gids = null; 3031 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3032 if (!app.isolated) { 3033 int[] permGids = null; 3034 try { 3035 final PackageManager pm = mContext.getPackageManager(); 3036 permGids = pm.getPackageGids(app.info.packageName); 3037 3038 if (Environment.isExternalStorageEmulated()) { 3039 if (pm.checkPermission( 3040 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3041 app.info.packageName) == PERMISSION_GRANTED) { 3042 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3043 } else { 3044 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3045 } 3046 } 3047 } catch (PackageManager.NameNotFoundException e) { 3048 Slog.w(TAG, "Unable to retrieve gids", e); 3049 } 3050 3051 /* 3052 * Add shared application and profile GIDs so applications can share some 3053 * resources like shared libraries and access user-wide resources 3054 */ 3055 if (permGids == null) { 3056 gids = new int[2]; 3057 } else { 3058 gids = new int[permGids.length + 2]; 3059 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3060 } 3061 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3062 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3063 } 3064 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3065 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3066 && mTopComponent != null 3067 && app.processName.equals(mTopComponent.getPackageName())) { 3068 uid = 0; 3069 } 3070 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3071 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3072 uid = 0; 3073 } 3074 } 3075 int debugFlags = 0; 3076 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3077 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3078 // Also turn on CheckJNI for debuggable apps. It's quite 3079 // awkward to turn on otherwise. 3080 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3081 } 3082 // Run the app in safe mode if its manifest requests so or the 3083 // system is booted in safe mode. 3084 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3085 mSafeMode == true) { 3086 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3087 } 3088 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3089 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3090 } 3091 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3092 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3093 } 3094 if ("1".equals(SystemProperties.get("debug.assert"))) { 3095 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3096 } 3097 3098 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3099 if (requiredAbi == null) { 3100 requiredAbi = Build.SUPPORTED_ABIS[0]; 3101 } 3102 3103 // Start the process. It will either succeed and return a result containing 3104 // the PID of the new process, or else throw a RuntimeException. 3105 boolean isActivityProcess = (entryPoint == null); 3106 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3107 Process.ProcessStartResult startResult = Process.start(entryPoint, 3108 app.processName, uid, uid, gids, debugFlags, mountExternal, 3109 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3110 3111 if (app.isolated) { 3112 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3113 } 3114 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3115 3116 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3117 UserHandle.getUserId(uid), startResult.pid, uid, 3118 app.processName, hostingType, 3119 hostingNameStr != null ? hostingNameStr : ""); 3120 3121 if (app.persistent) { 3122 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3123 } 3124 3125 StringBuilder buf = mStringBuilder; 3126 buf.setLength(0); 3127 buf.append("Start proc "); 3128 buf.append(app.processName); 3129 if (!isActivityProcess) { 3130 buf.append(" ["); 3131 buf.append(entryPoint); 3132 buf.append("]"); 3133 } 3134 buf.append(" for "); 3135 buf.append(hostingType); 3136 if (hostingNameStr != null) { 3137 buf.append(" "); 3138 buf.append(hostingNameStr); 3139 } 3140 buf.append(": pid="); 3141 buf.append(startResult.pid); 3142 buf.append(" uid="); 3143 buf.append(uid); 3144 buf.append(" gids={"); 3145 if (gids != null) { 3146 for (int gi=0; gi<gids.length; gi++) { 3147 if (gi != 0) buf.append(", "); 3148 buf.append(gids[gi]); 3149 3150 } 3151 } 3152 buf.append("}"); 3153 if (requiredAbi != null) { 3154 buf.append(" abi="); 3155 buf.append(requiredAbi); 3156 } 3157 Slog.i(TAG, buf.toString()); 3158 app.setPid(startResult.pid); 3159 app.usingWrapper = startResult.usingWrapper; 3160 app.removed = false; 3161 app.killedByAm = false; 3162 synchronized (mPidsSelfLocked) { 3163 this.mPidsSelfLocked.put(startResult.pid, app); 3164 if (isActivityProcess) { 3165 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3166 msg.obj = app; 3167 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3168 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3169 } 3170 } 3171 } catch (RuntimeException e) { 3172 // XXX do better error recovery. 3173 app.setPid(0); 3174 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3175 if (app.isolated) { 3176 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3177 } 3178 Slog.e(TAG, "Failure starting process " + app.processName, e); 3179 } 3180 } 3181 3182 void updateUsageStats(ActivityRecord component, boolean resumed) { 3183 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3184 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3185 if (resumed) { 3186 if (mUsageStatsService != null) { 3187 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3188 System.currentTimeMillis(), 3189 UsageEvents.Event.MOVE_TO_FOREGROUND); 3190 } 3191 synchronized (stats) { 3192 stats.noteActivityResumedLocked(component.app.uid); 3193 } 3194 } else { 3195 if (mUsageStatsService != null) { 3196 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3197 System.currentTimeMillis(), 3198 UsageEvents.Event.MOVE_TO_BACKGROUND); 3199 } 3200 synchronized (stats) { 3201 stats.noteActivityPausedLocked(component.app.uid); 3202 } 3203 } 3204 } 3205 3206 Intent getHomeIntent() { 3207 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3208 intent.setComponent(mTopComponent); 3209 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3210 intent.addCategory(Intent.CATEGORY_HOME); 3211 } 3212 return intent; 3213 } 3214 3215 boolean startHomeActivityLocked(int userId) { 3216 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3217 && mTopAction == null) { 3218 // We are running in factory test mode, but unable to find 3219 // the factory test app, so just sit around displaying the 3220 // error message and don't try to start anything. 3221 return false; 3222 } 3223 Intent intent = getHomeIntent(); 3224 ActivityInfo aInfo = 3225 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3226 if (aInfo != null) { 3227 intent.setComponent(new ComponentName( 3228 aInfo.applicationInfo.packageName, aInfo.name)); 3229 // Don't do this if the home app is currently being 3230 // instrumented. 3231 aInfo = new ActivityInfo(aInfo); 3232 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3233 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3234 aInfo.applicationInfo.uid, true); 3235 if (app == null || app.instrumentationClass == null) { 3236 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3237 mStackSupervisor.startHomeActivity(intent, aInfo); 3238 } 3239 } 3240 3241 return true; 3242 } 3243 3244 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3245 ActivityInfo ai = null; 3246 ComponentName comp = intent.getComponent(); 3247 try { 3248 if (comp != null) { 3249 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3250 } else { 3251 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3252 intent, 3253 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3254 flags, userId); 3255 3256 if (info != null) { 3257 ai = info.activityInfo; 3258 } 3259 } 3260 } catch (RemoteException e) { 3261 // ignore 3262 } 3263 3264 return ai; 3265 } 3266 3267 /** 3268 * Starts the "new version setup screen" if appropriate. 3269 */ 3270 void startSetupActivityLocked() { 3271 // Only do this once per boot. 3272 if (mCheckedForSetup) { 3273 return; 3274 } 3275 3276 // We will show this screen if the current one is a different 3277 // version than the last one shown, and we are not running in 3278 // low-level factory test mode. 3279 final ContentResolver resolver = mContext.getContentResolver(); 3280 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3281 Settings.Global.getInt(resolver, 3282 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3283 mCheckedForSetup = true; 3284 3285 // See if we should be showing the platform update setup UI. 3286 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3287 List<ResolveInfo> ris = mContext.getPackageManager() 3288 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3289 3290 // We don't allow third party apps to replace this. 3291 ResolveInfo ri = null; 3292 for (int i=0; ris != null && i<ris.size(); i++) { 3293 if ((ris.get(i).activityInfo.applicationInfo.flags 3294 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3295 ri = ris.get(i); 3296 break; 3297 } 3298 } 3299 3300 if (ri != null) { 3301 String vers = ri.activityInfo.metaData != null 3302 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3303 : null; 3304 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3305 vers = ri.activityInfo.applicationInfo.metaData.getString( 3306 Intent.METADATA_SETUP_VERSION); 3307 } 3308 String lastVers = Settings.Secure.getString( 3309 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3310 if (vers != null && !vers.equals(lastVers)) { 3311 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3312 intent.setComponent(new ComponentName( 3313 ri.activityInfo.packageName, ri.activityInfo.name)); 3314 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3315 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3316 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, String resultWho, int requestCode, 3442 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3443 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3444 resultWho, requestCode, startFlags, profilerInfo, options, 3445 UserHandle.getCallingUserId()); 3446 } 3447 3448 @Override 3449 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3450 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3451 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3452 enforceNotIsolatedCaller("startActivity"); 3453 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3454 false, ALLOW_FULL_ONLY, "startActivity", null); 3455 // TODO: Switch to user app stacks here. 3456 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3457 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3458 profilerInfo, null, null, options, userId, null, null); 3459 } 3460 3461 @Override 3462 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3464 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3465 3466 // This is very dangerous -- it allows you to perform a start activity (including 3467 // permission grants) as any app that may launch one of your own activities. So 3468 // we will only allow this to be done from activities that are part of the core framework, 3469 // and then only when they are running as the system. 3470 final ActivityRecord sourceRecord; 3471 final int targetUid; 3472 final String targetPackage; 3473 synchronized (this) { 3474 if (resultTo == null) { 3475 throw new SecurityException("Must be called from an activity"); 3476 } 3477 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3478 if (sourceRecord == null) { 3479 throw new SecurityException("Called with bad activity token: " + resultTo); 3480 } 3481 if (!sourceRecord.info.packageName.equals("android")) { 3482 throw new SecurityException( 3483 "Must be called from an activity that is declared in the android package"); 3484 } 3485 if (sourceRecord.app == null) { 3486 throw new SecurityException("Called without a process attached to activity"); 3487 } 3488 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3489 // This is still okay, as long as this activity is running under the 3490 // uid of the original calling activity. 3491 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3492 throw new SecurityException( 3493 "Calling activity in uid " + sourceRecord.app.uid 3494 + " must be system uid or original calling uid " 3495 + sourceRecord.launchedFromUid); 3496 } 3497 } 3498 targetUid = sourceRecord.launchedFromUid; 3499 targetPackage = sourceRecord.launchedFromPackage; 3500 } 3501 3502 // TODO: Switch to user app stacks here. 3503 try { 3504 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3505 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3506 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3507 return ret; 3508 } catch (SecurityException e) { 3509 // XXX need to figure out how to propagate to original app. 3510 // A SecurityException here is generally actually a fault of the original 3511 // calling activity (such as a fairly granting permissions), so propagate it 3512 // back to them. 3513 /* 3514 StringBuilder msg = new StringBuilder(); 3515 msg.append("While launching"); 3516 msg.append(intent.toString()); 3517 msg.append(": "); 3518 msg.append(e.getMessage()); 3519 */ 3520 throw e; 3521 } 3522 } 3523 3524 @Override 3525 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3527 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3528 enforceNotIsolatedCaller("startActivityAndWait"); 3529 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3530 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3531 WaitResult res = new WaitResult(); 3532 // TODO: Switch to user app stacks here. 3533 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3534 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3535 options, userId, null, null); 3536 return res; 3537 } 3538 3539 @Override 3540 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3541 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3542 int startFlags, Configuration config, Bundle options, int userId) { 3543 enforceNotIsolatedCaller("startActivityWithConfig"); 3544 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3545 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3546 // TODO: Switch to user app stacks here. 3547 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3548 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3549 null, null, config, options, userId, null, null); 3550 return ret; 3551 } 3552 3553 @Override 3554 public int startActivityIntentSender(IApplicationThread caller, 3555 IntentSender intent, Intent fillInIntent, String resolvedType, 3556 IBinder resultTo, String resultWho, int requestCode, 3557 int flagsMask, int flagsValues, Bundle options) { 3558 enforceNotIsolatedCaller("startActivityIntentSender"); 3559 // Refuse possible leaked file descriptors 3560 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3561 throw new IllegalArgumentException("File descriptors passed in Intent"); 3562 } 3563 3564 IIntentSender sender = intent.getTarget(); 3565 if (!(sender instanceof PendingIntentRecord)) { 3566 throw new IllegalArgumentException("Bad PendingIntent object"); 3567 } 3568 3569 PendingIntentRecord pir = (PendingIntentRecord)sender; 3570 3571 synchronized (this) { 3572 // If this is coming from the currently resumed activity, it is 3573 // effectively saying that app switches are allowed at this point. 3574 final ActivityStack stack = getFocusedStack(); 3575 if (stack.mResumedActivity != null && 3576 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3577 mAppSwitchesAllowedTime = 0; 3578 } 3579 } 3580 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3581 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3582 return ret; 3583 } 3584 3585 @Override 3586 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3587 Intent intent, String resolvedType, IVoiceInteractionSession session, 3588 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3589 Bundle options, int userId) { 3590 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3591 != PackageManager.PERMISSION_GRANTED) { 3592 String msg = "Permission Denial: startVoiceActivity() from pid=" 3593 + Binder.getCallingPid() 3594 + ", uid=" + Binder.getCallingUid() 3595 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3596 Slog.w(TAG, msg); 3597 throw new SecurityException(msg); 3598 } 3599 if (session == null || interactor == null) { 3600 throw new NullPointerException("null session or interactor"); 3601 } 3602 userId = handleIncomingUser(callingPid, callingUid, userId, 3603 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3604 // TODO: Switch to user app stacks here. 3605 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3606 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3607 null, options, userId, null, null); 3608 } 3609 3610 @Override 3611 public boolean startNextMatchingActivity(IBinder callingActivity, 3612 Intent intent, Bundle options) { 3613 // Refuse possible leaked file descriptors 3614 if (intent != null && intent.hasFileDescriptors() == true) { 3615 throw new IllegalArgumentException("File descriptors passed in Intent"); 3616 } 3617 3618 synchronized (this) { 3619 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3620 if (r == null) { 3621 ActivityOptions.abort(options); 3622 return false; 3623 } 3624 if (r.app == null || r.app.thread == null) { 3625 // The caller is not running... d'oh! 3626 ActivityOptions.abort(options); 3627 return false; 3628 } 3629 intent = new Intent(intent); 3630 // The caller is not allowed to change the data. 3631 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3632 // And we are resetting to find the next component... 3633 intent.setComponent(null); 3634 3635 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3636 3637 ActivityInfo aInfo = null; 3638 try { 3639 List<ResolveInfo> resolves = 3640 AppGlobals.getPackageManager().queryIntentActivities( 3641 intent, r.resolvedType, 3642 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3643 UserHandle.getCallingUserId()); 3644 3645 // Look for the original activity in the list... 3646 final int N = resolves != null ? resolves.size() : 0; 3647 for (int i=0; i<N; i++) { 3648 ResolveInfo rInfo = resolves.get(i); 3649 if (rInfo.activityInfo.packageName.equals(r.packageName) 3650 && rInfo.activityInfo.name.equals(r.info.name)) { 3651 // We found the current one... the next matching is 3652 // after it. 3653 i++; 3654 if (i<N) { 3655 aInfo = resolves.get(i).activityInfo; 3656 } 3657 if (debug) { 3658 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3659 + "/" + r.info.name); 3660 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3661 + "/" + aInfo.name); 3662 } 3663 break; 3664 } 3665 } 3666 } catch (RemoteException e) { 3667 } 3668 3669 if (aInfo == null) { 3670 // Nobody who is next! 3671 ActivityOptions.abort(options); 3672 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3673 return false; 3674 } 3675 3676 intent.setComponent(new ComponentName( 3677 aInfo.applicationInfo.packageName, aInfo.name)); 3678 intent.setFlags(intent.getFlags()&~( 3679 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3680 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3681 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3682 Intent.FLAG_ACTIVITY_NEW_TASK)); 3683 3684 // Okay now we need to start the new activity, replacing the 3685 // currently running activity. This is a little tricky because 3686 // we want to start the new one as if the current one is finished, 3687 // but not finish the current one first so that there is no flicker. 3688 // And thus... 3689 final boolean wasFinishing = r.finishing; 3690 r.finishing = true; 3691 3692 // Propagate reply information over to the new activity. 3693 final ActivityRecord resultTo = r.resultTo; 3694 final String resultWho = r.resultWho; 3695 final int requestCode = r.requestCode; 3696 r.resultTo = null; 3697 if (resultTo != null) { 3698 resultTo.removeResultsLocked(r, resultWho, requestCode); 3699 } 3700 3701 final long origId = Binder.clearCallingIdentity(); 3702 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3703 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3704 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3705 options, false, null, null, null); 3706 Binder.restoreCallingIdentity(origId); 3707 3708 r.finishing = wasFinishing; 3709 if (res != ActivityManager.START_SUCCESS) { 3710 return false; 3711 } 3712 return true; 3713 } 3714 } 3715 3716 @Override 3717 public final int startActivityFromRecents(int taskId, Bundle options) { 3718 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3719 String msg = "Permission Denial: startActivityFromRecents called without " + 3720 START_TASKS_FROM_RECENTS; 3721 Slog.w(TAG, msg); 3722 throw new SecurityException(msg); 3723 } 3724 return startActivityFromRecentsInner(taskId, options); 3725 } 3726 3727 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3728 final TaskRecord task; 3729 final int callingUid; 3730 final String callingPackage; 3731 final Intent intent; 3732 final int userId; 3733 synchronized (this) { 3734 task = recentTaskForIdLocked(taskId); 3735 if (task == null) { 3736 throw new IllegalArgumentException("Task " + taskId + " not found."); 3737 } 3738 callingUid = task.mCallingUid; 3739 callingPackage = task.mCallingPackage; 3740 intent = task.intent; 3741 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3742 userId = task.userId; 3743 } 3744 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3745 options, userId, null, task); 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, TaskRecord inTask) { 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, 3758 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3759 null, null, null, options, userId, container, inTask); 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 mRecentTasks.remove(i); 3801 tr.removedFromRecents(mTaskPersister); 3802 } 3803 } 3804 3805 // Remove tasks from persistent storage. 3806 mTaskPersister.wakeup(null, true); 3807 } 3808 3809 /** 3810 * Update the recent tasks lists: make sure tasks should still be here (their 3811 * applications / activities still exist), update their availability, fixup ordering 3812 * of affiliations. 3813 */ 3814 void cleanupRecentTasksLocked(int userId) { 3815 if (mRecentTasks == null) { 3816 // Happens when called from the packagemanager broadcast before boot. 3817 return; 3818 } 3819 3820 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3821 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3822 final IPackageManager pm = AppGlobals.getPackageManager(); 3823 final ActivityInfo dummyAct = new ActivityInfo(); 3824 final ApplicationInfo dummyApp = new ApplicationInfo(); 3825 3826 int N = mRecentTasks.size(); 3827 3828 int[] users = userId == UserHandle.USER_ALL 3829 ? getUsersLocked() : new int[] { userId }; 3830 for (int user : users) { 3831 for (int i = 0; i < N; i++) { 3832 TaskRecord task = mRecentTasks.get(i); 3833 if (task.userId != user) { 3834 // Only look at tasks for the user ID of interest. 3835 continue; 3836 } 3837 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3838 // This situation is broken, and we should just get rid of it now. 3839 mRecentTasks.remove(i); 3840 task.removedFromRecents(mTaskPersister); 3841 i--; 3842 N--; 3843 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3844 continue; 3845 } 3846 // Check whether this activity is currently available. 3847 if (task.realActivity != null) { 3848 ActivityInfo ai = availActCache.get(task.realActivity); 3849 if (ai == null) { 3850 try { 3851 ai = pm.getActivityInfo(task.realActivity, 3852 PackageManager.GET_UNINSTALLED_PACKAGES 3853 | PackageManager.GET_DISABLED_COMPONENTS, user); 3854 } catch (RemoteException e) { 3855 // Will never happen. 3856 continue; 3857 } 3858 if (ai == null) { 3859 ai = dummyAct; 3860 } 3861 availActCache.put(task.realActivity, ai); 3862 } 3863 if (ai == dummyAct) { 3864 // This could be either because the activity no longer exists, or the 3865 // app is temporarily gone. For the former we want to remove the recents 3866 // entry; for the latter we want to mark it as unavailable. 3867 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3868 if (app == null) { 3869 try { 3870 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3871 PackageManager.GET_UNINSTALLED_PACKAGES 3872 | PackageManager.GET_DISABLED_COMPONENTS, user); 3873 } catch (RemoteException e) { 3874 // Will never happen. 3875 continue; 3876 } 3877 if (app == null) { 3878 app = dummyApp; 3879 } 3880 availAppCache.put(task.realActivity.getPackageName(), app); 3881 } 3882 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3883 // Doesn't exist any more! Good-bye. 3884 mRecentTasks.remove(i); 3885 task.removedFromRecents(mTaskPersister); 3886 i--; 3887 N--; 3888 Slog.w(TAG, "Removing no longer valid recent: " + task); 3889 continue; 3890 } else { 3891 // Otherwise just not available for now. 3892 if (task.isAvailable) { 3893 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3894 + task); 3895 } 3896 task.isAvailable = false; 3897 } 3898 } else { 3899 if (!ai.enabled || !ai.applicationInfo.enabled 3900 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3901 if (task.isAvailable) { 3902 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3903 + task + " (enabled=" + ai.enabled + "/" 3904 + ai.applicationInfo.enabled + " flags=" 3905 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3906 } 3907 task.isAvailable = false; 3908 } else { 3909 if (!task.isAvailable) { 3910 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3911 + task); 3912 } 3913 task.isAvailable = true; 3914 } 3915 } 3916 } 3917 } 3918 } 3919 3920 // Verify the affiliate chain for each task. 3921 for (int i = 0; i < N; ) { 3922 TaskRecord task = mRecentTasks.remove(i); 3923 if (mTmpRecents.contains(task)) { 3924 continue; 3925 } 3926 int affiliatedTaskId = task.mAffiliatedTaskId; 3927 while (true) { 3928 TaskRecord next = task.mNextAffiliate; 3929 if (next == null) { 3930 break; 3931 } 3932 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3933 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3934 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3935 task.setNextAffiliate(null); 3936 if (next.mPrevAffiliate == task) { 3937 next.setPrevAffiliate(null); 3938 } 3939 break; 3940 } 3941 if (next.mPrevAffiliate != task) { 3942 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3943 next.mPrevAffiliate + " task=" + task); 3944 next.setPrevAffiliate(null); 3945 task.setNextAffiliate(null); 3946 break; 3947 } 3948 if (!mRecentTasks.contains(next)) { 3949 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3950 task.setNextAffiliate(null); 3951 // We know that next.mPrevAffiliate is always task, from above, so clear 3952 // its previous affiliate. 3953 next.setPrevAffiliate(null); 3954 break; 3955 } 3956 task = next; 3957 } 3958 // task is now the end of the list 3959 do { 3960 mRecentTasks.remove(task); 3961 mRecentTasks.add(i++, task); 3962 mTmpRecents.add(task); 3963 task.inRecents = true; 3964 } while ((task = task.mPrevAffiliate) != null); 3965 } 3966 mTmpRecents.clear(); 3967 // mRecentTasks is now in sorted, affiliated order. 3968 } 3969 3970 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3971 int N = mRecentTasks.size(); 3972 TaskRecord top = task; 3973 int topIndex = taskIndex; 3974 while (top.mNextAffiliate != null && topIndex > 0) { 3975 top = top.mNextAffiliate; 3976 topIndex--; 3977 } 3978 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3979 + topIndex + " from intial " + taskIndex); 3980 // Find the end of the chain, doing a sanity check along the way. 3981 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3982 int endIndex = topIndex; 3983 TaskRecord prev = top; 3984 while (endIndex < N) { 3985 TaskRecord cur = mRecentTasks.get(endIndex); 3986 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3987 + endIndex + " " + cur); 3988 if (cur == top) { 3989 // Verify start of the chain. 3990 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3991 Slog.wtf(TAG, "Bad chain @" + endIndex 3992 + ": first task has next affiliate: " + prev); 3993 sane = false; 3994 break; 3995 } 3996 } else { 3997 // Verify middle of the chain's next points back to the one before. 3998 if (cur.mNextAffiliate != prev 3999 || cur.mNextAffiliateTaskId != prev.taskId) { 4000 Slog.wtf(TAG, "Bad chain @" + endIndex 4001 + ": middle task " + cur + " @" + endIndex 4002 + " has bad next affiliate " 4003 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4004 + ", expected " + prev); 4005 sane = false; 4006 break; 4007 } 4008 } 4009 if (cur.mPrevAffiliateTaskId == -1) { 4010 // Chain ends here. 4011 if (cur.mPrevAffiliate != null) { 4012 Slog.wtf(TAG, "Bad chain @" + endIndex 4013 + ": last task " + cur + " has previous affiliate " 4014 + cur.mPrevAffiliate); 4015 sane = false; 4016 } 4017 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4018 break; 4019 } else { 4020 // Verify middle of the chain's prev points to a valid item. 4021 if (cur.mPrevAffiliate == null) { 4022 Slog.wtf(TAG, "Bad chain @" + endIndex 4023 + ": task " + cur + " has previous affiliate " 4024 + cur.mPrevAffiliate + " but should be id " 4025 + cur.mPrevAffiliate); 4026 sane = false; 4027 break; 4028 } 4029 } 4030 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4031 Slog.wtf(TAG, "Bad chain @" + endIndex 4032 + ": task " + cur + " has affiliated id " 4033 + cur.mAffiliatedTaskId + " but should be " 4034 + task.mAffiliatedTaskId); 4035 sane = false; 4036 break; 4037 } 4038 prev = cur; 4039 endIndex++; 4040 if (endIndex >= N) { 4041 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4042 + ": last task " + prev); 4043 sane = false; 4044 break; 4045 } 4046 } 4047 if (sane) { 4048 if (endIndex < taskIndex) { 4049 Slog.wtf(TAG, "Bad chain @" + endIndex 4050 + ": did not extend to task " + task + " @" + taskIndex); 4051 sane = false; 4052 } 4053 } 4054 if (sane) { 4055 // All looks good, we can just move all of the affiliated tasks 4056 // to the top. 4057 for (int i=topIndex; i<=endIndex; i++) { 4058 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4059 + " from " + i + " to " + (i-topIndex)); 4060 TaskRecord cur = mRecentTasks.remove(i); 4061 mRecentTasks.add(i-topIndex, cur); 4062 } 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4064 + " to " + endIndex); 4065 return true; 4066 } 4067 4068 // Whoops, couldn't do it. 4069 return false; 4070 } 4071 4072 final void addRecentTaskLocked(TaskRecord task) { 4073 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4074 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4075 4076 int N = mRecentTasks.size(); 4077 // Quick case: check if the top-most recent task is the same. 4078 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4079 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4080 return; 4081 } 4082 // Another quick case: check if this is part of a set of affiliated 4083 // tasks that are at the top. 4084 if (isAffiliated && N > 0 && task.inRecents 4085 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4086 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4087 + " at top when adding " + task); 4088 return; 4089 } 4090 // Another quick case: never add voice sessions. 4091 if (task.voiceSession != null) { 4092 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4093 return; 4094 } 4095 4096 boolean needAffiliationFix = false; 4097 4098 // Slightly less quick case: the task is already in recents, so all we need 4099 // to do is move it. 4100 if (task.inRecents) { 4101 int taskIndex = mRecentTasks.indexOf(task); 4102 if (taskIndex >= 0) { 4103 if (!isAffiliated) { 4104 // Simple case: this is not an affiliated task, so we just move it to the front. 4105 mRecentTasks.remove(taskIndex); 4106 mRecentTasks.add(0, task); 4107 notifyTaskPersisterLocked(task, false); 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4109 + " from " + taskIndex); 4110 return; 4111 } else { 4112 // More complicated: need to keep all affiliated tasks together. 4113 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4114 // All went well. 4115 return; 4116 } 4117 4118 // Uh oh... something bad in the affiliation chain, try to rebuild 4119 // everything and then go through our general path of adding a new task. 4120 needAffiliationFix = true; 4121 } 4122 } else { 4123 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4124 needAffiliationFix = true; 4125 } 4126 } 4127 4128 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4129 trimRecentsForTask(task, true); 4130 4131 N = mRecentTasks.size(); 4132 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4133 final TaskRecord tr = mRecentTasks.remove(N - 1); 4134 tr.removedFromRecents(mTaskPersister); 4135 N--; 4136 } 4137 task.inRecents = true; 4138 if (!isAffiliated || needAffiliationFix) { 4139 // If this is a simple non-affiliated task, or we had some failure trying to 4140 // handle it as part of an affilated task, then just place it at the top. 4141 mRecentTasks.add(0, task); 4142 } else if (isAffiliated) { 4143 // If this is a new affiliated task, then move all of the affiliated tasks 4144 // to the front and insert this new one. 4145 TaskRecord other = task.mNextAffiliate; 4146 if (other == null) { 4147 other = task.mPrevAffiliate; 4148 } 4149 if (other != null) { 4150 int otherIndex = mRecentTasks.indexOf(other); 4151 if (otherIndex >= 0) { 4152 // Insert new task at appropriate location. 4153 int taskIndex; 4154 if (other == task.mNextAffiliate) { 4155 // We found the index of our next affiliation, which is who is 4156 // before us in the list, so add after that point. 4157 taskIndex = otherIndex+1; 4158 } else { 4159 // We found the index of our previous affiliation, which is who is 4160 // after us in the list, so add at their position. 4161 taskIndex = otherIndex; 4162 } 4163 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4164 + taskIndex + ": " + task); 4165 mRecentTasks.add(taskIndex, task); 4166 4167 // Now move everything to the front. 4168 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4169 // All went well. 4170 return; 4171 } 4172 4173 // Uh oh... something bad in the affiliation chain, try to rebuild 4174 // everything and then go through our general path of adding a new task. 4175 needAffiliationFix = true; 4176 } else { 4177 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4178 + other); 4179 needAffiliationFix = true; 4180 } 4181 } else { 4182 if (DEBUG_RECENTS) Slog.d(TAG, 4183 "addRecent: adding affiliated task without next/prev:" + task); 4184 needAffiliationFix = true; 4185 } 4186 } 4187 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4188 4189 if (needAffiliationFix) { 4190 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4191 cleanupRecentTasksLocked(task.userId); 4192 } 4193 } 4194 4195 /** 4196 * If needed, remove oldest existing entries in recents that are for the same kind 4197 * of task as the given one. 4198 */ 4199 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4200 int N = mRecentTasks.size(); 4201 final Intent intent = task.intent; 4202 final boolean document = intent != null && intent.isDocument(); 4203 4204 int maxRecents = task.maxRecents - 1; 4205 for (int i=0; i<N; i++) { 4206 final TaskRecord tr = mRecentTasks.get(i); 4207 if (task != tr) { 4208 if (task.userId != tr.userId) { 4209 continue; 4210 } 4211 if (i > MAX_RECENT_BITMAPS) { 4212 tr.freeLastThumbnail(); 4213 } 4214 final Intent trIntent = tr.intent; 4215 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4216 (intent == null || !intent.filterEquals(trIntent))) { 4217 continue; 4218 } 4219 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4220 if (document && trIsDocument) { 4221 // These are the same document activity (not necessarily the same doc). 4222 if (maxRecents > 0) { 4223 --maxRecents; 4224 continue; 4225 } 4226 // Hit the maximum number of documents for this task. Fall through 4227 // and remove this document from recents. 4228 } else if (document || trIsDocument) { 4229 // Only one of these is a document. Not the droid we're looking for. 4230 continue; 4231 } 4232 } 4233 4234 if (!doTrim) { 4235 // If the caller is not actually asking for a trim, just tell them we reached 4236 // a point where the trim would happen. 4237 return i; 4238 } 4239 4240 // Either task and tr are the same or, their affinities match or their intents match 4241 // and neither of them is a document, or they are documents using the same activity 4242 // and their maxRecents has been reached. 4243 tr.disposeThumbnail(); 4244 mRecentTasks.remove(i); 4245 if (task != tr) { 4246 tr.removedFromRecents(mTaskPersister); 4247 } 4248 i--; 4249 N--; 4250 if (task.intent == null) { 4251 // If the new recent task we are adding is not fully 4252 // specified, then replace it with the existing recent task. 4253 task = tr; 4254 } 4255 notifyTaskPersisterLocked(tr, false); 4256 } 4257 4258 return -1; 4259 } 4260 4261 @Override 4262 public void reportActivityFullyDrawn(IBinder token) { 4263 synchronized (this) { 4264 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4265 if (r == null) { 4266 return; 4267 } 4268 r.reportFullyDrawnLocked(); 4269 } 4270 } 4271 4272 @Override 4273 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4274 synchronized (this) { 4275 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4276 if (r == null) { 4277 return; 4278 } 4279 final long origId = Binder.clearCallingIdentity(); 4280 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4281 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4282 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4283 if (config != null) { 4284 r.frozenBeforeDestroy = true; 4285 if (!updateConfigurationLocked(config, r, false, false)) { 4286 mStackSupervisor.resumeTopActivitiesLocked(); 4287 } 4288 } 4289 Binder.restoreCallingIdentity(origId); 4290 } 4291 } 4292 4293 @Override 4294 public int getRequestedOrientation(IBinder token) { 4295 synchronized (this) { 4296 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4297 if (r == null) { 4298 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4299 } 4300 return mWindowManager.getAppOrientation(r.appToken); 4301 } 4302 } 4303 4304 /** 4305 * This is the internal entry point for handling Activity.finish(). 4306 * 4307 * @param token The Binder token referencing the Activity we want to finish. 4308 * @param resultCode Result code, if any, from this Activity. 4309 * @param resultData Result data (Intent), if any, from this Activity. 4310 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4311 * the root Activity in the task. 4312 * 4313 * @return Returns true if the activity successfully finished, or false if it is still running. 4314 */ 4315 @Override 4316 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4317 boolean finishTask) { 4318 // Refuse possible leaked file descriptors 4319 if (resultData != null && resultData.hasFileDescriptors() == true) { 4320 throw new IllegalArgumentException("File descriptors passed in Intent"); 4321 } 4322 4323 synchronized(this) { 4324 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4325 if (r == null) { 4326 return true; 4327 } 4328 // Keep track of the root activity of the task before we finish it 4329 TaskRecord tr = r.task; 4330 ActivityRecord rootR = tr.getRootActivity(); 4331 // Do not allow task to finish in Lock Task mode. 4332 if (tr == mStackSupervisor.mLockTaskModeTask) { 4333 if (rootR == r) { 4334 mStackSupervisor.showLockTaskToast(); 4335 return false; 4336 } 4337 } 4338 if (mController != null) { 4339 // Find the first activity that is not finishing. 4340 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4341 if (next != null) { 4342 // ask watcher if this is allowed 4343 boolean resumeOK = true; 4344 try { 4345 resumeOK = mController.activityResuming(next.packageName); 4346 } catch (RemoteException e) { 4347 mController = null; 4348 Watchdog.getInstance().setActivityController(null); 4349 } 4350 4351 if (!resumeOK) { 4352 return false; 4353 } 4354 } 4355 } 4356 final long origId = Binder.clearCallingIdentity(); 4357 try { 4358 boolean res; 4359 if (finishTask && r == rootR) { 4360 // If requested, remove the task that is associated to this activity only if it 4361 // was the root activity in the task. The result code and data is ignored because 4362 // we don't support returning them across task boundaries. 4363 res = removeTaskByIdLocked(tr.taskId, 0); 4364 } else { 4365 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4366 resultData, "app-request", true); 4367 } 4368 return res; 4369 } finally { 4370 Binder.restoreCallingIdentity(origId); 4371 } 4372 } 4373 } 4374 4375 @Override 4376 public final void finishHeavyWeightApp() { 4377 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4378 != PackageManager.PERMISSION_GRANTED) { 4379 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4380 + Binder.getCallingPid() 4381 + ", uid=" + Binder.getCallingUid() 4382 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4383 Slog.w(TAG, msg); 4384 throw new SecurityException(msg); 4385 } 4386 4387 synchronized(this) { 4388 if (mHeavyWeightProcess == null) { 4389 return; 4390 } 4391 4392 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4393 mHeavyWeightProcess.activities); 4394 for (int i=0; i<activities.size(); i++) { 4395 ActivityRecord r = activities.get(i); 4396 if (!r.finishing) { 4397 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4398 null, "finish-heavy", true); 4399 } 4400 } 4401 4402 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4403 mHeavyWeightProcess.userId, 0)); 4404 mHeavyWeightProcess = null; 4405 } 4406 } 4407 4408 @Override 4409 public void crashApplication(int uid, int initialPid, String packageName, 4410 String message) { 4411 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4412 != PackageManager.PERMISSION_GRANTED) { 4413 String msg = "Permission Denial: crashApplication() from pid=" 4414 + Binder.getCallingPid() 4415 + ", uid=" + Binder.getCallingUid() 4416 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4417 Slog.w(TAG, msg); 4418 throw new SecurityException(msg); 4419 } 4420 4421 synchronized(this) { 4422 ProcessRecord proc = null; 4423 4424 // Figure out which process to kill. We don't trust that initialPid 4425 // still has any relation to current pids, so must scan through the 4426 // list. 4427 synchronized (mPidsSelfLocked) { 4428 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4429 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4430 if (p.uid != uid) { 4431 continue; 4432 } 4433 if (p.pid == initialPid) { 4434 proc = p; 4435 break; 4436 } 4437 if (p.pkgList.containsKey(packageName)) { 4438 proc = p; 4439 } 4440 } 4441 } 4442 4443 if (proc == null) { 4444 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4445 + " initialPid=" + initialPid 4446 + " packageName=" + packageName); 4447 return; 4448 } 4449 4450 if (proc.thread != null) { 4451 if (proc.pid == Process.myPid()) { 4452 Log.w(TAG, "crashApplication: trying to crash self!"); 4453 return; 4454 } 4455 long ident = Binder.clearCallingIdentity(); 4456 try { 4457 proc.thread.scheduleCrash(message); 4458 } catch (RemoteException e) { 4459 } 4460 Binder.restoreCallingIdentity(ident); 4461 } 4462 } 4463 } 4464 4465 @Override 4466 public final void finishSubActivity(IBinder token, String resultWho, 4467 int requestCode) { 4468 synchronized(this) { 4469 final long origId = Binder.clearCallingIdentity(); 4470 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4471 if (r != null) { 4472 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4473 } 4474 Binder.restoreCallingIdentity(origId); 4475 } 4476 } 4477 4478 @Override 4479 public boolean finishActivityAffinity(IBinder token) { 4480 synchronized(this) { 4481 final long origId = Binder.clearCallingIdentity(); 4482 try { 4483 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4484 4485 ActivityRecord rootR = r.task.getRootActivity(); 4486 // Do not allow task to finish in Lock Task mode. 4487 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4488 if (rootR == r) { 4489 mStackSupervisor.showLockTaskToast(); 4490 return false; 4491 } 4492 } 4493 boolean res = false; 4494 if (r != null) { 4495 res = r.task.stack.finishActivityAffinityLocked(r); 4496 } 4497 return res; 4498 } finally { 4499 Binder.restoreCallingIdentity(origId); 4500 } 4501 } 4502 } 4503 4504 @Override 4505 public void finishVoiceTask(IVoiceInteractionSession session) { 4506 synchronized(this) { 4507 final long origId = Binder.clearCallingIdentity(); 4508 try { 4509 mStackSupervisor.finishVoiceTask(session); 4510 } finally { 4511 Binder.restoreCallingIdentity(origId); 4512 } 4513 } 4514 4515 } 4516 4517 @Override 4518 public boolean releaseActivityInstance(IBinder token) { 4519 synchronized(this) { 4520 final long origId = Binder.clearCallingIdentity(); 4521 try { 4522 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4523 if (r.task == null || r.task.stack == null) { 4524 return false; 4525 } 4526 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4527 } finally { 4528 Binder.restoreCallingIdentity(origId); 4529 } 4530 } 4531 } 4532 4533 @Override 4534 public void releaseSomeActivities(IApplicationThread appInt) { 4535 synchronized(this) { 4536 final long origId = Binder.clearCallingIdentity(); 4537 try { 4538 ProcessRecord app = getRecordForAppLocked(appInt); 4539 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4540 } finally { 4541 Binder.restoreCallingIdentity(origId); 4542 } 4543 } 4544 } 4545 4546 @Override 4547 public boolean willActivityBeVisible(IBinder token) { 4548 synchronized(this) { 4549 ActivityStack stack = ActivityRecord.getStackLocked(token); 4550 if (stack != null) { 4551 return stack.willActivityBeVisibleLocked(token); 4552 } 4553 return false; 4554 } 4555 } 4556 4557 @Override 4558 public void overridePendingTransition(IBinder token, String packageName, 4559 int enterAnim, int exitAnim) { 4560 synchronized(this) { 4561 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4562 if (self == null) { 4563 return; 4564 } 4565 4566 final long origId = Binder.clearCallingIdentity(); 4567 4568 if (self.state == ActivityState.RESUMED 4569 || self.state == ActivityState.PAUSING) { 4570 mWindowManager.overridePendingAppTransition(packageName, 4571 enterAnim, exitAnim, null); 4572 } 4573 4574 Binder.restoreCallingIdentity(origId); 4575 } 4576 } 4577 4578 /** 4579 * Main function for removing an existing process from the activity manager 4580 * as a result of that process going away. Clears out all connections 4581 * to the process. 4582 */ 4583 private final void handleAppDiedLocked(ProcessRecord app, 4584 boolean restarting, boolean allowRestart) { 4585 int pid = app.pid; 4586 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4587 if (!restarting) { 4588 removeLruProcessLocked(app); 4589 if (pid > 0) { 4590 ProcessList.remove(pid); 4591 } 4592 } 4593 4594 if (mProfileProc == app) { 4595 clearProfilerLocked(); 4596 } 4597 4598 // Remove this application's activities from active lists. 4599 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4600 4601 app.activities.clear(); 4602 4603 if (app.instrumentationClass != null) { 4604 Slog.w(TAG, "Crash of app " + app.processName 4605 + " running instrumentation " + app.instrumentationClass); 4606 Bundle info = new Bundle(); 4607 info.putString("shortMsg", "Process crashed."); 4608 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4609 } 4610 4611 if (!restarting) { 4612 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4613 // If there was nothing to resume, and we are not already 4614 // restarting this process, but there is a visible activity that 4615 // is hosted by the process... then make sure all visible 4616 // activities are running, taking care of restarting this 4617 // process. 4618 if (hasVisibleActivities) { 4619 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4620 } 4621 } 4622 } 4623 } 4624 4625 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4626 IBinder threadBinder = thread.asBinder(); 4627 // Find the application record. 4628 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4629 ProcessRecord rec = mLruProcesses.get(i); 4630 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4631 return i; 4632 } 4633 } 4634 return -1; 4635 } 4636 4637 final ProcessRecord getRecordForAppLocked( 4638 IApplicationThread thread) { 4639 if (thread == null) { 4640 return null; 4641 } 4642 4643 int appIndex = getLRURecordIndexForAppLocked(thread); 4644 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4645 } 4646 4647 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4648 // If there are no longer any background processes running, 4649 // and the app that died was not running instrumentation, 4650 // then tell everyone we are now low on memory. 4651 boolean haveBg = false; 4652 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4653 ProcessRecord rec = mLruProcesses.get(i); 4654 if (rec.thread != null 4655 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4656 haveBg = true; 4657 break; 4658 } 4659 } 4660 4661 if (!haveBg) { 4662 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4663 if (doReport) { 4664 long now = SystemClock.uptimeMillis(); 4665 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4666 doReport = false; 4667 } else { 4668 mLastMemUsageReportTime = now; 4669 } 4670 } 4671 final ArrayList<ProcessMemInfo> memInfos 4672 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4673 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4674 long now = SystemClock.uptimeMillis(); 4675 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4676 ProcessRecord rec = mLruProcesses.get(i); 4677 if (rec == dyingProc || rec.thread == null) { 4678 continue; 4679 } 4680 if (doReport) { 4681 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4682 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4683 } 4684 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4685 // The low memory report is overriding any current 4686 // state for a GC request. Make sure to do 4687 // heavy/important/visible/foreground processes first. 4688 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4689 rec.lastRequestedGc = 0; 4690 } else { 4691 rec.lastRequestedGc = rec.lastLowMemory; 4692 } 4693 rec.reportLowMemory = true; 4694 rec.lastLowMemory = now; 4695 mProcessesToGc.remove(rec); 4696 addProcessToGcListLocked(rec); 4697 } 4698 } 4699 if (doReport) { 4700 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4701 mHandler.sendMessage(msg); 4702 } 4703 scheduleAppGcsLocked(); 4704 } 4705 } 4706 4707 final void appDiedLocked(ProcessRecord app) { 4708 appDiedLocked(app, app.pid, app.thread); 4709 } 4710 4711 final void appDiedLocked(ProcessRecord app, int pid, 4712 IApplicationThread thread) { 4713 4714 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4715 synchronized (stats) { 4716 stats.noteProcessDiedLocked(app.info.uid, pid); 4717 } 4718 4719 Process.killProcessGroup(app.info.uid, pid); 4720 4721 // Clean up already done if the process has been re-started. 4722 if (app.pid == pid && app.thread != null && 4723 app.thread.asBinder() == thread.asBinder()) { 4724 boolean doLowMem = app.instrumentationClass == null; 4725 boolean doOomAdj = doLowMem; 4726 if (!app.killedByAm) { 4727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4728 + ") has died."); 4729 mAllowLowerMemLevel = true; 4730 } else { 4731 // Note that we always want to do oom adj to update our state with the 4732 // new number of procs. 4733 mAllowLowerMemLevel = false; 4734 doLowMem = false; 4735 } 4736 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4737 if (DEBUG_CLEANUP) Slog.v( 4738 TAG, "Dying app: " + app + ", pid: " + pid 4739 + ", thread: " + thread.asBinder()); 4740 handleAppDiedLocked(app, false, true); 4741 4742 if (doOomAdj) { 4743 updateOomAdjLocked(); 4744 } 4745 if (doLowMem) { 4746 doLowMemReportIfNeededLocked(app); 4747 } 4748 } else if (app.pid != pid) { 4749 // A new process has already been started. 4750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4751 + ") has died and restarted (pid " + app.pid + ")."); 4752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4753 } else if (DEBUG_PROCESSES) { 4754 Slog.d(TAG, "Received spurious death notification for thread " 4755 + thread.asBinder()); 4756 } 4757 } 4758 4759 /** 4760 * If a stack trace dump file is configured, dump process stack traces. 4761 * @param clearTraces causes the dump file to be erased prior to the new 4762 * traces being written, if true; when false, the new traces will be 4763 * appended to any existing file content. 4764 * @param firstPids of dalvik VM processes to dump stack traces for first 4765 * @param lastPids of dalvik VM processes to dump stack traces for last 4766 * @param nativeProcs optional list of native process names to dump stack crawls 4767 * @return file containing stack traces, or null if no dump file is configured 4768 */ 4769 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4770 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4771 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4772 if (tracesPath == null || tracesPath.length() == 0) { 4773 return null; 4774 } 4775 4776 File tracesFile = new File(tracesPath); 4777 try { 4778 File tracesDir = tracesFile.getParentFile(); 4779 if (!tracesDir.exists()) { 4780 tracesFile.mkdirs(); 4781 if (!SELinux.restorecon(tracesDir)) { 4782 return null; 4783 } 4784 } 4785 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4786 4787 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4788 tracesFile.createNewFile(); 4789 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4790 } catch (IOException e) { 4791 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4792 return null; 4793 } 4794 4795 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4796 return tracesFile; 4797 } 4798 4799 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4801 // Use a FileObserver to detect when traces finish writing. 4802 // The order of traces is considered important to maintain for legibility. 4803 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4804 @Override 4805 public synchronized void onEvent(int event, String path) { notify(); } 4806 }; 4807 4808 try { 4809 observer.startWatching(); 4810 4811 // First collect all of the stacks of the most important pids. 4812 if (firstPids != null) { 4813 try { 4814 int num = firstPids.size(); 4815 for (int i = 0; i < num; i++) { 4816 synchronized (observer) { 4817 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4818 observer.wait(200); // Wait for write-close, give up after 200msec 4819 } 4820 } 4821 } catch (InterruptedException e) { 4822 Log.wtf(TAG, e); 4823 } 4824 } 4825 4826 // Next collect the stacks of the native pids 4827 if (nativeProcs != null) { 4828 int[] pids = Process.getPidsForCommands(nativeProcs); 4829 if (pids != null) { 4830 for (int pid : pids) { 4831 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4832 } 4833 } 4834 } 4835 4836 // Lastly, measure CPU usage. 4837 if (processCpuTracker != null) { 4838 processCpuTracker.init(); 4839 System.gc(); 4840 processCpuTracker.update(); 4841 try { 4842 synchronized (processCpuTracker) { 4843 processCpuTracker.wait(500); // measure over 1/2 second. 4844 } 4845 } catch (InterruptedException e) { 4846 } 4847 processCpuTracker.update(); 4848 4849 // We'll take the stack crawls of just the top apps using CPU. 4850 final int N = processCpuTracker.countWorkingStats(); 4851 int numProcs = 0; 4852 for (int i=0; i<N && numProcs<5; i++) { 4853 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4854 if (lastPids.indexOfKey(stats.pid) >= 0) { 4855 numProcs++; 4856 try { 4857 synchronized (observer) { 4858 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4859 observer.wait(200); // Wait for write-close, give up after 200msec 4860 } 4861 } catch (InterruptedException e) { 4862 Log.wtf(TAG, e); 4863 } 4864 4865 } 4866 } 4867 } 4868 } finally { 4869 observer.stopWatching(); 4870 } 4871 } 4872 4873 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4874 if (true || IS_USER_BUILD) { 4875 return; 4876 } 4877 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4878 if (tracesPath == null || tracesPath.length() == 0) { 4879 return; 4880 } 4881 4882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4883 StrictMode.allowThreadDiskWrites(); 4884 try { 4885 final File tracesFile = new File(tracesPath); 4886 final File tracesDir = tracesFile.getParentFile(); 4887 final File tracesTmp = new File(tracesDir, "__tmp__"); 4888 try { 4889 if (!tracesDir.exists()) { 4890 tracesFile.mkdirs(); 4891 if (!SELinux.restorecon(tracesDir.getPath())) { 4892 return; 4893 } 4894 } 4895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4896 4897 if (tracesFile.exists()) { 4898 tracesTmp.delete(); 4899 tracesFile.renameTo(tracesTmp); 4900 } 4901 StringBuilder sb = new StringBuilder(); 4902 Time tobj = new Time(); 4903 tobj.set(System.currentTimeMillis()); 4904 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4905 sb.append(": "); 4906 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4907 sb.append(" since "); 4908 sb.append(msg); 4909 FileOutputStream fos = new FileOutputStream(tracesFile); 4910 fos.write(sb.toString().getBytes()); 4911 if (app == null) { 4912 fos.write("\n*** No application process!".getBytes()); 4913 } 4914 fos.close(); 4915 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4916 } catch (IOException e) { 4917 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4918 return; 4919 } 4920 4921 if (app != null) { 4922 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4923 firstPids.add(app.pid); 4924 dumpStackTraces(tracesPath, firstPids, null, null, null); 4925 } 4926 4927 File lastTracesFile = null; 4928 File curTracesFile = null; 4929 for (int i=9; i>=0; i--) { 4930 String name = String.format(Locale.US, "slow%02d.txt", i); 4931 curTracesFile = new File(tracesDir, name); 4932 if (curTracesFile.exists()) { 4933 if (lastTracesFile != null) { 4934 curTracesFile.renameTo(lastTracesFile); 4935 } else { 4936 curTracesFile.delete(); 4937 } 4938 } 4939 lastTracesFile = curTracesFile; 4940 } 4941 tracesFile.renameTo(curTracesFile); 4942 if (tracesTmp.exists()) { 4943 tracesTmp.renameTo(tracesFile); 4944 } 4945 } finally { 4946 StrictMode.setThreadPolicy(oldPolicy); 4947 } 4948 } 4949 4950 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4951 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4952 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4953 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4954 4955 if (mController != null) { 4956 try { 4957 // 0 == continue, -1 = kill process immediately 4958 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4959 if (res < 0 && app.pid != MY_PID) { 4960 app.kill("anr", true); 4961 } 4962 } catch (RemoteException e) { 4963 mController = null; 4964 Watchdog.getInstance().setActivityController(null); 4965 } 4966 } 4967 4968 long anrTime = SystemClock.uptimeMillis(); 4969 if (MONITOR_CPU_USAGE) { 4970 updateCpuStatsNow(); 4971 } 4972 4973 synchronized (this) { 4974 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4975 if (mShuttingDown) { 4976 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4977 return; 4978 } else if (app.notResponding) { 4979 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4980 return; 4981 } else if (app.crashing) { 4982 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4983 return; 4984 } 4985 4986 // In case we come through here for the same app before completing 4987 // this one, mark as anring now so we will bail out. 4988 app.notResponding = true; 4989 4990 // Log the ANR to the event log. 4991 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4992 app.processName, app.info.flags, annotation); 4993 4994 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4995 firstPids.add(app.pid); 4996 4997 int parentPid = app.pid; 4998 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4999 if (parentPid != app.pid) firstPids.add(parentPid); 5000 5001 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5002 5003 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5004 ProcessRecord r = mLruProcesses.get(i); 5005 if (r != null && r.thread != null) { 5006 int pid = r.pid; 5007 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5008 if (r.persistent) { 5009 firstPids.add(pid); 5010 } else { 5011 lastPids.put(pid, Boolean.TRUE); 5012 } 5013 } 5014 } 5015 } 5016 } 5017 5018 // Log the ANR to the main log. 5019 StringBuilder info = new StringBuilder(); 5020 info.setLength(0); 5021 info.append("ANR in ").append(app.processName); 5022 if (activity != null && activity.shortComponentName != null) { 5023 info.append(" (").append(activity.shortComponentName).append(")"); 5024 } 5025 info.append("\n"); 5026 info.append("PID: ").append(app.pid).append("\n"); 5027 if (annotation != null) { 5028 info.append("Reason: ").append(annotation).append("\n"); 5029 } 5030 if (parent != null && parent != activity) { 5031 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5032 } 5033 5034 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5035 5036 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5037 NATIVE_STACKS_OF_INTEREST); 5038 5039 String cpuInfo = null; 5040 if (MONITOR_CPU_USAGE) { 5041 updateCpuStatsNow(); 5042 synchronized (mProcessCpuThread) { 5043 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5044 } 5045 info.append(processCpuTracker.printCurrentLoad()); 5046 info.append(cpuInfo); 5047 } 5048 5049 info.append(processCpuTracker.printCurrentState(anrTime)); 5050 5051 Slog.e(TAG, info.toString()); 5052 if (tracesFile == null) { 5053 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5054 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5055 } 5056 5057 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5058 cpuInfo, tracesFile, null); 5059 5060 if (mController != null) { 5061 try { 5062 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5063 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5064 if (res != 0) { 5065 if (res < 0 && app.pid != MY_PID) { 5066 app.kill("anr", true); 5067 } else { 5068 synchronized (this) { 5069 mServices.scheduleServiceTimeoutLocked(app); 5070 } 5071 } 5072 return; 5073 } 5074 } catch (RemoteException e) { 5075 mController = null; 5076 Watchdog.getInstance().setActivityController(null); 5077 } 5078 } 5079 5080 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5081 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5082 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5083 5084 synchronized (this) { 5085 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5086 app.kill("bg anr", true); 5087 return; 5088 } 5089 5090 // Set the app's notResponding state, and look up the errorReportReceiver 5091 makeAppNotRespondingLocked(app, 5092 activity != null ? activity.shortComponentName : null, 5093 annotation != null ? "ANR " + annotation : "ANR", 5094 info.toString()); 5095 5096 // Bring up the infamous App Not Responding dialog 5097 Message msg = Message.obtain(); 5098 HashMap<String, Object> map = new HashMap<String, Object>(); 5099 msg.what = SHOW_NOT_RESPONDING_MSG; 5100 msg.obj = map; 5101 msg.arg1 = aboveSystem ? 1 : 0; 5102 map.put("app", app); 5103 if (activity != null) { 5104 map.put("activity", activity); 5105 } 5106 5107 mHandler.sendMessage(msg); 5108 } 5109 } 5110 5111 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5112 if (!mLaunchWarningShown) { 5113 mLaunchWarningShown = true; 5114 mHandler.post(new Runnable() { 5115 @Override 5116 public void run() { 5117 synchronized (ActivityManagerService.this) { 5118 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5119 d.show(); 5120 mHandler.postDelayed(new Runnable() { 5121 @Override 5122 public void run() { 5123 synchronized (ActivityManagerService.this) { 5124 d.dismiss(); 5125 mLaunchWarningShown = false; 5126 } 5127 } 5128 }, 4000); 5129 } 5130 } 5131 }); 5132 } 5133 } 5134 5135 @Override 5136 public boolean clearApplicationUserData(final String packageName, 5137 final IPackageDataObserver observer, int userId) { 5138 enforceNotIsolatedCaller("clearApplicationUserData"); 5139 int uid = Binder.getCallingUid(); 5140 int pid = Binder.getCallingPid(); 5141 userId = handleIncomingUser(pid, uid, 5142 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5143 long callingId = Binder.clearCallingIdentity(); 5144 try { 5145 IPackageManager pm = AppGlobals.getPackageManager(); 5146 int pkgUid = -1; 5147 synchronized(this) { 5148 try { 5149 pkgUid = pm.getPackageUid(packageName, userId); 5150 } catch (RemoteException e) { 5151 } 5152 if (pkgUid == -1) { 5153 Slog.w(TAG, "Invalid packageName: " + packageName); 5154 if (observer != null) { 5155 try { 5156 observer.onRemoveCompleted(packageName, false); 5157 } catch (RemoteException e) { 5158 Slog.i(TAG, "Observer no longer exists."); 5159 } 5160 } 5161 return false; 5162 } 5163 if (uid == pkgUid || checkComponentPermission( 5164 android.Manifest.permission.CLEAR_APP_USER_DATA, 5165 pid, uid, -1, true) 5166 == PackageManager.PERMISSION_GRANTED) { 5167 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5168 } else { 5169 throw new SecurityException("PID " + pid + " does not have permission " 5170 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5171 + " of package " + packageName); 5172 } 5173 5174 // Remove all tasks match the cleared application package and user 5175 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5176 final TaskRecord tr = mRecentTasks.get(i); 5177 final String taskPackageName = 5178 tr.getBaseIntent().getComponent().getPackageName(); 5179 if (tr.userId != userId) continue; 5180 if (!taskPackageName.equals(packageName)) continue; 5181 removeTaskByIdLocked(tr.taskId, 0); 5182 } 5183 } 5184 5185 try { 5186 // Clear application user data 5187 pm.clearApplicationUserData(packageName, observer, userId); 5188 5189 synchronized(this) { 5190 // Remove all permissions granted from/to this package 5191 removeUriPermissionsForPackageLocked(packageName, userId, true); 5192 } 5193 5194 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5195 Uri.fromParts("package", packageName, null)); 5196 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5197 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5198 null, null, 0, null, null, null, false, false, userId); 5199 } catch (RemoteException e) { 5200 } 5201 } finally { 5202 Binder.restoreCallingIdentity(callingId); 5203 } 5204 return true; 5205 } 5206 5207 @Override 5208 public void killBackgroundProcesses(final String packageName, int userId) { 5209 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5210 != PackageManager.PERMISSION_GRANTED && 5211 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5212 != PackageManager.PERMISSION_GRANTED) { 5213 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5214 + Binder.getCallingPid() 5215 + ", uid=" + Binder.getCallingUid() 5216 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5217 Slog.w(TAG, msg); 5218 throw new SecurityException(msg); 5219 } 5220 5221 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5222 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5223 long callingId = Binder.clearCallingIdentity(); 5224 try { 5225 IPackageManager pm = AppGlobals.getPackageManager(); 5226 synchronized(this) { 5227 int appId = -1; 5228 try { 5229 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5230 } catch (RemoteException e) { 5231 } 5232 if (appId == -1) { 5233 Slog.w(TAG, "Invalid packageName: " + packageName); 5234 return; 5235 } 5236 killPackageProcessesLocked(packageName, appId, userId, 5237 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5238 } 5239 } finally { 5240 Binder.restoreCallingIdentity(callingId); 5241 } 5242 } 5243 5244 @Override 5245 public void killAllBackgroundProcesses() { 5246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5247 != PackageManager.PERMISSION_GRANTED) { 5248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5249 + Binder.getCallingPid() 5250 + ", uid=" + Binder.getCallingUid() 5251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5252 Slog.w(TAG, msg); 5253 throw new SecurityException(msg); 5254 } 5255 5256 long callingId = Binder.clearCallingIdentity(); 5257 try { 5258 synchronized(this) { 5259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5260 final int NP = mProcessNames.getMap().size(); 5261 for (int ip=0; ip<NP; ip++) { 5262 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5263 final int NA = apps.size(); 5264 for (int ia=0; ia<NA; ia++) { 5265 ProcessRecord app = apps.valueAt(ia); 5266 if (app.persistent) { 5267 // we don't kill persistent processes 5268 continue; 5269 } 5270 if (app.removed) { 5271 procs.add(app); 5272 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5273 app.removed = true; 5274 procs.add(app); 5275 } 5276 } 5277 } 5278 5279 int N = procs.size(); 5280 for (int i=0; i<N; i++) { 5281 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5282 } 5283 mAllowLowerMemLevel = true; 5284 updateOomAdjLocked(); 5285 doLowMemReportIfNeededLocked(null); 5286 } 5287 } finally { 5288 Binder.restoreCallingIdentity(callingId); 5289 } 5290 } 5291 5292 @Override 5293 public void forceStopPackage(final String packageName, int userId) { 5294 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5295 != PackageManager.PERMISSION_GRANTED) { 5296 String msg = "Permission Denial: forceStopPackage() from pid=" 5297 + Binder.getCallingPid() 5298 + ", uid=" + Binder.getCallingUid() 5299 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5300 Slog.w(TAG, msg); 5301 throw new SecurityException(msg); 5302 } 5303 final int callingPid = Binder.getCallingPid(); 5304 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5305 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5306 long callingId = Binder.clearCallingIdentity(); 5307 try { 5308 IPackageManager pm = AppGlobals.getPackageManager(); 5309 synchronized(this) { 5310 int[] users = userId == UserHandle.USER_ALL 5311 ? getUsersLocked() : new int[] { userId }; 5312 for (int user : users) { 5313 int pkgUid = -1; 5314 try { 5315 pkgUid = pm.getPackageUid(packageName, user); 5316 } catch (RemoteException e) { 5317 } 5318 if (pkgUid == -1) { 5319 Slog.w(TAG, "Invalid packageName: " + packageName); 5320 continue; 5321 } 5322 try { 5323 pm.setPackageStoppedState(packageName, true, user); 5324 } catch (RemoteException e) { 5325 } catch (IllegalArgumentException e) { 5326 Slog.w(TAG, "Failed trying to unstop package " 5327 + packageName + ": " + e); 5328 } 5329 if (isUserRunningLocked(user, false)) { 5330 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5331 } 5332 } 5333 } 5334 } finally { 5335 Binder.restoreCallingIdentity(callingId); 5336 } 5337 } 5338 5339 @Override 5340 public void addPackageDependency(String packageName) { 5341 synchronized (this) { 5342 int callingPid = Binder.getCallingPid(); 5343 if (callingPid == Process.myPid()) { 5344 // Yeah, um, no. 5345 Slog.w(TAG, "Can't addPackageDependency on system process"); 5346 return; 5347 } 5348 ProcessRecord proc; 5349 synchronized (mPidsSelfLocked) { 5350 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5351 } 5352 if (proc != null) { 5353 if (proc.pkgDeps == null) { 5354 proc.pkgDeps = new ArraySet<String>(1); 5355 } 5356 proc.pkgDeps.add(packageName); 5357 } 5358 } 5359 } 5360 5361 /* 5362 * The pkg name and app id have to be specified. 5363 */ 5364 @Override 5365 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5366 if (pkg == null) { 5367 return; 5368 } 5369 // Make sure the uid is valid. 5370 if (appid < 0) { 5371 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5372 return; 5373 } 5374 int callerUid = Binder.getCallingUid(); 5375 // Only the system server can kill an application 5376 if (callerUid == Process.SYSTEM_UID) { 5377 // Post an aysnc message to kill the application 5378 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5379 msg.arg1 = appid; 5380 msg.arg2 = 0; 5381 Bundle bundle = new Bundle(); 5382 bundle.putString("pkg", pkg); 5383 bundle.putString("reason", reason); 5384 msg.obj = bundle; 5385 mHandler.sendMessage(msg); 5386 } else { 5387 throw new SecurityException(callerUid + " cannot kill pkg: " + 5388 pkg); 5389 } 5390 } 5391 5392 @Override 5393 public void closeSystemDialogs(String reason) { 5394 enforceNotIsolatedCaller("closeSystemDialogs"); 5395 5396 final int pid = Binder.getCallingPid(); 5397 final int uid = Binder.getCallingUid(); 5398 final long origId = Binder.clearCallingIdentity(); 5399 try { 5400 synchronized (this) { 5401 // Only allow this from foreground processes, so that background 5402 // applications can't abuse it to prevent system UI from being shown. 5403 if (uid >= Process.FIRST_APPLICATION_UID) { 5404 ProcessRecord proc; 5405 synchronized (mPidsSelfLocked) { 5406 proc = mPidsSelfLocked.get(pid); 5407 } 5408 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5409 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5410 + " from background process " + proc); 5411 return; 5412 } 5413 } 5414 closeSystemDialogsLocked(reason); 5415 } 5416 } finally { 5417 Binder.restoreCallingIdentity(origId); 5418 } 5419 } 5420 5421 void closeSystemDialogsLocked(String reason) { 5422 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5423 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5424 | Intent.FLAG_RECEIVER_FOREGROUND); 5425 if (reason != null) { 5426 intent.putExtra("reason", reason); 5427 } 5428 mWindowManager.closeSystemDialogs(reason); 5429 5430 mStackSupervisor.closeSystemDialogsLocked(); 5431 5432 broadcastIntentLocked(null, null, intent, null, 5433 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5434 Process.SYSTEM_UID, UserHandle.USER_ALL); 5435 } 5436 5437 @Override 5438 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5439 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5440 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5441 for (int i=pids.length-1; i>=0; i--) { 5442 ProcessRecord proc; 5443 int oomAdj; 5444 synchronized (this) { 5445 synchronized (mPidsSelfLocked) { 5446 proc = mPidsSelfLocked.get(pids[i]); 5447 oomAdj = proc != null ? proc.setAdj : 0; 5448 } 5449 } 5450 infos[i] = new Debug.MemoryInfo(); 5451 Debug.getMemoryInfo(pids[i], infos[i]); 5452 if (proc != null) { 5453 synchronized (this) { 5454 if (proc.thread != null && proc.setAdj == oomAdj) { 5455 // Record this for posterity if the process has been stable. 5456 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5457 infos[i].getTotalUss(), false, proc.pkgList); 5458 } 5459 } 5460 } 5461 } 5462 return infos; 5463 } 5464 5465 @Override 5466 public long[] getProcessPss(int[] pids) { 5467 enforceNotIsolatedCaller("getProcessPss"); 5468 long[] pss = new long[pids.length]; 5469 for (int i=pids.length-1; i>=0; i--) { 5470 ProcessRecord proc; 5471 int oomAdj; 5472 synchronized (this) { 5473 synchronized (mPidsSelfLocked) { 5474 proc = mPidsSelfLocked.get(pids[i]); 5475 oomAdj = proc != null ? proc.setAdj : 0; 5476 } 5477 } 5478 long[] tmpUss = new long[1]; 5479 pss[i] = Debug.getPss(pids[i], tmpUss); 5480 if (proc != null) { 5481 synchronized (this) { 5482 if (proc.thread != null && proc.setAdj == oomAdj) { 5483 // Record this for posterity if the process has been stable. 5484 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5485 } 5486 } 5487 } 5488 } 5489 return pss; 5490 } 5491 5492 @Override 5493 public void killApplicationProcess(String processName, int uid) { 5494 if (processName == null) { 5495 return; 5496 } 5497 5498 int callerUid = Binder.getCallingUid(); 5499 // Only the system server can kill an application 5500 if (callerUid == Process.SYSTEM_UID) { 5501 synchronized (this) { 5502 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5503 if (app != null && app.thread != null) { 5504 try { 5505 app.thread.scheduleSuicide(); 5506 } catch (RemoteException e) { 5507 // If the other end already died, then our work here is done. 5508 } 5509 } else { 5510 Slog.w(TAG, "Process/uid not found attempting kill of " 5511 + processName + " / " + uid); 5512 } 5513 } 5514 } else { 5515 throw new SecurityException(callerUid + " cannot kill app process: " + 5516 processName); 5517 } 5518 } 5519 5520 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5521 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5522 false, true, false, false, UserHandle.getUserId(uid), reason); 5523 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5524 Uri.fromParts("package", packageName, null)); 5525 if (!mProcessesReady) { 5526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5527 | Intent.FLAG_RECEIVER_FOREGROUND); 5528 } 5529 intent.putExtra(Intent.EXTRA_UID, uid); 5530 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5531 broadcastIntentLocked(null, null, intent, 5532 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5533 false, false, 5534 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5535 } 5536 5537 private void forceStopUserLocked(int userId, String reason) { 5538 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5539 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5540 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5541 | Intent.FLAG_RECEIVER_FOREGROUND); 5542 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5543 broadcastIntentLocked(null, null, intent, 5544 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5545 false, false, 5546 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5547 } 5548 5549 private final boolean killPackageProcessesLocked(String packageName, int appId, 5550 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5551 boolean doit, boolean evenPersistent, String reason) { 5552 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5553 5554 // Remove all processes this package may have touched: all with the 5555 // same UID (except for the system or root user), and all whose name 5556 // matches the package name. 5557 final int NP = mProcessNames.getMap().size(); 5558 for (int ip=0; ip<NP; ip++) { 5559 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5560 final int NA = apps.size(); 5561 for (int ia=0; ia<NA; ia++) { 5562 ProcessRecord app = apps.valueAt(ia); 5563 if (app.persistent && !evenPersistent) { 5564 // we don't kill persistent processes 5565 continue; 5566 } 5567 if (app.removed) { 5568 if (doit) { 5569 procs.add(app); 5570 } 5571 continue; 5572 } 5573 5574 // Skip process if it doesn't meet our oom adj requirement. 5575 if (app.setAdj < minOomAdj) { 5576 continue; 5577 } 5578 5579 // If no package is specified, we call all processes under the 5580 // give user id. 5581 if (packageName == null) { 5582 if (app.userId != userId) { 5583 continue; 5584 } 5585 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5586 continue; 5587 } 5588 // Package has been specified, we want to hit all processes 5589 // that match it. We need to qualify this by the processes 5590 // that are running under the specified app and user ID. 5591 } else { 5592 final boolean isDep = app.pkgDeps != null 5593 && app.pkgDeps.contains(packageName); 5594 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5595 continue; 5596 } 5597 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5598 continue; 5599 } 5600 if (!app.pkgList.containsKey(packageName) && !isDep) { 5601 continue; 5602 } 5603 } 5604 5605 // Process has passed all conditions, kill it! 5606 if (!doit) { 5607 return true; 5608 } 5609 app.removed = true; 5610 procs.add(app); 5611 } 5612 } 5613 5614 int N = procs.size(); 5615 for (int i=0; i<N; i++) { 5616 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5617 } 5618 updateOomAdjLocked(); 5619 return N > 0; 5620 } 5621 5622 private final boolean forceStopPackageLocked(String name, int appId, 5623 boolean callerWillRestart, boolean purgeCache, boolean doit, 5624 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5625 int i; 5626 int N; 5627 5628 if (userId == UserHandle.USER_ALL && name == null) { 5629 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5630 } 5631 5632 if (appId < 0 && name != null) { 5633 try { 5634 appId = UserHandle.getAppId( 5635 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5636 } catch (RemoteException e) { 5637 } 5638 } 5639 5640 if (doit) { 5641 if (name != null) { 5642 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5643 + " user=" + userId + ": " + reason); 5644 } else { 5645 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5646 } 5647 5648 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5649 for (int ip=pmap.size()-1; ip>=0; ip--) { 5650 SparseArray<Long> ba = pmap.valueAt(ip); 5651 for (i=ba.size()-1; i>=0; i--) { 5652 boolean remove = false; 5653 final int entUid = ba.keyAt(i); 5654 if (name != null) { 5655 if (userId == UserHandle.USER_ALL) { 5656 if (UserHandle.getAppId(entUid) == appId) { 5657 remove = true; 5658 } 5659 } else { 5660 if (entUid == UserHandle.getUid(userId, appId)) { 5661 remove = true; 5662 } 5663 } 5664 } else if (UserHandle.getUserId(entUid) == userId) { 5665 remove = true; 5666 } 5667 if (remove) { 5668 ba.removeAt(i); 5669 } 5670 } 5671 if (ba.size() == 0) { 5672 pmap.removeAt(ip); 5673 } 5674 } 5675 } 5676 5677 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5678 -100, callerWillRestart, true, doit, evenPersistent, 5679 name == null ? ("stop user " + userId) : ("stop " + name)); 5680 5681 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5682 if (!doit) { 5683 return true; 5684 } 5685 didSomething = true; 5686 } 5687 5688 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5689 if (!doit) { 5690 return true; 5691 } 5692 didSomething = true; 5693 } 5694 5695 if (name == null) { 5696 // Remove all sticky broadcasts from this user. 5697 mStickyBroadcasts.remove(userId); 5698 } 5699 5700 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5701 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5702 userId, providers)) { 5703 if (!doit) { 5704 return true; 5705 } 5706 didSomething = true; 5707 } 5708 N = providers.size(); 5709 for (i=0; i<N; i++) { 5710 removeDyingProviderLocked(null, providers.get(i), true); 5711 } 5712 5713 // Remove transient permissions granted from/to this package/user 5714 removeUriPermissionsForPackageLocked(name, userId, false); 5715 5716 if (name == null || uninstalling) { 5717 // Remove pending intents. For now we only do this when force 5718 // stopping users, because we have some problems when doing this 5719 // for packages -- app widgets are not currently cleaned up for 5720 // such packages, so they can be left with bad pending intents. 5721 if (mIntentSenderRecords.size() > 0) { 5722 Iterator<WeakReference<PendingIntentRecord>> it 5723 = mIntentSenderRecords.values().iterator(); 5724 while (it.hasNext()) { 5725 WeakReference<PendingIntentRecord> wpir = it.next(); 5726 if (wpir == null) { 5727 it.remove(); 5728 continue; 5729 } 5730 PendingIntentRecord pir = wpir.get(); 5731 if (pir == null) { 5732 it.remove(); 5733 continue; 5734 } 5735 if (name == null) { 5736 // Stopping user, remove all objects for the user. 5737 if (pir.key.userId != userId) { 5738 // Not the same user, skip it. 5739 continue; 5740 } 5741 } else { 5742 if (UserHandle.getAppId(pir.uid) != appId) { 5743 // Different app id, skip it. 5744 continue; 5745 } 5746 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5747 // Different user, skip it. 5748 continue; 5749 } 5750 if (!pir.key.packageName.equals(name)) { 5751 // Different package, skip it. 5752 continue; 5753 } 5754 } 5755 if (!doit) { 5756 return true; 5757 } 5758 didSomething = true; 5759 it.remove(); 5760 pir.canceled = true; 5761 if (pir.key.activity != null) { 5762 pir.key.activity.pendingResults.remove(pir.ref); 5763 } 5764 } 5765 } 5766 } 5767 5768 if (doit) { 5769 if (purgeCache && name != null) { 5770 AttributeCache ac = AttributeCache.instance(); 5771 if (ac != null) { 5772 ac.removePackage(name); 5773 } 5774 } 5775 if (mBooted) { 5776 mStackSupervisor.resumeTopActivitiesLocked(); 5777 mStackSupervisor.scheduleIdleLocked(); 5778 } 5779 } 5780 5781 return didSomething; 5782 } 5783 5784 private final boolean removeProcessLocked(ProcessRecord app, 5785 boolean callerWillRestart, boolean allowRestart, String reason) { 5786 final String name = app.processName; 5787 final int uid = app.uid; 5788 if (DEBUG_PROCESSES) Slog.d( 5789 TAG, "Force removing proc " + app.toShortString() + " (" + name 5790 + "/" + uid + ")"); 5791 5792 mProcessNames.remove(name, uid); 5793 mIsolatedProcesses.remove(app.uid); 5794 if (mHeavyWeightProcess == app) { 5795 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5796 mHeavyWeightProcess.userId, 0)); 5797 mHeavyWeightProcess = null; 5798 } 5799 boolean needRestart = false; 5800 if (app.pid > 0 && app.pid != MY_PID) { 5801 int pid = app.pid; 5802 synchronized (mPidsSelfLocked) { 5803 mPidsSelfLocked.remove(pid); 5804 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5805 } 5806 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5807 if (app.isolated) { 5808 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5809 } 5810 app.kill(reason, true); 5811 handleAppDiedLocked(app, true, allowRestart); 5812 removeLruProcessLocked(app); 5813 5814 if (app.persistent && !app.isolated) { 5815 if (!callerWillRestart) { 5816 addAppLocked(app.info, false, null /* ABI override */); 5817 } else { 5818 needRestart = true; 5819 } 5820 } 5821 } else { 5822 mRemovedProcesses.add(app); 5823 } 5824 5825 return needRestart; 5826 } 5827 5828 private final void processStartTimedOutLocked(ProcessRecord app) { 5829 final int pid = app.pid; 5830 boolean gone = false; 5831 synchronized (mPidsSelfLocked) { 5832 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5833 if (knownApp != null && knownApp.thread == null) { 5834 mPidsSelfLocked.remove(pid); 5835 gone = true; 5836 } 5837 } 5838 5839 if (gone) { 5840 Slog.w(TAG, "Process " + app + " failed to attach"); 5841 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5842 pid, app.uid, app.processName); 5843 mProcessNames.remove(app.processName, app.uid); 5844 mIsolatedProcesses.remove(app.uid); 5845 if (mHeavyWeightProcess == app) { 5846 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5847 mHeavyWeightProcess.userId, 0)); 5848 mHeavyWeightProcess = null; 5849 } 5850 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5851 if (app.isolated) { 5852 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5853 } 5854 // Take care of any launching providers waiting for this process. 5855 checkAppInLaunchingProvidersLocked(app, true); 5856 // Take care of any services that are waiting for the process. 5857 mServices.processStartTimedOutLocked(app); 5858 app.kill("start timeout", true); 5859 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5860 Slog.w(TAG, "Unattached app died before backup, skipping"); 5861 try { 5862 IBackupManager bm = IBackupManager.Stub.asInterface( 5863 ServiceManager.getService(Context.BACKUP_SERVICE)); 5864 bm.agentDisconnected(app.info.packageName); 5865 } catch (RemoteException e) { 5866 // Can't happen; the backup manager is local 5867 } 5868 } 5869 if (isPendingBroadcastProcessLocked(pid)) { 5870 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5871 skipPendingBroadcastLocked(pid); 5872 } 5873 } else { 5874 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5875 } 5876 } 5877 5878 private final boolean attachApplicationLocked(IApplicationThread thread, 5879 int pid) { 5880 5881 // Find the application record that is being attached... either via 5882 // the pid if we are running in multiple processes, or just pull the 5883 // next app record if we are emulating process with anonymous threads. 5884 ProcessRecord app; 5885 if (pid != MY_PID && pid >= 0) { 5886 synchronized (mPidsSelfLocked) { 5887 app = mPidsSelfLocked.get(pid); 5888 } 5889 } else { 5890 app = null; 5891 } 5892 5893 if (app == null) { 5894 Slog.w(TAG, "No pending application record for pid " + pid 5895 + " (IApplicationThread " + thread + "); dropping process"); 5896 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5897 if (pid > 0 && pid != MY_PID) { 5898 Process.killProcessQuiet(pid); 5899 //TODO: Process.killProcessGroup(app.info.uid, pid); 5900 } else { 5901 try { 5902 thread.scheduleExit(); 5903 } catch (Exception e) { 5904 // Ignore exceptions. 5905 } 5906 } 5907 return false; 5908 } 5909 5910 // If this application record is still attached to a previous 5911 // process, clean it up now. 5912 if (app.thread != null) { 5913 handleAppDiedLocked(app, true, true); 5914 } 5915 5916 // Tell the process all about itself. 5917 5918 if (localLOGV) Slog.v( 5919 TAG, "Binding process pid " + pid + " to record " + app); 5920 5921 final String processName = app.processName; 5922 try { 5923 AppDeathRecipient adr = new AppDeathRecipient( 5924 app, pid, thread); 5925 thread.asBinder().linkToDeath(adr, 0); 5926 app.deathRecipient = adr; 5927 } catch (RemoteException e) { 5928 app.resetPackageList(mProcessStats); 5929 startProcessLocked(app, "link fail", processName); 5930 return false; 5931 } 5932 5933 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5934 5935 app.makeActive(thread, mProcessStats); 5936 app.curAdj = app.setAdj = -100; 5937 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5938 app.forcingToForeground = null; 5939 updateProcessForegroundLocked(app, false, false); 5940 app.hasShownUi = false; 5941 app.debugging = false; 5942 app.cached = false; 5943 5944 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5945 5946 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5947 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5948 5949 if (!normalMode) { 5950 Slog.i(TAG, "Launching preboot mode app: " + app); 5951 } 5952 5953 if (localLOGV) Slog.v( 5954 TAG, "New app record " + app 5955 + " thread=" + thread.asBinder() + " pid=" + pid); 5956 try { 5957 int testMode = IApplicationThread.DEBUG_OFF; 5958 if (mDebugApp != null && mDebugApp.equals(processName)) { 5959 testMode = mWaitForDebugger 5960 ? IApplicationThread.DEBUG_WAIT 5961 : IApplicationThread.DEBUG_ON; 5962 app.debugging = true; 5963 if (mDebugTransient) { 5964 mDebugApp = mOrigDebugApp; 5965 mWaitForDebugger = mOrigWaitForDebugger; 5966 } 5967 } 5968 String profileFile = app.instrumentationProfileFile; 5969 ParcelFileDescriptor profileFd = null; 5970 int samplingInterval = 0; 5971 boolean profileAutoStop = false; 5972 if (mProfileApp != null && mProfileApp.equals(processName)) { 5973 mProfileProc = app; 5974 profileFile = mProfileFile; 5975 profileFd = mProfileFd; 5976 samplingInterval = mSamplingInterval; 5977 profileAutoStop = mAutoStopProfiler; 5978 } 5979 boolean enableOpenGlTrace = false; 5980 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5981 enableOpenGlTrace = true; 5982 mOpenGlTraceApp = null; 5983 } 5984 5985 // If the app is being launched for restore or full backup, set it up specially 5986 boolean isRestrictedBackupMode = false; 5987 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5988 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5989 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5990 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5991 } 5992 5993 ensurePackageDexOpt(app.instrumentationInfo != null 5994 ? app.instrumentationInfo.packageName 5995 : app.info.packageName); 5996 if (app.instrumentationClass != null) { 5997 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5998 } 5999 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6000 + processName + " with config " + mConfiguration); 6001 ApplicationInfo appInfo = app.instrumentationInfo != null 6002 ? app.instrumentationInfo : app.info; 6003 app.compat = compatibilityInfoForPackageLocked(appInfo); 6004 if (profileFd != null) { 6005 profileFd = profileFd.dup(); 6006 } 6007 ProfilerInfo profilerInfo = profileFile == null ? null 6008 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6009 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6010 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6011 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6012 isRestrictedBackupMode || !normalMode, app.persistent, 6013 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6014 mCoreSettingsObserver.getCoreSettingsLocked()); 6015 updateLruProcessLocked(app, false, null); 6016 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6017 } catch (Exception e) { 6018 // todo: Yikes! What should we do? For now we will try to 6019 // start another process, but that could easily get us in 6020 // an infinite loop of restarting processes... 6021 Slog.w(TAG, "Exception thrown during bind!", e); 6022 6023 app.resetPackageList(mProcessStats); 6024 app.unlinkDeathRecipient(); 6025 startProcessLocked(app, "bind fail", processName); 6026 return false; 6027 } 6028 6029 // Remove this record from the list of starting applications. 6030 mPersistentStartingProcesses.remove(app); 6031 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6032 "Attach application locked removing on hold: " + app); 6033 mProcessesOnHold.remove(app); 6034 6035 boolean badApp = false; 6036 boolean didSomething = false; 6037 6038 // See if the top visible activity is waiting to run in this process... 6039 if (normalMode) { 6040 try { 6041 if (mStackSupervisor.attachApplicationLocked(app)) { 6042 didSomething = true; 6043 } 6044 } catch (Exception e) { 6045 badApp = true; 6046 } 6047 } 6048 6049 // Find any services that should be running in this process... 6050 if (!badApp) { 6051 try { 6052 didSomething |= mServices.attachApplicationLocked(app, processName); 6053 } catch (Exception e) { 6054 badApp = true; 6055 } 6056 } 6057 6058 // Check if a next-broadcast receiver is in this process... 6059 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6060 try { 6061 didSomething |= sendPendingBroadcastsLocked(app); 6062 } catch (Exception e) { 6063 // If the app died trying to launch the receiver we declare it 'bad' 6064 badApp = true; 6065 } 6066 } 6067 6068 // Check whether the next backup agent is in this process... 6069 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6070 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6071 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6072 try { 6073 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6074 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6075 mBackupTarget.backupMode); 6076 } catch (Exception e) { 6077 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6078 e.printStackTrace(); 6079 } 6080 } 6081 6082 if (badApp) { 6083 // todo: Also need to kill application to deal with all 6084 // kinds of exceptions. 6085 handleAppDiedLocked(app, false, true); 6086 return false; 6087 } 6088 6089 if (!didSomething) { 6090 updateOomAdjLocked(); 6091 } 6092 6093 return true; 6094 } 6095 6096 @Override 6097 public final void attachApplication(IApplicationThread thread) { 6098 synchronized (this) { 6099 int callingPid = Binder.getCallingPid(); 6100 final long origId = Binder.clearCallingIdentity(); 6101 attachApplicationLocked(thread, callingPid); 6102 Binder.restoreCallingIdentity(origId); 6103 } 6104 } 6105 6106 @Override 6107 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6108 final long origId = Binder.clearCallingIdentity(); 6109 synchronized (this) { 6110 ActivityStack stack = ActivityRecord.getStackLocked(token); 6111 if (stack != null) { 6112 ActivityRecord r = 6113 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6114 if (stopProfiling) { 6115 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6116 try { 6117 mProfileFd.close(); 6118 } catch (IOException e) { 6119 } 6120 clearProfilerLocked(); 6121 } 6122 } 6123 } 6124 } 6125 Binder.restoreCallingIdentity(origId); 6126 } 6127 6128 void postEnableScreenAfterBootLocked() { 6129 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6130 } 6131 6132 void enableScreenAfterBoot() { 6133 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6134 SystemClock.uptimeMillis()); 6135 mWindowManager.enableScreenAfterBoot(); 6136 6137 synchronized (this) { 6138 updateEventDispatchingLocked(); 6139 } 6140 } 6141 6142 @Override 6143 public void showBootMessage(final CharSequence msg, final boolean always) { 6144 enforceNotIsolatedCaller("showBootMessage"); 6145 mWindowManager.showBootMessage(msg, always); 6146 } 6147 6148 @Override 6149 public void keyguardWaitingForActivityDrawn() { 6150 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6151 final long token = Binder.clearCallingIdentity(); 6152 try { 6153 synchronized (this) { 6154 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6155 mWindowManager.keyguardWaitingForActivityDrawn(); 6156 } 6157 } finally { 6158 Binder.restoreCallingIdentity(token); 6159 } 6160 } 6161 6162 final void finishBooting() { 6163 // Register receivers to handle package update events 6164 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6165 6166 // Let system services know. 6167 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6168 6169 synchronized (this) { 6170 // Ensure that any processes we had put on hold are now started 6171 // up. 6172 final int NP = mProcessesOnHold.size(); 6173 if (NP > 0) { 6174 ArrayList<ProcessRecord> procs = 6175 new ArrayList<ProcessRecord>(mProcessesOnHold); 6176 for (int ip=0; ip<NP; ip++) { 6177 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6178 + procs.get(ip)); 6179 startProcessLocked(procs.get(ip), "on-hold", null); 6180 } 6181 } 6182 6183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6184 // Start looking for apps that are abusing wake locks. 6185 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6186 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6187 // Tell anyone interested that we are done booting! 6188 SystemProperties.set("sys.boot_completed", "1"); 6189 SystemProperties.set("dev.bootcomplete", "1"); 6190 for (int i=0; i<mStartedUsers.size(); i++) { 6191 UserStartedState uss = mStartedUsers.valueAt(i); 6192 if (uss.mState == UserStartedState.STATE_BOOTING) { 6193 uss.mState = UserStartedState.STATE_RUNNING; 6194 final int userId = mStartedUsers.keyAt(i); 6195 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6196 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6197 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6198 broadcastIntentLocked(null, null, intent, null, 6199 new IIntentReceiver.Stub() { 6200 @Override 6201 public void performReceive(Intent intent, int resultCode, 6202 String data, Bundle extras, boolean ordered, 6203 boolean sticky, int sendingUser) { 6204 synchronized (ActivityManagerService.this) { 6205 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6206 true, false); 6207 } 6208 } 6209 }, 6210 0, null, null, 6211 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6212 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6213 userId); 6214 } 6215 } 6216 scheduleStartProfilesLocked(); 6217 } 6218 } 6219 } 6220 6221 final void ensureBootCompleted() { 6222 boolean booting; 6223 boolean enableScreen; 6224 synchronized (this) { 6225 booting = mBooting; 6226 mBooting = false; 6227 enableScreen = !mBooted; 6228 mBooted = true; 6229 } 6230 6231 if (booting) { 6232 finishBooting(); 6233 } 6234 6235 if (enableScreen) { 6236 enableScreenAfterBoot(); 6237 } 6238 } 6239 6240 @Override 6241 public final void activityResumed(IBinder token) { 6242 final long origId = Binder.clearCallingIdentity(); 6243 synchronized(this) { 6244 ActivityStack stack = ActivityRecord.getStackLocked(token); 6245 if (stack != null) { 6246 ActivityRecord.activityResumedLocked(token); 6247 } 6248 } 6249 Binder.restoreCallingIdentity(origId); 6250 } 6251 6252 @Override 6253 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6254 final long origId = Binder.clearCallingIdentity(); 6255 synchronized(this) { 6256 ActivityStack stack = ActivityRecord.getStackLocked(token); 6257 if (stack != null) { 6258 stack.activityPausedLocked(token, false, persistentState); 6259 } 6260 } 6261 Binder.restoreCallingIdentity(origId); 6262 } 6263 6264 @Override 6265 public final void activityStopped(IBinder token, Bundle icicle, 6266 PersistableBundle persistentState, CharSequence description) { 6267 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6268 6269 // Refuse possible leaked file descriptors 6270 if (icicle != null && icicle.hasFileDescriptors()) { 6271 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6272 } 6273 6274 final long origId = Binder.clearCallingIdentity(); 6275 6276 synchronized (this) { 6277 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6278 if (r != null) { 6279 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6280 } 6281 } 6282 6283 trimApplications(); 6284 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 @Override 6289 public final void activityDestroyed(IBinder token) { 6290 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6291 synchronized (this) { 6292 ActivityStack stack = ActivityRecord.getStackLocked(token); 6293 if (stack != null) { 6294 stack.activityDestroyedLocked(token); 6295 } 6296 } 6297 } 6298 6299 @Override 6300 public final void backgroundResourcesReleased(IBinder token) { 6301 final long origId = Binder.clearCallingIdentity(); 6302 try { 6303 synchronized (this) { 6304 ActivityStack stack = ActivityRecord.getStackLocked(token); 6305 if (stack != null) { 6306 stack.backgroundResourcesReleased(token); 6307 } 6308 } 6309 } finally { 6310 Binder.restoreCallingIdentity(origId); 6311 } 6312 } 6313 6314 @Override 6315 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6316 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6317 } 6318 6319 @Override 6320 public final void notifyEnterAnimationComplete(IBinder token) { 6321 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6322 } 6323 6324 @Override 6325 public String getCallingPackage(IBinder token) { 6326 synchronized (this) { 6327 ActivityRecord r = getCallingRecordLocked(token); 6328 return r != null ? r.info.packageName : null; 6329 } 6330 } 6331 6332 @Override 6333 public ComponentName getCallingActivity(IBinder token) { 6334 synchronized (this) { 6335 ActivityRecord r = getCallingRecordLocked(token); 6336 return r != null ? r.intent.getComponent() : null; 6337 } 6338 } 6339 6340 private ActivityRecord getCallingRecordLocked(IBinder token) { 6341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6342 if (r == null) { 6343 return null; 6344 } 6345 return r.resultTo; 6346 } 6347 6348 @Override 6349 public ComponentName getActivityClassForToken(IBinder token) { 6350 synchronized(this) { 6351 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6352 if (r == null) { 6353 return null; 6354 } 6355 return r.intent.getComponent(); 6356 } 6357 } 6358 6359 @Override 6360 public String getPackageForToken(IBinder token) { 6361 synchronized(this) { 6362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6363 if (r == null) { 6364 return null; 6365 } 6366 return r.packageName; 6367 } 6368 } 6369 6370 @Override 6371 public IIntentSender getIntentSender(int type, 6372 String packageName, IBinder token, String resultWho, 6373 int requestCode, Intent[] intents, String[] resolvedTypes, 6374 int flags, Bundle options, int userId) { 6375 enforceNotIsolatedCaller("getIntentSender"); 6376 // Refuse possible leaked file descriptors 6377 if (intents != null) { 6378 if (intents.length < 1) { 6379 throw new IllegalArgumentException("Intents array length must be >= 1"); 6380 } 6381 for (int i=0; i<intents.length; i++) { 6382 Intent intent = intents[i]; 6383 if (intent != null) { 6384 if (intent.hasFileDescriptors()) { 6385 throw new IllegalArgumentException("File descriptors passed in Intent"); 6386 } 6387 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6388 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6389 throw new IllegalArgumentException( 6390 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6391 } 6392 intents[i] = new Intent(intent); 6393 } 6394 } 6395 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6396 throw new IllegalArgumentException( 6397 "Intent array length does not match resolvedTypes length"); 6398 } 6399 } 6400 if (options != null) { 6401 if (options.hasFileDescriptors()) { 6402 throw new IllegalArgumentException("File descriptors passed in options"); 6403 } 6404 } 6405 6406 synchronized(this) { 6407 int callingUid = Binder.getCallingUid(); 6408 int origUserId = userId; 6409 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6410 type == ActivityManager.INTENT_SENDER_BROADCAST, 6411 ALLOW_NON_FULL, "getIntentSender", null); 6412 if (origUserId == UserHandle.USER_CURRENT) { 6413 // We don't want to evaluate this until the pending intent is 6414 // actually executed. However, we do want to always do the 6415 // security checking for it above. 6416 userId = UserHandle.USER_CURRENT; 6417 } 6418 try { 6419 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6420 int uid = AppGlobals.getPackageManager() 6421 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6422 if (!UserHandle.isSameApp(callingUid, uid)) { 6423 String msg = "Permission Denial: getIntentSender() from pid=" 6424 + Binder.getCallingPid() 6425 + ", uid=" + Binder.getCallingUid() 6426 + ", (need uid=" + uid + ")" 6427 + " is not allowed to send as package " + packageName; 6428 Slog.w(TAG, msg); 6429 throw new SecurityException(msg); 6430 } 6431 } 6432 6433 return getIntentSenderLocked(type, packageName, callingUid, userId, 6434 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6435 6436 } catch (RemoteException e) { 6437 throw new SecurityException(e); 6438 } 6439 } 6440 } 6441 6442 IIntentSender getIntentSenderLocked(int type, String packageName, 6443 int callingUid, int userId, IBinder token, String resultWho, 6444 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6445 Bundle options) { 6446 if (DEBUG_MU) 6447 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6448 ActivityRecord activity = null; 6449 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6450 activity = ActivityRecord.isInStackLocked(token); 6451 if (activity == null) { 6452 return null; 6453 } 6454 if (activity.finishing) { 6455 return null; 6456 } 6457 } 6458 6459 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6460 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6461 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6462 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6463 |PendingIntent.FLAG_UPDATE_CURRENT); 6464 6465 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6466 type, packageName, activity, resultWho, 6467 requestCode, intents, resolvedTypes, flags, options, userId); 6468 WeakReference<PendingIntentRecord> ref; 6469 ref = mIntentSenderRecords.get(key); 6470 PendingIntentRecord rec = ref != null ? ref.get() : null; 6471 if (rec != null) { 6472 if (!cancelCurrent) { 6473 if (updateCurrent) { 6474 if (rec.key.requestIntent != null) { 6475 rec.key.requestIntent.replaceExtras(intents != null ? 6476 intents[intents.length - 1] : null); 6477 } 6478 if (intents != null) { 6479 intents[intents.length-1] = rec.key.requestIntent; 6480 rec.key.allIntents = intents; 6481 rec.key.allResolvedTypes = resolvedTypes; 6482 } else { 6483 rec.key.allIntents = null; 6484 rec.key.allResolvedTypes = null; 6485 } 6486 } 6487 return rec; 6488 } 6489 rec.canceled = true; 6490 mIntentSenderRecords.remove(key); 6491 } 6492 if (noCreate) { 6493 return rec; 6494 } 6495 rec = new PendingIntentRecord(this, key, callingUid); 6496 mIntentSenderRecords.put(key, rec.ref); 6497 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6498 if (activity.pendingResults == null) { 6499 activity.pendingResults 6500 = new HashSet<WeakReference<PendingIntentRecord>>(); 6501 } 6502 activity.pendingResults.add(rec.ref); 6503 } 6504 return rec; 6505 } 6506 6507 @Override 6508 public void cancelIntentSender(IIntentSender sender) { 6509 if (!(sender instanceof PendingIntentRecord)) { 6510 return; 6511 } 6512 synchronized(this) { 6513 PendingIntentRecord rec = (PendingIntentRecord)sender; 6514 try { 6515 int uid = AppGlobals.getPackageManager() 6516 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6517 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6518 String msg = "Permission Denial: cancelIntentSender() from pid=" 6519 + Binder.getCallingPid() 6520 + ", uid=" + Binder.getCallingUid() 6521 + " is not allowed to cancel packges " 6522 + rec.key.packageName; 6523 Slog.w(TAG, msg); 6524 throw new SecurityException(msg); 6525 } 6526 } catch (RemoteException e) { 6527 throw new SecurityException(e); 6528 } 6529 cancelIntentSenderLocked(rec, true); 6530 } 6531 } 6532 6533 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6534 rec.canceled = true; 6535 mIntentSenderRecords.remove(rec.key); 6536 if (cleanActivity && rec.key.activity != null) { 6537 rec.key.activity.pendingResults.remove(rec.ref); 6538 } 6539 } 6540 6541 @Override 6542 public String getPackageForIntentSender(IIntentSender pendingResult) { 6543 if (!(pendingResult instanceof PendingIntentRecord)) { 6544 return null; 6545 } 6546 try { 6547 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6548 return res.key.packageName; 6549 } catch (ClassCastException e) { 6550 } 6551 return null; 6552 } 6553 6554 @Override 6555 public int getUidForIntentSender(IIntentSender sender) { 6556 if (sender instanceof PendingIntentRecord) { 6557 try { 6558 PendingIntentRecord res = (PendingIntentRecord)sender; 6559 return res.uid; 6560 } catch (ClassCastException e) { 6561 } 6562 } 6563 return -1; 6564 } 6565 6566 @Override 6567 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6568 if (!(pendingResult instanceof PendingIntentRecord)) { 6569 return false; 6570 } 6571 try { 6572 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6573 if (res.key.allIntents == null) { 6574 return false; 6575 } 6576 for (int i=0; i<res.key.allIntents.length; i++) { 6577 Intent intent = res.key.allIntents[i]; 6578 if (intent.getPackage() != null && intent.getComponent() != null) { 6579 return false; 6580 } 6581 } 6582 return true; 6583 } catch (ClassCastException e) { 6584 } 6585 return false; 6586 } 6587 6588 @Override 6589 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6590 if (!(pendingResult instanceof PendingIntentRecord)) { 6591 return false; 6592 } 6593 try { 6594 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6595 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6596 return true; 6597 } 6598 return false; 6599 } catch (ClassCastException e) { 6600 } 6601 return false; 6602 } 6603 6604 @Override 6605 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6606 if (!(pendingResult instanceof PendingIntentRecord)) { 6607 return null; 6608 } 6609 try { 6610 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6611 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6612 } catch (ClassCastException e) { 6613 } 6614 return null; 6615 } 6616 6617 @Override 6618 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6619 if (!(pendingResult instanceof PendingIntentRecord)) { 6620 return null; 6621 } 6622 try { 6623 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6624 Intent intent = res.key.requestIntent; 6625 if (intent != null) { 6626 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6627 || res.lastTagPrefix.equals(prefix))) { 6628 return res.lastTag; 6629 } 6630 res.lastTagPrefix = prefix; 6631 StringBuilder sb = new StringBuilder(128); 6632 if (prefix != null) { 6633 sb.append(prefix); 6634 } 6635 if (intent.getAction() != null) { 6636 sb.append(intent.getAction()); 6637 } else if (intent.getComponent() != null) { 6638 intent.getComponent().appendShortString(sb); 6639 } else { 6640 sb.append("?"); 6641 } 6642 return res.lastTag = sb.toString(); 6643 } 6644 } catch (ClassCastException e) { 6645 } 6646 return null; 6647 } 6648 6649 @Override 6650 public void setProcessLimit(int max) { 6651 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6652 "setProcessLimit()"); 6653 synchronized (this) { 6654 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6655 mProcessLimitOverride = max; 6656 } 6657 trimApplications(); 6658 } 6659 6660 @Override 6661 public int getProcessLimit() { 6662 synchronized (this) { 6663 return mProcessLimitOverride; 6664 } 6665 } 6666 6667 void foregroundTokenDied(ForegroundToken token) { 6668 synchronized (ActivityManagerService.this) { 6669 synchronized (mPidsSelfLocked) { 6670 ForegroundToken cur 6671 = mForegroundProcesses.get(token.pid); 6672 if (cur != token) { 6673 return; 6674 } 6675 mForegroundProcesses.remove(token.pid); 6676 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6677 if (pr == null) { 6678 return; 6679 } 6680 pr.forcingToForeground = null; 6681 updateProcessForegroundLocked(pr, false, false); 6682 } 6683 updateOomAdjLocked(); 6684 } 6685 } 6686 6687 @Override 6688 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6689 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6690 "setProcessForeground()"); 6691 synchronized(this) { 6692 boolean changed = false; 6693 6694 synchronized (mPidsSelfLocked) { 6695 ProcessRecord pr = mPidsSelfLocked.get(pid); 6696 if (pr == null && isForeground) { 6697 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6698 return; 6699 } 6700 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6701 if (oldToken != null) { 6702 oldToken.token.unlinkToDeath(oldToken, 0); 6703 mForegroundProcesses.remove(pid); 6704 if (pr != null) { 6705 pr.forcingToForeground = null; 6706 } 6707 changed = true; 6708 } 6709 if (isForeground && token != null) { 6710 ForegroundToken newToken = new ForegroundToken() { 6711 @Override 6712 public void binderDied() { 6713 foregroundTokenDied(this); 6714 } 6715 }; 6716 newToken.pid = pid; 6717 newToken.token = token; 6718 try { 6719 token.linkToDeath(newToken, 0); 6720 mForegroundProcesses.put(pid, newToken); 6721 pr.forcingToForeground = token; 6722 changed = true; 6723 } catch (RemoteException e) { 6724 // If the process died while doing this, we will later 6725 // do the cleanup with the process death link. 6726 } 6727 } 6728 } 6729 6730 if (changed) { 6731 updateOomAdjLocked(); 6732 } 6733 } 6734 } 6735 6736 // ========================================================= 6737 // PERMISSIONS 6738 // ========================================================= 6739 6740 static class PermissionController extends IPermissionController.Stub { 6741 ActivityManagerService mActivityManagerService; 6742 PermissionController(ActivityManagerService activityManagerService) { 6743 mActivityManagerService = activityManagerService; 6744 } 6745 6746 @Override 6747 public boolean checkPermission(String permission, int pid, int uid) { 6748 return mActivityManagerService.checkPermission(permission, pid, 6749 uid) == PackageManager.PERMISSION_GRANTED; 6750 } 6751 } 6752 6753 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6754 @Override 6755 public int checkComponentPermission(String permission, int pid, int uid, 6756 int owningUid, boolean exported) { 6757 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6758 owningUid, exported); 6759 } 6760 6761 @Override 6762 public Object getAMSLock() { 6763 return ActivityManagerService.this; 6764 } 6765 } 6766 6767 /** 6768 * This can be called with or without the global lock held. 6769 */ 6770 int checkComponentPermission(String permission, int pid, int uid, 6771 int owningUid, boolean exported) { 6772 // We might be performing an operation on behalf of an indirect binder 6773 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6774 // client identity accordingly before proceeding. 6775 Identity tlsIdentity = sCallerIdentity.get(); 6776 if (tlsIdentity != null) { 6777 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6778 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6779 uid = tlsIdentity.uid; 6780 pid = tlsIdentity.pid; 6781 } 6782 6783 if (pid == MY_PID) { 6784 return PackageManager.PERMISSION_GRANTED; 6785 } 6786 6787 return ActivityManager.checkComponentPermission(permission, uid, 6788 owningUid, exported); 6789 } 6790 6791 /** 6792 * As the only public entry point for permissions checking, this method 6793 * can enforce the semantic that requesting a check on a null global 6794 * permission is automatically denied. (Internally a null permission 6795 * string is used when calling {@link #checkComponentPermission} in cases 6796 * when only uid-based security is needed.) 6797 * 6798 * This can be called with or without the global lock held. 6799 */ 6800 @Override 6801 public int checkPermission(String permission, int pid, int uid) { 6802 if (permission == null) { 6803 return PackageManager.PERMISSION_DENIED; 6804 } 6805 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6806 } 6807 6808 /** 6809 * Binder IPC calls go through the public entry point. 6810 * This can be called with or without the global lock held. 6811 */ 6812 int checkCallingPermission(String permission) { 6813 return checkPermission(permission, 6814 Binder.getCallingPid(), 6815 UserHandle.getAppId(Binder.getCallingUid())); 6816 } 6817 6818 /** 6819 * This can be called with or without the global lock held. 6820 */ 6821 void enforceCallingPermission(String permission, String func) { 6822 if (checkCallingPermission(permission) 6823 == PackageManager.PERMISSION_GRANTED) { 6824 return; 6825 } 6826 6827 String msg = "Permission Denial: " + func + " from pid=" 6828 + Binder.getCallingPid() 6829 + ", uid=" + Binder.getCallingUid() 6830 + " requires " + permission; 6831 Slog.w(TAG, msg); 6832 throw new SecurityException(msg); 6833 } 6834 6835 /** 6836 * Determine if UID is holding permissions required to access {@link Uri} in 6837 * the given {@link ProviderInfo}. Final permission checking is always done 6838 * in {@link ContentProvider}. 6839 */ 6840 private final boolean checkHoldingPermissionsLocked( 6841 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6842 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6843 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6844 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6845 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6846 != PERMISSION_GRANTED) { 6847 return false; 6848 } 6849 } 6850 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6851 } 6852 6853 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6854 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6855 if (pi.applicationInfo.uid == uid) { 6856 return true; 6857 } else if (!pi.exported) { 6858 return false; 6859 } 6860 6861 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6862 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6863 try { 6864 // check if target holds top-level <provider> permissions 6865 if (!readMet && pi.readPermission != null && considerUidPermissions 6866 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6867 readMet = true; 6868 } 6869 if (!writeMet && pi.writePermission != null && considerUidPermissions 6870 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6871 writeMet = true; 6872 } 6873 6874 // track if unprotected read/write is allowed; any denied 6875 // <path-permission> below removes this ability 6876 boolean allowDefaultRead = pi.readPermission == null; 6877 boolean allowDefaultWrite = pi.writePermission == null; 6878 6879 // check if target holds any <path-permission> that match uri 6880 final PathPermission[] pps = pi.pathPermissions; 6881 if (pps != null) { 6882 final String path = grantUri.uri.getPath(); 6883 int i = pps.length; 6884 while (i > 0 && (!readMet || !writeMet)) { 6885 i--; 6886 PathPermission pp = pps[i]; 6887 if (pp.match(path)) { 6888 if (!readMet) { 6889 final String pprperm = pp.getReadPermission(); 6890 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6891 + pprperm + " for " + pp.getPath() 6892 + ": match=" + pp.match(path) 6893 + " check=" + pm.checkUidPermission(pprperm, uid)); 6894 if (pprperm != null) { 6895 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6896 == PERMISSION_GRANTED) { 6897 readMet = true; 6898 } else { 6899 allowDefaultRead = false; 6900 } 6901 } 6902 } 6903 if (!writeMet) { 6904 final String ppwperm = pp.getWritePermission(); 6905 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6906 + ppwperm + " for " + pp.getPath() 6907 + ": match=" + pp.match(path) 6908 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6909 if (ppwperm != null) { 6910 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6911 == PERMISSION_GRANTED) { 6912 writeMet = true; 6913 } else { 6914 allowDefaultWrite = false; 6915 } 6916 } 6917 } 6918 } 6919 } 6920 } 6921 6922 // grant unprotected <provider> read/write, if not blocked by 6923 // <path-permission> above 6924 if (allowDefaultRead) readMet = true; 6925 if (allowDefaultWrite) writeMet = true; 6926 6927 } catch (RemoteException e) { 6928 return false; 6929 } 6930 6931 return readMet && writeMet; 6932 } 6933 6934 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6935 ProviderInfo pi = null; 6936 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6937 if (cpr != null) { 6938 pi = cpr.info; 6939 } else { 6940 try { 6941 pi = AppGlobals.getPackageManager().resolveContentProvider( 6942 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6943 } catch (RemoteException ex) { 6944 } 6945 } 6946 return pi; 6947 } 6948 6949 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6950 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6951 if (targetUris != null) { 6952 return targetUris.get(grantUri); 6953 } 6954 return null; 6955 } 6956 6957 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6958 String targetPkg, int targetUid, GrantUri grantUri) { 6959 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6960 if (targetUris == null) { 6961 targetUris = Maps.newArrayMap(); 6962 mGrantedUriPermissions.put(targetUid, targetUris); 6963 } 6964 6965 UriPermission perm = targetUris.get(grantUri); 6966 if (perm == null) { 6967 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6968 targetUris.put(grantUri, perm); 6969 } 6970 6971 return perm; 6972 } 6973 6974 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6975 final int modeFlags) { 6976 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6977 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6978 : UriPermission.STRENGTH_OWNED; 6979 6980 // Root gets to do everything. 6981 if (uid == 0) { 6982 return true; 6983 } 6984 6985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6986 if (perms == null) return false; 6987 6988 // First look for exact match 6989 final UriPermission exactPerm = perms.get(grantUri); 6990 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6991 return true; 6992 } 6993 6994 // No exact match, look for prefixes 6995 final int N = perms.size(); 6996 for (int i = 0; i < N; i++) { 6997 final UriPermission perm = perms.valueAt(i); 6998 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6999 && perm.getStrength(modeFlags) >= minStrength) { 7000 return true; 7001 } 7002 } 7003 7004 return false; 7005 } 7006 7007 /** 7008 * @param uri This uri must NOT contain an embedded userId. 7009 * @param userId The userId in which the uri is to be resolved. 7010 */ 7011 @Override 7012 public int checkUriPermission(Uri uri, int pid, int uid, 7013 final int modeFlags, int userId) { 7014 enforceNotIsolatedCaller("checkUriPermission"); 7015 7016 // Another redirected-binder-call permissions check as in 7017 // {@link checkComponentPermission}. 7018 Identity tlsIdentity = sCallerIdentity.get(); 7019 if (tlsIdentity != null) { 7020 uid = tlsIdentity.uid; 7021 pid = tlsIdentity.pid; 7022 } 7023 7024 // Our own process gets to do everything. 7025 if (pid == MY_PID) { 7026 return PackageManager.PERMISSION_GRANTED; 7027 } 7028 synchronized (this) { 7029 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7030 ? PackageManager.PERMISSION_GRANTED 7031 : PackageManager.PERMISSION_DENIED; 7032 } 7033 } 7034 7035 /** 7036 * Check if the targetPkg can be granted permission to access uri by 7037 * the callingUid using the given modeFlags. Throws a security exception 7038 * if callingUid is not allowed to do this. Returns the uid of the target 7039 * if the URI permission grant should be performed; returns -1 if it is not 7040 * needed (for example targetPkg already has permission to access the URI). 7041 * If you already know the uid of the target, you can supply it in 7042 * lastTargetUid else set that to -1. 7043 */ 7044 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7045 final int modeFlags, int lastTargetUid) { 7046 if (!Intent.isAccessUriMode(modeFlags)) { 7047 return -1; 7048 } 7049 7050 if (targetPkg != null) { 7051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7052 "Checking grant " + targetPkg + " permission to " + grantUri); 7053 } 7054 7055 final IPackageManager pm = AppGlobals.getPackageManager(); 7056 7057 // If this is not a content: uri, we can't do anything with it. 7058 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7059 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7060 "Can't grant URI permission for non-content URI: " + grantUri); 7061 return -1; 7062 } 7063 7064 final String authority = grantUri.uri.getAuthority(); 7065 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7066 if (pi == null) { 7067 Slog.w(TAG, "No content provider found for permission check: " + 7068 grantUri.uri.toSafeString()); 7069 return -1; 7070 } 7071 7072 int targetUid = lastTargetUid; 7073 if (targetUid < 0 && targetPkg != null) { 7074 try { 7075 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7076 if (targetUid < 0) { 7077 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7078 "Can't grant URI permission no uid for: " + targetPkg); 7079 return -1; 7080 } 7081 } catch (RemoteException ex) { 7082 return -1; 7083 } 7084 } 7085 7086 if (targetUid >= 0) { 7087 // First... does the target actually need this permission? 7088 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7089 // No need to grant the target this permission. 7090 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7091 "Target " + targetPkg + " already has full permission to " + grantUri); 7092 return -1; 7093 } 7094 } else { 7095 // First... there is no target package, so can anyone access it? 7096 boolean allowed = pi.exported; 7097 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7098 if (pi.readPermission != null) { 7099 allowed = false; 7100 } 7101 } 7102 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7103 if (pi.writePermission != null) { 7104 allowed = false; 7105 } 7106 } 7107 if (allowed) { 7108 return -1; 7109 } 7110 } 7111 7112 /* There is a special cross user grant if: 7113 * - The target is on another user. 7114 * - Apps on the current user can access the uri without any uid permissions. 7115 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7116 * grant uri permissions. 7117 */ 7118 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7119 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7120 modeFlags, false /*without considering the uid permissions*/); 7121 7122 // Second... is the provider allowing granting of URI permissions? 7123 if (!specialCrossUserGrant) { 7124 if (!pi.grantUriPermissions) { 7125 throw new SecurityException("Provider " + pi.packageName 7126 + "/" + pi.name 7127 + " does not allow granting of Uri permissions (uri " 7128 + grantUri + ")"); 7129 } 7130 if (pi.uriPermissionPatterns != null) { 7131 final int N = pi.uriPermissionPatterns.length; 7132 boolean allowed = false; 7133 for (int i=0; i<N; i++) { 7134 if (pi.uriPermissionPatterns[i] != null 7135 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7136 allowed = true; 7137 break; 7138 } 7139 } 7140 if (!allowed) { 7141 throw new SecurityException("Provider " + pi.packageName 7142 + "/" + pi.name 7143 + " does not allow granting of permission to path of Uri " 7144 + grantUri); 7145 } 7146 } 7147 } 7148 7149 // Third... does the caller itself have permission to access 7150 // this uri? 7151 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7152 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7153 // Require they hold a strong enough Uri permission 7154 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7155 throw new SecurityException("Uid " + callingUid 7156 + " does not have permission to uri " + grantUri); 7157 } 7158 } 7159 } 7160 return targetUid; 7161 } 7162 7163 /** 7164 * @param uri This uri must NOT contain an embedded userId. 7165 * @param userId The userId in which the uri is to be resolved. 7166 */ 7167 @Override 7168 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7169 final int modeFlags, int userId) { 7170 enforceNotIsolatedCaller("checkGrantUriPermission"); 7171 synchronized(this) { 7172 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7173 new GrantUri(userId, uri, false), modeFlags, -1); 7174 } 7175 } 7176 7177 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7178 final int modeFlags, UriPermissionOwner owner) { 7179 if (!Intent.isAccessUriMode(modeFlags)) { 7180 return; 7181 } 7182 7183 // So here we are: the caller has the assumed permission 7184 // to the uri, and the target doesn't. Let's now give this to 7185 // the target. 7186 7187 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7188 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7189 7190 final String authority = grantUri.uri.getAuthority(); 7191 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7192 if (pi == null) { 7193 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7194 return; 7195 } 7196 7197 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7198 grantUri.prefix = true; 7199 } 7200 final UriPermission perm = findOrCreateUriPermissionLocked( 7201 pi.packageName, targetPkg, targetUid, grantUri); 7202 perm.grantModes(modeFlags, owner); 7203 } 7204 7205 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7206 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7207 if (targetPkg == null) { 7208 throw new NullPointerException("targetPkg"); 7209 } 7210 int targetUid; 7211 final IPackageManager pm = AppGlobals.getPackageManager(); 7212 try { 7213 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7214 } catch (RemoteException ex) { 7215 return; 7216 } 7217 7218 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7219 targetUid); 7220 if (targetUid < 0) { 7221 return; 7222 } 7223 7224 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7225 owner); 7226 } 7227 7228 static class NeededUriGrants extends ArrayList<GrantUri> { 7229 final String targetPkg; 7230 final int targetUid; 7231 final int flags; 7232 7233 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7234 this.targetPkg = targetPkg; 7235 this.targetUid = targetUid; 7236 this.flags = flags; 7237 } 7238 } 7239 7240 /** 7241 * Like checkGrantUriPermissionLocked, but takes an Intent. 7242 */ 7243 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7244 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7246 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7247 + " clip=" + (intent != null ? intent.getClipData() : null) 7248 + " from " + intent + "; flags=0x" 7249 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7250 7251 if (targetPkg == null) { 7252 throw new NullPointerException("targetPkg"); 7253 } 7254 7255 if (intent == null) { 7256 return null; 7257 } 7258 Uri data = intent.getData(); 7259 ClipData clip = intent.getClipData(); 7260 if (data == null && clip == null) { 7261 return null; 7262 } 7263 // Default userId for uris in the intent (if they don't specify it themselves) 7264 int contentUserHint = intent.getContentUserHint(); 7265 if (contentUserHint == UserHandle.USER_CURRENT) { 7266 contentUserHint = UserHandle.getUserId(callingUid); 7267 } 7268 final IPackageManager pm = AppGlobals.getPackageManager(); 7269 int targetUid; 7270 if (needed != null) { 7271 targetUid = needed.targetUid; 7272 } else { 7273 try { 7274 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7275 } catch (RemoteException ex) { 7276 return null; 7277 } 7278 if (targetUid < 0) { 7279 if (DEBUG_URI_PERMISSION) { 7280 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7281 + " on user " + targetUserId); 7282 } 7283 return null; 7284 } 7285 } 7286 if (data != null) { 7287 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7288 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7289 targetUid); 7290 if (targetUid > 0) { 7291 if (needed == null) { 7292 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7293 } 7294 needed.add(grantUri); 7295 } 7296 } 7297 if (clip != null) { 7298 for (int i=0; i<clip.getItemCount(); i++) { 7299 Uri uri = clip.getItemAt(i).getUri(); 7300 if (uri != null) { 7301 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7302 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7303 targetUid); 7304 if (targetUid > 0) { 7305 if (needed == null) { 7306 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7307 } 7308 needed.add(grantUri); 7309 } 7310 } else { 7311 Intent clipIntent = clip.getItemAt(i).getIntent(); 7312 if (clipIntent != null) { 7313 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7314 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7315 if (newNeeded != null) { 7316 needed = newNeeded; 7317 } 7318 } 7319 } 7320 } 7321 } 7322 7323 return needed; 7324 } 7325 7326 /** 7327 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7328 */ 7329 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7330 UriPermissionOwner owner) { 7331 if (needed != null) { 7332 for (int i=0; i<needed.size(); i++) { 7333 GrantUri grantUri = needed.get(i); 7334 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7335 grantUri, needed.flags, owner); 7336 } 7337 } 7338 } 7339 7340 void grantUriPermissionFromIntentLocked(int callingUid, 7341 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7342 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7343 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7344 if (needed == null) { 7345 return; 7346 } 7347 7348 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7349 } 7350 7351 /** 7352 * @param uri This uri must NOT contain an embedded userId. 7353 * @param userId The userId in which the uri is to be resolved. 7354 */ 7355 @Override 7356 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7357 final int modeFlags, int userId) { 7358 enforceNotIsolatedCaller("grantUriPermission"); 7359 GrantUri grantUri = new GrantUri(userId, uri, false); 7360 synchronized(this) { 7361 final ProcessRecord r = getRecordForAppLocked(caller); 7362 if (r == null) { 7363 throw new SecurityException("Unable to find app for caller " 7364 + caller 7365 + " when granting permission to uri " + grantUri); 7366 } 7367 if (targetPkg == null) { 7368 throw new IllegalArgumentException("null target"); 7369 } 7370 if (grantUri == null) { 7371 throw new IllegalArgumentException("null uri"); 7372 } 7373 7374 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7376 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7377 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7378 7379 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7380 UserHandle.getUserId(r.uid)); 7381 } 7382 } 7383 7384 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7385 if (perm.modeFlags == 0) { 7386 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7387 perm.targetUid); 7388 if (perms != null) { 7389 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7390 "Removing " + perm.targetUid + " permission to " + perm.uri); 7391 7392 perms.remove(perm.uri); 7393 if (perms.isEmpty()) { 7394 mGrantedUriPermissions.remove(perm.targetUid); 7395 } 7396 } 7397 } 7398 } 7399 7400 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7401 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7402 7403 final IPackageManager pm = AppGlobals.getPackageManager(); 7404 final String authority = grantUri.uri.getAuthority(); 7405 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7406 if (pi == null) { 7407 Slog.w(TAG, "No content provider found for permission revoke: " 7408 + grantUri.toSafeString()); 7409 return; 7410 } 7411 7412 // Does the caller have this permission on the URI? 7413 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7414 // Right now, if you are not the original owner of the permission, 7415 // you are not allowed to revoke it. 7416 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7417 throw new SecurityException("Uid " + callingUid 7418 + " does not have permission to uri " + grantUri); 7419 //} 7420 } 7421 7422 boolean persistChanged = false; 7423 7424 // Go through all of the permissions and remove any that match. 7425 int N = mGrantedUriPermissions.size(); 7426 for (int i = 0; i < N; i++) { 7427 final int targetUid = mGrantedUriPermissions.keyAt(i); 7428 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7429 7430 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7431 final UriPermission perm = it.next(); 7432 if (perm.uri.sourceUserId == grantUri.sourceUserId 7433 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7434 if (DEBUG_URI_PERMISSION) 7435 Slog.v(TAG, 7436 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7437 persistChanged |= perm.revokeModes( 7438 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7439 if (perm.modeFlags == 0) { 7440 it.remove(); 7441 } 7442 } 7443 } 7444 7445 if (perms.isEmpty()) { 7446 mGrantedUriPermissions.remove(targetUid); 7447 N--; 7448 i--; 7449 } 7450 } 7451 7452 if (persistChanged) { 7453 schedulePersistUriGrants(); 7454 } 7455 } 7456 7457 /** 7458 * @param uri This uri must NOT contain an embedded userId. 7459 * @param userId The userId in which the uri is to be resolved. 7460 */ 7461 @Override 7462 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7463 int userId) { 7464 enforceNotIsolatedCaller("revokeUriPermission"); 7465 synchronized(this) { 7466 final ProcessRecord r = getRecordForAppLocked(caller); 7467 if (r == null) { 7468 throw new SecurityException("Unable to find app for caller " 7469 + caller 7470 + " when revoking permission to uri " + uri); 7471 } 7472 if (uri == null) { 7473 Slog.w(TAG, "revokeUriPermission: null uri"); 7474 return; 7475 } 7476 7477 if (!Intent.isAccessUriMode(modeFlags)) { 7478 return; 7479 } 7480 7481 final IPackageManager pm = AppGlobals.getPackageManager(); 7482 final String authority = uri.getAuthority(); 7483 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7484 if (pi == null) { 7485 Slog.w(TAG, "No content provider found for permission revoke: " 7486 + uri.toSafeString()); 7487 return; 7488 } 7489 7490 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7491 } 7492 } 7493 7494 /** 7495 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7496 * given package. 7497 * 7498 * @param packageName Package name to match, or {@code null} to apply to all 7499 * packages. 7500 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7501 * to all users. 7502 * @param persistable If persistable grants should be removed. 7503 */ 7504 private void removeUriPermissionsForPackageLocked( 7505 String packageName, int userHandle, boolean persistable) { 7506 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7507 throw new IllegalArgumentException("Must narrow by either package or user"); 7508 } 7509 7510 boolean persistChanged = false; 7511 7512 int N = mGrantedUriPermissions.size(); 7513 for (int i = 0; i < N; i++) { 7514 final int targetUid = mGrantedUriPermissions.keyAt(i); 7515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7516 7517 // Only inspect grants matching user 7518 if (userHandle == UserHandle.USER_ALL 7519 || userHandle == UserHandle.getUserId(targetUid)) { 7520 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7521 final UriPermission perm = it.next(); 7522 7523 // Only inspect grants matching package 7524 if (packageName == null || perm.sourcePkg.equals(packageName) 7525 || perm.targetPkg.equals(packageName)) { 7526 persistChanged |= perm.revokeModes( 7527 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7528 7529 // Only remove when no modes remain; any persisted grants 7530 // will keep this alive. 7531 if (perm.modeFlags == 0) { 7532 it.remove(); 7533 } 7534 } 7535 } 7536 7537 if (perms.isEmpty()) { 7538 mGrantedUriPermissions.remove(targetUid); 7539 N--; 7540 i--; 7541 } 7542 } 7543 } 7544 7545 if (persistChanged) { 7546 schedulePersistUriGrants(); 7547 } 7548 } 7549 7550 @Override 7551 public IBinder newUriPermissionOwner(String name) { 7552 enforceNotIsolatedCaller("newUriPermissionOwner"); 7553 synchronized(this) { 7554 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7555 return owner.getExternalTokenLocked(); 7556 } 7557 } 7558 7559 /** 7560 * @param uri This uri must NOT contain an embedded userId. 7561 * @param sourceUserId The userId in which the uri is to be resolved. 7562 * @param targetUserId The userId of the app that receives the grant. 7563 */ 7564 @Override 7565 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7566 final int modeFlags, int sourceUserId, int targetUserId) { 7567 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7568 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7569 synchronized(this) { 7570 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7571 if (owner == null) { 7572 throw new IllegalArgumentException("Unknown owner: " + token); 7573 } 7574 if (fromUid != Binder.getCallingUid()) { 7575 if (Binder.getCallingUid() != Process.myUid()) { 7576 // Only system code can grant URI permissions on behalf 7577 // of other users. 7578 throw new SecurityException("nice try"); 7579 } 7580 } 7581 if (targetPkg == null) { 7582 throw new IllegalArgumentException("null target"); 7583 } 7584 if (uri == null) { 7585 throw new IllegalArgumentException("null uri"); 7586 } 7587 7588 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7589 modeFlags, owner, targetUserId); 7590 } 7591 } 7592 7593 /** 7594 * @param uri This uri must NOT contain an embedded userId. 7595 * @param userId The userId in which the uri is to be resolved. 7596 */ 7597 @Override 7598 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 7605 if (uri == null) { 7606 owner.removeUriPermissionsLocked(mode); 7607 } else { 7608 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7609 } 7610 } 7611 } 7612 7613 private void schedulePersistUriGrants() { 7614 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7615 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7616 10 * DateUtils.SECOND_IN_MILLIS); 7617 } 7618 } 7619 7620 private void writeGrantedUriPermissions() { 7621 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7622 7623 // Snapshot permissions so we can persist without lock 7624 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7625 synchronized (this) { 7626 final int size = mGrantedUriPermissions.size(); 7627 for (int i = 0; i < size; i++) { 7628 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7629 for (UriPermission perm : perms.values()) { 7630 if (perm.persistedModeFlags != 0) { 7631 persist.add(perm.snapshot()); 7632 } 7633 } 7634 } 7635 } 7636 7637 FileOutputStream fos = null; 7638 try { 7639 fos = mGrantFile.startWrite(); 7640 7641 XmlSerializer out = new FastXmlSerializer(); 7642 out.setOutput(fos, "utf-8"); 7643 out.startDocument(null, true); 7644 out.startTag(null, TAG_URI_GRANTS); 7645 for (UriPermission.Snapshot perm : persist) { 7646 out.startTag(null, TAG_URI_GRANT); 7647 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7648 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7649 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7650 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7651 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7652 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7653 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7654 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7655 out.endTag(null, TAG_URI_GRANT); 7656 } 7657 out.endTag(null, TAG_URI_GRANTS); 7658 out.endDocument(); 7659 7660 mGrantFile.finishWrite(fos); 7661 } catch (IOException e) { 7662 if (fos != null) { 7663 mGrantFile.failWrite(fos); 7664 } 7665 } 7666 } 7667 7668 private void readGrantedUriPermissionsLocked() { 7669 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7670 7671 final long now = System.currentTimeMillis(); 7672 7673 FileInputStream fis = null; 7674 try { 7675 fis = mGrantFile.openRead(); 7676 final XmlPullParser in = Xml.newPullParser(); 7677 in.setInput(fis, null); 7678 7679 int type; 7680 while ((type = in.next()) != END_DOCUMENT) { 7681 final String tag = in.getName(); 7682 if (type == START_TAG) { 7683 if (TAG_URI_GRANT.equals(tag)) { 7684 final int sourceUserId; 7685 final int targetUserId; 7686 final int userHandle = readIntAttribute(in, 7687 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7688 if (userHandle != UserHandle.USER_NULL) { 7689 // For backwards compatibility. 7690 sourceUserId = userHandle; 7691 targetUserId = userHandle; 7692 } else { 7693 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7694 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7695 } 7696 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7697 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7698 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7699 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7700 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7701 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7702 7703 // Sanity check that provider still belongs to source package 7704 final ProviderInfo pi = getProviderInfoLocked( 7705 uri.getAuthority(), sourceUserId); 7706 if (pi != null && sourcePkg.equals(pi.packageName)) { 7707 int targetUid = -1; 7708 try { 7709 targetUid = AppGlobals.getPackageManager() 7710 .getPackageUid(targetPkg, targetUserId); 7711 } catch (RemoteException e) { 7712 } 7713 if (targetUid != -1) { 7714 final UriPermission perm = findOrCreateUriPermissionLocked( 7715 sourcePkg, targetPkg, targetUid, 7716 new GrantUri(sourceUserId, uri, prefix)); 7717 perm.initPersistedModes(modeFlags, createdTime); 7718 } 7719 } else { 7720 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7721 + " but instead found " + pi); 7722 } 7723 } 7724 } 7725 } 7726 } catch (FileNotFoundException e) { 7727 // Missing grants is okay 7728 } catch (IOException e) { 7729 Log.wtf(TAG, "Failed reading Uri grants", e); 7730 } catch (XmlPullParserException e) { 7731 Log.wtf(TAG, "Failed reading Uri grants", e); 7732 } finally { 7733 IoUtils.closeQuietly(fis); 7734 } 7735 } 7736 7737 /** 7738 * @param uri This uri must NOT contain an embedded userId. 7739 * @param userId The userId in which the uri is to be resolved. 7740 */ 7741 @Override 7742 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7743 enforceNotIsolatedCaller("takePersistableUriPermission"); 7744 7745 Preconditions.checkFlagsArgument(modeFlags, 7746 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7747 7748 synchronized (this) { 7749 final int callingUid = Binder.getCallingUid(); 7750 boolean persistChanged = false; 7751 GrantUri grantUri = new GrantUri(userId, uri, false); 7752 7753 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7754 new GrantUri(userId, uri, false)); 7755 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7756 new GrantUri(userId, uri, true)); 7757 7758 final boolean exactValid = (exactPerm != null) 7759 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7760 final boolean prefixValid = (prefixPerm != null) 7761 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7762 7763 if (!(exactValid || prefixValid)) { 7764 throw new SecurityException("No persistable permission grants found for UID " 7765 + callingUid + " and Uri " + grantUri.toSafeString()); 7766 } 7767 7768 if (exactValid) { 7769 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7770 } 7771 if (prefixValid) { 7772 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7773 } 7774 7775 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7776 7777 if (persistChanged) { 7778 schedulePersistUriGrants(); 7779 } 7780 } 7781 } 7782 7783 /** 7784 * @param uri This uri must NOT contain an embedded userId. 7785 * @param userId The userId in which the uri is to be resolved. 7786 */ 7787 @Override 7788 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7789 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7790 7791 Preconditions.checkFlagsArgument(modeFlags, 7792 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7793 7794 synchronized (this) { 7795 final int callingUid = Binder.getCallingUid(); 7796 boolean persistChanged = false; 7797 7798 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7799 new GrantUri(userId, uri, false)); 7800 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7801 new GrantUri(userId, uri, true)); 7802 if (exactPerm == null && prefixPerm == null) { 7803 throw new SecurityException("No permission grants found for UID " + callingUid 7804 + " and Uri " + uri.toSafeString()); 7805 } 7806 7807 if (exactPerm != null) { 7808 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7809 removeUriPermissionIfNeededLocked(exactPerm); 7810 } 7811 if (prefixPerm != null) { 7812 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7813 removeUriPermissionIfNeededLocked(prefixPerm); 7814 } 7815 7816 if (persistChanged) { 7817 schedulePersistUriGrants(); 7818 } 7819 } 7820 } 7821 7822 /** 7823 * Prune any older {@link UriPermission} for the given UID until outstanding 7824 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7825 * 7826 * @return if any mutations occured that require persisting. 7827 */ 7828 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7829 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7830 if (perms == null) return false; 7831 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7832 7833 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7834 for (UriPermission perm : perms.values()) { 7835 if (perm.persistedModeFlags != 0) { 7836 persisted.add(perm); 7837 } 7838 } 7839 7840 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7841 if (trimCount <= 0) return false; 7842 7843 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7844 for (int i = 0; i < trimCount; i++) { 7845 final UriPermission perm = persisted.get(i); 7846 7847 if (DEBUG_URI_PERMISSION) { 7848 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7849 } 7850 7851 perm.releasePersistableModes(~0); 7852 removeUriPermissionIfNeededLocked(perm); 7853 } 7854 7855 return true; 7856 } 7857 7858 @Override 7859 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7860 String packageName, boolean incoming) { 7861 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7862 Preconditions.checkNotNull(packageName, "packageName"); 7863 7864 final int callingUid = Binder.getCallingUid(); 7865 final IPackageManager pm = AppGlobals.getPackageManager(); 7866 try { 7867 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7868 if (packageUid != callingUid) { 7869 throw new SecurityException( 7870 "Package " + packageName + " does not belong to calling UID " + callingUid); 7871 } 7872 } catch (RemoteException e) { 7873 throw new SecurityException("Failed to verify package name ownership"); 7874 } 7875 7876 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7877 synchronized (this) { 7878 if (incoming) { 7879 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7880 callingUid); 7881 if (perms == null) { 7882 Slog.w(TAG, "No permission grants found for " + packageName); 7883 } else { 7884 for (UriPermission perm : perms.values()) { 7885 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7886 result.add(perm.buildPersistedPublicApiObject()); 7887 } 7888 } 7889 } 7890 } else { 7891 final int size = mGrantedUriPermissions.size(); 7892 for (int i = 0; i < size; i++) { 7893 final ArrayMap<GrantUri, UriPermission> perms = 7894 mGrantedUriPermissions.valueAt(i); 7895 for (UriPermission perm : perms.values()) { 7896 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7897 result.add(perm.buildPersistedPublicApiObject()); 7898 } 7899 } 7900 } 7901 } 7902 } 7903 return new ParceledListSlice<android.content.UriPermission>(result); 7904 } 7905 7906 @Override 7907 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7908 synchronized (this) { 7909 ProcessRecord app = 7910 who != null ? getRecordForAppLocked(who) : null; 7911 if (app == null) return; 7912 7913 Message msg = Message.obtain(); 7914 msg.what = WAIT_FOR_DEBUGGER_MSG; 7915 msg.obj = app; 7916 msg.arg1 = waiting ? 1 : 0; 7917 mHandler.sendMessage(msg); 7918 } 7919 } 7920 7921 @Override 7922 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7923 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7924 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7925 outInfo.availMem = Process.getFreeMemory(); 7926 outInfo.totalMem = Process.getTotalMemory(); 7927 outInfo.threshold = homeAppMem; 7928 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7929 outInfo.hiddenAppThreshold = cachedAppMem; 7930 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7931 ProcessList.SERVICE_ADJ); 7932 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7933 ProcessList.VISIBLE_APP_ADJ); 7934 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7935 ProcessList.FOREGROUND_APP_ADJ); 7936 } 7937 7938 // ========================================================= 7939 // TASK MANAGEMENT 7940 // ========================================================= 7941 7942 @Override 7943 public List<IAppTask> getAppTasks(String callingPackage) { 7944 int callingUid = Binder.getCallingUid(); 7945 long ident = Binder.clearCallingIdentity(); 7946 7947 synchronized(this) { 7948 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7949 try { 7950 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7951 7952 final int N = mRecentTasks.size(); 7953 for (int i = 0; i < N; i++) { 7954 TaskRecord tr = mRecentTasks.get(i); 7955 // Skip tasks that do not match the caller. We don't need to verify 7956 // callingPackage, because we are also limiting to callingUid and know 7957 // that will limit to the correct security sandbox. 7958 if (tr.effectiveUid != callingUid) { 7959 continue; 7960 } 7961 Intent intent = tr.getBaseIntent(); 7962 if (intent == null || 7963 !callingPackage.equals(intent.getComponent().getPackageName())) { 7964 continue; 7965 } 7966 ActivityManager.RecentTaskInfo taskInfo = 7967 createRecentTaskInfoFromTaskRecord(tr); 7968 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7969 list.add(taskImpl); 7970 } 7971 } finally { 7972 Binder.restoreCallingIdentity(ident); 7973 } 7974 return list; 7975 } 7976 } 7977 7978 @Override 7979 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7980 final int callingUid = Binder.getCallingUid(); 7981 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7982 7983 synchronized(this) { 7984 if (localLOGV) Slog.v( 7985 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7986 7987 final boolean allowed = checkCallingPermission( 7988 android.Manifest.permission.GET_TASKS) 7989 == PackageManager.PERMISSION_GRANTED; 7990 if (!allowed) { 7991 Slog.w(TAG, "getTasks: caller " + callingUid 7992 + " does not hold GET_TASKS; limiting output"); 7993 } 7994 7995 // TODO: Improve with MRU list from all ActivityStacks. 7996 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7997 } 7998 7999 return list; 8000 } 8001 8002 TaskRecord getMostRecentTask() { 8003 return mRecentTasks.get(0); 8004 } 8005 8006 /** 8007 * Creates a new RecentTaskInfo from a TaskRecord. 8008 */ 8009 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8010 // Update the task description to reflect any changes in the task stack 8011 tr.updateTaskDescription(); 8012 8013 // Compose the recent task info 8014 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8015 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8016 rti.persistentId = tr.taskId; 8017 rti.baseIntent = new Intent(tr.getBaseIntent()); 8018 rti.origActivity = tr.origActivity; 8019 rti.description = tr.lastDescription; 8020 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8021 rti.userId = tr.userId; 8022 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8023 rti.firstActiveTime = tr.firstActiveTime; 8024 rti.lastActiveTime = tr.lastActiveTime; 8025 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8026 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8027 return rti; 8028 } 8029 8030 @Override 8031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8032 final int callingUid = Binder.getCallingUid(); 8033 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8034 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8035 8036 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8037 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8038 synchronized (this) { 8039 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8040 == PackageManager.PERMISSION_GRANTED; 8041 if (!allowed) { 8042 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8043 + " does not hold GET_TASKS; limiting output"); 8044 } 8045 final boolean detailed = checkCallingPermission( 8046 android.Manifest.permission.GET_DETAILED_TASKS) 8047 == PackageManager.PERMISSION_GRANTED; 8048 8049 final int N = mRecentTasks.size(); 8050 ArrayList<ActivityManager.RecentTaskInfo> res 8051 = new ArrayList<ActivityManager.RecentTaskInfo>( 8052 maxNum < N ? maxNum : N); 8053 8054 final Set<Integer> includedUsers; 8055 if (includeProfiles) { 8056 includedUsers = getProfileIdsLocked(userId); 8057 } else { 8058 includedUsers = new HashSet<Integer>(); 8059 } 8060 includedUsers.add(Integer.valueOf(userId)); 8061 8062 for (int i=0; i<N && maxNum > 0; i++) { 8063 TaskRecord tr = mRecentTasks.get(i); 8064 // Only add calling user or related users recent tasks 8065 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8066 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8067 continue; 8068 } 8069 8070 // Return the entry if desired by the caller. We always return 8071 // the first entry, because callers always expect this to be the 8072 // foreground app. We may filter others if the caller has 8073 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8074 // we should exclude the entry. 8075 8076 if (i == 0 8077 || withExcluded 8078 || (tr.intent == null) 8079 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8080 == 0)) { 8081 if (!allowed) { 8082 // If the caller doesn't have the GET_TASKS permission, then only 8083 // allow them to see a small subset of tasks -- their own and home. 8084 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8085 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8086 continue; 8087 } 8088 } 8089 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8090 if (tr.stack != null && tr.stack.isHomeStack()) { 8091 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8092 continue; 8093 } 8094 } 8095 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8096 // Don't include auto remove tasks that are finished or finishing. 8097 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8098 + tr); 8099 continue; 8100 } 8101 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8102 && !tr.isAvailable) { 8103 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8104 continue; 8105 } 8106 8107 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8108 if (!detailed) { 8109 rti.baseIntent.replaceExtras((Bundle)null); 8110 } 8111 8112 res.add(rti); 8113 maxNum--; 8114 } 8115 } 8116 return res; 8117 } 8118 } 8119 8120 private TaskRecord recentTaskForIdLocked(int id) { 8121 final int N = mRecentTasks.size(); 8122 for (int i=0; i<N; i++) { 8123 TaskRecord tr = mRecentTasks.get(i); 8124 if (tr.taskId == id) { 8125 return tr; 8126 } 8127 } 8128 return null; 8129 } 8130 8131 @Override 8132 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8133 synchronized (this) { 8134 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8135 "getTaskThumbnail()"); 8136 TaskRecord tr = recentTaskForIdLocked(id); 8137 if (tr != null) { 8138 return tr.getTaskThumbnailLocked(); 8139 } 8140 } 8141 return null; 8142 } 8143 8144 @Override 8145 public int addAppTask(IBinder activityToken, Intent intent, 8146 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8147 final int callingUid = Binder.getCallingUid(); 8148 final long callingIdent = Binder.clearCallingIdentity(); 8149 8150 try { 8151 synchronized (this) { 8152 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8153 if (r == null) { 8154 throw new IllegalArgumentException("Activity does not exist; token=" 8155 + activityToken); 8156 } 8157 ComponentName comp = intent.getComponent(); 8158 if (comp == null) { 8159 throw new IllegalArgumentException("Intent " + intent 8160 + " must specify explicit component"); 8161 } 8162 if (thumbnail.getWidth() != mThumbnailWidth 8163 || thumbnail.getHeight() != mThumbnailHeight) { 8164 throw new IllegalArgumentException("Bad thumbnail size: got " 8165 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8166 + mThumbnailWidth + "x" + mThumbnailHeight); 8167 } 8168 if (intent.getSelector() != null) { 8169 intent.setSelector(null); 8170 } 8171 if (intent.getSourceBounds() != null) { 8172 intent.setSourceBounds(null); 8173 } 8174 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8175 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8176 // The caller has added this as an auto-remove task... that makes no 8177 // sense, so turn off auto-remove. 8178 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8179 } 8180 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8181 // Must be a new task. 8182 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8183 } 8184 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8185 mLastAddedTaskActivity = null; 8186 } 8187 ActivityInfo ainfo = mLastAddedTaskActivity; 8188 if (ainfo == null) { 8189 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8190 comp, 0, UserHandle.getUserId(callingUid)); 8191 if (ainfo.applicationInfo.uid != callingUid) { 8192 throw new SecurityException( 8193 "Can't add task for another application: target uid=" 8194 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8195 } 8196 } 8197 8198 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8199 intent, description); 8200 8201 int trimIdx = trimRecentsForTask(task, false); 8202 if (trimIdx >= 0) { 8203 // If this would have caused a trim, then we'll abort because that 8204 // means it would be added at the end of the list but then just removed. 8205 return -1; 8206 } 8207 8208 final int N = mRecentTasks.size(); 8209 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8210 final TaskRecord tr = mRecentTasks.remove(N - 1); 8211 tr.removedFromRecents(mTaskPersister); 8212 } 8213 8214 task.inRecents = true; 8215 mRecentTasks.add(task); 8216 r.task.stack.addTask(task, false, false); 8217 8218 task.setLastThumbnail(thumbnail); 8219 task.freeLastThumbnail(); 8220 8221 return task.taskId; 8222 } 8223 } finally { 8224 Binder.restoreCallingIdentity(callingIdent); 8225 } 8226 } 8227 8228 @Override 8229 public Point getAppTaskThumbnailSize() { 8230 synchronized (this) { 8231 return new Point(mThumbnailWidth, mThumbnailHeight); 8232 } 8233 } 8234 8235 @Override 8236 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8237 synchronized (this) { 8238 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8239 if (r != null) { 8240 r.taskDescription = td; 8241 r.task.updateTaskDescription(); 8242 } 8243 } 8244 } 8245 8246 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8247 mRecentTasks.remove(tr); 8248 tr.removedFromRecents(mTaskPersister); 8249 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8250 Intent baseIntent = new Intent( 8251 tr.intent != null ? tr.intent : tr.affinityIntent); 8252 ComponentName component = baseIntent.getComponent(); 8253 if (component == null) { 8254 Slog.w(TAG, "Now component for base intent of task: " + tr); 8255 return; 8256 } 8257 8258 // Find any running services associated with this app. 8259 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8260 8261 if (killProcesses) { 8262 // Find any running processes associated with this app. 8263 final String pkg = component.getPackageName(); 8264 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8265 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8266 for (int i=0; i<pmap.size(); i++) { 8267 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8268 for (int j=0; j<uids.size(); j++) { 8269 ProcessRecord proc = uids.valueAt(j); 8270 if (proc.userId != tr.userId) { 8271 continue; 8272 } 8273 if (!proc.pkgList.containsKey(pkg)) { 8274 continue; 8275 } 8276 procs.add(proc); 8277 } 8278 } 8279 8280 // Kill the running processes. 8281 for (int i=0; i<procs.size(); i++) { 8282 ProcessRecord pr = procs.get(i); 8283 if (pr == mHomeProcess) { 8284 // Don't kill the home process along with tasks from the same package. 8285 continue; 8286 } 8287 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8288 pr.kill("remove task", true); 8289 } else { 8290 pr.waitingToKill = "remove task"; 8291 } 8292 } 8293 } 8294 } 8295 8296 /** 8297 * Removes the task with the specified task id. 8298 * 8299 * @param taskId Identifier of the task to be removed. 8300 * @param flags Additional operational flags. May be 0 or 8301 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8302 * @return Returns true if the given task was found and removed. 8303 */ 8304 private boolean removeTaskByIdLocked(int taskId, int flags) { 8305 TaskRecord tr = recentTaskForIdLocked(taskId); 8306 if (tr != null) { 8307 tr.removeTaskActivitiesLocked(); 8308 cleanUpRemovedTaskLocked(tr, flags); 8309 if (tr.isPersistable) { 8310 notifyTaskPersisterLocked(null, true); 8311 } 8312 return true; 8313 } 8314 return false; 8315 } 8316 8317 @Override 8318 public boolean removeTask(int taskId, int flags) { 8319 synchronized (this) { 8320 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8321 "removeTask()"); 8322 long ident = Binder.clearCallingIdentity(); 8323 try { 8324 return removeTaskByIdLocked(taskId, flags); 8325 } finally { 8326 Binder.restoreCallingIdentity(ident); 8327 } 8328 } 8329 } 8330 8331 /** 8332 * TODO: Add mController hook 8333 */ 8334 @Override 8335 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8336 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8337 "moveTaskToFront()"); 8338 8339 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8340 synchronized(this) { 8341 moveTaskToFrontLocked(taskId, flags, options); 8342 } 8343 } 8344 8345 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8346 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8347 Binder.getCallingUid(), "Task to front")) { 8348 ActivityOptions.abort(options); 8349 return; 8350 } 8351 final long origId = Binder.clearCallingIdentity(); 8352 try { 8353 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8354 if (task == null) { 8355 return; 8356 } 8357 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8358 mStackSupervisor.showLockTaskToast(); 8359 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8360 return; 8361 } 8362 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8363 if (prev != null && prev.isRecentsActivity()) { 8364 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8365 } 8366 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8367 } finally { 8368 Binder.restoreCallingIdentity(origId); 8369 } 8370 ActivityOptions.abort(options); 8371 } 8372 8373 @Override 8374 public void moveTaskToBack(int taskId) { 8375 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8376 "moveTaskToBack()"); 8377 8378 synchronized(this) { 8379 TaskRecord tr = recentTaskForIdLocked(taskId); 8380 if (tr != null) { 8381 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8382 ActivityStack stack = tr.stack; 8383 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8385 Binder.getCallingUid(), "Task to back")) { 8386 return; 8387 } 8388 } 8389 final long origId = Binder.clearCallingIdentity(); 8390 try { 8391 stack.moveTaskToBackLocked(taskId, null); 8392 } finally { 8393 Binder.restoreCallingIdentity(origId); 8394 } 8395 } 8396 } 8397 } 8398 8399 /** 8400 * Moves an activity, and all of the other activities within the same task, to the bottom 8401 * of the history stack. The activity's order within the task is unchanged. 8402 * 8403 * @param token A reference to the activity we wish to move 8404 * @param nonRoot If false then this only works if the activity is the root 8405 * of a task; if true it will work for any activity in a task. 8406 * @return Returns true if the move completed, false if not. 8407 */ 8408 @Override 8409 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8410 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8411 synchronized(this) { 8412 final long origId = Binder.clearCallingIdentity(); 8413 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8414 if (taskId >= 0) { 8415 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8416 } 8417 Binder.restoreCallingIdentity(origId); 8418 } 8419 return false; 8420 } 8421 8422 @Override 8423 public void moveTaskBackwards(int task) { 8424 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8425 "moveTaskBackwards()"); 8426 8427 synchronized(this) { 8428 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8429 Binder.getCallingUid(), "Task backwards")) { 8430 return; 8431 } 8432 final long origId = Binder.clearCallingIdentity(); 8433 moveTaskBackwardsLocked(task); 8434 Binder.restoreCallingIdentity(origId); 8435 } 8436 } 8437 8438 private final void moveTaskBackwardsLocked(int task) { 8439 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8440 } 8441 8442 @Override 8443 public IBinder getHomeActivityToken() throws RemoteException { 8444 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8445 "getHomeActivityToken()"); 8446 synchronized (this) { 8447 return mStackSupervisor.getHomeActivityToken(); 8448 } 8449 } 8450 8451 @Override 8452 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8453 IActivityContainerCallback callback) throws RemoteException { 8454 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8455 "createActivityContainer()"); 8456 synchronized (this) { 8457 if (parentActivityToken == null) { 8458 throw new IllegalArgumentException("parent token must not be null"); 8459 } 8460 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8461 if (r == null) { 8462 return null; 8463 } 8464 if (callback == null) { 8465 throw new IllegalArgumentException("callback must not be null"); 8466 } 8467 return mStackSupervisor.createActivityContainer(r, callback); 8468 } 8469 } 8470 8471 @Override 8472 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8473 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8474 "deleteActivityContainer()"); 8475 synchronized (this) { 8476 mStackSupervisor.deleteActivityContainer(container); 8477 } 8478 } 8479 8480 @Override 8481 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8482 throws RemoteException { 8483 synchronized (this) { 8484 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8485 if (stack != null) { 8486 return stack.mActivityContainer; 8487 } 8488 return null; 8489 } 8490 } 8491 8492 @Override 8493 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8494 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8495 "moveTaskToStack()"); 8496 if (stackId == HOME_STACK_ID) { 8497 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8498 new RuntimeException("here").fillInStackTrace()); 8499 } 8500 synchronized (this) { 8501 long ident = Binder.clearCallingIdentity(); 8502 try { 8503 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8504 + stackId + " toTop=" + toTop); 8505 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8506 } finally { 8507 Binder.restoreCallingIdentity(ident); 8508 } 8509 } 8510 } 8511 8512 @Override 8513 public void resizeStack(int stackBoxId, Rect bounds) { 8514 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8515 "resizeStackBox()"); 8516 long ident = Binder.clearCallingIdentity(); 8517 try { 8518 mWindowManager.resizeStack(stackBoxId, bounds); 8519 } finally { 8520 Binder.restoreCallingIdentity(ident); 8521 } 8522 } 8523 8524 @Override 8525 public List<StackInfo> getAllStackInfos() { 8526 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8527 "getAllStackInfos()"); 8528 long ident = Binder.clearCallingIdentity(); 8529 try { 8530 synchronized (this) { 8531 return mStackSupervisor.getAllStackInfosLocked(); 8532 } 8533 } finally { 8534 Binder.restoreCallingIdentity(ident); 8535 } 8536 } 8537 8538 @Override 8539 public StackInfo getStackInfo(int stackId) { 8540 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8541 "getStackInfo()"); 8542 long ident = Binder.clearCallingIdentity(); 8543 try { 8544 synchronized (this) { 8545 return mStackSupervisor.getStackInfoLocked(stackId); 8546 } 8547 } finally { 8548 Binder.restoreCallingIdentity(ident); 8549 } 8550 } 8551 8552 @Override 8553 public boolean isInHomeStack(int taskId) { 8554 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8555 "getStackInfo()"); 8556 long ident = Binder.clearCallingIdentity(); 8557 try { 8558 synchronized (this) { 8559 TaskRecord tr = recentTaskForIdLocked(taskId); 8560 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8561 } 8562 } finally { 8563 Binder.restoreCallingIdentity(ident); 8564 } 8565 } 8566 8567 @Override 8568 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8569 synchronized(this) { 8570 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8571 } 8572 } 8573 8574 private boolean isLockTaskAuthorized(String pkg) { 8575 final DevicePolicyManager dpm = (DevicePolicyManager) 8576 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8577 try { 8578 int uid = mContext.getPackageManager().getPackageUid(pkg, 8579 Binder.getCallingUserHandle().getIdentifier()); 8580 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8581 } catch (NameNotFoundException e) { 8582 return false; 8583 } 8584 } 8585 8586 void startLockTaskMode(TaskRecord task) { 8587 final String pkg; 8588 synchronized (this) { 8589 pkg = task.intent.getComponent().getPackageName(); 8590 } 8591 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8592 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8593 final TaskRecord taskRecord = task; 8594 mHandler.post(new Runnable() { 8595 @Override 8596 public void run() { 8597 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8598 } 8599 }); 8600 return; 8601 } 8602 long ident = Binder.clearCallingIdentity(); 8603 try { 8604 synchronized (this) { 8605 // Since we lost lock on task, make sure it is still there. 8606 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8607 if (task != null) { 8608 if (!isSystemInitiated 8609 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8610 throw new IllegalArgumentException("Invalid task, not in foreground"); 8611 } 8612 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8613 } 8614 } 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public void startLockTaskMode(int taskId) { 8622 final TaskRecord task; 8623 long ident = Binder.clearCallingIdentity(); 8624 try { 8625 synchronized (this) { 8626 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8627 } 8628 } finally { 8629 Binder.restoreCallingIdentity(ident); 8630 } 8631 if (task != null) { 8632 startLockTaskMode(task); 8633 } 8634 } 8635 8636 @Override 8637 public void startLockTaskMode(IBinder token) { 8638 final TaskRecord task; 8639 long ident = Binder.clearCallingIdentity(); 8640 try { 8641 synchronized (this) { 8642 final ActivityRecord r = ActivityRecord.forToken(token); 8643 if (r == null) { 8644 return; 8645 } 8646 task = r.task; 8647 } 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 if (task != null) { 8652 startLockTaskMode(task); 8653 } 8654 } 8655 8656 @Override 8657 public void startLockTaskModeOnCurrent() throws RemoteException { 8658 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8659 ActivityRecord r = null; 8660 synchronized (this) { 8661 r = mStackSupervisor.topRunningActivityLocked(); 8662 } 8663 startLockTaskMode(r.task); 8664 } 8665 8666 @Override 8667 public void stopLockTaskMode() { 8668 // Verify that the user matches the package of the intent for the TaskRecord 8669 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8670 // and stopLockTaskMode. 8671 final int callingUid = Binder.getCallingUid(); 8672 if (callingUid != Process.SYSTEM_UID) { 8673 try { 8674 String pkg = 8675 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8676 int uid = mContext.getPackageManager().getPackageUid(pkg, 8677 Binder.getCallingUserHandle().getIdentifier()); 8678 if (uid != callingUid) { 8679 throw new SecurityException("Invalid uid, expected " + uid); 8680 } 8681 } catch (NameNotFoundException e) { 8682 Log.d(TAG, "stopLockTaskMode " + e); 8683 return; 8684 } 8685 } 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 Log.d(TAG, "stopLockTaskMode"); 8689 // Stop lock task 8690 synchronized (this) { 8691 mStackSupervisor.setLockTaskModeLocked(null, false); 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(ident); 8695 } 8696 } 8697 8698 @Override 8699 public void stopLockTaskModeOnCurrent() throws RemoteException { 8700 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 stopLockTaskMode(); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public boolean isInLockTaskMode() { 8711 synchronized (this) { 8712 return mStackSupervisor.isInLockTaskMode(); 8713 } 8714 } 8715 8716 // ========================================================= 8717 // CONTENT PROVIDERS 8718 // ========================================================= 8719 8720 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8721 List<ProviderInfo> providers = null; 8722 try { 8723 providers = AppGlobals.getPackageManager(). 8724 queryContentProviders(app.processName, app.uid, 8725 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8726 } catch (RemoteException ex) { 8727 } 8728 if (DEBUG_MU) 8729 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8730 int userId = app.userId; 8731 if (providers != null) { 8732 int N = providers.size(); 8733 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8734 for (int i=0; i<N; i++) { 8735 ProviderInfo cpi = 8736 (ProviderInfo)providers.get(i); 8737 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8738 cpi.name, cpi.flags); 8739 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8740 // This is a singleton provider, but a user besides the 8741 // default user is asking to initialize a process it runs 8742 // in... well, no, it doesn't actually run in this process, 8743 // it runs in the process of the default user. Get rid of it. 8744 providers.remove(i); 8745 N--; 8746 i--; 8747 continue; 8748 } 8749 8750 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8751 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8752 if (cpr == null) { 8753 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8754 mProviderMap.putProviderByClass(comp, cpr); 8755 } 8756 if (DEBUG_MU) 8757 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8758 app.pubProviders.put(cpi.name, cpr); 8759 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8760 // Don't add this if it is a platform component that is marked 8761 // to run in multiple processes, because this is actually 8762 // part of the framework so doesn't make sense to track as a 8763 // separate apk in the process. 8764 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8765 mProcessStats); 8766 } 8767 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8768 } 8769 } 8770 return providers; 8771 } 8772 8773 /** 8774 * Check if {@link ProcessRecord} has a possible chance at accessing the 8775 * given {@link ProviderInfo}. Final permission checking is always done 8776 * in {@link ContentProvider}. 8777 */ 8778 private final String checkContentProviderPermissionLocked( 8779 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8780 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8781 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8782 boolean checkedGrants = false; 8783 if (checkUser) { 8784 // Looking for cross-user grants before enforcing the typical cross-users permissions 8785 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8786 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8787 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8788 return null; 8789 } 8790 checkedGrants = true; 8791 } 8792 userId = handleIncomingUser(callingPid, callingUid, userId, 8793 false, ALLOW_NON_FULL, 8794 "checkContentProviderPermissionLocked " + cpi.authority, null); 8795 if (userId != tmpTargetUserId) { 8796 // When we actually went to determine the final targer user ID, this ended 8797 // up different than our initial check for the authority. This is because 8798 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8799 // SELF. So we need to re-check the grants again. 8800 checkedGrants = false; 8801 } 8802 } 8803 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8804 cpi.applicationInfo.uid, cpi.exported) 8805 == PackageManager.PERMISSION_GRANTED) { 8806 return null; 8807 } 8808 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8809 cpi.applicationInfo.uid, cpi.exported) 8810 == PackageManager.PERMISSION_GRANTED) { 8811 return null; 8812 } 8813 8814 PathPermission[] pps = cpi.pathPermissions; 8815 if (pps != null) { 8816 int i = pps.length; 8817 while (i > 0) { 8818 i--; 8819 PathPermission pp = pps[i]; 8820 String pprperm = pp.getReadPermission(); 8821 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8822 cpi.applicationInfo.uid, cpi.exported) 8823 == PackageManager.PERMISSION_GRANTED) { 8824 return null; 8825 } 8826 String ppwperm = pp.getWritePermission(); 8827 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8828 cpi.applicationInfo.uid, cpi.exported) 8829 == PackageManager.PERMISSION_GRANTED) { 8830 return null; 8831 } 8832 } 8833 } 8834 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8835 return null; 8836 } 8837 8838 String msg; 8839 if (!cpi.exported) { 8840 msg = "Permission Denial: opening provider " + cpi.name 8841 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8842 + ", uid=" + callingUid + ") that is not exported from uid " 8843 + cpi.applicationInfo.uid; 8844 } else { 8845 msg = "Permission Denial: opening provider " + cpi.name 8846 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8847 + ", uid=" + callingUid + ") requires " 8848 + cpi.readPermission + " or " + cpi.writePermission; 8849 } 8850 Slog.w(TAG, msg); 8851 return msg; 8852 } 8853 8854 /** 8855 * Returns if the ContentProvider has granted a uri to callingUid 8856 */ 8857 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8858 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8859 if (perms != null) { 8860 for (int i=perms.size()-1; i>=0; i--) { 8861 GrantUri grantUri = perms.keyAt(i); 8862 if (grantUri.sourceUserId == userId || !checkUser) { 8863 if (matchesProvider(grantUri.uri, cpi)) { 8864 return true; 8865 } 8866 } 8867 } 8868 } 8869 return false; 8870 } 8871 8872 /** 8873 * Returns true if the uri authority is one of the authorities specified in the provider. 8874 */ 8875 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8876 String uriAuth = uri.getAuthority(); 8877 String cpiAuth = cpi.authority; 8878 if (cpiAuth.indexOf(';') == -1) { 8879 return cpiAuth.equals(uriAuth); 8880 } 8881 String[] cpiAuths = cpiAuth.split(";"); 8882 int length = cpiAuths.length; 8883 for (int i = 0; i < length; i++) { 8884 if (cpiAuths[i].equals(uriAuth)) return true; 8885 } 8886 return false; 8887 } 8888 8889 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8890 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8891 if (r != null) { 8892 for (int i=0; i<r.conProviders.size(); i++) { 8893 ContentProviderConnection conn = r.conProviders.get(i); 8894 if (conn.provider == cpr) { 8895 if (DEBUG_PROVIDER) Slog.v(TAG, 8896 "Adding provider requested by " 8897 + r.processName + " from process " 8898 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8899 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8900 if (stable) { 8901 conn.stableCount++; 8902 conn.numStableIncs++; 8903 } else { 8904 conn.unstableCount++; 8905 conn.numUnstableIncs++; 8906 } 8907 return conn; 8908 } 8909 } 8910 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8911 if (stable) { 8912 conn.stableCount = 1; 8913 conn.numStableIncs = 1; 8914 } else { 8915 conn.unstableCount = 1; 8916 conn.numUnstableIncs = 1; 8917 } 8918 cpr.connections.add(conn); 8919 r.conProviders.add(conn); 8920 return conn; 8921 } 8922 cpr.addExternalProcessHandleLocked(externalProcessToken); 8923 return null; 8924 } 8925 8926 boolean decProviderCountLocked(ContentProviderConnection conn, 8927 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8928 if (conn != null) { 8929 cpr = conn.provider; 8930 if (DEBUG_PROVIDER) Slog.v(TAG, 8931 "Removing provider requested by " 8932 + conn.client.processName + " from process " 8933 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8934 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8935 if (stable) { 8936 conn.stableCount--; 8937 } else { 8938 conn.unstableCount--; 8939 } 8940 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8941 cpr.connections.remove(conn); 8942 conn.client.conProviders.remove(conn); 8943 return true; 8944 } 8945 return false; 8946 } 8947 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8948 return false; 8949 } 8950 8951 private void checkTime(long startTime, String where) { 8952 long now = SystemClock.elapsedRealtime(); 8953 if ((now-startTime) > 1000) { 8954 // If we are taking more than a second, log about it. 8955 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8956 } 8957 } 8958 8959 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8960 String name, IBinder token, boolean stable, int userId) { 8961 ContentProviderRecord cpr; 8962 ContentProviderConnection conn = null; 8963 ProviderInfo cpi = null; 8964 8965 synchronized(this) { 8966 long startTime = SystemClock.elapsedRealtime(); 8967 8968 ProcessRecord r = null; 8969 if (caller != null) { 8970 r = getRecordForAppLocked(caller); 8971 if (r == null) { 8972 throw new SecurityException( 8973 "Unable to find app for caller " + caller 8974 + " (pid=" + Binder.getCallingPid() 8975 + ") when getting content provider " + name); 8976 } 8977 } 8978 8979 boolean checkCrossUser = true; 8980 8981 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 8982 8983 // First check if this content provider has been published... 8984 cpr = mProviderMap.getProviderByName(name, userId); 8985 // If that didn't work, check if it exists for user 0 and then 8986 // verify that it's a singleton provider before using it. 8987 if (cpr == null && userId != UserHandle.USER_OWNER) { 8988 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8989 if (cpr != null) { 8990 cpi = cpr.info; 8991 if (isSingleton(cpi.processName, cpi.applicationInfo, 8992 cpi.name, cpi.flags) 8993 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8994 userId = UserHandle.USER_OWNER; 8995 checkCrossUser = false; 8996 } else { 8997 cpr = null; 8998 cpi = null; 8999 } 9000 } 9001 } 9002 9003 boolean providerRunning = cpr != null; 9004 if (providerRunning) { 9005 cpi = cpr.info; 9006 String msg; 9007 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9008 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9009 != null) { 9010 throw new SecurityException(msg); 9011 } 9012 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9013 9014 if (r != null && cpr.canRunHere(r)) { 9015 // This provider has been published or is in the process 9016 // of being published... but it is also allowed to run 9017 // in the caller's process, so don't make a connection 9018 // and just let the caller instantiate its own instance. 9019 ContentProviderHolder holder = cpr.newHolder(null); 9020 // don't give caller the provider object, it needs 9021 // to make its own. 9022 holder.provider = null; 9023 return holder; 9024 } 9025 9026 final long origId = Binder.clearCallingIdentity(); 9027 9028 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9029 9030 // In this case the provider instance already exists, so we can 9031 // return it right away. 9032 conn = incProviderCountLocked(r, cpr, token, stable); 9033 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9034 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9035 // If this is a perceptible app accessing the provider, 9036 // make sure to count it as being accessed and thus 9037 // back up on the LRU list. This is good because 9038 // content providers are often expensive to start. 9039 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9040 updateLruProcessLocked(cpr.proc, false, null); 9041 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9042 } 9043 } 9044 9045 if (cpr.proc != null) { 9046 if (false) { 9047 if (cpr.name.flattenToShortString().equals( 9048 "com.android.providers.calendar/.CalendarProvider2")) { 9049 Slog.v(TAG, "****************** KILLING " 9050 + cpr.name.flattenToShortString()); 9051 Process.killProcess(cpr.proc.pid); 9052 } 9053 } 9054 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9055 boolean success = updateOomAdjLocked(cpr.proc); 9056 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9057 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9058 // NOTE: there is still a race here where a signal could be 9059 // pending on the process even though we managed to update its 9060 // adj level. Not sure what to do about this, but at least 9061 // the race is now smaller. 9062 if (!success) { 9063 // Uh oh... it looks like the provider's process 9064 // has been killed on us. We need to wait for a new 9065 // process to be started, and make sure its death 9066 // doesn't kill our process. 9067 Slog.i(TAG, 9068 "Existing provider " + cpr.name.flattenToShortString() 9069 + " is crashing; detaching " + r); 9070 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9071 checkTime(startTime, "getContentProviderImpl: before appDied"); 9072 appDiedLocked(cpr.proc); 9073 checkTime(startTime, "getContentProviderImpl: after appDied"); 9074 if (!lastRef) { 9075 // This wasn't the last ref our process had on 9076 // the provider... we have now been killed, bail. 9077 return null; 9078 } 9079 providerRunning = false; 9080 conn = null; 9081 } 9082 } 9083 9084 Binder.restoreCallingIdentity(origId); 9085 } 9086 9087 boolean singleton; 9088 if (!providerRunning) { 9089 try { 9090 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9091 cpi = AppGlobals.getPackageManager(). 9092 resolveContentProvider(name, 9093 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9094 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9095 } catch (RemoteException ex) { 9096 } 9097 if (cpi == null) { 9098 return null; 9099 } 9100 // If the provider is a singleton AND 9101 // (it's a call within the same user || the provider is a 9102 // privileged app) 9103 // Then allow connecting to the singleton provider 9104 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9105 cpi.name, cpi.flags) 9106 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9107 if (singleton) { 9108 userId = UserHandle.USER_OWNER; 9109 } 9110 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9111 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9112 9113 String msg; 9114 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9115 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9116 != null) { 9117 throw new SecurityException(msg); 9118 } 9119 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9120 9121 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9122 && !cpi.processName.equals("system")) { 9123 // If this content provider does not run in the system 9124 // process, and the system is not yet ready to run other 9125 // processes, then fail fast instead of hanging. 9126 throw new IllegalArgumentException( 9127 "Attempt to launch content provider before system ready"); 9128 } 9129 9130 // Make sure that the user who owns this provider is started. If not, 9131 // we don't want to allow it to run. 9132 if (mStartedUsers.get(userId) == null) { 9133 Slog.w(TAG, "Unable to launch app " 9134 + cpi.applicationInfo.packageName + "/" 9135 + cpi.applicationInfo.uid + " for provider " 9136 + name + ": user " + userId + " is stopped"); 9137 return null; 9138 } 9139 9140 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9141 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9142 cpr = mProviderMap.getProviderByClass(comp, userId); 9143 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9144 final boolean firstClass = cpr == null; 9145 if (firstClass) { 9146 try { 9147 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9148 ApplicationInfo ai = 9149 AppGlobals.getPackageManager(). 9150 getApplicationInfo( 9151 cpi.applicationInfo.packageName, 9152 STOCK_PM_FLAGS, userId); 9153 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9154 if (ai == null) { 9155 Slog.w(TAG, "No package info for content provider " 9156 + cpi.name); 9157 return null; 9158 } 9159 ai = getAppInfoForUser(ai, userId); 9160 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9161 } catch (RemoteException ex) { 9162 // pm is in same process, this will never happen. 9163 } 9164 } 9165 9166 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9167 9168 if (r != null && cpr.canRunHere(r)) { 9169 // If this is a multiprocess provider, then just return its 9170 // info and allow the caller to instantiate it. Only do 9171 // this if the provider is the same user as the caller's 9172 // process, or can run as root (so can be in any process). 9173 return cpr.newHolder(null); 9174 } 9175 9176 if (DEBUG_PROVIDER) { 9177 RuntimeException e = new RuntimeException("here"); 9178 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9179 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9180 } 9181 9182 // This is single process, and our app is now connecting to it. 9183 // See if we are already in the process of launching this 9184 // provider. 9185 final int N = mLaunchingProviders.size(); 9186 int i; 9187 for (i=0; i<N; i++) { 9188 if (mLaunchingProviders.get(i) == cpr) { 9189 break; 9190 } 9191 } 9192 9193 // If the provider is not already being launched, then get it 9194 // started. 9195 if (i >= N) { 9196 final long origId = Binder.clearCallingIdentity(); 9197 9198 try { 9199 // Content provider is now in use, its package can't be stopped. 9200 try { 9201 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9202 AppGlobals.getPackageManager().setPackageStoppedState( 9203 cpr.appInfo.packageName, false, userId); 9204 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9205 } catch (RemoteException e) { 9206 } catch (IllegalArgumentException e) { 9207 Slog.w(TAG, "Failed trying to unstop package " 9208 + cpr.appInfo.packageName + ": " + e); 9209 } 9210 9211 // Use existing process if already started 9212 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9213 ProcessRecord proc = getProcessRecordLocked( 9214 cpi.processName, cpr.appInfo.uid, false); 9215 if (proc != null && proc.thread != null) { 9216 if (DEBUG_PROVIDER) { 9217 Slog.d(TAG, "Installing in existing process " + proc); 9218 } 9219 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9220 proc.pubProviders.put(cpi.name, cpr); 9221 try { 9222 proc.thread.scheduleInstallProvider(cpi); 9223 } catch (RemoteException e) { 9224 } 9225 } else { 9226 checkTime(startTime, "getContentProviderImpl: before start process"); 9227 proc = startProcessLocked(cpi.processName, 9228 cpr.appInfo, false, 0, "content provider", 9229 new ComponentName(cpi.applicationInfo.packageName, 9230 cpi.name), false, false, false); 9231 checkTime(startTime, "getContentProviderImpl: after start process"); 9232 if (proc == null) { 9233 Slog.w(TAG, "Unable to launch app " 9234 + cpi.applicationInfo.packageName + "/" 9235 + cpi.applicationInfo.uid + " for provider " 9236 + name + ": process is bad"); 9237 return null; 9238 } 9239 } 9240 cpr.launchingApp = proc; 9241 mLaunchingProviders.add(cpr); 9242 } finally { 9243 Binder.restoreCallingIdentity(origId); 9244 } 9245 } 9246 9247 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9248 9249 // Make sure the provider is published (the same provider class 9250 // may be published under multiple names). 9251 if (firstClass) { 9252 mProviderMap.putProviderByClass(comp, cpr); 9253 } 9254 9255 mProviderMap.putProviderByName(name, cpr); 9256 conn = incProviderCountLocked(r, cpr, token, stable); 9257 if (conn != null) { 9258 conn.waiting = true; 9259 } 9260 } 9261 checkTime(startTime, "getContentProviderImpl: done!"); 9262 } 9263 9264 // Wait for the provider to be published... 9265 synchronized (cpr) { 9266 while (cpr.provider == null) { 9267 if (cpr.launchingApp == null) { 9268 Slog.w(TAG, "Unable to launch app " 9269 + cpi.applicationInfo.packageName + "/" 9270 + cpi.applicationInfo.uid + " for provider " 9271 + name + ": launching app became null"); 9272 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9273 UserHandle.getUserId(cpi.applicationInfo.uid), 9274 cpi.applicationInfo.packageName, 9275 cpi.applicationInfo.uid, name); 9276 return null; 9277 } 9278 try { 9279 if (DEBUG_MU) { 9280 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9281 + cpr.launchingApp); 9282 } 9283 if (conn != null) { 9284 conn.waiting = true; 9285 } 9286 cpr.wait(); 9287 } catch (InterruptedException ex) { 9288 } finally { 9289 if (conn != null) { 9290 conn.waiting = false; 9291 } 9292 } 9293 } 9294 } 9295 return cpr != null ? cpr.newHolder(conn) : null; 9296 } 9297 9298 @Override 9299 public final ContentProviderHolder getContentProvider( 9300 IApplicationThread caller, String name, int userId, boolean stable) { 9301 enforceNotIsolatedCaller("getContentProvider"); 9302 if (caller == null) { 9303 String msg = "null IApplicationThread when getting content provider " 9304 + name; 9305 Slog.w(TAG, msg); 9306 throw new SecurityException(msg); 9307 } 9308 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9309 // with cross-user grant. 9310 return getContentProviderImpl(caller, name, null, stable, userId); 9311 } 9312 9313 public ContentProviderHolder getContentProviderExternal( 9314 String name, int userId, IBinder token) { 9315 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9316 "Do not have permission in call getContentProviderExternal()"); 9317 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9318 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9319 return getContentProviderExternalUnchecked(name, token, userId); 9320 } 9321 9322 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9323 IBinder token, int userId) { 9324 return getContentProviderImpl(null, name, token, true, userId); 9325 } 9326 9327 /** 9328 * Drop a content provider from a ProcessRecord's bookkeeping 9329 */ 9330 public void removeContentProvider(IBinder connection, boolean stable) { 9331 enforceNotIsolatedCaller("removeContentProvider"); 9332 long ident = Binder.clearCallingIdentity(); 9333 try { 9334 synchronized (this) { 9335 ContentProviderConnection conn; 9336 try { 9337 conn = (ContentProviderConnection)connection; 9338 } catch (ClassCastException e) { 9339 String msg ="removeContentProvider: " + connection 9340 + " not a ContentProviderConnection"; 9341 Slog.w(TAG, msg); 9342 throw new IllegalArgumentException(msg); 9343 } 9344 if (conn == null) { 9345 throw new NullPointerException("connection is null"); 9346 } 9347 if (decProviderCountLocked(conn, null, null, stable)) { 9348 updateOomAdjLocked(); 9349 } 9350 } 9351 } finally { 9352 Binder.restoreCallingIdentity(ident); 9353 } 9354 } 9355 9356 public void removeContentProviderExternal(String name, IBinder token) { 9357 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9358 "Do not have permission in call removeContentProviderExternal()"); 9359 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9360 } 9361 9362 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9363 synchronized (this) { 9364 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9365 if(cpr == null) { 9366 //remove from mProvidersByClass 9367 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9368 return; 9369 } 9370 9371 //update content provider record entry info 9372 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9373 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9374 if (localCpr.hasExternalProcessHandles()) { 9375 if (localCpr.removeExternalProcessHandleLocked(token)) { 9376 updateOomAdjLocked(); 9377 } else { 9378 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9379 + " with no external reference for token: " 9380 + token + "."); 9381 } 9382 } else { 9383 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9384 + " with no external references."); 9385 } 9386 } 9387 } 9388 9389 public final void publishContentProviders(IApplicationThread caller, 9390 List<ContentProviderHolder> providers) { 9391 if (providers == null) { 9392 return; 9393 } 9394 9395 enforceNotIsolatedCaller("publishContentProviders"); 9396 synchronized (this) { 9397 final ProcessRecord r = getRecordForAppLocked(caller); 9398 if (DEBUG_MU) 9399 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9400 if (r == null) { 9401 throw new SecurityException( 9402 "Unable to find app for caller " + caller 9403 + " (pid=" + Binder.getCallingPid() 9404 + ") when publishing content providers"); 9405 } 9406 9407 final long origId = Binder.clearCallingIdentity(); 9408 9409 final int N = providers.size(); 9410 for (int i=0; i<N; i++) { 9411 ContentProviderHolder src = providers.get(i); 9412 if (src == null || src.info == null || src.provider == null) { 9413 continue; 9414 } 9415 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9416 if (DEBUG_MU) 9417 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9418 if (dst != null) { 9419 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9420 mProviderMap.putProviderByClass(comp, dst); 9421 String names[] = dst.info.authority.split(";"); 9422 for (int j = 0; j < names.length; j++) { 9423 mProviderMap.putProviderByName(names[j], dst); 9424 } 9425 9426 int NL = mLaunchingProviders.size(); 9427 int j; 9428 for (j=0; j<NL; j++) { 9429 if (mLaunchingProviders.get(j) == dst) { 9430 mLaunchingProviders.remove(j); 9431 j--; 9432 NL--; 9433 } 9434 } 9435 synchronized (dst) { 9436 dst.provider = src.provider; 9437 dst.proc = r; 9438 dst.notifyAll(); 9439 } 9440 updateOomAdjLocked(r); 9441 } 9442 } 9443 9444 Binder.restoreCallingIdentity(origId); 9445 } 9446 } 9447 9448 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9449 ContentProviderConnection conn; 9450 try { 9451 conn = (ContentProviderConnection)connection; 9452 } catch (ClassCastException e) { 9453 String msg ="refContentProvider: " + connection 9454 + " not a ContentProviderConnection"; 9455 Slog.w(TAG, msg); 9456 throw new IllegalArgumentException(msg); 9457 } 9458 if (conn == null) { 9459 throw new NullPointerException("connection is null"); 9460 } 9461 9462 synchronized (this) { 9463 if (stable > 0) { 9464 conn.numStableIncs += stable; 9465 } 9466 stable = conn.stableCount + stable; 9467 if (stable < 0) { 9468 throw new IllegalStateException("stableCount < 0: " + stable); 9469 } 9470 9471 if (unstable > 0) { 9472 conn.numUnstableIncs += unstable; 9473 } 9474 unstable = conn.unstableCount + unstable; 9475 if (unstable < 0) { 9476 throw new IllegalStateException("unstableCount < 0: " + unstable); 9477 } 9478 9479 if ((stable+unstable) <= 0) { 9480 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9481 + stable + " unstable=" + unstable); 9482 } 9483 conn.stableCount = stable; 9484 conn.unstableCount = unstable; 9485 return !conn.dead; 9486 } 9487 } 9488 9489 public void unstableProviderDied(IBinder connection) { 9490 ContentProviderConnection conn; 9491 try { 9492 conn = (ContentProviderConnection)connection; 9493 } catch (ClassCastException e) { 9494 String msg ="refContentProvider: " + connection 9495 + " not a ContentProviderConnection"; 9496 Slog.w(TAG, msg); 9497 throw new IllegalArgumentException(msg); 9498 } 9499 if (conn == null) { 9500 throw new NullPointerException("connection is null"); 9501 } 9502 9503 // Safely retrieve the content provider associated with the connection. 9504 IContentProvider provider; 9505 synchronized (this) { 9506 provider = conn.provider.provider; 9507 } 9508 9509 if (provider == null) { 9510 // Um, yeah, we're way ahead of you. 9511 return; 9512 } 9513 9514 // Make sure the caller is being honest with us. 9515 if (provider.asBinder().pingBinder()) { 9516 // Er, no, still looks good to us. 9517 synchronized (this) { 9518 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9519 + " says " + conn + " died, but we don't agree"); 9520 return; 9521 } 9522 } 9523 9524 // Well look at that! It's dead! 9525 synchronized (this) { 9526 if (conn.provider.provider != provider) { 9527 // But something changed... good enough. 9528 return; 9529 } 9530 9531 ProcessRecord proc = conn.provider.proc; 9532 if (proc == null || proc.thread == null) { 9533 // Seems like the process is already cleaned up. 9534 return; 9535 } 9536 9537 // As far as we're concerned, this is just like receiving a 9538 // death notification... just a bit prematurely. 9539 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9540 + ") early provider death"); 9541 final long ident = Binder.clearCallingIdentity(); 9542 try { 9543 appDiedLocked(proc); 9544 } finally { 9545 Binder.restoreCallingIdentity(ident); 9546 } 9547 } 9548 } 9549 9550 @Override 9551 public void appNotRespondingViaProvider(IBinder connection) { 9552 enforceCallingPermission( 9553 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9554 9555 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9556 if (conn == null) { 9557 Slog.w(TAG, "ContentProviderConnection is null"); 9558 return; 9559 } 9560 9561 final ProcessRecord host = conn.provider.proc; 9562 if (host == null) { 9563 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9564 return; 9565 } 9566 9567 final long token = Binder.clearCallingIdentity(); 9568 try { 9569 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9570 } finally { 9571 Binder.restoreCallingIdentity(token); 9572 } 9573 } 9574 9575 public final void installSystemProviders() { 9576 List<ProviderInfo> providers; 9577 synchronized (this) { 9578 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9579 providers = generateApplicationProvidersLocked(app); 9580 if (providers != null) { 9581 for (int i=providers.size()-1; i>=0; i--) { 9582 ProviderInfo pi = (ProviderInfo)providers.get(i); 9583 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9584 Slog.w(TAG, "Not installing system proc provider " + pi.name 9585 + ": not system .apk"); 9586 providers.remove(i); 9587 } 9588 } 9589 } 9590 } 9591 if (providers != null) { 9592 mSystemThread.installSystemProviders(providers); 9593 } 9594 9595 mCoreSettingsObserver = new CoreSettingsObserver(this); 9596 9597 //mUsageStatsService.monitorPackages(); 9598 } 9599 9600 /** 9601 * Allows apps to retrieve the MIME type of a URI. 9602 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9603 * users, then it does not need permission to access the ContentProvider. 9604 * Either, it needs cross-user uri grants. 9605 * 9606 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9607 * 9608 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9609 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9610 */ 9611 public String getProviderMimeType(Uri uri, int userId) { 9612 enforceNotIsolatedCaller("getProviderMimeType"); 9613 final String name = uri.getAuthority(); 9614 int callingUid = Binder.getCallingUid(); 9615 int callingPid = Binder.getCallingPid(); 9616 long ident = 0; 9617 boolean clearedIdentity = false; 9618 userId = unsafeConvertIncomingUser(userId); 9619 if (UserHandle.getUserId(callingUid) != userId) { 9620 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9621 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9622 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9623 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9624 clearedIdentity = true; 9625 ident = Binder.clearCallingIdentity(); 9626 } 9627 } 9628 ContentProviderHolder holder = null; 9629 try { 9630 holder = getContentProviderExternalUnchecked(name, null, userId); 9631 if (holder != null) { 9632 return holder.provider.getType(uri); 9633 } 9634 } catch (RemoteException e) { 9635 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9636 return null; 9637 } finally { 9638 // We need to clear the identity to call removeContentProviderExternalUnchecked 9639 if (!clearedIdentity) { 9640 ident = Binder.clearCallingIdentity(); 9641 } 9642 try { 9643 if (holder != null) { 9644 removeContentProviderExternalUnchecked(name, null, userId); 9645 } 9646 } finally { 9647 Binder.restoreCallingIdentity(ident); 9648 } 9649 } 9650 9651 return null; 9652 } 9653 9654 // ========================================================= 9655 // GLOBAL MANAGEMENT 9656 // ========================================================= 9657 9658 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9659 boolean isolated, int isolatedUid) { 9660 String proc = customProcess != null ? customProcess : info.processName; 9661 BatteryStatsImpl.Uid.Proc ps = null; 9662 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9663 int uid = info.uid; 9664 if (isolated) { 9665 if (isolatedUid == 0) { 9666 int userId = UserHandle.getUserId(uid); 9667 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9668 while (true) { 9669 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9670 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9671 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9672 } 9673 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9674 mNextIsolatedProcessUid++; 9675 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9676 // No process for this uid, use it. 9677 break; 9678 } 9679 stepsLeft--; 9680 if (stepsLeft <= 0) { 9681 return null; 9682 } 9683 } 9684 } else { 9685 // Special case for startIsolatedProcess (internal only), where 9686 // the uid of the isolated process is specified by the caller. 9687 uid = isolatedUid; 9688 } 9689 } 9690 return new ProcessRecord(stats, info, proc, uid); 9691 } 9692 9693 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9694 String abiOverride) { 9695 ProcessRecord app; 9696 if (!isolated) { 9697 app = getProcessRecordLocked(info.processName, info.uid, true); 9698 } else { 9699 app = null; 9700 } 9701 9702 if (app == null) { 9703 app = newProcessRecordLocked(info, null, isolated, 0); 9704 mProcessNames.put(info.processName, app.uid, app); 9705 if (isolated) { 9706 mIsolatedProcesses.put(app.uid, app); 9707 } 9708 updateLruProcessLocked(app, false, null); 9709 updateOomAdjLocked(); 9710 } 9711 9712 // This package really, really can not be stopped. 9713 try { 9714 AppGlobals.getPackageManager().setPackageStoppedState( 9715 info.packageName, false, UserHandle.getUserId(app.uid)); 9716 } catch (RemoteException e) { 9717 } catch (IllegalArgumentException e) { 9718 Slog.w(TAG, "Failed trying to unstop package " 9719 + info.packageName + ": " + e); 9720 } 9721 9722 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9723 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9724 app.persistent = true; 9725 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9726 } 9727 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9728 mPersistentStartingProcesses.add(app); 9729 startProcessLocked(app, "added application", app.processName, abiOverride, 9730 null /* entryPoint */, null /* entryPointArgs */); 9731 } 9732 9733 return app; 9734 } 9735 9736 public void unhandledBack() { 9737 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9738 "unhandledBack()"); 9739 9740 synchronized(this) { 9741 final long origId = Binder.clearCallingIdentity(); 9742 try { 9743 getFocusedStack().unhandledBackLocked(); 9744 } finally { 9745 Binder.restoreCallingIdentity(origId); 9746 } 9747 } 9748 } 9749 9750 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9751 enforceNotIsolatedCaller("openContentUri"); 9752 final int userId = UserHandle.getCallingUserId(); 9753 String name = uri.getAuthority(); 9754 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9755 ParcelFileDescriptor pfd = null; 9756 if (cph != null) { 9757 // We record the binder invoker's uid in thread-local storage before 9758 // going to the content provider to open the file. Later, in the code 9759 // that handles all permissions checks, we look for this uid and use 9760 // that rather than the Activity Manager's own uid. The effect is that 9761 // we do the check against the caller's permissions even though it looks 9762 // to the content provider like the Activity Manager itself is making 9763 // the request. 9764 sCallerIdentity.set(new Identity( 9765 Binder.getCallingPid(), Binder.getCallingUid())); 9766 try { 9767 pfd = cph.provider.openFile(null, uri, "r", null); 9768 } catch (FileNotFoundException e) { 9769 // do nothing; pfd will be returned null 9770 } finally { 9771 // Ensure that whatever happens, we clean up the identity state 9772 sCallerIdentity.remove(); 9773 } 9774 9775 // We've got the fd now, so we're done with the provider. 9776 removeContentProviderExternalUnchecked(name, null, userId); 9777 } else { 9778 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9779 } 9780 return pfd; 9781 } 9782 9783 // Actually is sleeping or shutting down or whatever else in the future 9784 // is an inactive state. 9785 public boolean isSleepingOrShuttingDown() { 9786 return mSleeping || mShuttingDown; 9787 } 9788 9789 public boolean isSleeping() { 9790 return mSleeping; 9791 } 9792 9793 void goingToSleep() { 9794 synchronized(this) { 9795 mWentToSleep = true; 9796 updateEventDispatchingLocked(); 9797 goToSleepIfNeededLocked(); 9798 } 9799 } 9800 9801 void finishRunningVoiceLocked() { 9802 if (mRunningVoice) { 9803 mRunningVoice = false; 9804 goToSleepIfNeededLocked(); 9805 } 9806 } 9807 9808 void goToSleepIfNeededLocked() { 9809 if (mWentToSleep && !mRunningVoice) { 9810 if (!mSleeping) { 9811 mSleeping = true; 9812 mStackSupervisor.goingToSleepLocked(); 9813 9814 // Initialize the wake times of all processes. 9815 checkExcessivePowerUsageLocked(false); 9816 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9817 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9818 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9819 } 9820 } 9821 } 9822 9823 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9824 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9825 // Never persist the home stack. 9826 return; 9827 } 9828 mTaskPersister.wakeup(task, flush); 9829 } 9830 9831 @Override 9832 public boolean shutdown(int timeout) { 9833 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9834 != PackageManager.PERMISSION_GRANTED) { 9835 throw new SecurityException("Requires permission " 9836 + android.Manifest.permission.SHUTDOWN); 9837 } 9838 9839 boolean timedout = false; 9840 9841 synchronized(this) { 9842 mShuttingDown = true; 9843 updateEventDispatchingLocked(); 9844 timedout = mStackSupervisor.shutdownLocked(timeout); 9845 } 9846 9847 mAppOpsService.shutdown(); 9848 if (mUsageStatsService != null) { 9849 mUsageStatsService.prepareShutdown(); 9850 } 9851 mBatteryStatsService.shutdown(); 9852 synchronized (this) { 9853 mProcessStats.shutdownLocked(); 9854 } 9855 notifyTaskPersisterLocked(null, true); 9856 9857 return timedout; 9858 } 9859 9860 public final void activitySlept(IBinder token) { 9861 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9862 9863 final long origId = Binder.clearCallingIdentity(); 9864 9865 synchronized (this) { 9866 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9867 if (r != null) { 9868 mStackSupervisor.activitySleptLocked(r); 9869 } 9870 } 9871 9872 Binder.restoreCallingIdentity(origId); 9873 } 9874 9875 void logLockScreen(String msg) { 9876 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9877 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9878 mWentToSleep + " mSleeping=" + mSleeping); 9879 } 9880 9881 private void comeOutOfSleepIfNeededLocked() { 9882 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9883 if (mSleeping) { 9884 mSleeping = false; 9885 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9886 } 9887 } 9888 } 9889 9890 void wakingUp() { 9891 synchronized(this) { 9892 mWentToSleep = false; 9893 updateEventDispatchingLocked(); 9894 comeOutOfSleepIfNeededLocked(); 9895 } 9896 } 9897 9898 void startRunningVoiceLocked() { 9899 if (!mRunningVoice) { 9900 mRunningVoice = true; 9901 comeOutOfSleepIfNeededLocked(); 9902 } 9903 } 9904 9905 private void updateEventDispatchingLocked() { 9906 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9907 } 9908 9909 public void setLockScreenShown(boolean shown) { 9910 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9911 != PackageManager.PERMISSION_GRANTED) { 9912 throw new SecurityException("Requires permission " 9913 + android.Manifest.permission.DEVICE_POWER); 9914 } 9915 9916 synchronized(this) { 9917 long ident = Binder.clearCallingIdentity(); 9918 try { 9919 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9920 mLockScreenShown = shown; 9921 comeOutOfSleepIfNeededLocked(); 9922 } finally { 9923 Binder.restoreCallingIdentity(ident); 9924 } 9925 } 9926 } 9927 9928 @Override 9929 public void stopAppSwitches() { 9930 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9931 != PackageManager.PERMISSION_GRANTED) { 9932 throw new SecurityException("Requires permission " 9933 + android.Manifest.permission.STOP_APP_SWITCHES); 9934 } 9935 9936 synchronized(this) { 9937 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9938 + APP_SWITCH_DELAY_TIME; 9939 mDidAppSwitch = false; 9940 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9941 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9942 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9943 } 9944 } 9945 9946 public void resumeAppSwitches() { 9947 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9948 != PackageManager.PERMISSION_GRANTED) { 9949 throw new SecurityException("Requires permission " 9950 + android.Manifest.permission.STOP_APP_SWITCHES); 9951 } 9952 9953 synchronized(this) { 9954 // Note that we don't execute any pending app switches... we will 9955 // let those wait until either the timeout, or the next start 9956 // activity request. 9957 mAppSwitchesAllowedTime = 0; 9958 } 9959 } 9960 9961 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9962 String name) { 9963 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9964 return true; 9965 } 9966 9967 final int perm = checkComponentPermission( 9968 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9969 callingUid, -1, true); 9970 if (perm == PackageManager.PERMISSION_GRANTED) { 9971 return true; 9972 } 9973 9974 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9975 return false; 9976 } 9977 9978 public void setDebugApp(String packageName, boolean waitForDebugger, 9979 boolean persistent) { 9980 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9981 "setDebugApp()"); 9982 9983 long ident = Binder.clearCallingIdentity(); 9984 try { 9985 // Note that this is not really thread safe if there are multiple 9986 // callers into it at the same time, but that's not a situation we 9987 // care about. 9988 if (persistent) { 9989 final ContentResolver resolver = mContext.getContentResolver(); 9990 Settings.Global.putString( 9991 resolver, Settings.Global.DEBUG_APP, 9992 packageName); 9993 Settings.Global.putInt( 9994 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9995 waitForDebugger ? 1 : 0); 9996 } 9997 9998 synchronized (this) { 9999 if (!persistent) { 10000 mOrigDebugApp = mDebugApp; 10001 mOrigWaitForDebugger = mWaitForDebugger; 10002 } 10003 mDebugApp = packageName; 10004 mWaitForDebugger = waitForDebugger; 10005 mDebugTransient = !persistent; 10006 if (packageName != null) { 10007 forceStopPackageLocked(packageName, -1, false, false, true, true, 10008 false, UserHandle.USER_ALL, "set debug app"); 10009 } 10010 } 10011 } finally { 10012 Binder.restoreCallingIdentity(ident); 10013 } 10014 } 10015 10016 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10017 synchronized (this) { 10018 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10019 if (!isDebuggable) { 10020 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10021 throw new SecurityException("Process not debuggable: " + app.packageName); 10022 } 10023 } 10024 10025 mOpenGlTraceApp = processName; 10026 } 10027 } 10028 10029 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10030 synchronized (this) { 10031 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10032 if (!isDebuggable) { 10033 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10034 throw new SecurityException("Process not debuggable: " + app.packageName); 10035 } 10036 } 10037 mProfileApp = processName; 10038 mProfileFile = profilerInfo.profileFile; 10039 if (mProfileFd != null) { 10040 try { 10041 mProfileFd.close(); 10042 } catch (IOException e) { 10043 } 10044 mProfileFd = null; 10045 } 10046 mProfileFd = profilerInfo.profileFd; 10047 mSamplingInterval = profilerInfo.samplingInterval; 10048 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10049 mProfileType = 0; 10050 } 10051 } 10052 10053 @Override 10054 public void setAlwaysFinish(boolean enabled) { 10055 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10056 "setAlwaysFinish()"); 10057 10058 Settings.Global.putInt( 10059 mContext.getContentResolver(), 10060 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10061 10062 synchronized (this) { 10063 mAlwaysFinishActivities = enabled; 10064 } 10065 } 10066 10067 @Override 10068 public void setActivityController(IActivityController controller) { 10069 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10070 "setActivityController()"); 10071 synchronized (this) { 10072 mController = controller; 10073 Watchdog.getInstance().setActivityController(controller); 10074 } 10075 } 10076 10077 @Override 10078 public void setUserIsMonkey(boolean userIsMonkey) { 10079 synchronized (this) { 10080 synchronized (mPidsSelfLocked) { 10081 final int callingPid = Binder.getCallingPid(); 10082 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10083 if (precessRecord == null) { 10084 throw new SecurityException("Unknown process: " + callingPid); 10085 } 10086 if (precessRecord.instrumentationUiAutomationConnection == null) { 10087 throw new SecurityException("Only an instrumentation process " 10088 + "with a UiAutomation can call setUserIsMonkey"); 10089 } 10090 } 10091 mUserIsMonkey = userIsMonkey; 10092 } 10093 } 10094 10095 @Override 10096 public boolean isUserAMonkey() { 10097 synchronized (this) { 10098 // If there is a controller also implies the user is a monkey. 10099 return (mUserIsMonkey || mController != null); 10100 } 10101 } 10102 10103 public void requestBugReport() { 10104 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10105 SystemProperties.set("ctl.start", "bugreport"); 10106 } 10107 10108 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10109 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10110 } 10111 10112 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10113 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10114 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10115 } 10116 return KEY_DISPATCHING_TIMEOUT; 10117 } 10118 10119 @Override 10120 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10121 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10122 != PackageManager.PERMISSION_GRANTED) { 10123 throw new SecurityException("Requires permission " 10124 + android.Manifest.permission.FILTER_EVENTS); 10125 } 10126 ProcessRecord proc; 10127 long timeout; 10128 synchronized (this) { 10129 synchronized (mPidsSelfLocked) { 10130 proc = mPidsSelfLocked.get(pid); 10131 } 10132 timeout = getInputDispatchingTimeoutLocked(proc); 10133 } 10134 10135 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10136 return -1; 10137 } 10138 10139 return timeout; 10140 } 10141 10142 /** 10143 * Handle input dispatching timeouts. 10144 * Returns whether input dispatching should be aborted or not. 10145 */ 10146 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10147 final ActivityRecord activity, final ActivityRecord parent, 10148 final boolean aboveSystem, String reason) { 10149 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10150 != PackageManager.PERMISSION_GRANTED) { 10151 throw new SecurityException("Requires permission " 10152 + android.Manifest.permission.FILTER_EVENTS); 10153 } 10154 10155 final String annotation; 10156 if (reason == null) { 10157 annotation = "Input dispatching timed out"; 10158 } else { 10159 annotation = "Input dispatching timed out (" + reason + ")"; 10160 } 10161 10162 if (proc != null) { 10163 synchronized (this) { 10164 if (proc.debugging) { 10165 return false; 10166 } 10167 10168 if (mDidDexOpt) { 10169 // Give more time since we were dexopting. 10170 mDidDexOpt = false; 10171 return false; 10172 } 10173 10174 if (proc.instrumentationClass != null) { 10175 Bundle info = new Bundle(); 10176 info.putString("shortMsg", "keyDispatchingTimedOut"); 10177 info.putString("longMsg", annotation); 10178 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10179 return true; 10180 } 10181 } 10182 mHandler.post(new Runnable() { 10183 @Override 10184 public void run() { 10185 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10186 } 10187 }); 10188 } 10189 10190 return true; 10191 } 10192 10193 public Bundle getAssistContextExtras(int requestType) { 10194 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10195 "getAssistContextExtras()"); 10196 PendingAssistExtras pae; 10197 Bundle extras = new Bundle(); 10198 synchronized (this) { 10199 ActivityRecord activity = getFocusedStack().mResumedActivity; 10200 if (activity == null) { 10201 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10202 return null; 10203 } 10204 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10205 if (activity.app == null || activity.app.thread == null) { 10206 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10207 return extras; 10208 } 10209 if (activity.app.pid == Binder.getCallingPid()) { 10210 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10211 return extras; 10212 } 10213 pae = new PendingAssistExtras(activity); 10214 try { 10215 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10216 requestType); 10217 mPendingAssistExtras.add(pae); 10218 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10219 } catch (RemoteException e) { 10220 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10221 return extras; 10222 } 10223 } 10224 synchronized (pae) { 10225 while (!pae.haveResult) { 10226 try { 10227 pae.wait(); 10228 } catch (InterruptedException e) { 10229 } 10230 } 10231 if (pae.result != null) { 10232 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10233 } 10234 } 10235 synchronized (this) { 10236 mPendingAssistExtras.remove(pae); 10237 mHandler.removeCallbacks(pae); 10238 } 10239 return extras; 10240 } 10241 10242 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10243 PendingAssistExtras pae = (PendingAssistExtras)token; 10244 synchronized (pae) { 10245 pae.result = extras; 10246 pae.haveResult = true; 10247 pae.notifyAll(); 10248 } 10249 } 10250 10251 public void registerProcessObserver(IProcessObserver observer) { 10252 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10253 "registerProcessObserver()"); 10254 synchronized (this) { 10255 mProcessObservers.register(observer); 10256 } 10257 } 10258 10259 @Override 10260 public void unregisterProcessObserver(IProcessObserver observer) { 10261 synchronized (this) { 10262 mProcessObservers.unregister(observer); 10263 } 10264 } 10265 10266 @Override 10267 public boolean convertFromTranslucent(IBinder token) { 10268 final long origId = Binder.clearCallingIdentity(); 10269 try { 10270 synchronized (this) { 10271 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10272 if (r == null) { 10273 return false; 10274 } 10275 if (r.changeWindowTranslucency(true)) { 10276 mWindowManager.setAppFullscreen(token, true); 10277 r.task.stack.releaseBackgroundResources(); 10278 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10279 return true; 10280 } 10281 return false; 10282 } 10283 } finally { 10284 Binder.restoreCallingIdentity(origId); 10285 } 10286 } 10287 10288 @Override 10289 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10290 final long origId = Binder.clearCallingIdentity(); 10291 try { 10292 synchronized (this) { 10293 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10294 if (r == null) { 10295 return false; 10296 } 10297 int index = r.task.mActivities.lastIndexOf(r); 10298 if (index > 0) { 10299 ActivityRecord under = r.task.mActivities.get(index - 1); 10300 under.returningOptions = options; 10301 } 10302 if (r.changeWindowTranslucency(false)) { 10303 r.task.stack.convertToTranslucent(r); 10304 mWindowManager.setAppFullscreen(token, false); 10305 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10306 return true; 10307 } else { 10308 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10309 return false; 10310 } 10311 } 10312 } finally { 10313 Binder.restoreCallingIdentity(origId); 10314 } 10315 } 10316 10317 @Override 10318 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10319 final long origId = Binder.clearCallingIdentity(); 10320 try { 10321 synchronized (this) { 10322 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10323 if (r != null) { 10324 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10325 } 10326 } 10327 return false; 10328 } finally { 10329 Binder.restoreCallingIdentity(origId); 10330 } 10331 } 10332 10333 @Override 10334 public boolean isBackgroundVisibleBehind(IBinder token) { 10335 final long origId = Binder.clearCallingIdentity(); 10336 try { 10337 synchronized (this) { 10338 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10339 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10340 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10341 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10342 return visible; 10343 } 10344 } finally { 10345 Binder.restoreCallingIdentity(origId); 10346 } 10347 } 10348 10349 @Override 10350 public ActivityOptions getActivityOptions(IBinder token) { 10351 final long origId = Binder.clearCallingIdentity(); 10352 try { 10353 synchronized (this) { 10354 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10355 if (r != null) { 10356 final ActivityOptions activityOptions = r.pendingOptions; 10357 r.pendingOptions = null; 10358 return activityOptions; 10359 } 10360 return null; 10361 } 10362 } finally { 10363 Binder.restoreCallingIdentity(origId); 10364 } 10365 } 10366 10367 @Override 10368 public void setImmersive(IBinder token, boolean immersive) { 10369 synchronized(this) { 10370 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10371 if (r == null) { 10372 throw new IllegalArgumentException(); 10373 } 10374 r.immersive = immersive; 10375 10376 // update associated state if we're frontmost 10377 if (r == mFocusedActivity) { 10378 if (DEBUG_IMMERSIVE) { 10379 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10380 } 10381 applyUpdateLockStateLocked(r); 10382 } 10383 } 10384 } 10385 10386 @Override 10387 public boolean isImmersive(IBinder token) { 10388 synchronized (this) { 10389 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10390 if (r == null) { 10391 throw new IllegalArgumentException(); 10392 } 10393 return r.immersive; 10394 } 10395 } 10396 10397 public boolean isTopActivityImmersive() { 10398 enforceNotIsolatedCaller("startActivity"); 10399 synchronized (this) { 10400 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10401 return (r != null) ? r.immersive : false; 10402 } 10403 } 10404 10405 @Override 10406 public boolean isTopOfTask(IBinder token) { 10407 synchronized (this) { 10408 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10409 if (r == null) { 10410 throw new IllegalArgumentException(); 10411 } 10412 return r.task.getTopActivity() == r; 10413 } 10414 } 10415 10416 public final void enterSafeMode() { 10417 synchronized(this) { 10418 // It only makes sense to do this before the system is ready 10419 // and started launching other packages. 10420 if (!mSystemReady) { 10421 try { 10422 AppGlobals.getPackageManager().enterSafeMode(); 10423 } catch (RemoteException e) { 10424 } 10425 } 10426 10427 mSafeMode = true; 10428 } 10429 } 10430 10431 public final void showSafeModeOverlay() { 10432 View v = LayoutInflater.from(mContext).inflate( 10433 com.android.internal.R.layout.safe_mode, null); 10434 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10435 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10436 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10437 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10438 lp.gravity = Gravity.BOTTOM | Gravity.START; 10439 lp.format = v.getBackground().getOpacity(); 10440 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10441 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10442 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10443 ((WindowManager)mContext.getSystemService( 10444 Context.WINDOW_SERVICE)).addView(v, lp); 10445 } 10446 10447 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10448 if (!(sender instanceof PendingIntentRecord)) { 10449 return; 10450 } 10451 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10452 synchronized (stats) { 10453 if (mBatteryStatsService.isOnBattery()) { 10454 mBatteryStatsService.enforceCallingPermission(); 10455 PendingIntentRecord rec = (PendingIntentRecord)sender; 10456 int MY_UID = Binder.getCallingUid(); 10457 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10458 BatteryStatsImpl.Uid.Pkg pkg = 10459 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10460 sourcePkg != null ? sourcePkg : rec.key.packageName); 10461 pkg.incWakeupsLocked(); 10462 } 10463 } 10464 } 10465 10466 public boolean killPids(int[] pids, String pReason, boolean secure) { 10467 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10468 throw new SecurityException("killPids only available to the system"); 10469 } 10470 String reason = (pReason == null) ? "Unknown" : pReason; 10471 // XXX Note: don't acquire main activity lock here, because the window 10472 // manager calls in with its locks held. 10473 10474 boolean killed = false; 10475 synchronized (mPidsSelfLocked) { 10476 int[] types = new int[pids.length]; 10477 int worstType = 0; 10478 for (int i=0; i<pids.length; i++) { 10479 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10480 if (proc != null) { 10481 int type = proc.setAdj; 10482 types[i] = type; 10483 if (type > worstType) { 10484 worstType = type; 10485 } 10486 } 10487 } 10488 10489 // If the worst oom_adj is somewhere in the cached proc LRU range, 10490 // then constrain it so we will kill all cached procs. 10491 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10492 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10493 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10494 } 10495 10496 // If this is not a secure call, don't let it kill processes that 10497 // are important. 10498 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10499 worstType = ProcessList.SERVICE_ADJ; 10500 } 10501 10502 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10503 for (int i=0; i<pids.length; i++) { 10504 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10505 if (proc == null) { 10506 continue; 10507 } 10508 int adj = proc.setAdj; 10509 if (adj >= worstType && !proc.killedByAm) { 10510 proc.kill(reason, true); 10511 killed = true; 10512 } 10513 } 10514 } 10515 return killed; 10516 } 10517 10518 @Override 10519 public void killUid(int uid, String reason) { 10520 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10521 throw new SecurityException("killUid only available to the system"); 10522 } 10523 synchronized (this) { 10524 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10525 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10526 reason != null ? reason : "kill uid"); 10527 } 10528 } 10529 10530 @Override 10531 public boolean killProcessesBelowForeground(String reason) { 10532 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10533 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10534 } 10535 10536 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10537 } 10538 10539 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10540 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10541 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10542 } 10543 10544 boolean killed = false; 10545 synchronized (mPidsSelfLocked) { 10546 final int size = mPidsSelfLocked.size(); 10547 for (int i = 0; i < size; i++) { 10548 final int pid = mPidsSelfLocked.keyAt(i); 10549 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10550 if (proc == null) continue; 10551 10552 final int adj = proc.setAdj; 10553 if (adj > belowAdj && !proc.killedByAm) { 10554 proc.kill(reason, true); 10555 killed = true; 10556 } 10557 } 10558 } 10559 return killed; 10560 } 10561 10562 @Override 10563 public void hang(final IBinder who, boolean allowRestart) { 10564 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10565 != PackageManager.PERMISSION_GRANTED) { 10566 throw new SecurityException("Requires permission " 10567 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10568 } 10569 10570 final IBinder.DeathRecipient death = new DeathRecipient() { 10571 @Override 10572 public void binderDied() { 10573 synchronized (this) { 10574 notifyAll(); 10575 } 10576 } 10577 }; 10578 10579 try { 10580 who.linkToDeath(death, 0); 10581 } catch (RemoteException e) { 10582 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10583 return; 10584 } 10585 10586 synchronized (this) { 10587 Watchdog.getInstance().setAllowRestart(allowRestart); 10588 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10589 synchronized (death) { 10590 while (who.isBinderAlive()) { 10591 try { 10592 death.wait(); 10593 } catch (InterruptedException e) { 10594 } 10595 } 10596 } 10597 Watchdog.getInstance().setAllowRestart(true); 10598 } 10599 } 10600 10601 @Override 10602 public void restart() { 10603 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10604 != PackageManager.PERMISSION_GRANTED) { 10605 throw new SecurityException("Requires permission " 10606 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10607 } 10608 10609 Log.i(TAG, "Sending shutdown broadcast..."); 10610 10611 BroadcastReceiver br = new BroadcastReceiver() { 10612 @Override public void onReceive(Context context, Intent intent) { 10613 // Now the broadcast is done, finish up the low-level shutdown. 10614 Log.i(TAG, "Shutting down activity manager..."); 10615 shutdown(10000); 10616 Log.i(TAG, "Shutdown complete, restarting!"); 10617 Process.killProcess(Process.myPid()); 10618 System.exit(10); 10619 } 10620 }; 10621 10622 // First send the high-level shut down broadcast. 10623 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10624 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10625 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10626 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10627 mContext.sendOrderedBroadcastAsUser(intent, 10628 UserHandle.ALL, null, br, mHandler, 0, null, null); 10629 */ 10630 br.onReceive(mContext, intent); 10631 } 10632 10633 private long getLowRamTimeSinceIdle(long now) { 10634 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10635 } 10636 10637 @Override 10638 public void performIdleMaintenance() { 10639 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10640 != PackageManager.PERMISSION_GRANTED) { 10641 throw new SecurityException("Requires permission " 10642 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10643 } 10644 10645 synchronized (this) { 10646 final long now = SystemClock.uptimeMillis(); 10647 final long timeSinceLastIdle = now - mLastIdleTime; 10648 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10649 mLastIdleTime = now; 10650 mLowRamTimeSinceLastIdle = 0; 10651 if (mLowRamStartTime != 0) { 10652 mLowRamStartTime = now; 10653 } 10654 10655 StringBuilder sb = new StringBuilder(128); 10656 sb.append("Idle maintenance over "); 10657 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10658 sb.append(" low RAM for "); 10659 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10660 Slog.i(TAG, sb.toString()); 10661 10662 // If at least 1/3 of our time since the last idle period has been spent 10663 // with RAM low, then we want to kill processes. 10664 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10665 10666 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10667 ProcessRecord proc = mLruProcesses.get(i); 10668 if (proc.notCachedSinceIdle) { 10669 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10670 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10671 if (doKilling && proc.initialIdlePss != 0 10672 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10673 proc.kill("idle maint (pss " + proc.lastPss 10674 + " from " + proc.initialIdlePss + ")", true); 10675 } 10676 } 10677 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10678 proc.notCachedSinceIdle = true; 10679 proc.initialIdlePss = 0; 10680 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10681 isSleeping(), now); 10682 } 10683 } 10684 10685 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10686 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10687 } 10688 } 10689 10690 private void retrieveSettings() { 10691 final ContentResolver resolver = mContext.getContentResolver(); 10692 String debugApp = Settings.Global.getString( 10693 resolver, Settings.Global.DEBUG_APP); 10694 boolean waitForDebugger = Settings.Global.getInt( 10695 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10696 boolean alwaysFinishActivities = Settings.Global.getInt( 10697 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10698 boolean forceRtl = Settings.Global.getInt( 10699 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10700 // Transfer any global setting for forcing RTL layout, into a System Property 10701 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10702 10703 Configuration configuration = new Configuration(); 10704 Settings.System.getConfiguration(resolver, configuration); 10705 if (forceRtl) { 10706 // This will take care of setting the correct layout direction flags 10707 configuration.setLayoutDirection(configuration.locale); 10708 } 10709 10710 synchronized (this) { 10711 mDebugApp = mOrigDebugApp = debugApp; 10712 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10713 mAlwaysFinishActivities = alwaysFinishActivities; 10714 // This happens before any activities are started, so we can 10715 // change mConfiguration in-place. 10716 updateConfigurationLocked(configuration, null, false, true); 10717 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10718 } 10719 } 10720 10721 /** Loads resources after the current configuration has been set. */ 10722 private void loadResourcesOnSystemReady() { 10723 final Resources res = mContext.getResources(); 10724 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10725 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10726 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10727 } 10728 10729 public boolean testIsSystemReady() { 10730 // no need to synchronize(this) just to read & return the value 10731 return mSystemReady; 10732 } 10733 10734 private static File getCalledPreBootReceiversFile() { 10735 File dataDir = Environment.getDataDirectory(); 10736 File systemDir = new File(dataDir, "system"); 10737 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10738 return fname; 10739 } 10740 10741 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10742 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10743 File file = getCalledPreBootReceiversFile(); 10744 FileInputStream fis = null; 10745 try { 10746 fis = new FileInputStream(file); 10747 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10748 int fvers = dis.readInt(); 10749 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10750 String vers = dis.readUTF(); 10751 String codename = dis.readUTF(); 10752 String build = dis.readUTF(); 10753 if (android.os.Build.VERSION.RELEASE.equals(vers) 10754 && android.os.Build.VERSION.CODENAME.equals(codename) 10755 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10756 int num = dis.readInt(); 10757 while (num > 0) { 10758 num--; 10759 String pkg = dis.readUTF(); 10760 String cls = dis.readUTF(); 10761 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10762 } 10763 } 10764 } 10765 } catch (FileNotFoundException e) { 10766 } catch (IOException e) { 10767 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10768 } finally { 10769 if (fis != null) { 10770 try { 10771 fis.close(); 10772 } catch (IOException e) { 10773 } 10774 } 10775 } 10776 return lastDoneReceivers; 10777 } 10778 10779 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10780 File file = getCalledPreBootReceiversFile(); 10781 FileOutputStream fos = null; 10782 DataOutputStream dos = null; 10783 try { 10784 fos = new FileOutputStream(file); 10785 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10786 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10787 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10788 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10789 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10790 dos.writeInt(list.size()); 10791 for (int i=0; i<list.size(); i++) { 10792 dos.writeUTF(list.get(i).getPackageName()); 10793 dos.writeUTF(list.get(i).getClassName()); 10794 } 10795 } catch (IOException e) { 10796 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10797 file.delete(); 10798 } finally { 10799 FileUtils.sync(fos); 10800 if (dos != null) { 10801 try { 10802 dos.close(); 10803 } catch (IOException e) { 10804 // TODO Auto-generated catch block 10805 e.printStackTrace(); 10806 } 10807 } 10808 } 10809 } 10810 10811 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10812 ArrayList<ComponentName> doneReceivers, int userId) { 10813 boolean waitingUpdate = false; 10814 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10815 List<ResolveInfo> ris = null; 10816 try { 10817 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10818 intent, null, 0, userId); 10819 } catch (RemoteException e) { 10820 } 10821 if (ris != null) { 10822 for (int i=ris.size()-1; i>=0; i--) { 10823 if ((ris.get(i).activityInfo.applicationInfo.flags 10824 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10825 ris.remove(i); 10826 } 10827 } 10828 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10829 10830 // For User 0, load the version number. When delivering to a new user, deliver 10831 // to all receivers. 10832 if (userId == UserHandle.USER_OWNER) { 10833 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10834 for (int i=0; i<ris.size(); i++) { 10835 ActivityInfo ai = ris.get(i).activityInfo; 10836 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10837 if (lastDoneReceivers.contains(comp)) { 10838 // We already did the pre boot receiver for this app with the current 10839 // platform version, so don't do it again... 10840 ris.remove(i); 10841 i--; 10842 // ...however, do keep it as one that has been done, so we don't 10843 // forget about it when rewriting the file of last done receivers. 10844 doneReceivers.add(comp); 10845 } 10846 } 10847 } 10848 10849 // If primary user, send broadcast to all available users, else just to userId 10850 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10851 : new int[] { userId }; 10852 for (int i = 0; i < ris.size(); i++) { 10853 ActivityInfo ai = ris.get(i).activityInfo; 10854 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10855 doneReceivers.add(comp); 10856 intent.setComponent(comp); 10857 for (int j=0; j<users.length; j++) { 10858 IIntentReceiver finisher = null; 10859 // On last receiver and user, set up a completion callback 10860 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10861 finisher = new IIntentReceiver.Stub() { 10862 public void performReceive(Intent intent, int resultCode, 10863 String data, Bundle extras, boolean ordered, 10864 boolean sticky, int sendingUser) { 10865 // The raw IIntentReceiver interface is called 10866 // with the AM lock held, so redispatch to 10867 // execute our code without the lock. 10868 mHandler.post(onFinishCallback); 10869 } 10870 }; 10871 } 10872 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10873 + " for user " + users[j]); 10874 broadcastIntentLocked(null, null, intent, null, finisher, 10875 0, null, null, null, AppOpsManager.OP_NONE, 10876 true, false, MY_PID, Process.SYSTEM_UID, 10877 users[j]); 10878 if (finisher != null) { 10879 waitingUpdate = true; 10880 } 10881 } 10882 } 10883 } 10884 10885 return waitingUpdate; 10886 } 10887 10888 public void systemReady(final Runnable goingCallback) { 10889 synchronized(this) { 10890 if (mSystemReady) { 10891 // If we're done calling all the receivers, run the next "boot phase" passed in 10892 // by the SystemServer 10893 if (goingCallback != null) { 10894 goingCallback.run(); 10895 } 10896 return; 10897 } 10898 10899 // Make sure we have the current profile info, since it is needed for 10900 // security checks. 10901 updateCurrentProfileIdsLocked(); 10902 10903 if (mRecentTasks == null) { 10904 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10905 if (!mRecentTasks.isEmpty()) { 10906 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10907 } 10908 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10909 mTaskPersister.startPersisting(); 10910 } 10911 10912 // Check to see if there are any update receivers to run. 10913 if (!mDidUpdate) { 10914 if (mWaitingUpdate) { 10915 return; 10916 } 10917 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10918 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10919 public void run() { 10920 synchronized (ActivityManagerService.this) { 10921 mDidUpdate = true; 10922 } 10923 writeLastDonePreBootReceivers(doneReceivers); 10924 showBootMessage(mContext.getText( 10925 R.string.android_upgrading_complete), 10926 false); 10927 systemReady(goingCallback); 10928 } 10929 }, doneReceivers, UserHandle.USER_OWNER); 10930 10931 if (mWaitingUpdate) { 10932 return; 10933 } 10934 mDidUpdate = true; 10935 } 10936 10937 mAppOpsService.systemReady(); 10938 mSystemReady = true; 10939 } 10940 10941 ArrayList<ProcessRecord> procsToKill = null; 10942 synchronized(mPidsSelfLocked) { 10943 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10944 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10945 if (!isAllowedWhileBooting(proc.info)){ 10946 if (procsToKill == null) { 10947 procsToKill = new ArrayList<ProcessRecord>(); 10948 } 10949 procsToKill.add(proc); 10950 } 10951 } 10952 } 10953 10954 synchronized(this) { 10955 if (procsToKill != null) { 10956 for (int i=procsToKill.size()-1; i>=0; i--) { 10957 ProcessRecord proc = procsToKill.get(i); 10958 Slog.i(TAG, "Removing system update proc: " + proc); 10959 removeProcessLocked(proc, true, false, "system update done"); 10960 } 10961 } 10962 10963 // Now that we have cleaned up any update processes, we 10964 // are ready to start launching real processes and know that 10965 // we won't trample on them any more. 10966 mProcessesReady = true; 10967 } 10968 10969 Slog.i(TAG, "System now ready"); 10970 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10971 SystemClock.uptimeMillis()); 10972 10973 synchronized(this) { 10974 // Make sure we have no pre-ready processes sitting around. 10975 10976 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10977 ResolveInfo ri = mContext.getPackageManager() 10978 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10979 STOCK_PM_FLAGS); 10980 CharSequence errorMsg = null; 10981 if (ri != null) { 10982 ActivityInfo ai = ri.activityInfo; 10983 ApplicationInfo app = ai.applicationInfo; 10984 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10985 mTopAction = Intent.ACTION_FACTORY_TEST; 10986 mTopData = null; 10987 mTopComponent = new ComponentName(app.packageName, 10988 ai.name); 10989 } else { 10990 errorMsg = mContext.getResources().getText( 10991 com.android.internal.R.string.factorytest_not_system); 10992 } 10993 } else { 10994 errorMsg = mContext.getResources().getText( 10995 com.android.internal.R.string.factorytest_no_action); 10996 } 10997 if (errorMsg != null) { 10998 mTopAction = null; 10999 mTopData = null; 11000 mTopComponent = null; 11001 Message msg = Message.obtain(); 11002 msg.what = SHOW_FACTORY_ERROR_MSG; 11003 msg.getData().putCharSequence("msg", errorMsg); 11004 mHandler.sendMessage(msg); 11005 } 11006 } 11007 } 11008 11009 retrieveSettings(); 11010 loadResourcesOnSystemReady(); 11011 11012 synchronized (this) { 11013 readGrantedUriPermissionsLocked(); 11014 } 11015 11016 if (goingCallback != null) goingCallback.run(); 11017 11018 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11019 Integer.toString(mCurrentUserId), mCurrentUserId); 11020 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11021 Integer.toString(mCurrentUserId), mCurrentUserId); 11022 mSystemServiceManager.startUser(mCurrentUserId); 11023 11024 synchronized (this) { 11025 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11026 try { 11027 List apps = AppGlobals.getPackageManager(). 11028 getPersistentApplications(STOCK_PM_FLAGS); 11029 if (apps != null) { 11030 int N = apps.size(); 11031 int i; 11032 for (i=0; i<N; i++) { 11033 ApplicationInfo info 11034 = (ApplicationInfo)apps.get(i); 11035 if (info != null && 11036 !info.packageName.equals("android")) { 11037 addAppLocked(info, false, null /* ABI override */); 11038 } 11039 } 11040 } 11041 } catch (RemoteException ex) { 11042 // pm is in same process, this will never happen. 11043 } 11044 } 11045 11046 // Start up initial activity. 11047 mBooting = true; 11048 11049 try { 11050 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11051 Message msg = Message.obtain(); 11052 msg.what = SHOW_UID_ERROR_MSG; 11053 mHandler.sendMessage(msg); 11054 } 11055 } catch (RemoteException e) { 11056 } 11057 11058 long ident = Binder.clearCallingIdentity(); 11059 try { 11060 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11062 | Intent.FLAG_RECEIVER_FOREGROUND); 11063 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11064 broadcastIntentLocked(null, null, intent, 11065 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11066 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11067 intent = new Intent(Intent.ACTION_USER_STARTING); 11068 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11069 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11070 broadcastIntentLocked(null, null, intent, 11071 null, new IIntentReceiver.Stub() { 11072 @Override 11073 public void performReceive(Intent intent, int resultCode, String data, 11074 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11075 throws RemoteException { 11076 } 11077 }, 0, null, null, 11078 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11079 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11080 } catch (Throwable t) { 11081 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11082 } finally { 11083 Binder.restoreCallingIdentity(ident); 11084 } 11085 mStackSupervisor.resumeTopActivitiesLocked(); 11086 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11087 } 11088 } 11089 11090 private boolean makeAppCrashingLocked(ProcessRecord app, 11091 String shortMsg, String longMsg, String stackTrace) { 11092 app.crashing = true; 11093 app.crashingReport = generateProcessError(app, 11094 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11095 startAppProblemLocked(app); 11096 app.stopFreezingAllLocked(); 11097 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11098 } 11099 11100 private void makeAppNotRespondingLocked(ProcessRecord app, 11101 String activity, String shortMsg, String longMsg) { 11102 app.notResponding = true; 11103 app.notRespondingReport = generateProcessError(app, 11104 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11105 activity, shortMsg, longMsg, null); 11106 startAppProblemLocked(app); 11107 app.stopFreezingAllLocked(); 11108 } 11109 11110 /** 11111 * Generate a process error record, suitable for attachment to a ProcessRecord. 11112 * 11113 * @param app The ProcessRecord in which the error occurred. 11114 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11115 * ActivityManager.AppErrorStateInfo 11116 * @param activity The activity associated with the crash, if known. 11117 * @param shortMsg Short message describing the crash. 11118 * @param longMsg Long message describing the crash. 11119 * @param stackTrace Full crash stack trace, may be null. 11120 * 11121 * @return Returns a fully-formed AppErrorStateInfo record. 11122 */ 11123 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11124 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11125 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11126 11127 report.condition = condition; 11128 report.processName = app.processName; 11129 report.pid = app.pid; 11130 report.uid = app.info.uid; 11131 report.tag = activity; 11132 report.shortMsg = shortMsg; 11133 report.longMsg = longMsg; 11134 report.stackTrace = stackTrace; 11135 11136 return report; 11137 } 11138 11139 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11140 synchronized (this) { 11141 app.crashing = false; 11142 app.crashingReport = null; 11143 app.notResponding = false; 11144 app.notRespondingReport = null; 11145 if (app.anrDialog == fromDialog) { 11146 app.anrDialog = null; 11147 } 11148 if (app.waitDialog == fromDialog) { 11149 app.waitDialog = null; 11150 } 11151 if (app.pid > 0 && app.pid != MY_PID) { 11152 handleAppCrashLocked(app, null, null, null); 11153 app.kill("user request after error", true); 11154 } 11155 } 11156 } 11157 11158 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11159 String stackTrace) { 11160 long now = SystemClock.uptimeMillis(); 11161 11162 Long crashTime; 11163 if (!app.isolated) { 11164 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11165 } else { 11166 crashTime = null; 11167 } 11168 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11169 // This process loses! 11170 Slog.w(TAG, "Process " + app.info.processName 11171 + " has crashed too many times: killing!"); 11172 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11173 app.userId, app.info.processName, app.uid); 11174 mStackSupervisor.handleAppCrashLocked(app); 11175 if (!app.persistent) { 11176 // We don't want to start this process again until the user 11177 // explicitly does so... but for persistent process, we really 11178 // need to keep it running. If a persistent process is actually 11179 // repeatedly crashing, then badness for everyone. 11180 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11181 app.info.processName); 11182 if (!app.isolated) { 11183 // XXX We don't have a way to mark isolated processes 11184 // as bad, since they don't have a peristent identity. 11185 mBadProcesses.put(app.info.processName, app.uid, 11186 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11187 mProcessCrashTimes.remove(app.info.processName, app.uid); 11188 } 11189 app.bad = true; 11190 app.removed = true; 11191 // Don't let services in this process be restarted and potentially 11192 // annoy the user repeatedly. Unless it is persistent, since those 11193 // processes run critical code. 11194 removeProcessLocked(app, false, false, "crash"); 11195 mStackSupervisor.resumeTopActivitiesLocked(); 11196 return false; 11197 } 11198 mStackSupervisor.resumeTopActivitiesLocked(); 11199 } else { 11200 mStackSupervisor.finishTopRunningActivityLocked(app); 11201 } 11202 11203 // Bump up the crash count of any services currently running in the proc. 11204 for (int i=app.services.size()-1; i>=0; i--) { 11205 // Any services running in the application need to be placed 11206 // back in the pending list. 11207 ServiceRecord sr = app.services.valueAt(i); 11208 sr.crashCount++; 11209 } 11210 11211 // If the crashing process is what we consider to be the "home process" and it has been 11212 // replaced by a third-party app, clear the package preferred activities from packages 11213 // with a home activity running in the process to prevent a repeatedly crashing app 11214 // from blocking the user to manually clear the list. 11215 final ArrayList<ActivityRecord> activities = app.activities; 11216 if (app == mHomeProcess && activities.size() > 0 11217 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11218 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11219 final ActivityRecord r = activities.get(activityNdx); 11220 if (r.isHomeActivity()) { 11221 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11222 try { 11223 ActivityThread.getPackageManager() 11224 .clearPackagePreferredActivities(r.packageName); 11225 } catch (RemoteException c) { 11226 // pm is in same process, this will never happen. 11227 } 11228 } 11229 } 11230 } 11231 11232 if (!app.isolated) { 11233 // XXX Can't keep track of crash times for isolated processes, 11234 // because they don't have a perisistent identity. 11235 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11236 } 11237 11238 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11239 return true; 11240 } 11241 11242 void startAppProblemLocked(ProcessRecord app) { 11243 // If this app is not running under the current user, then we 11244 // can't give it a report button because that would require 11245 // launching the report UI under a different user. 11246 app.errorReportReceiver = null; 11247 11248 for (int userId : mCurrentProfileIds) { 11249 if (app.userId == userId) { 11250 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11251 mContext, app.info.packageName, app.info.flags); 11252 } 11253 } 11254 skipCurrentReceiverLocked(app); 11255 } 11256 11257 void skipCurrentReceiverLocked(ProcessRecord app) { 11258 for (BroadcastQueue queue : mBroadcastQueues) { 11259 queue.skipCurrentReceiverLocked(app); 11260 } 11261 } 11262 11263 /** 11264 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11265 * The application process will exit immediately after this call returns. 11266 * @param app object of the crashing app, null for the system server 11267 * @param crashInfo describing the exception 11268 */ 11269 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11270 ProcessRecord r = findAppProcess(app, "Crash"); 11271 final String processName = app == null ? "system_server" 11272 : (r == null ? "unknown" : r.processName); 11273 11274 handleApplicationCrashInner("crash", r, processName, crashInfo); 11275 } 11276 11277 /* Native crash reporting uses this inner version because it needs to be somewhat 11278 * decoupled from the AM-managed cleanup lifecycle 11279 */ 11280 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11281 ApplicationErrorReport.CrashInfo crashInfo) { 11282 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11283 UserHandle.getUserId(Binder.getCallingUid()), processName, 11284 r == null ? -1 : r.info.flags, 11285 crashInfo.exceptionClassName, 11286 crashInfo.exceptionMessage, 11287 crashInfo.throwFileName, 11288 crashInfo.throwLineNumber); 11289 11290 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11291 11292 crashApplication(r, crashInfo); 11293 } 11294 11295 public void handleApplicationStrictModeViolation( 11296 IBinder app, 11297 int violationMask, 11298 StrictMode.ViolationInfo info) { 11299 ProcessRecord r = findAppProcess(app, "StrictMode"); 11300 if (r == null) { 11301 return; 11302 } 11303 11304 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11305 Integer stackFingerprint = info.hashCode(); 11306 boolean logIt = true; 11307 synchronized (mAlreadyLoggedViolatedStacks) { 11308 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11309 logIt = false; 11310 // TODO: sub-sample into EventLog for these, with 11311 // the info.durationMillis? Then we'd get 11312 // the relative pain numbers, without logging all 11313 // the stack traces repeatedly. We'd want to do 11314 // likewise in the client code, which also does 11315 // dup suppression, before the Binder call. 11316 } else { 11317 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11318 mAlreadyLoggedViolatedStacks.clear(); 11319 } 11320 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11321 } 11322 } 11323 if (logIt) { 11324 logStrictModeViolationToDropBox(r, info); 11325 } 11326 } 11327 11328 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11329 AppErrorResult result = new AppErrorResult(); 11330 synchronized (this) { 11331 final long origId = Binder.clearCallingIdentity(); 11332 11333 Message msg = Message.obtain(); 11334 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11335 HashMap<String, Object> data = new HashMap<String, Object>(); 11336 data.put("result", result); 11337 data.put("app", r); 11338 data.put("violationMask", violationMask); 11339 data.put("info", info); 11340 msg.obj = data; 11341 mHandler.sendMessage(msg); 11342 11343 Binder.restoreCallingIdentity(origId); 11344 } 11345 int res = result.get(); 11346 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11347 } 11348 } 11349 11350 // Depending on the policy in effect, there could be a bunch of 11351 // these in quick succession so we try to batch these together to 11352 // minimize disk writes, number of dropbox entries, and maximize 11353 // compression, by having more fewer, larger records. 11354 private void logStrictModeViolationToDropBox( 11355 ProcessRecord process, 11356 StrictMode.ViolationInfo info) { 11357 if (info == null) { 11358 return; 11359 } 11360 final boolean isSystemApp = process == null || 11361 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11362 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11363 final String processName = process == null ? "unknown" : process.processName; 11364 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11365 final DropBoxManager dbox = (DropBoxManager) 11366 mContext.getSystemService(Context.DROPBOX_SERVICE); 11367 11368 // Exit early if the dropbox isn't configured to accept this report type. 11369 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11370 11371 boolean bufferWasEmpty; 11372 boolean needsFlush; 11373 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11374 synchronized (sb) { 11375 bufferWasEmpty = sb.length() == 0; 11376 appendDropBoxProcessHeaders(process, processName, sb); 11377 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11378 sb.append("System-App: ").append(isSystemApp).append("\n"); 11379 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11380 if (info.violationNumThisLoop != 0) { 11381 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11382 } 11383 if (info.numAnimationsRunning != 0) { 11384 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11385 } 11386 if (info.broadcastIntentAction != null) { 11387 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11388 } 11389 if (info.durationMillis != -1) { 11390 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11391 } 11392 if (info.numInstances != -1) { 11393 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11394 } 11395 if (info.tags != null) { 11396 for (String tag : info.tags) { 11397 sb.append("Span-Tag: ").append(tag).append("\n"); 11398 } 11399 } 11400 sb.append("\n"); 11401 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11402 sb.append(info.crashInfo.stackTrace); 11403 } 11404 sb.append("\n"); 11405 11406 // Only buffer up to ~64k. Various logging bits truncate 11407 // things at 128k. 11408 needsFlush = (sb.length() > 64 * 1024); 11409 } 11410 11411 // Flush immediately if the buffer's grown too large, or this 11412 // is a non-system app. Non-system apps are isolated with a 11413 // different tag & policy and not batched. 11414 // 11415 // Batching is useful during internal testing with 11416 // StrictMode settings turned up high. Without batching, 11417 // thousands of separate files could be created on boot. 11418 if (!isSystemApp || needsFlush) { 11419 new Thread("Error dump: " + dropboxTag) { 11420 @Override 11421 public void run() { 11422 String report; 11423 synchronized (sb) { 11424 report = sb.toString(); 11425 sb.delete(0, sb.length()); 11426 sb.trimToSize(); 11427 } 11428 if (report.length() != 0) { 11429 dbox.addText(dropboxTag, report); 11430 } 11431 } 11432 }.start(); 11433 return; 11434 } 11435 11436 // System app batching: 11437 if (!bufferWasEmpty) { 11438 // An existing dropbox-writing thread is outstanding, so 11439 // we don't need to start it up. The existing thread will 11440 // catch the buffer appends we just did. 11441 return; 11442 } 11443 11444 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11445 // (After this point, we shouldn't access AMS internal data structures.) 11446 new Thread("Error dump: " + dropboxTag) { 11447 @Override 11448 public void run() { 11449 // 5 second sleep to let stacks arrive and be batched together 11450 try { 11451 Thread.sleep(5000); // 5 seconds 11452 } catch (InterruptedException e) {} 11453 11454 String errorReport; 11455 synchronized (mStrictModeBuffer) { 11456 errorReport = mStrictModeBuffer.toString(); 11457 if (errorReport.length() == 0) { 11458 return; 11459 } 11460 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11461 mStrictModeBuffer.trimToSize(); 11462 } 11463 dbox.addText(dropboxTag, errorReport); 11464 } 11465 }.start(); 11466 } 11467 11468 /** 11469 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11470 * @param app object of the crashing app, null for the system server 11471 * @param tag reported by the caller 11472 * @param system whether this wtf is coming from the system 11473 * @param crashInfo describing the context of the error 11474 * @return true if the process should exit immediately (WTF is fatal) 11475 */ 11476 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11477 final ApplicationErrorReport.CrashInfo crashInfo) { 11478 final ProcessRecord r = findAppProcess(app, "WTF"); 11479 final String processName = app == null ? "system_server" 11480 : (r == null ? "unknown" : r.processName); 11481 11482 EventLog.writeEvent(EventLogTags.AM_WTF, 11483 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11484 processName, 11485 r == null ? -1 : r.info.flags, 11486 tag, crashInfo.exceptionMessage); 11487 11488 if (system) { 11489 // If this is coming from the system, we could very well have low-level 11490 // system locks held, so we want to do this all asynchronously. And we 11491 // never want this to become fatal, so there is that too. 11492 mHandler.post(new Runnable() { 11493 @Override public void run() { 11494 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11495 crashInfo); 11496 } 11497 }); 11498 return false; 11499 } 11500 11501 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11502 11503 if (r != null && r.pid != Process.myPid() && 11504 Settings.Global.getInt(mContext.getContentResolver(), 11505 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11506 crashApplication(r, crashInfo); 11507 return true; 11508 } else { 11509 return false; 11510 } 11511 } 11512 11513 /** 11514 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11515 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11516 */ 11517 private ProcessRecord findAppProcess(IBinder app, String reason) { 11518 if (app == null) { 11519 return null; 11520 } 11521 11522 synchronized (this) { 11523 final int NP = mProcessNames.getMap().size(); 11524 for (int ip=0; ip<NP; ip++) { 11525 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11526 final int NA = apps.size(); 11527 for (int ia=0; ia<NA; ia++) { 11528 ProcessRecord p = apps.valueAt(ia); 11529 if (p.thread != null && p.thread.asBinder() == app) { 11530 return p; 11531 } 11532 } 11533 } 11534 11535 Slog.w(TAG, "Can't find mystery application for " + reason 11536 + " from pid=" + Binder.getCallingPid() 11537 + " uid=" + Binder.getCallingUid() + ": " + app); 11538 return null; 11539 } 11540 } 11541 11542 /** 11543 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11544 * to append various headers to the dropbox log text. 11545 */ 11546 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11547 StringBuilder sb) { 11548 // Watchdog thread ends up invoking this function (with 11549 // a null ProcessRecord) to add the stack file to dropbox. 11550 // Do not acquire a lock on this (am) in such cases, as it 11551 // could cause a potential deadlock, if and when watchdog 11552 // is invoked due to unavailability of lock on am and it 11553 // would prevent watchdog from killing system_server. 11554 if (process == null) { 11555 sb.append("Process: ").append(processName).append("\n"); 11556 return; 11557 } 11558 // Note: ProcessRecord 'process' is guarded by the service 11559 // instance. (notably process.pkgList, which could otherwise change 11560 // concurrently during execution of this method) 11561 synchronized (this) { 11562 sb.append("Process: ").append(processName).append("\n"); 11563 int flags = process.info.flags; 11564 IPackageManager pm = AppGlobals.getPackageManager(); 11565 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11566 for (int ip=0; ip<process.pkgList.size(); ip++) { 11567 String pkg = process.pkgList.keyAt(ip); 11568 sb.append("Package: ").append(pkg); 11569 try { 11570 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11571 if (pi != null) { 11572 sb.append(" v").append(pi.versionCode); 11573 if (pi.versionName != null) { 11574 sb.append(" (").append(pi.versionName).append(")"); 11575 } 11576 } 11577 } catch (RemoteException e) { 11578 Slog.e(TAG, "Error getting package info: " + pkg, e); 11579 } 11580 sb.append("\n"); 11581 } 11582 } 11583 } 11584 11585 private static String processClass(ProcessRecord process) { 11586 if (process == null || process.pid == MY_PID) { 11587 return "system_server"; 11588 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11589 return "system_app"; 11590 } else { 11591 return "data_app"; 11592 } 11593 } 11594 11595 /** 11596 * Write a description of an error (crash, WTF, ANR) to the drop box. 11597 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11598 * @param process which caused the error, null means the system server 11599 * @param activity which triggered the error, null if unknown 11600 * @param parent activity related to the error, null if unknown 11601 * @param subject line related to the error, null if absent 11602 * @param report in long form describing the error, null if absent 11603 * @param logFile to include in the report, null if none 11604 * @param crashInfo giving an application stack trace, null if absent 11605 */ 11606 public void addErrorToDropBox(String eventType, 11607 ProcessRecord process, String processName, ActivityRecord activity, 11608 ActivityRecord parent, String subject, 11609 final String report, final File logFile, 11610 final ApplicationErrorReport.CrashInfo crashInfo) { 11611 // NOTE -- this must never acquire the ActivityManagerService lock, 11612 // otherwise the watchdog may be prevented from resetting the system. 11613 11614 final String dropboxTag = processClass(process) + "_" + eventType; 11615 final DropBoxManager dbox = (DropBoxManager) 11616 mContext.getSystemService(Context.DROPBOX_SERVICE); 11617 11618 // Exit early if the dropbox isn't configured to accept this report type. 11619 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11620 11621 final StringBuilder sb = new StringBuilder(1024); 11622 appendDropBoxProcessHeaders(process, processName, sb); 11623 if (activity != null) { 11624 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11625 } 11626 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11627 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11628 } 11629 if (parent != null && parent != activity) { 11630 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11631 } 11632 if (subject != null) { 11633 sb.append("Subject: ").append(subject).append("\n"); 11634 } 11635 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11636 if (Debug.isDebuggerConnected()) { 11637 sb.append("Debugger: Connected\n"); 11638 } 11639 sb.append("\n"); 11640 11641 // Do the rest in a worker thread to avoid blocking the caller on I/O 11642 // (After this point, we shouldn't access AMS internal data structures.) 11643 Thread worker = new Thread("Error dump: " + dropboxTag) { 11644 @Override 11645 public void run() { 11646 if (report != null) { 11647 sb.append(report); 11648 } 11649 if (logFile != null) { 11650 try { 11651 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11652 "\n\n[[TRUNCATED]]")); 11653 } catch (IOException e) { 11654 Slog.e(TAG, "Error reading " + logFile, e); 11655 } 11656 } 11657 if (crashInfo != null && crashInfo.stackTrace != null) { 11658 sb.append(crashInfo.stackTrace); 11659 } 11660 11661 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11662 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11663 if (lines > 0) { 11664 sb.append("\n"); 11665 11666 // Merge several logcat streams, and take the last N lines 11667 InputStreamReader input = null; 11668 try { 11669 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11670 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11671 "-b", "crash", 11672 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11673 11674 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11675 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11676 input = new InputStreamReader(logcat.getInputStream()); 11677 11678 int num; 11679 char[] buf = new char[8192]; 11680 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11681 } catch (IOException e) { 11682 Slog.e(TAG, "Error running logcat", e); 11683 } finally { 11684 if (input != null) try { input.close(); } catch (IOException e) {} 11685 } 11686 } 11687 11688 dbox.addText(dropboxTag, sb.toString()); 11689 } 11690 }; 11691 11692 if (process == null) { 11693 // If process is null, we are being called from some internal code 11694 // and may be about to die -- run this synchronously. 11695 worker.run(); 11696 } else { 11697 worker.start(); 11698 } 11699 } 11700 11701 /** 11702 * Bring up the "unexpected error" dialog box for a crashing app. 11703 * Deal with edge cases (intercepts from instrumented applications, 11704 * ActivityController, error intent receivers, that sort of thing). 11705 * @param r the application crashing 11706 * @param crashInfo describing the failure 11707 */ 11708 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11709 long timeMillis = System.currentTimeMillis(); 11710 String shortMsg = crashInfo.exceptionClassName; 11711 String longMsg = crashInfo.exceptionMessage; 11712 String stackTrace = crashInfo.stackTrace; 11713 if (shortMsg != null && longMsg != null) { 11714 longMsg = shortMsg + ": " + longMsg; 11715 } else if (shortMsg != null) { 11716 longMsg = shortMsg; 11717 } 11718 11719 AppErrorResult result = new AppErrorResult(); 11720 synchronized (this) { 11721 if (mController != null) { 11722 try { 11723 String name = r != null ? r.processName : null; 11724 int pid = r != null ? r.pid : Binder.getCallingPid(); 11725 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11726 if (!mController.appCrashed(name, pid, 11727 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11728 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11729 && "Native crash".equals(crashInfo.exceptionClassName)) { 11730 Slog.w(TAG, "Skip killing native crashed app " + name 11731 + "(" + pid + ") during testing"); 11732 } else { 11733 Slog.w(TAG, "Force-killing crashed app " + name 11734 + " at watcher's request"); 11735 if (r != null) { 11736 r.kill("crash", true); 11737 } else { 11738 // Huh. 11739 Process.killProcess(pid); 11740 Process.killProcessGroup(uid, pid); 11741 } 11742 } 11743 return; 11744 } 11745 } catch (RemoteException e) { 11746 mController = null; 11747 Watchdog.getInstance().setActivityController(null); 11748 } 11749 } 11750 11751 final long origId = Binder.clearCallingIdentity(); 11752 11753 // If this process is running instrumentation, finish it. 11754 if (r != null && r.instrumentationClass != null) { 11755 Slog.w(TAG, "Error in app " + r.processName 11756 + " running instrumentation " + r.instrumentationClass + ":"); 11757 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11758 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11759 Bundle info = new Bundle(); 11760 info.putString("shortMsg", shortMsg); 11761 info.putString("longMsg", longMsg); 11762 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11763 Binder.restoreCallingIdentity(origId); 11764 return; 11765 } 11766 11767 // If we can't identify the process or it's already exceeded its crash quota, 11768 // quit right away without showing a crash dialog. 11769 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11770 Binder.restoreCallingIdentity(origId); 11771 return; 11772 } 11773 11774 Message msg = Message.obtain(); 11775 msg.what = SHOW_ERROR_MSG; 11776 HashMap data = new HashMap(); 11777 data.put("result", result); 11778 data.put("app", r); 11779 msg.obj = data; 11780 mHandler.sendMessage(msg); 11781 11782 Binder.restoreCallingIdentity(origId); 11783 } 11784 11785 int res = result.get(); 11786 11787 Intent appErrorIntent = null; 11788 synchronized (this) { 11789 if (r != null && !r.isolated) { 11790 // XXX Can't keep track of crash time for isolated processes, 11791 // since they don't have a persistent identity. 11792 mProcessCrashTimes.put(r.info.processName, r.uid, 11793 SystemClock.uptimeMillis()); 11794 } 11795 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11796 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11797 } 11798 } 11799 11800 if (appErrorIntent != null) { 11801 try { 11802 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11803 } catch (ActivityNotFoundException e) { 11804 Slog.w(TAG, "bug report receiver dissappeared", e); 11805 } 11806 } 11807 } 11808 11809 Intent createAppErrorIntentLocked(ProcessRecord r, 11810 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11811 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11812 if (report == null) { 11813 return null; 11814 } 11815 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11816 result.setComponent(r.errorReportReceiver); 11817 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11818 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11819 return result; 11820 } 11821 11822 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11823 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11824 if (r.errorReportReceiver == null) { 11825 return null; 11826 } 11827 11828 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11829 return null; 11830 } 11831 11832 ApplicationErrorReport report = new ApplicationErrorReport(); 11833 report.packageName = r.info.packageName; 11834 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11835 report.processName = r.processName; 11836 report.time = timeMillis; 11837 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11838 11839 if (r.crashing || r.forceCrashReport) { 11840 report.type = ApplicationErrorReport.TYPE_CRASH; 11841 report.crashInfo = crashInfo; 11842 } else if (r.notResponding) { 11843 report.type = ApplicationErrorReport.TYPE_ANR; 11844 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11845 11846 report.anrInfo.activity = r.notRespondingReport.tag; 11847 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11848 report.anrInfo.info = r.notRespondingReport.longMsg; 11849 } 11850 11851 return report; 11852 } 11853 11854 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11855 enforceNotIsolatedCaller("getProcessesInErrorState"); 11856 // assume our apps are happy - lazy create the list 11857 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11858 11859 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11860 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11861 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11862 11863 synchronized (this) { 11864 11865 // iterate across all processes 11866 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11867 ProcessRecord app = mLruProcesses.get(i); 11868 if (!allUsers && app.userId != userId) { 11869 continue; 11870 } 11871 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11872 // This one's in trouble, so we'll generate a report for it 11873 // crashes are higher priority (in case there's a crash *and* an anr) 11874 ActivityManager.ProcessErrorStateInfo report = null; 11875 if (app.crashing) { 11876 report = app.crashingReport; 11877 } else if (app.notResponding) { 11878 report = app.notRespondingReport; 11879 } 11880 11881 if (report != null) { 11882 if (errList == null) { 11883 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11884 } 11885 errList.add(report); 11886 } else { 11887 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11888 " crashing = " + app.crashing + 11889 " notResponding = " + app.notResponding); 11890 } 11891 } 11892 } 11893 } 11894 11895 return errList; 11896 } 11897 11898 static int procStateToImportance(int procState, int memAdj, 11899 ActivityManager.RunningAppProcessInfo currApp) { 11900 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11901 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11902 currApp.lru = memAdj; 11903 } else { 11904 currApp.lru = 0; 11905 } 11906 return imp; 11907 } 11908 11909 private void fillInProcMemInfo(ProcessRecord app, 11910 ActivityManager.RunningAppProcessInfo outInfo) { 11911 outInfo.pid = app.pid; 11912 outInfo.uid = app.info.uid; 11913 if (mHeavyWeightProcess == app) { 11914 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11915 } 11916 if (app.persistent) { 11917 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11918 } 11919 if (app.activities.size() > 0) { 11920 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11921 } 11922 outInfo.lastTrimLevel = app.trimMemoryLevel; 11923 int adj = app.curAdj; 11924 int procState = app.curProcState; 11925 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11926 outInfo.importanceReasonCode = app.adjTypeCode; 11927 outInfo.processState = app.curProcState; 11928 } 11929 11930 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11931 enforceNotIsolatedCaller("getRunningAppProcesses"); 11932 // Lazy instantiation of list 11933 List<ActivityManager.RunningAppProcessInfo> runList = null; 11934 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11935 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11936 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11937 synchronized (this) { 11938 // Iterate across all processes 11939 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11940 ProcessRecord app = mLruProcesses.get(i); 11941 if (!allUsers && app.userId != userId) { 11942 continue; 11943 } 11944 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11945 // Generate process state info for running application 11946 ActivityManager.RunningAppProcessInfo currApp = 11947 new ActivityManager.RunningAppProcessInfo(app.processName, 11948 app.pid, app.getPackageList()); 11949 fillInProcMemInfo(app, currApp); 11950 if (app.adjSource instanceof ProcessRecord) { 11951 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11952 currApp.importanceReasonImportance = 11953 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11954 app.adjSourceProcState); 11955 } else if (app.adjSource instanceof ActivityRecord) { 11956 ActivityRecord r = (ActivityRecord)app.adjSource; 11957 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11958 } 11959 if (app.adjTarget instanceof ComponentName) { 11960 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11961 } 11962 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11963 // + " lru=" + currApp.lru); 11964 if (runList == null) { 11965 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11966 } 11967 runList.add(currApp); 11968 } 11969 } 11970 } 11971 return runList; 11972 } 11973 11974 public List<ApplicationInfo> getRunningExternalApplications() { 11975 enforceNotIsolatedCaller("getRunningExternalApplications"); 11976 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11977 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11978 if (runningApps != null && runningApps.size() > 0) { 11979 Set<String> extList = new HashSet<String>(); 11980 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11981 if (app.pkgList != null) { 11982 for (String pkg : app.pkgList) { 11983 extList.add(pkg); 11984 } 11985 } 11986 } 11987 IPackageManager pm = AppGlobals.getPackageManager(); 11988 for (String pkg : extList) { 11989 try { 11990 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11991 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11992 retList.add(info); 11993 } 11994 } catch (RemoteException e) { 11995 } 11996 } 11997 } 11998 return retList; 11999 } 12000 12001 @Override 12002 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12003 enforceNotIsolatedCaller("getMyMemoryState"); 12004 synchronized (this) { 12005 ProcessRecord proc; 12006 synchronized (mPidsSelfLocked) { 12007 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12008 } 12009 fillInProcMemInfo(proc, outInfo); 12010 } 12011 } 12012 12013 @Override 12014 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12015 if (checkCallingPermission(android.Manifest.permission.DUMP) 12016 != PackageManager.PERMISSION_GRANTED) { 12017 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12018 + Binder.getCallingPid() 12019 + ", uid=" + Binder.getCallingUid() 12020 + " without permission " 12021 + android.Manifest.permission.DUMP); 12022 return; 12023 } 12024 12025 boolean dumpAll = false; 12026 boolean dumpClient = false; 12027 String dumpPackage = null; 12028 12029 int opti = 0; 12030 while (opti < args.length) { 12031 String opt = args[opti]; 12032 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12033 break; 12034 } 12035 opti++; 12036 if ("-a".equals(opt)) { 12037 dumpAll = true; 12038 } else if ("-c".equals(opt)) { 12039 dumpClient = true; 12040 } else if ("-h".equals(opt)) { 12041 pw.println("Activity manager dump options:"); 12042 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12043 pw.println(" cmd may be one of:"); 12044 pw.println(" a[ctivities]: activity stack state"); 12045 pw.println(" r[recents]: recent activities state"); 12046 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12047 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12048 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12049 pw.println(" o[om]: out of memory management"); 12050 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12051 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12052 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12053 pw.println(" service [COMP_SPEC]: service client-side state"); 12054 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12055 pw.println(" all: dump all activities"); 12056 pw.println(" top: dump the top activity"); 12057 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12058 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12059 pw.println(" a partial substring in a component name, a"); 12060 pw.println(" hex object identifier."); 12061 pw.println(" -a: include all available server state."); 12062 pw.println(" -c: include client state."); 12063 return; 12064 } else { 12065 pw.println("Unknown argument: " + opt + "; use -h for help"); 12066 } 12067 } 12068 12069 long origId = Binder.clearCallingIdentity(); 12070 boolean more = false; 12071 // Is the caller requesting to dump a particular piece of data? 12072 if (opti < args.length) { 12073 String cmd = args[opti]; 12074 opti++; 12075 if ("activities".equals(cmd) || "a".equals(cmd)) { 12076 synchronized (this) { 12077 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12078 } 12079 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12080 synchronized (this) { 12081 dumpRecentsLocked(fd, pw, args, opti, true, null); 12082 } 12083 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12084 String[] newArgs; 12085 String name; 12086 if (opti >= args.length) { 12087 name = null; 12088 newArgs = EMPTY_STRING_ARRAY; 12089 } else { 12090 name = args[opti]; 12091 opti++; 12092 newArgs = new String[args.length - opti]; 12093 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12094 args.length - opti); 12095 } 12096 synchronized (this) { 12097 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12098 } 12099 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12100 String[] newArgs; 12101 String name; 12102 if (opti >= args.length) { 12103 name = null; 12104 newArgs = EMPTY_STRING_ARRAY; 12105 } else { 12106 name = args[opti]; 12107 opti++; 12108 newArgs = new String[args.length - opti]; 12109 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12110 args.length - opti); 12111 } 12112 synchronized (this) { 12113 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12114 } 12115 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12116 String[] newArgs; 12117 String name; 12118 if (opti >= args.length) { 12119 name = null; 12120 newArgs = EMPTY_STRING_ARRAY; 12121 } else { 12122 name = args[opti]; 12123 opti++; 12124 newArgs = new String[args.length - opti]; 12125 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12126 args.length - opti); 12127 } 12128 synchronized (this) { 12129 dumpProcessesLocked(fd, pw, args, opti, true, name); 12130 } 12131 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12132 synchronized (this) { 12133 dumpOomLocked(fd, pw, args, opti, true); 12134 } 12135 } else if ("provider".equals(cmd)) { 12136 String[] newArgs; 12137 String name; 12138 if (opti >= args.length) { 12139 name = null; 12140 newArgs = EMPTY_STRING_ARRAY; 12141 } else { 12142 name = args[opti]; 12143 opti++; 12144 newArgs = new String[args.length - opti]; 12145 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12146 } 12147 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12148 pw.println("No providers match: " + name); 12149 pw.println("Use -h for help."); 12150 } 12151 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12152 synchronized (this) { 12153 dumpProvidersLocked(fd, pw, args, opti, true, null); 12154 } 12155 } else if ("service".equals(cmd)) { 12156 String[] newArgs; 12157 String name; 12158 if (opti >= args.length) { 12159 name = null; 12160 newArgs = EMPTY_STRING_ARRAY; 12161 } else { 12162 name = args[opti]; 12163 opti++; 12164 newArgs = new String[args.length - opti]; 12165 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12166 args.length - opti); 12167 } 12168 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12169 pw.println("No services match: " + name); 12170 pw.println("Use -h for help."); 12171 } 12172 } else if ("package".equals(cmd)) { 12173 String[] newArgs; 12174 if (opti >= args.length) { 12175 pw.println("package: no package name specified"); 12176 pw.println("Use -h for help."); 12177 } else { 12178 dumpPackage = args[opti]; 12179 opti++; 12180 newArgs = new String[args.length - opti]; 12181 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12182 args.length - opti); 12183 args = newArgs; 12184 opti = 0; 12185 more = true; 12186 } 12187 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12188 synchronized (this) { 12189 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12190 } 12191 } else { 12192 // Dumping a single activity? 12193 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12194 pw.println("Bad activity command, or no activities match: " + cmd); 12195 pw.println("Use -h for help."); 12196 } 12197 } 12198 if (!more) { 12199 Binder.restoreCallingIdentity(origId); 12200 return; 12201 } 12202 } 12203 12204 // No piece of data specified, dump everything. 12205 synchronized (this) { 12206 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12207 pw.println(); 12208 if (dumpAll) { 12209 pw.println("-------------------------------------------------------------------------------"); 12210 } 12211 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12212 pw.println(); 12213 if (dumpAll) { 12214 pw.println("-------------------------------------------------------------------------------"); 12215 } 12216 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12217 pw.println(); 12218 if (dumpAll) { 12219 pw.println("-------------------------------------------------------------------------------"); 12220 } 12221 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12222 pw.println(); 12223 if (dumpAll) { 12224 pw.println("-------------------------------------------------------------------------------"); 12225 } 12226 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12227 pw.println(); 12228 if (dumpAll) { 12229 pw.println("-------------------------------------------------------------------------------"); 12230 } 12231 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12232 pw.println(); 12233 if (dumpAll) { 12234 pw.println("-------------------------------------------------------------------------------"); 12235 } 12236 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12237 } 12238 Binder.restoreCallingIdentity(origId); 12239 } 12240 12241 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12242 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12243 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12244 12245 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12246 dumpPackage); 12247 boolean needSep = printedAnything; 12248 12249 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12250 dumpPackage, needSep, " mFocusedActivity: "); 12251 if (printed) { 12252 printedAnything = true; 12253 needSep = false; 12254 } 12255 12256 if (dumpPackage == null) { 12257 if (needSep) { 12258 pw.println(); 12259 } 12260 needSep = true; 12261 printedAnything = true; 12262 mStackSupervisor.dump(pw, " "); 12263 } 12264 12265 if (!printedAnything) { 12266 pw.println(" (nothing)"); 12267 } 12268 } 12269 12270 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12271 int opti, boolean dumpAll, String dumpPackage) { 12272 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12273 12274 boolean printedAnything = false; 12275 12276 if (mRecentTasks.size() > 0) { 12277 boolean printedHeader = false; 12278 12279 final int N = mRecentTasks.size(); 12280 for (int i=0; i<N; i++) { 12281 TaskRecord tr = mRecentTasks.get(i); 12282 if (dumpPackage != null) { 12283 if (tr.realActivity == null || 12284 !dumpPackage.equals(tr.realActivity)) { 12285 continue; 12286 } 12287 } 12288 if (!printedHeader) { 12289 pw.println(" Recent tasks:"); 12290 printedHeader = true; 12291 printedAnything = true; 12292 } 12293 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12294 pw.println(tr); 12295 if (dumpAll) { 12296 mRecentTasks.get(i).dump(pw, " "); 12297 } 12298 } 12299 } 12300 12301 if (!printedAnything) { 12302 pw.println(" (nothing)"); 12303 } 12304 } 12305 12306 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12307 int opti, boolean dumpAll, String dumpPackage) { 12308 boolean needSep = false; 12309 boolean printedAnything = false; 12310 int numPers = 0; 12311 12312 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12313 12314 if (dumpAll) { 12315 final int NP = mProcessNames.getMap().size(); 12316 for (int ip=0; ip<NP; ip++) { 12317 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12318 final int NA = procs.size(); 12319 for (int ia=0; ia<NA; ia++) { 12320 ProcessRecord r = procs.valueAt(ia); 12321 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12322 continue; 12323 } 12324 if (!needSep) { 12325 pw.println(" All known processes:"); 12326 needSep = true; 12327 printedAnything = true; 12328 } 12329 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12330 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12331 pw.print(" "); pw.println(r); 12332 r.dump(pw, " "); 12333 if (r.persistent) { 12334 numPers++; 12335 } 12336 } 12337 } 12338 } 12339 12340 if (mIsolatedProcesses.size() > 0) { 12341 boolean printed = false; 12342 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12343 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12344 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12345 continue; 12346 } 12347 if (!printed) { 12348 if (needSep) { 12349 pw.println(); 12350 } 12351 pw.println(" Isolated process list (sorted by uid):"); 12352 printedAnything = true; 12353 printed = true; 12354 needSep = true; 12355 } 12356 pw.println(String.format("%sIsolated #%2d: %s", 12357 " ", i, r.toString())); 12358 } 12359 } 12360 12361 if (mLruProcesses.size() > 0) { 12362 if (needSep) { 12363 pw.println(); 12364 } 12365 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12366 pw.print(" total, non-act at "); 12367 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12368 pw.print(", non-svc at "); 12369 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12370 pw.println("):"); 12371 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12372 needSep = true; 12373 printedAnything = true; 12374 } 12375 12376 if (dumpAll || dumpPackage != null) { 12377 synchronized (mPidsSelfLocked) { 12378 boolean printed = false; 12379 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12380 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12381 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12382 continue; 12383 } 12384 if (!printed) { 12385 if (needSep) pw.println(); 12386 needSep = true; 12387 pw.println(" PID mappings:"); 12388 printed = true; 12389 printedAnything = true; 12390 } 12391 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12392 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12393 } 12394 } 12395 } 12396 12397 if (mForegroundProcesses.size() > 0) { 12398 synchronized (mPidsSelfLocked) { 12399 boolean printed = false; 12400 for (int i=0; i<mForegroundProcesses.size(); i++) { 12401 ProcessRecord r = mPidsSelfLocked.get( 12402 mForegroundProcesses.valueAt(i).pid); 12403 if (dumpPackage != null && (r == null 12404 || !r.pkgList.containsKey(dumpPackage))) { 12405 continue; 12406 } 12407 if (!printed) { 12408 if (needSep) pw.println(); 12409 needSep = true; 12410 pw.println(" Foreground Processes:"); 12411 printed = true; 12412 printedAnything = true; 12413 } 12414 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12415 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12416 } 12417 } 12418 } 12419 12420 if (mPersistentStartingProcesses.size() > 0) { 12421 if (needSep) pw.println(); 12422 needSep = true; 12423 printedAnything = true; 12424 pw.println(" Persisent processes that are starting:"); 12425 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12426 "Starting Norm", "Restarting PERS", dumpPackage); 12427 } 12428 12429 if (mRemovedProcesses.size() > 0) { 12430 if (needSep) pw.println(); 12431 needSep = true; 12432 printedAnything = true; 12433 pw.println(" Processes that are being removed:"); 12434 dumpProcessList(pw, this, mRemovedProcesses, " ", 12435 "Removed Norm", "Removed PERS", dumpPackage); 12436 } 12437 12438 if (mProcessesOnHold.size() > 0) { 12439 if (needSep) pw.println(); 12440 needSep = true; 12441 printedAnything = true; 12442 pw.println(" Processes that are on old until the system is ready:"); 12443 dumpProcessList(pw, this, mProcessesOnHold, " ", 12444 "OnHold Norm", "OnHold PERS", dumpPackage); 12445 } 12446 12447 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12448 12449 if (mProcessCrashTimes.getMap().size() > 0) { 12450 boolean printed = false; 12451 long now = SystemClock.uptimeMillis(); 12452 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12453 final int NP = pmap.size(); 12454 for (int ip=0; ip<NP; ip++) { 12455 String pname = pmap.keyAt(ip); 12456 SparseArray<Long> uids = pmap.valueAt(ip); 12457 final int N = uids.size(); 12458 for (int i=0; i<N; i++) { 12459 int puid = uids.keyAt(i); 12460 ProcessRecord r = mProcessNames.get(pname, puid); 12461 if (dumpPackage != null && (r == null 12462 || !r.pkgList.containsKey(dumpPackage))) { 12463 continue; 12464 } 12465 if (!printed) { 12466 if (needSep) pw.println(); 12467 needSep = true; 12468 pw.println(" Time since processes crashed:"); 12469 printed = true; 12470 printedAnything = true; 12471 } 12472 pw.print(" Process "); pw.print(pname); 12473 pw.print(" uid "); pw.print(puid); 12474 pw.print(": last crashed "); 12475 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12476 pw.println(" ago"); 12477 } 12478 } 12479 } 12480 12481 if (mBadProcesses.getMap().size() > 0) { 12482 boolean printed = false; 12483 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12484 final int NP = pmap.size(); 12485 for (int ip=0; ip<NP; ip++) { 12486 String pname = pmap.keyAt(ip); 12487 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12488 final int N = uids.size(); 12489 for (int i=0; i<N; i++) { 12490 int puid = uids.keyAt(i); 12491 ProcessRecord r = mProcessNames.get(pname, puid); 12492 if (dumpPackage != null && (r == null 12493 || !r.pkgList.containsKey(dumpPackage))) { 12494 continue; 12495 } 12496 if (!printed) { 12497 if (needSep) pw.println(); 12498 needSep = true; 12499 pw.println(" Bad processes:"); 12500 printedAnything = true; 12501 } 12502 BadProcessInfo info = uids.valueAt(i); 12503 pw.print(" Bad process "); pw.print(pname); 12504 pw.print(" uid "); pw.print(puid); 12505 pw.print(": crashed at time "); pw.println(info.time); 12506 if (info.shortMsg != null) { 12507 pw.print(" Short msg: "); pw.println(info.shortMsg); 12508 } 12509 if (info.longMsg != null) { 12510 pw.print(" Long msg: "); pw.println(info.longMsg); 12511 } 12512 if (info.stack != null) { 12513 pw.println(" Stack:"); 12514 int lastPos = 0; 12515 for (int pos=0; pos<info.stack.length(); pos++) { 12516 if (info.stack.charAt(pos) == '\n') { 12517 pw.print(" "); 12518 pw.write(info.stack, lastPos, pos-lastPos); 12519 pw.println(); 12520 lastPos = pos+1; 12521 } 12522 } 12523 if (lastPos < info.stack.length()) { 12524 pw.print(" "); 12525 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12526 pw.println(); 12527 } 12528 } 12529 } 12530 } 12531 } 12532 12533 if (dumpPackage == null) { 12534 pw.println(); 12535 needSep = false; 12536 pw.println(" mStartedUsers:"); 12537 for (int i=0; i<mStartedUsers.size(); i++) { 12538 UserStartedState uss = mStartedUsers.valueAt(i); 12539 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12540 pw.print(": "); uss.dump("", pw); 12541 } 12542 pw.print(" mStartedUserArray: ["); 12543 for (int i=0; i<mStartedUserArray.length; i++) { 12544 if (i > 0) pw.print(", "); 12545 pw.print(mStartedUserArray[i]); 12546 } 12547 pw.println("]"); 12548 pw.print(" mUserLru: ["); 12549 for (int i=0; i<mUserLru.size(); i++) { 12550 if (i > 0) pw.print(", "); 12551 pw.print(mUserLru.get(i)); 12552 } 12553 pw.println("]"); 12554 if (dumpAll) { 12555 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12556 } 12557 synchronized (mUserProfileGroupIdsSelfLocked) { 12558 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12559 pw.println(" mUserProfileGroupIds:"); 12560 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12561 pw.print(" User #"); 12562 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12563 pw.print(" -> profile #"); 12564 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12565 } 12566 } 12567 } 12568 } 12569 if (mHomeProcess != null && (dumpPackage == null 12570 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12571 if (needSep) { 12572 pw.println(); 12573 needSep = false; 12574 } 12575 pw.println(" mHomeProcess: " + mHomeProcess); 12576 } 12577 if (mPreviousProcess != null && (dumpPackage == null 12578 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12579 if (needSep) { 12580 pw.println(); 12581 needSep = false; 12582 } 12583 pw.println(" mPreviousProcess: " + mPreviousProcess); 12584 } 12585 if (dumpAll) { 12586 StringBuilder sb = new StringBuilder(128); 12587 sb.append(" mPreviousProcessVisibleTime: "); 12588 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12589 pw.println(sb); 12590 } 12591 if (mHeavyWeightProcess != null && (dumpPackage == null 12592 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12593 if (needSep) { 12594 pw.println(); 12595 needSep = false; 12596 } 12597 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12598 } 12599 if (dumpPackage == null) { 12600 pw.println(" mConfiguration: " + mConfiguration); 12601 } 12602 if (dumpAll) { 12603 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12604 if (mCompatModePackages.getPackages().size() > 0) { 12605 boolean printed = false; 12606 for (Map.Entry<String, Integer> entry 12607 : mCompatModePackages.getPackages().entrySet()) { 12608 String pkg = entry.getKey(); 12609 int mode = entry.getValue(); 12610 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12611 continue; 12612 } 12613 if (!printed) { 12614 pw.println(" mScreenCompatPackages:"); 12615 printed = true; 12616 } 12617 pw.print(" "); pw.print(pkg); pw.print(": "); 12618 pw.print(mode); pw.println(); 12619 } 12620 } 12621 } 12622 if (dumpPackage == null) { 12623 if (mSleeping || mWentToSleep || mLockScreenShown) { 12624 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12625 + " mLockScreenShown " + mLockScreenShown); 12626 } 12627 if (mShuttingDown || mRunningVoice) { 12628 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12629 } 12630 } 12631 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12632 || mOrigWaitForDebugger) { 12633 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12634 || dumpPackage.equals(mOrigDebugApp)) { 12635 if (needSep) { 12636 pw.println(); 12637 needSep = false; 12638 } 12639 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12640 + " mDebugTransient=" + mDebugTransient 12641 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12642 } 12643 } 12644 if (mOpenGlTraceApp != null) { 12645 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12646 if (needSep) { 12647 pw.println(); 12648 needSep = false; 12649 } 12650 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12651 } 12652 } 12653 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12654 || mProfileFd != null) { 12655 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12656 if (needSep) { 12657 pw.println(); 12658 needSep = false; 12659 } 12660 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12661 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12662 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12663 + mAutoStopProfiler); 12664 pw.println(" mProfileType=" + mProfileType); 12665 } 12666 } 12667 if (dumpPackage == null) { 12668 if (mAlwaysFinishActivities || mController != null) { 12669 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12670 + " mController=" + mController); 12671 } 12672 if (dumpAll) { 12673 pw.println(" Total persistent processes: " + numPers); 12674 pw.println(" mProcessesReady=" + mProcessesReady 12675 + " mSystemReady=" + mSystemReady); 12676 pw.println(" mBooting=" + mBooting 12677 + " mBooted=" + mBooted 12678 + " mFactoryTest=" + mFactoryTest); 12679 pw.print(" mLastPowerCheckRealtime="); 12680 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12681 pw.println(""); 12682 pw.print(" mLastPowerCheckUptime="); 12683 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12684 pw.println(""); 12685 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12686 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12687 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12688 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12689 + " (" + mLruProcesses.size() + " total)" 12690 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12691 + " mNumServiceProcs=" + mNumServiceProcs 12692 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12693 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12694 + " mLastMemoryLevel" + mLastMemoryLevel 12695 + " mLastNumProcesses" + mLastNumProcesses); 12696 long now = SystemClock.uptimeMillis(); 12697 pw.print(" mLastIdleTime="); 12698 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12699 pw.print(" mLowRamSinceLastIdle="); 12700 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12701 pw.println(); 12702 } 12703 } 12704 12705 if (!printedAnything) { 12706 pw.println(" (nothing)"); 12707 } 12708 } 12709 12710 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12711 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12712 if (mProcessesToGc.size() > 0) { 12713 boolean printed = false; 12714 long now = SystemClock.uptimeMillis(); 12715 for (int i=0; i<mProcessesToGc.size(); i++) { 12716 ProcessRecord proc = mProcessesToGc.get(i); 12717 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12718 continue; 12719 } 12720 if (!printed) { 12721 if (needSep) pw.println(); 12722 needSep = true; 12723 pw.println(" Processes that are waiting to GC:"); 12724 printed = true; 12725 } 12726 pw.print(" Process "); pw.println(proc); 12727 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12728 pw.print(", last gced="); 12729 pw.print(now-proc.lastRequestedGc); 12730 pw.print(" ms ago, last lowMem="); 12731 pw.print(now-proc.lastLowMemory); 12732 pw.println(" ms ago"); 12733 12734 } 12735 } 12736 return needSep; 12737 } 12738 12739 void printOomLevel(PrintWriter pw, String name, int adj) { 12740 pw.print(" "); 12741 if (adj >= 0) { 12742 pw.print(' '); 12743 if (adj < 10) pw.print(' '); 12744 } else { 12745 if (adj > -10) pw.print(' '); 12746 } 12747 pw.print(adj); 12748 pw.print(": "); 12749 pw.print(name); 12750 pw.print(" ("); 12751 pw.print(mProcessList.getMemLevel(adj)/1024); 12752 pw.println(" kB)"); 12753 } 12754 12755 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12756 int opti, boolean dumpAll) { 12757 boolean needSep = false; 12758 12759 if (mLruProcesses.size() > 0) { 12760 if (needSep) pw.println(); 12761 needSep = true; 12762 pw.println(" OOM levels:"); 12763 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12764 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12765 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12766 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12767 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12768 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12769 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12770 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12771 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12772 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12773 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12774 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12775 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12776 12777 if (needSep) pw.println(); 12778 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12779 pw.print(" total, non-act at "); 12780 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12781 pw.print(", non-svc at "); 12782 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12783 pw.println("):"); 12784 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12785 needSep = true; 12786 } 12787 12788 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12789 12790 pw.println(); 12791 pw.println(" mHomeProcess: " + mHomeProcess); 12792 pw.println(" mPreviousProcess: " + mPreviousProcess); 12793 if (mHeavyWeightProcess != null) { 12794 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12795 } 12796 12797 return true; 12798 } 12799 12800 /** 12801 * There are three ways to call this: 12802 * - no provider specified: dump all the providers 12803 * - a flattened component name that matched an existing provider was specified as the 12804 * first arg: dump that one provider 12805 * - the first arg isn't the flattened component name of an existing provider: 12806 * dump all providers whose component contains the first arg as a substring 12807 */ 12808 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12809 int opti, boolean dumpAll) { 12810 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12811 } 12812 12813 static class ItemMatcher { 12814 ArrayList<ComponentName> components; 12815 ArrayList<String> strings; 12816 ArrayList<Integer> objects; 12817 boolean all; 12818 12819 ItemMatcher() { 12820 all = true; 12821 } 12822 12823 void build(String name) { 12824 ComponentName componentName = ComponentName.unflattenFromString(name); 12825 if (componentName != null) { 12826 if (components == null) { 12827 components = new ArrayList<ComponentName>(); 12828 } 12829 components.add(componentName); 12830 all = false; 12831 } else { 12832 int objectId = 0; 12833 // Not a '/' separated full component name; maybe an object ID? 12834 try { 12835 objectId = Integer.parseInt(name, 16); 12836 if (objects == null) { 12837 objects = new ArrayList<Integer>(); 12838 } 12839 objects.add(objectId); 12840 all = false; 12841 } catch (RuntimeException e) { 12842 // Not an integer; just do string match. 12843 if (strings == null) { 12844 strings = new ArrayList<String>(); 12845 } 12846 strings.add(name); 12847 all = false; 12848 } 12849 } 12850 } 12851 12852 int build(String[] args, int opti) { 12853 for (; opti<args.length; opti++) { 12854 String name = args[opti]; 12855 if ("--".equals(name)) { 12856 return opti+1; 12857 } 12858 build(name); 12859 } 12860 return opti; 12861 } 12862 12863 boolean match(Object object, ComponentName comp) { 12864 if (all) { 12865 return true; 12866 } 12867 if (components != null) { 12868 for (int i=0; i<components.size(); i++) { 12869 if (components.get(i).equals(comp)) { 12870 return true; 12871 } 12872 } 12873 } 12874 if (objects != null) { 12875 for (int i=0; i<objects.size(); i++) { 12876 if (System.identityHashCode(object) == objects.get(i)) { 12877 return true; 12878 } 12879 } 12880 } 12881 if (strings != null) { 12882 String flat = comp.flattenToString(); 12883 for (int i=0; i<strings.size(); i++) { 12884 if (flat.contains(strings.get(i))) { 12885 return true; 12886 } 12887 } 12888 } 12889 return false; 12890 } 12891 } 12892 12893 /** 12894 * There are three things that cmd can be: 12895 * - a flattened component name that matches an existing activity 12896 * - the cmd arg isn't the flattened component name of an existing activity: 12897 * dump all activity whose component contains the cmd as a substring 12898 * - A hex number of the ActivityRecord object instance. 12899 */ 12900 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12901 int opti, boolean dumpAll) { 12902 ArrayList<ActivityRecord> activities; 12903 12904 synchronized (this) { 12905 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12906 } 12907 12908 if (activities.size() <= 0) { 12909 return false; 12910 } 12911 12912 String[] newArgs = new String[args.length - opti]; 12913 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12914 12915 TaskRecord lastTask = null; 12916 boolean needSep = false; 12917 for (int i=activities.size()-1; i>=0; i--) { 12918 ActivityRecord r = activities.get(i); 12919 if (needSep) { 12920 pw.println(); 12921 } 12922 needSep = true; 12923 synchronized (this) { 12924 if (lastTask != r.task) { 12925 lastTask = r.task; 12926 pw.print("TASK "); pw.print(lastTask.affinity); 12927 pw.print(" id="); pw.println(lastTask.taskId); 12928 if (dumpAll) { 12929 lastTask.dump(pw, " "); 12930 } 12931 } 12932 } 12933 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12934 } 12935 return true; 12936 } 12937 12938 /** 12939 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12940 * there is a thread associated with the activity. 12941 */ 12942 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12943 final ActivityRecord r, String[] args, boolean dumpAll) { 12944 String innerPrefix = prefix + " "; 12945 synchronized (this) { 12946 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12947 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12948 pw.print(" pid="); 12949 if (r.app != null) pw.println(r.app.pid); 12950 else pw.println("(not running)"); 12951 if (dumpAll) { 12952 r.dump(pw, innerPrefix); 12953 } 12954 } 12955 if (r.app != null && r.app.thread != null) { 12956 // flush anything that is already in the PrintWriter since the thread is going 12957 // to write to the file descriptor directly 12958 pw.flush(); 12959 try { 12960 TransferPipe tp = new TransferPipe(); 12961 try { 12962 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12963 r.appToken, innerPrefix, args); 12964 tp.go(fd); 12965 } finally { 12966 tp.kill(); 12967 } 12968 } catch (IOException e) { 12969 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12970 } catch (RemoteException e) { 12971 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12972 } 12973 } 12974 } 12975 12976 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12977 int opti, boolean dumpAll, String dumpPackage) { 12978 boolean needSep = false; 12979 boolean onlyHistory = false; 12980 boolean printedAnything = false; 12981 12982 if ("history".equals(dumpPackage)) { 12983 if (opti < args.length && "-s".equals(args[opti])) { 12984 dumpAll = false; 12985 } 12986 onlyHistory = true; 12987 dumpPackage = null; 12988 } 12989 12990 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12991 if (!onlyHistory && dumpAll) { 12992 if (mRegisteredReceivers.size() > 0) { 12993 boolean printed = false; 12994 Iterator it = mRegisteredReceivers.values().iterator(); 12995 while (it.hasNext()) { 12996 ReceiverList r = (ReceiverList)it.next(); 12997 if (dumpPackage != null && (r.app == null || 12998 !dumpPackage.equals(r.app.info.packageName))) { 12999 continue; 13000 } 13001 if (!printed) { 13002 pw.println(" Registered Receivers:"); 13003 needSep = true; 13004 printed = true; 13005 printedAnything = true; 13006 } 13007 pw.print(" * "); pw.println(r); 13008 r.dump(pw, " "); 13009 } 13010 } 13011 13012 if (mReceiverResolver.dump(pw, needSep ? 13013 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13014 " ", dumpPackage, false)) { 13015 needSep = true; 13016 printedAnything = true; 13017 } 13018 } 13019 13020 for (BroadcastQueue q : mBroadcastQueues) { 13021 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13022 printedAnything |= needSep; 13023 } 13024 13025 needSep = true; 13026 13027 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13028 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13029 if (needSep) { 13030 pw.println(); 13031 } 13032 needSep = true; 13033 printedAnything = true; 13034 pw.print(" Sticky broadcasts for user "); 13035 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13036 StringBuilder sb = new StringBuilder(128); 13037 for (Map.Entry<String, ArrayList<Intent>> ent 13038 : mStickyBroadcasts.valueAt(user).entrySet()) { 13039 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13040 if (dumpAll) { 13041 pw.println(":"); 13042 ArrayList<Intent> intents = ent.getValue(); 13043 final int N = intents.size(); 13044 for (int i=0; i<N; i++) { 13045 sb.setLength(0); 13046 sb.append(" Intent: "); 13047 intents.get(i).toShortString(sb, false, true, false, false); 13048 pw.println(sb.toString()); 13049 Bundle bundle = intents.get(i).getExtras(); 13050 if (bundle != null) { 13051 pw.print(" "); 13052 pw.println(bundle.toString()); 13053 } 13054 } 13055 } else { 13056 pw.println(""); 13057 } 13058 } 13059 } 13060 } 13061 13062 if (!onlyHistory && dumpAll) { 13063 pw.println(); 13064 for (BroadcastQueue queue : mBroadcastQueues) { 13065 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13066 + queue.mBroadcastsScheduled); 13067 } 13068 pw.println(" mHandler:"); 13069 mHandler.dump(new PrintWriterPrinter(pw), " "); 13070 needSep = true; 13071 printedAnything = true; 13072 } 13073 13074 if (!printedAnything) { 13075 pw.println(" (nothing)"); 13076 } 13077 } 13078 13079 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13080 int opti, boolean dumpAll, String dumpPackage) { 13081 boolean needSep; 13082 boolean printedAnything = false; 13083 13084 ItemMatcher matcher = new ItemMatcher(); 13085 matcher.build(args, opti); 13086 13087 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13088 13089 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13090 printedAnything |= needSep; 13091 13092 if (mLaunchingProviders.size() > 0) { 13093 boolean printed = false; 13094 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13095 ContentProviderRecord r = mLaunchingProviders.get(i); 13096 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13097 continue; 13098 } 13099 if (!printed) { 13100 if (needSep) pw.println(); 13101 needSep = true; 13102 pw.println(" Launching content providers:"); 13103 printed = true; 13104 printedAnything = true; 13105 } 13106 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13107 pw.println(r); 13108 } 13109 } 13110 13111 if (mGrantedUriPermissions.size() > 0) { 13112 boolean printed = false; 13113 int dumpUid = -2; 13114 if (dumpPackage != null) { 13115 try { 13116 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13117 } catch (NameNotFoundException e) { 13118 dumpUid = -1; 13119 } 13120 } 13121 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13122 int uid = mGrantedUriPermissions.keyAt(i); 13123 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13124 continue; 13125 } 13126 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13127 if (!printed) { 13128 if (needSep) pw.println(); 13129 needSep = true; 13130 pw.println(" Granted Uri Permissions:"); 13131 printed = true; 13132 printedAnything = true; 13133 } 13134 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13135 for (UriPermission perm : perms.values()) { 13136 pw.print(" "); pw.println(perm); 13137 if (dumpAll) { 13138 perm.dump(pw, " "); 13139 } 13140 } 13141 } 13142 } 13143 13144 if (!printedAnything) { 13145 pw.println(" (nothing)"); 13146 } 13147 } 13148 13149 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13150 int opti, boolean dumpAll, String dumpPackage) { 13151 boolean printed = false; 13152 13153 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13154 13155 if (mIntentSenderRecords.size() > 0) { 13156 Iterator<WeakReference<PendingIntentRecord>> it 13157 = mIntentSenderRecords.values().iterator(); 13158 while (it.hasNext()) { 13159 WeakReference<PendingIntentRecord> ref = it.next(); 13160 PendingIntentRecord rec = ref != null ? ref.get(): null; 13161 if (dumpPackage != null && (rec == null 13162 || !dumpPackage.equals(rec.key.packageName))) { 13163 continue; 13164 } 13165 printed = true; 13166 if (rec != null) { 13167 pw.print(" * "); pw.println(rec); 13168 if (dumpAll) { 13169 rec.dump(pw, " "); 13170 } 13171 } else { 13172 pw.print(" * "); pw.println(ref); 13173 } 13174 } 13175 } 13176 13177 if (!printed) { 13178 pw.println(" (nothing)"); 13179 } 13180 } 13181 13182 private static final int dumpProcessList(PrintWriter pw, 13183 ActivityManagerService service, List list, 13184 String prefix, String normalLabel, String persistentLabel, 13185 String dumpPackage) { 13186 int numPers = 0; 13187 final int N = list.size()-1; 13188 for (int i=N; i>=0; i--) { 13189 ProcessRecord r = (ProcessRecord)list.get(i); 13190 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13191 continue; 13192 } 13193 pw.println(String.format("%s%s #%2d: %s", 13194 prefix, (r.persistent ? persistentLabel : normalLabel), 13195 i, r.toString())); 13196 if (r.persistent) { 13197 numPers++; 13198 } 13199 } 13200 return numPers; 13201 } 13202 13203 private static final boolean dumpProcessOomList(PrintWriter pw, 13204 ActivityManagerService service, List<ProcessRecord> origList, 13205 String prefix, String normalLabel, String persistentLabel, 13206 boolean inclDetails, String dumpPackage) { 13207 13208 ArrayList<Pair<ProcessRecord, Integer>> list 13209 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13210 for (int i=0; i<origList.size(); i++) { 13211 ProcessRecord r = origList.get(i); 13212 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13213 continue; 13214 } 13215 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13216 } 13217 13218 if (list.size() <= 0) { 13219 return false; 13220 } 13221 13222 Comparator<Pair<ProcessRecord, Integer>> comparator 13223 = new Comparator<Pair<ProcessRecord, Integer>>() { 13224 @Override 13225 public int compare(Pair<ProcessRecord, Integer> object1, 13226 Pair<ProcessRecord, Integer> object2) { 13227 if (object1.first.setAdj != object2.first.setAdj) { 13228 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13229 } 13230 if (object1.second.intValue() != object2.second.intValue()) { 13231 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13232 } 13233 return 0; 13234 } 13235 }; 13236 13237 Collections.sort(list, comparator); 13238 13239 final long curRealtime = SystemClock.elapsedRealtime(); 13240 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13241 final long curUptime = SystemClock.uptimeMillis(); 13242 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13243 13244 for (int i=list.size()-1; i>=0; i--) { 13245 ProcessRecord r = list.get(i).first; 13246 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13247 char schedGroup; 13248 switch (r.setSchedGroup) { 13249 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13250 schedGroup = 'B'; 13251 break; 13252 case Process.THREAD_GROUP_DEFAULT: 13253 schedGroup = 'F'; 13254 break; 13255 default: 13256 schedGroup = '?'; 13257 break; 13258 } 13259 char foreground; 13260 if (r.foregroundActivities) { 13261 foreground = 'A'; 13262 } else if (r.foregroundServices) { 13263 foreground = 'S'; 13264 } else { 13265 foreground = ' '; 13266 } 13267 String procState = ProcessList.makeProcStateString(r.curProcState); 13268 pw.print(prefix); 13269 pw.print(r.persistent ? persistentLabel : normalLabel); 13270 pw.print(" #"); 13271 int num = (origList.size()-1)-list.get(i).second; 13272 if (num < 10) pw.print(' '); 13273 pw.print(num); 13274 pw.print(": "); 13275 pw.print(oomAdj); 13276 pw.print(' '); 13277 pw.print(schedGroup); 13278 pw.print('/'); 13279 pw.print(foreground); 13280 pw.print('/'); 13281 pw.print(procState); 13282 pw.print(" trm:"); 13283 if (r.trimMemoryLevel < 10) pw.print(' '); 13284 pw.print(r.trimMemoryLevel); 13285 pw.print(' '); 13286 pw.print(r.toShortString()); 13287 pw.print(" ("); 13288 pw.print(r.adjType); 13289 pw.println(')'); 13290 if (r.adjSource != null || r.adjTarget != null) { 13291 pw.print(prefix); 13292 pw.print(" "); 13293 if (r.adjTarget instanceof ComponentName) { 13294 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13295 } else if (r.adjTarget != null) { 13296 pw.print(r.adjTarget.toString()); 13297 } else { 13298 pw.print("{null}"); 13299 } 13300 pw.print("<="); 13301 if (r.adjSource instanceof ProcessRecord) { 13302 pw.print("Proc{"); 13303 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13304 pw.println("}"); 13305 } else if (r.adjSource != null) { 13306 pw.println(r.adjSource.toString()); 13307 } else { 13308 pw.println("{null}"); 13309 } 13310 } 13311 if (inclDetails) { 13312 pw.print(prefix); 13313 pw.print(" "); 13314 pw.print("oom: max="); pw.print(r.maxAdj); 13315 pw.print(" curRaw="); pw.print(r.curRawAdj); 13316 pw.print(" setRaw="); pw.print(r.setRawAdj); 13317 pw.print(" cur="); pw.print(r.curAdj); 13318 pw.print(" set="); pw.println(r.setAdj); 13319 pw.print(prefix); 13320 pw.print(" "); 13321 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13322 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13323 pw.print(" lastPss="); pw.print(r.lastPss); 13324 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13325 pw.print(prefix); 13326 pw.print(" "); 13327 pw.print("cached="); pw.print(r.cached); 13328 pw.print(" empty="); pw.print(r.empty); 13329 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13330 13331 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13332 if (r.lastWakeTime != 0) { 13333 long wtime; 13334 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13335 synchronized (stats) { 13336 wtime = stats.getProcessWakeTime(r.info.uid, 13337 r.pid, curRealtime); 13338 } 13339 long timeUsed = wtime - r.lastWakeTime; 13340 pw.print(prefix); 13341 pw.print(" "); 13342 pw.print("keep awake over "); 13343 TimeUtils.formatDuration(realtimeSince, pw); 13344 pw.print(" used "); 13345 TimeUtils.formatDuration(timeUsed, pw); 13346 pw.print(" ("); 13347 pw.print((timeUsed*100)/realtimeSince); 13348 pw.println("%)"); 13349 } 13350 if (r.lastCpuTime != 0) { 13351 long timeUsed = r.curCpuTime - r.lastCpuTime; 13352 pw.print(prefix); 13353 pw.print(" "); 13354 pw.print("run cpu over "); 13355 TimeUtils.formatDuration(uptimeSince, pw); 13356 pw.print(" used "); 13357 TimeUtils.formatDuration(timeUsed, pw); 13358 pw.print(" ("); 13359 pw.print((timeUsed*100)/uptimeSince); 13360 pw.println("%)"); 13361 } 13362 } 13363 } 13364 } 13365 return true; 13366 } 13367 13368 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13369 ArrayList<ProcessRecord> procs; 13370 synchronized (this) { 13371 if (args != null && args.length > start 13372 && args[start].charAt(0) != '-') { 13373 procs = new ArrayList<ProcessRecord>(); 13374 int pid = -1; 13375 try { 13376 pid = Integer.parseInt(args[start]); 13377 } catch (NumberFormatException e) { 13378 } 13379 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13380 ProcessRecord proc = mLruProcesses.get(i); 13381 if (proc.pid == pid) { 13382 procs.add(proc); 13383 } else if (proc.processName.equals(args[start])) { 13384 procs.add(proc); 13385 } 13386 } 13387 if (procs.size() <= 0) { 13388 return null; 13389 } 13390 } else { 13391 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13392 } 13393 } 13394 return procs; 13395 } 13396 13397 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13398 PrintWriter pw, String[] args) { 13399 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13400 if (procs == null) { 13401 pw.println("No process found for: " + args[0]); 13402 return; 13403 } 13404 13405 long uptime = SystemClock.uptimeMillis(); 13406 long realtime = SystemClock.elapsedRealtime(); 13407 pw.println("Applications Graphics Acceleration Info:"); 13408 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13409 13410 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13411 ProcessRecord r = procs.get(i); 13412 if (r.thread != null) { 13413 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13414 pw.flush(); 13415 try { 13416 TransferPipe tp = new TransferPipe(); 13417 try { 13418 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13419 tp.go(fd); 13420 } finally { 13421 tp.kill(); 13422 } 13423 } catch (IOException e) { 13424 pw.println("Failure while dumping the app: " + r); 13425 pw.flush(); 13426 } catch (RemoteException e) { 13427 pw.println("Got a RemoteException while dumping the app " + r); 13428 pw.flush(); 13429 } 13430 } 13431 } 13432 } 13433 13434 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13435 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13436 if (procs == null) { 13437 pw.println("No process found for: " + args[0]); 13438 return; 13439 } 13440 13441 pw.println("Applications Database Info:"); 13442 13443 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13444 ProcessRecord r = procs.get(i); 13445 if (r.thread != null) { 13446 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13447 pw.flush(); 13448 try { 13449 TransferPipe tp = new TransferPipe(); 13450 try { 13451 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13452 tp.go(fd); 13453 } finally { 13454 tp.kill(); 13455 } 13456 } catch (IOException e) { 13457 pw.println("Failure while dumping the app: " + r); 13458 pw.flush(); 13459 } catch (RemoteException e) { 13460 pw.println("Got a RemoteException while dumping the app " + r); 13461 pw.flush(); 13462 } 13463 } 13464 } 13465 } 13466 13467 final static class MemItem { 13468 final boolean isProc; 13469 final String label; 13470 final String shortLabel; 13471 final long pss; 13472 final int id; 13473 final boolean hasActivities; 13474 ArrayList<MemItem> subitems; 13475 13476 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13477 boolean _hasActivities) { 13478 isProc = true; 13479 label = _label; 13480 shortLabel = _shortLabel; 13481 pss = _pss; 13482 id = _id; 13483 hasActivities = _hasActivities; 13484 } 13485 13486 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13487 isProc = false; 13488 label = _label; 13489 shortLabel = _shortLabel; 13490 pss = _pss; 13491 id = _id; 13492 hasActivities = false; 13493 } 13494 } 13495 13496 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13497 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13498 if (sort && !isCompact) { 13499 Collections.sort(items, new Comparator<MemItem>() { 13500 @Override 13501 public int compare(MemItem lhs, MemItem rhs) { 13502 if (lhs.pss < rhs.pss) { 13503 return 1; 13504 } else if (lhs.pss > rhs.pss) { 13505 return -1; 13506 } 13507 return 0; 13508 } 13509 }); 13510 } 13511 13512 for (int i=0; i<items.size(); i++) { 13513 MemItem mi = items.get(i); 13514 if (!isCompact) { 13515 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13516 } else if (mi.isProc) { 13517 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13518 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13519 pw.println(mi.hasActivities ? ",a" : ",e"); 13520 } else { 13521 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13522 pw.println(mi.pss); 13523 } 13524 if (mi.subitems != null) { 13525 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13526 true, isCompact); 13527 } 13528 } 13529 } 13530 13531 // These are in KB. 13532 static final long[] DUMP_MEM_BUCKETS = new long[] { 13533 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13534 120*1024, 160*1024, 200*1024, 13535 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13536 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13537 }; 13538 13539 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13540 boolean stackLike) { 13541 int start = label.lastIndexOf('.'); 13542 if (start >= 0) start++; 13543 else start = 0; 13544 int end = label.length(); 13545 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13546 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13547 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13548 out.append(bucket); 13549 out.append(stackLike ? "MB." : "MB "); 13550 out.append(label, start, end); 13551 return; 13552 } 13553 } 13554 out.append(memKB/1024); 13555 out.append(stackLike ? "MB." : "MB "); 13556 out.append(label, start, end); 13557 } 13558 13559 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13560 ProcessList.NATIVE_ADJ, 13561 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13562 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13563 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13564 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13565 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13566 }; 13567 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13568 "Native", 13569 "System", "Persistent", "Foreground", 13570 "Visible", "Perceptible", 13571 "Heavy Weight", "Backup", 13572 "A Services", "Home", 13573 "Previous", "B Services", "Cached" 13574 }; 13575 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13576 "native", 13577 "sys", "pers", "fore", 13578 "vis", "percept", 13579 "heavy", "backup", 13580 "servicea", "home", 13581 "prev", "serviceb", "cached" 13582 }; 13583 13584 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13585 long realtime, boolean isCheckinRequest, boolean isCompact) { 13586 if (isCheckinRequest || isCompact) { 13587 // short checkin version 13588 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13589 } else { 13590 pw.println("Applications Memory Usage (kB):"); 13591 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13592 } 13593 } 13594 13595 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13596 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13597 boolean dumpDetails = false; 13598 boolean dumpFullDetails = false; 13599 boolean dumpDalvik = false; 13600 boolean oomOnly = false; 13601 boolean isCompact = false; 13602 boolean localOnly = false; 13603 13604 int opti = 0; 13605 while (opti < args.length) { 13606 String opt = args[opti]; 13607 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13608 break; 13609 } 13610 opti++; 13611 if ("-a".equals(opt)) { 13612 dumpDetails = true; 13613 dumpFullDetails = true; 13614 dumpDalvik = true; 13615 } else if ("-d".equals(opt)) { 13616 dumpDalvik = true; 13617 } else if ("-c".equals(opt)) { 13618 isCompact = true; 13619 } else if ("--oom".equals(opt)) { 13620 oomOnly = true; 13621 } else if ("--local".equals(opt)) { 13622 localOnly = true; 13623 } else if ("-h".equals(opt)) { 13624 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13625 pw.println(" -a: include all available information for each process."); 13626 pw.println(" -d: include dalvik details when dumping process details."); 13627 pw.println(" -c: dump in a compact machine-parseable representation."); 13628 pw.println(" --oom: only show processes organized by oom adj."); 13629 pw.println(" --local: only collect details locally, don't call process."); 13630 pw.println("If [process] is specified it can be the name or "); 13631 pw.println("pid of a specific process to dump."); 13632 return; 13633 } else { 13634 pw.println("Unknown argument: " + opt + "; use -h for help"); 13635 } 13636 } 13637 13638 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13639 long uptime = SystemClock.uptimeMillis(); 13640 long realtime = SystemClock.elapsedRealtime(); 13641 final long[] tmpLong = new long[1]; 13642 13643 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13644 if (procs == null) { 13645 // No Java processes. Maybe they want to print a native process. 13646 if (args != null && args.length > opti 13647 && args[opti].charAt(0) != '-') { 13648 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13649 = new ArrayList<ProcessCpuTracker.Stats>(); 13650 updateCpuStatsNow(); 13651 int findPid = -1; 13652 try { 13653 findPid = Integer.parseInt(args[opti]); 13654 } catch (NumberFormatException e) { 13655 } 13656 synchronized (mProcessCpuThread) { 13657 final int N = mProcessCpuTracker.countStats(); 13658 for (int i=0; i<N; i++) { 13659 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13660 if (st.pid == findPid || (st.baseName != null 13661 && st.baseName.equals(args[opti]))) { 13662 nativeProcs.add(st); 13663 } 13664 } 13665 } 13666 if (nativeProcs.size() > 0) { 13667 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13668 isCompact); 13669 Debug.MemoryInfo mi = null; 13670 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13671 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13672 final int pid = r.pid; 13673 if (!isCheckinRequest && dumpDetails) { 13674 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13675 } 13676 if (mi == null) { 13677 mi = new Debug.MemoryInfo(); 13678 } 13679 if (dumpDetails || (!brief && !oomOnly)) { 13680 Debug.getMemoryInfo(pid, mi); 13681 } else { 13682 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13683 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13684 } 13685 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13686 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13687 if (isCheckinRequest) { 13688 pw.println(); 13689 } 13690 } 13691 return; 13692 } 13693 } 13694 pw.println("No process found for: " + args[opti]); 13695 return; 13696 } 13697 13698 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13699 dumpDetails = true; 13700 } 13701 13702 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13703 13704 String[] innerArgs = new String[args.length-opti]; 13705 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13706 13707 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13708 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13709 long nativePss=0, dalvikPss=0, otherPss=0; 13710 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13711 13712 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13713 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13714 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13715 13716 long totalPss = 0; 13717 long cachedPss = 0; 13718 13719 Debug.MemoryInfo mi = null; 13720 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13721 final ProcessRecord r = procs.get(i); 13722 final IApplicationThread thread; 13723 final int pid; 13724 final int oomAdj; 13725 final boolean hasActivities; 13726 synchronized (this) { 13727 thread = r.thread; 13728 pid = r.pid; 13729 oomAdj = r.getSetAdjWithServices(); 13730 hasActivities = r.activities.size() > 0; 13731 } 13732 if (thread != null) { 13733 if (!isCheckinRequest && dumpDetails) { 13734 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13735 } 13736 if (mi == null) { 13737 mi = new Debug.MemoryInfo(); 13738 } 13739 if (dumpDetails || (!brief && !oomOnly)) { 13740 Debug.getMemoryInfo(pid, mi); 13741 } else { 13742 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13743 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13744 } 13745 if (dumpDetails) { 13746 if (localOnly) { 13747 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13748 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13749 if (isCheckinRequest) { 13750 pw.println(); 13751 } 13752 } else { 13753 try { 13754 pw.flush(); 13755 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13756 dumpDalvik, innerArgs); 13757 } catch (RemoteException e) { 13758 if (!isCheckinRequest) { 13759 pw.println("Got RemoteException!"); 13760 pw.flush(); 13761 } 13762 } 13763 } 13764 } 13765 13766 final long myTotalPss = mi.getTotalPss(); 13767 final long myTotalUss = mi.getTotalUss(); 13768 13769 synchronized (this) { 13770 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13771 // Record this for posterity if the process has been stable. 13772 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13773 } 13774 } 13775 13776 if (!isCheckinRequest && mi != null) { 13777 totalPss += myTotalPss; 13778 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13779 (hasActivities ? " / activities)" : ")"), 13780 r.processName, myTotalPss, pid, hasActivities); 13781 procMems.add(pssItem); 13782 procMemsMap.put(pid, pssItem); 13783 13784 nativePss += mi.nativePss; 13785 dalvikPss += mi.dalvikPss; 13786 otherPss += mi.otherPss; 13787 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13788 long mem = mi.getOtherPss(j); 13789 miscPss[j] += mem; 13790 otherPss -= mem; 13791 } 13792 13793 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13794 cachedPss += myTotalPss; 13795 } 13796 13797 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13798 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13799 || oomIndex == (oomPss.length-1)) { 13800 oomPss[oomIndex] += myTotalPss; 13801 if (oomProcs[oomIndex] == null) { 13802 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13803 } 13804 oomProcs[oomIndex].add(pssItem); 13805 break; 13806 } 13807 } 13808 } 13809 } 13810 } 13811 13812 long nativeProcTotalPss = 0; 13813 13814 if (!isCheckinRequest && procs.size() > 1) { 13815 // If we are showing aggregations, also look for native processes to 13816 // include so that our aggregations are more accurate. 13817 updateCpuStatsNow(); 13818 synchronized (mProcessCpuThread) { 13819 final int N = mProcessCpuTracker.countStats(); 13820 for (int i=0; i<N; i++) { 13821 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13822 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13823 if (mi == null) { 13824 mi = new Debug.MemoryInfo(); 13825 } 13826 if (!brief && !oomOnly) { 13827 Debug.getMemoryInfo(st.pid, mi); 13828 } else { 13829 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13830 mi.nativePrivateDirty = (int)tmpLong[0]; 13831 } 13832 13833 final long myTotalPss = mi.getTotalPss(); 13834 totalPss += myTotalPss; 13835 nativeProcTotalPss += myTotalPss; 13836 13837 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13838 st.name, myTotalPss, st.pid, false); 13839 procMems.add(pssItem); 13840 13841 nativePss += mi.nativePss; 13842 dalvikPss += mi.dalvikPss; 13843 otherPss += mi.otherPss; 13844 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13845 long mem = mi.getOtherPss(j); 13846 miscPss[j] += mem; 13847 otherPss -= mem; 13848 } 13849 oomPss[0] += myTotalPss; 13850 if (oomProcs[0] == null) { 13851 oomProcs[0] = new ArrayList<MemItem>(); 13852 } 13853 oomProcs[0].add(pssItem); 13854 } 13855 } 13856 } 13857 13858 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13859 13860 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13861 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13862 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13863 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13864 String label = Debug.MemoryInfo.getOtherLabel(j); 13865 catMems.add(new MemItem(label, label, miscPss[j], j)); 13866 } 13867 13868 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13869 for (int j=0; j<oomPss.length; j++) { 13870 if (oomPss[j] != 0) { 13871 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13872 : DUMP_MEM_OOM_LABEL[j]; 13873 MemItem item = new MemItem(label, label, oomPss[j], 13874 DUMP_MEM_OOM_ADJ[j]); 13875 item.subitems = oomProcs[j]; 13876 oomMems.add(item); 13877 } 13878 } 13879 13880 if (!brief && !oomOnly && !isCompact) { 13881 pw.println(); 13882 pw.println("Total PSS by process:"); 13883 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13884 pw.println(); 13885 } 13886 if (!isCompact) { 13887 pw.println("Total PSS by OOM adjustment:"); 13888 } 13889 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13890 if (!brief && !oomOnly) { 13891 PrintWriter out = categoryPw != null ? categoryPw : pw; 13892 if (!isCompact) { 13893 out.println(); 13894 out.println("Total PSS by category:"); 13895 } 13896 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13897 } 13898 if (!isCompact) { 13899 pw.println(); 13900 } 13901 MemInfoReader memInfo = new MemInfoReader(); 13902 memInfo.readMemInfo(); 13903 if (nativeProcTotalPss > 0) { 13904 synchronized (this) { 13905 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13906 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13907 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13908 nativeProcTotalPss); 13909 } 13910 } 13911 if (!brief) { 13912 if (!isCompact) { 13913 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13914 pw.print(" kB (status "); 13915 switch (mLastMemoryLevel) { 13916 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13917 pw.println("normal)"); 13918 break; 13919 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13920 pw.println("moderate)"); 13921 break; 13922 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13923 pw.println("low)"); 13924 break; 13925 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13926 pw.println("critical)"); 13927 break; 13928 default: 13929 pw.print(mLastMemoryLevel); 13930 pw.println(")"); 13931 break; 13932 } 13933 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13934 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13935 pw.print(cachedPss); pw.print(" cached pss + "); 13936 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13937 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13938 } else { 13939 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13940 pw.print(cachedPss + memInfo.getCachedSizeKb() 13941 + memInfo.getFreeSizeKb()); pw.print(","); 13942 pw.println(totalPss - cachedPss); 13943 } 13944 } 13945 if (!isCompact) { 13946 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13947 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13948 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13949 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13950 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13951 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13952 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13953 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13954 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13955 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13956 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13957 } 13958 if (!brief) { 13959 if (memInfo.getZramTotalSizeKb() != 0) { 13960 if (!isCompact) { 13961 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13962 pw.print(" kB physical used for "); 13963 pw.print(memInfo.getSwapTotalSizeKb() 13964 - memInfo.getSwapFreeSizeKb()); 13965 pw.print(" kB in swap ("); 13966 pw.print(memInfo.getSwapTotalSizeKb()); 13967 pw.println(" kB total swap)"); 13968 } else { 13969 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13970 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13971 pw.println(memInfo.getSwapFreeSizeKb()); 13972 } 13973 } 13974 final int[] SINGLE_LONG_FORMAT = new int[] { 13975 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13976 }; 13977 long[] longOut = new long[1]; 13978 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13979 SINGLE_LONG_FORMAT, null, longOut, null); 13980 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13981 longOut[0] = 0; 13982 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13983 SINGLE_LONG_FORMAT, null, longOut, null); 13984 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13985 longOut[0] = 0; 13986 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13987 SINGLE_LONG_FORMAT, null, longOut, null); 13988 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13989 longOut[0] = 0; 13990 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13991 SINGLE_LONG_FORMAT, null, longOut, null); 13992 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13993 if (!isCompact) { 13994 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13995 pw.print(" KSM: "); pw.print(sharing); 13996 pw.print(" kB saved from shared "); 13997 pw.print(shared); pw.println(" kB"); 13998 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13999 pw.print(voltile); pw.println(" kB volatile"); 14000 } 14001 pw.print(" Tuning: "); 14002 pw.print(ActivityManager.staticGetMemoryClass()); 14003 pw.print(" (large "); 14004 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14005 pw.print("), oom "); 14006 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14007 pw.print(" kB"); 14008 pw.print(", restore limit "); 14009 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14010 pw.print(" kB"); 14011 if (ActivityManager.isLowRamDeviceStatic()) { 14012 pw.print(" (low-ram)"); 14013 } 14014 if (ActivityManager.isHighEndGfx()) { 14015 pw.print(" (high-end-gfx)"); 14016 } 14017 pw.println(); 14018 } else { 14019 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14020 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14021 pw.println(voltile); 14022 pw.print("tuning,"); 14023 pw.print(ActivityManager.staticGetMemoryClass()); 14024 pw.print(','); 14025 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14026 pw.print(','); 14027 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14028 if (ActivityManager.isLowRamDeviceStatic()) { 14029 pw.print(",low-ram"); 14030 } 14031 if (ActivityManager.isHighEndGfx()) { 14032 pw.print(",high-end-gfx"); 14033 } 14034 pw.println(); 14035 } 14036 } 14037 } 14038 } 14039 14040 /** 14041 * Searches array of arguments for the specified string 14042 * @param args array of argument strings 14043 * @param value value to search for 14044 * @return true if the value is contained in the array 14045 */ 14046 private static boolean scanArgs(String[] args, String value) { 14047 if (args != null) { 14048 for (String arg : args) { 14049 if (value.equals(arg)) { 14050 return true; 14051 } 14052 } 14053 } 14054 return false; 14055 } 14056 14057 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14058 ContentProviderRecord cpr, boolean always) { 14059 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14060 14061 if (!inLaunching || always) { 14062 synchronized (cpr) { 14063 cpr.launchingApp = null; 14064 cpr.notifyAll(); 14065 } 14066 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14067 String names[] = cpr.info.authority.split(";"); 14068 for (int j = 0; j < names.length; j++) { 14069 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14070 } 14071 } 14072 14073 for (int i=0; i<cpr.connections.size(); i++) { 14074 ContentProviderConnection conn = cpr.connections.get(i); 14075 if (conn.waiting) { 14076 // If this connection is waiting for the provider, then we don't 14077 // need to mess with its process unless we are always removing 14078 // or for some reason the provider is not currently launching. 14079 if (inLaunching && !always) { 14080 continue; 14081 } 14082 } 14083 ProcessRecord capp = conn.client; 14084 conn.dead = true; 14085 if (conn.stableCount > 0) { 14086 if (!capp.persistent && capp.thread != null 14087 && capp.pid != 0 14088 && capp.pid != MY_PID) { 14089 capp.kill("depends on provider " 14090 + cpr.name.flattenToShortString() 14091 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14092 } 14093 } else if (capp.thread != null && conn.provider.provider != null) { 14094 try { 14095 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14096 } catch (RemoteException e) { 14097 } 14098 // In the protocol here, we don't expect the client to correctly 14099 // clean up this connection, we'll just remove it. 14100 cpr.connections.remove(i); 14101 conn.client.conProviders.remove(conn); 14102 } 14103 } 14104 14105 if (inLaunching && always) { 14106 mLaunchingProviders.remove(cpr); 14107 } 14108 return inLaunching; 14109 } 14110 14111 /** 14112 * Main code for cleaning up a process when it has gone away. This is 14113 * called both as a result of the process dying, or directly when stopping 14114 * a process when running in single process mode. 14115 */ 14116 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14117 boolean restarting, boolean allowRestart, int index) { 14118 if (index >= 0) { 14119 removeLruProcessLocked(app); 14120 ProcessList.remove(app.pid); 14121 } 14122 14123 mProcessesToGc.remove(app); 14124 mPendingPssProcesses.remove(app); 14125 14126 // Dismiss any open dialogs. 14127 if (app.crashDialog != null && !app.forceCrashReport) { 14128 app.crashDialog.dismiss(); 14129 app.crashDialog = null; 14130 } 14131 if (app.anrDialog != null) { 14132 app.anrDialog.dismiss(); 14133 app.anrDialog = null; 14134 } 14135 if (app.waitDialog != null) { 14136 app.waitDialog.dismiss(); 14137 app.waitDialog = null; 14138 } 14139 14140 app.crashing = false; 14141 app.notResponding = false; 14142 14143 app.resetPackageList(mProcessStats); 14144 app.unlinkDeathRecipient(); 14145 app.makeInactive(mProcessStats); 14146 app.waitingToKill = null; 14147 app.forcingToForeground = null; 14148 updateProcessForegroundLocked(app, false, false); 14149 app.foregroundActivities = false; 14150 app.hasShownUi = false; 14151 app.treatLikeActivity = false; 14152 app.hasAboveClient = false; 14153 app.hasClientActivities = false; 14154 14155 mServices.killServicesLocked(app, allowRestart); 14156 14157 boolean restart = false; 14158 14159 // Remove published content providers. 14160 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14161 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14162 final boolean always = app.bad || !allowRestart; 14163 if (removeDyingProviderLocked(app, cpr, always) || always) { 14164 // We left the provider in the launching list, need to 14165 // restart it. 14166 restart = true; 14167 } 14168 14169 cpr.provider = null; 14170 cpr.proc = null; 14171 } 14172 app.pubProviders.clear(); 14173 14174 // Take care of any launching providers waiting for this process. 14175 if (checkAppInLaunchingProvidersLocked(app, false)) { 14176 restart = true; 14177 } 14178 14179 // Unregister from connected content providers. 14180 if (!app.conProviders.isEmpty()) { 14181 for (int i=0; i<app.conProviders.size(); i++) { 14182 ContentProviderConnection conn = app.conProviders.get(i); 14183 conn.provider.connections.remove(conn); 14184 } 14185 app.conProviders.clear(); 14186 } 14187 14188 // At this point there may be remaining entries in mLaunchingProviders 14189 // where we were the only one waiting, so they are no longer of use. 14190 // Look for these and clean up if found. 14191 // XXX Commented out for now. Trying to figure out a way to reproduce 14192 // the actual situation to identify what is actually going on. 14193 if (false) { 14194 for (int i=0; i<mLaunchingProviders.size(); i++) { 14195 ContentProviderRecord cpr = (ContentProviderRecord) 14196 mLaunchingProviders.get(i); 14197 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14198 synchronized (cpr) { 14199 cpr.launchingApp = null; 14200 cpr.notifyAll(); 14201 } 14202 } 14203 } 14204 } 14205 14206 skipCurrentReceiverLocked(app); 14207 14208 // Unregister any receivers. 14209 for (int i=app.receivers.size()-1; i>=0; i--) { 14210 removeReceiverLocked(app.receivers.valueAt(i)); 14211 } 14212 app.receivers.clear(); 14213 14214 // If the app is undergoing backup, tell the backup manager about it 14215 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14216 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14217 + mBackupTarget.appInfo + " died during backup"); 14218 try { 14219 IBackupManager bm = IBackupManager.Stub.asInterface( 14220 ServiceManager.getService(Context.BACKUP_SERVICE)); 14221 bm.agentDisconnected(app.info.packageName); 14222 } catch (RemoteException e) { 14223 // can't happen; backup manager is local 14224 } 14225 } 14226 14227 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14228 ProcessChangeItem item = mPendingProcessChanges.get(i); 14229 if (item.pid == app.pid) { 14230 mPendingProcessChanges.remove(i); 14231 mAvailProcessChanges.add(item); 14232 } 14233 } 14234 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14235 14236 // If the caller is restarting this app, then leave it in its 14237 // current lists and let the caller take care of it. 14238 if (restarting) { 14239 return; 14240 } 14241 14242 if (!app.persistent || app.isolated) { 14243 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14244 "Removing non-persistent process during cleanup: " + app); 14245 mProcessNames.remove(app.processName, app.uid); 14246 mIsolatedProcesses.remove(app.uid); 14247 if (mHeavyWeightProcess == app) { 14248 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14249 mHeavyWeightProcess.userId, 0)); 14250 mHeavyWeightProcess = null; 14251 } 14252 } else if (!app.removed) { 14253 // This app is persistent, so we need to keep its record around. 14254 // If it is not already on the pending app list, add it there 14255 // and start a new process for it. 14256 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14257 mPersistentStartingProcesses.add(app); 14258 restart = true; 14259 } 14260 } 14261 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14262 "Clean-up removing on hold: " + app); 14263 mProcessesOnHold.remove(app); 14264 14265 if (app == mHomeProcess) { 14266 mHomeProcess = null; 14267 } 14268 if (app == mPreviousProcess) { 14269 mPreviousProcess = null; 14270 } 14271 14272 if (restart && !app.isolated) { 14273 // We have components that still need to be running in the 14274 // process, so re-launch it. 14275 mProcessNames.put(app.processName, app.uid, app); 14276 startProcessLocked(app, "restart", app.processName); 14277 } else if (app.pid > 0 && app.pid != MY_PID) { 14278 // Goodbye! 14279 boolean removed; 14280 synchronized (mPidsSelfLocked) { 14281 mPidsSelfLocked.remove(app.pid); 14282 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14283 } 14284 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14285 if (app.isolated) { 14286 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14287 } 14288 app.setPid(0); 14289 } 14290 } 14291 14292 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14293 // Look through the content providers we are waiting to have launched, 14294 // and if any run in this process then either schedule a restart of 14295 // the process or kill the client waiting for it if this process has 14296 // gone bad. 14297 int NL = mLaunchingProviders.size(); 14298 boolean restart = false; 14299 for (int i=0; i<NL; i++) { 14300 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14301 if (cpr.launchingApp == app) { 14302 if (!alwaysBad && !app.bad) { 14303 restart = true; 14304 } else { 14305 removeDyingProviderLocked(app, cpr, true); 14306 // cpr should have been removed from mLaunchingProviders 14307 NL = mLaunchingProviders.size(); 14308 i--; 14309 } 14310 } 14311 } 14312 return restart; 14313 } 14314 14315 // ========================================================= 14316 // SERVICES 14317 // ========================================================= 14318 14319 @Override 14320 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14321 int flags) { 14322 enforceNotIsolatedCaller("getServices"); 14323 synchronized (this) { 14324 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14325 } 14326 } 14327 14328 @Override 14329 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14330 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14331 synchronized (this) { 14332 return mServices.getRunningServiceControlPanelLocked(name); 14333 } 14334 } 14335 14336 @Override 14337 public ComponentName startService(IApplicationThread caller, Intent service, 14338 String resolvedType, int userId) { 14339 enforceNotIsolatedCaller("startService"); 14340 // Refuse possible leaked file descriptors 14341 if (service != null && service.hasFileDescriptors() == true) { 14342 throw new IllegalArgumentException("File descriptors passed in Intent"); 14343 } 14344 14345 if (DEBUG_SERVICE) 14346 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14347 synchronized(this) { 14348 final int callingPid = Binder.getCallingPid(); 14349 final int callingUid = Binder.getCallingUid(); 14350 final long origId = Binder.clearCallingIdentity(); 14351 ComponentName res = mServices.startServiceLocked(caller, service, 14352 resolvedType, callingPid, callingUid, userId); 14353 Binder.restoreCallingIdentity(origId); 14354 return res; 14355 } 14356 } 14357 14358 ComponentName startServiceInPackage(int uid, 14359 Intent service, String resolvedType, int userId) { 14360 synchronized(this) { 14361 if (DEBUG_SERVICE) 14362 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14363 final long origId = Binder.clearCallingIdentity(); 14364 ComponentName res = mServices.startServiceLocked(null, service, 14365 resolvedType, -1, uid, userId); 14366 Binder.restoreCallingIdentity(origId); 14367 return res; 14368 } 14369 } 14370 14371 @Override 14372 public int stopService(IApplicationThread caller, Intent service, 14373 String resolvedType, int userId) { 14374 enforceNotIsolatedCaller("stopService"); 14375 // Refuse possible leaked file descriptors 14376 if (service != null && service.hasFileDescriptors() == true) { 14377 throw new IllegalArgumentException("File descriptors passed in Intent"); 14378 } 14379 14380 synchronized(this) { 14381 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14382 } 14383 } 14384 14385 @Override 14386 public IBinder peekService(Intent service, String resolvedType) { 14387 enforceNotIsolatedCaller("peekService"); 14388 // Refuse possible leaked file descriptors 14389 if (service != null && service.hasFileDescriptors() == true) { 14390 throw new IllegalArgumentException("File descriptors passed in Intent"); 14391 } 14392 synchronized(this) { 14393 return mServices.peekServiceLocked(service, resolvedType); 14394 } 14395 } 14396 14397 @Override 14398 public boolean stopServiceToken(ComponentName className, IBinder token, 14399 int startId) { 14400 synchronized(this) { 14401 return mServices.stopServiceTokenLocked(className, token, startId); 14402 } 14403 } 14404 14405 @Override 14406 public void setServiceForeground(ComponentName className, IBinder token, 14407 int id, Notification notification, boolean removeNotification) { 14408 synchronized(this) { 14409 mServices.setServiceForegroundLocked(className, token, id, notification, 14410 removeNotification); 14411 } 14412 } 14413 14414 @Override 14415 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14416 boolean requireFull, String name, String callerPackage) { 14417 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14418 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14419 } 14420 14421 int unsafeConvertIncomingUser(int userId) { 14422 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14423 ? mCurrentUserId : userId; 14424 } 14425 14426 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14427 int allowMode, String name, String callerPackage) { 14428 final int callingUserId = UserHandle.getUserId(callingUid); 14429 if (callingUserId == userId) { 14430 return userId; 14431 } 14432 14433 // Note that we may be accessing mCurrentUserId outside of a lock... 14434 // shouldn't be a big deal, if this is being called outside 14435 // of a locked context there is intrinsically a race with 14436 // the value the caller will receive and someone else changing it. 14437 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14438 // we will switch to the calling user if access to the current user fails. 14439 int targetUserId = unsafeConvertIncomingUser(userId); 14440 14441 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14442 final boolean allow; 14443 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14444 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14445 // If the caller has this permission, they always pass go. And collect $200. 14446 allow = true; 14447 } else if (allowMode == ALLOW_FULL_ONLY) { 14448 // We require full access, sucks to be you. 14449 allow = false; 14450 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14451 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14452 // If the caller does not have either permission, they are always doomed. 14453 allow = false; 14454 } else if (allowMode == ALLOW_NON_FULL) { 14455 // We are blanket allowing non-full access, you lucky caller! 14456 allow = true; 14457 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14458 // We may or may not allow this depending on whether the two users are 14459 // in the same profile. 14460 synchronized (mUserProfileGroupIdsSelfLocked) { 14461 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14462 UserInfo.NO_PROFILE_GROUP_ID); 14463 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14464 UserInfo.NO_PROFILE_GROUP_ID); 14465 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14466 && callingProfile == targetProfile; 14467 } 14468 } else { 14469 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14470 } 14471 if (!allow) { 14472 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14473 // In this case, they would like to just execute as their 14474 // owner user instead of failing. 14475 targetUserId = callingUserId; 14476 } else { 14477 StringBuilder builder = new StringBuilder(128); 14478 builder.append("Permission Denial: "); 14479 builder.append(name); 14480 if (callerPackage != null) { 14481 builder.append(" from "); 14482 builder.append(callerPackage); 14483 } 14484 builder.append(" asks to run as user "); 14485 builder.append(userId); 14486 builder.append(" but is calling from user "); 14487 builder.append(UserHandle.getUserId(callingUid)); 14488 builder.append("; this requires "); 14489 builder.append(INTERACT_ACROSS_USERS_FULL); 14490 if (allowMode != ALLOW_FULL_ONLY) { 14491 builder.append(" or "); 14492 builder.append(INTERACT_ACROSS_USERS); 14493 } 14494 String msg = builder.toString(); 14495 Slog.w(TAG, msg); 14496 throw new SecurityException(msg); 14497 } 14498 } 14499 } 14500 if (!allowAll && targetUserId < 0) { 14501 throw new IllegalArgumentException( 14502 "Call does not support special user #" + targetUserId); 14503 } 14504 return targetUserId; 14505 } 14506 14507 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14508 String className, int flags) { 14509 boolean result = false; 14510 // For apps that don't have pre-defined UIDs, check for permission 14511 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14512 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14513 if (ActivityManager.checkUidPermission( 14514 INTERACT_ACROSS_USERS, 14515 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14516 ComponentName comp = new ComponentName(aInfo.packageName, className); 14517 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14518 + " requests FLAG_SINGLE_USER, but app does not hold " 14519 + INTERACT_ACROSS_USERS; 14520 Slog.w(TAG, msg); 14521 throw new SecurityException(msg); 14522 } 14523 // Permission passed 14524 result = true; 14525 } 14526 } else if ("system".equals(componentProcessName)) { 14527 result = true; 14528 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14529 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14530 // Phone app is allowed to export singleuser providers. 14531 result = true; 14532 } else { 14533 // App with pre-defined UID, check if it's a persistent app 14534 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14535 } 14536 if (DEBUG_MU) { 14537 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14538 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14539 } 14540 return result; 14541 } 14542 14543 /** 14544 * Checks to see if the caller is in the same app as the singleton 14545 * component, or the component is in a special app. It allows special apps 14546 * to export singleton components but prevents exporting singleton 14547 * components for regular apps. 14548 */ 14549 boolean isValidSingletonCall(int callingUid, int componentUid) { 14550 int componentAppId = UserHandle.getAppId(componentUid); 14551 return UserHandle.isSameApp(callingUid, componentUid) 14552 || componentAppId == Process.SYSTEM_UID 14553 || componentAppId == Process.PHONE_UID 14554 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14555 == PackageManager.PERMISSION_GRANTED; 14556 } 14557 14558 public int bindService(IApplicationThread caller, IBinder token, 14559 Intent service, String resolvedType, 14560 IServiceConnection connection, int flags, int userId) { 14561 enforceNotIsolatedCaller("bindService"); 14562 // Refuse possible leaked file descriptors 14563 if (service != null && service.hasFileDescriptors() == true) { 14564 throw new IllegalArgumentException("File descriptors passed in Intent"); 14565 } 14566 14567 synchronized(this) { 14568 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14569 connection, flags, userId); 14570 } 14571 } 14572 14573 public boolean unbindService(IServiceConnection connection) { 14574 synchronized (this) { 14575 return mServices.unbindServiceLocked(connection); 14576 } 14577 } 14578 14579 public void publishService(IBinder token, Intent intent, IBinder service) { 14580 // Refuse possible leaked file descriptors 14581 if (intent != null && intent.hasFileDescriptors() == true) { 14582 throw new IllegalArgumentException("File descriptors passed in Intent"); 14583 } 14584 14585 synchronized(this) { 14586 if (!(token instanceof ServiceRecord)) { 14587 throw new IllegalArgumentException("Invalid service token"); 14588 } 14589 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14590 } 14591 } 14592 14593 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14594 // Refuse possible leaked file descriptors 14595 if (intent != null && intent.hasFileDescriptors() == true) { 14596 throw new IllegalArgumentException("File descriptors passed in Intent"); 14597 } 14598 14599 synchronized(this) { 14600 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14601 } 14602 } 14603 14604 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14605 synchronized(this) { 14606 if (!(token instanceof ServiceRecord)) { 14607 throw new IllegalArgumentException("Invalid service token"); 14608 } 14609 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14610 } 14611 } 14612 14613 // ========================================================= 14614 // BACKUP AND RESTORE 14615 // ========================================================= 14616 14617 // Cause the target app to be launched if necessary and its backup agent 14618 // instantiated. The backup agent will invoke backupAgentCreated() on the 14619 // activity manager to announce its creation. 14620 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14621 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14622 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14623 14624 synchronized(this) { 14625 // !!! TODO: currently no check here that we're already bound 14626 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14627 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14628 synchronized (stats) { 14629 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14630 } 14631 14632 // Backup agent is now in use, its package can't be stopped. 14633 try { 14634 AppGlobals.getPackageManager().setPackageStoppedState( 14635 app.packageName, false, UserHandle.getUserId(app.uid)); 14636 } catch (RemoteException e) { 14637 } catch (IllegalArgumentException e) { 14638 Slog.w(TAG, "Failed trying to unstop package " 14639 + app.packageName + ": " + e); 14640 } 14641 14642 BackupRecord r = new BackupRecord(ss, app, backupMode); 14643 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14644 ? new ComponentName(app.packageName, app.backupAgentName) 14645 : new ComponentName("android", "FullBackupAgent"); 14646 // startProcessLocked() returns existing proc's record if it's already running 14647 ProcessRecord proc = startProcessLocked(app.processName, app, 14648 false, 0, "backup", hostingName, false, false, false); 14649 if (proc == null) { 14650 Slog.e(TAG, "Unable to start backup agent process " + r); 14651 return false; 14652 } 14653 14654 r.app = proc; 14655 mBackupTarget = r; 14656 mBackupAppName = app.packageName; 14657 14658 // Try not to kill the process during backup 14659 updateOomAdjLocked(proc); 14660 14661 // If the process is already attached, schedule the creation of the backup agent now. 14662 // If it is not yet live, this will be done when it attaches to the framework. 14663 if (proc.thread != null) { 14664 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14665 try { 14666 proc.thread.scheduleCreateBackupAgent(app, 14667 compatibilityInfoForPackageLocked(app), backupMode); 14668 } catch (RemoteException e) { 14669 // Will time out on the backup manager side 14670 } 14671 } else { 14672 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14673 } 14674 // Invariants: at this point, the target app process exists and the application 14675 // is either already running or in the process of coming up. mBackupTarget and 14676 // mBackupAppName describe the app, so that when it binds back to the AM we 14677 // know that it's scheduled for a backup-agent operation. 14678 } 14679 14680 return true; 14681 } 14682 14683 @Override 14684 public void clearPendingBackup() { 14685 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14686 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14687 14688 synchronized (this) { 14689 mBackupTarget = null; 14690 mBackupAppName = null; 14691 } 14692 } 14693 14694 // A backup agent has just come up 14695 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14696 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14697 + " = " + agent); 14698 14699 synchronized(this) { 14700 if (!agentPackageName.equals(mBackupAppName)) { 14701 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14702 return; 14703 } 14704 } 14705 14706 long oldIdent = Binder.clearCallingIdentity(); 14707 try { 14708 IBackupManager bm = IBackupManager.Stub.asInterface( 14709 ServiceManager.getService(Context.BACKUP_SERVICE)); 14710 bm.agentConnected(agentPackageName, agent); 14711 } catch (RemoteException e) { 14712 // can't happen; the backup manager service is local 14713 } catch (Exception e) { 14714 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14715 e.printStackTrace(); 14716 } finally { 14717 Binder.restoreCallingIdentity(oldIdent); 14718 } 14719 } 14720 14721 // done with this agent 14722 public void unbindBackupAgent(ApplicationInfo appInfo) { 14723 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14724 if (appInfo == null) { 14725 Slog.w(TAG, "unbind backup agent for null app"); 14726 return; 14727 } 14728 14729 synchronized(this) { 14730 try { 14731 if (mBackupAppName == null) { 14732 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14733 return; 14734 } 14735 14736 if (!mBackupAppName.equals(appInfo.packageName)) { 14737 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14738 return; 14739 } 14740 14741 // Not backing this app up any more; reset its OOM adjustment 14742 final ProcessRecord proc = mBackupTarget.app; 14743 updateOomAdjLocked(proc); 14744 14745 // If the app crashed during backup, 'thread' will be null here 14746 if (proc.thread != null) { 14747 try { 14748 proc.thread.scheduleDestroyBackupAgent(appInfo, 14749 compatibilityInfoForPackageLocked(appInfo)); 14750 } catch (Exception e) { 14751 Slog.e(TAG, "Exception when unbinding backup agent:"); 14752 e.printStackTrace(); 14753 } 14754 } 14755 } finally { 14756 mBackupTarget = null; 14757 mBackupAppName = null; 14758 } 14759 } 14760 } 14761 // ========================================================= 14762 // BROADCASTS 14763 // ========================================================= 14764 14765 private final List getStickiesLocked(String action, IntentFilter filter, 14766 List cur, int userId) { 14767 final ContentResolver resolver = mContext.getContentResolver(); 14768 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14769 if (stickies == null) { 14770 return cur; 14771 } 14772 final ArrayList<Intent> list = stickies.get(action); 14773 if (list == null) { 14774 return cur; 14775 } 14776 int N = list.size(); 14777 for (int i=0; i<N; i++) { 14778 Intent intent = list.get(i); 14779 if (filter.match(resolver, intent, true, TAG) >= 0) { 14780 if (cur == null) { 14781 cur = new ArrayList<Intent>(); 14782 } 14783 cur.add(intent); 14784 } 14785 } 14786 return cur; 14787 } 14788 14789 boolean isPendingBroadcastProcessLocked(int pid) { 14790 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14791 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14792 } 14793 14794 void skipPendingBroadcastLocked(int pid) { 14795 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14796 for (BroadcastQueue queue : mBroadcastQueues) { 14797 queue.skipPendingBroadcastLocked(pid); 14798 } 14799 } 14800 14801 // The app just attached; send any pending broadcasts that it should receive 14802 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14803 boolean didSomething = false; 14804 for (BroadcastQueue queue : mBroadcastQueues) { 14805 didSomething |= queue.sendPendingBroadcastsLocked(app); 14806 } 14807 return didSomething; 14808 } 14809 14810 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14811 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14812 enforceNotIsolatedCaller("registerReceiver"); 14813 int callingUid; 14814 int callingPid; 14815 synchronized(this) { 14816 ProcessRecord callerApp = null; 14817 if (caller != null) { 14818 callerApp = getRecordForAppLocked(caller); 14819 if (callerApp == null) { 14820 throw new SecurityException( 14821 "Unable to find app for caller " + caller 14822 + " (pid=" + Binder.getCallingPid() 14823 + ") when registering receiver " + receiver); 14824 } 14825 if (callerApp.info.uid != Process.SYSTEM_UID && 14826 !callerApp.pkgList.containsKey(callerPackage) && 14827 !"android".equals(callerPackage)) { 14828 throw new SecurityException("Given caller package " + callerPackage 14829 + " is not running in process " + callerApp); 14830 } 14831 callingUid = callerApp.info.uid; 14832 callingPid = callerApp.pid; 14833 } else { 14834 callerPackage = null; 14835 callingUid = Binder.getCallingUid(); 14836 callingPid = Binder.getCallingPid(); 14837 } 14838 14839 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14840 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14841 14842 List allSticky = null; 14843 14844 // Look for any matching sticky broadcasts... 14845 Iterator actions = filter.actionsIterator(); 14846 if (actions != null) { 14847 while (actions.hasNext()) { 14848 String action = (String)actions.next(); 14849 allSticky = getStickiesLocked(action, filter, allSticky, 14850 UserHandle.USER_ALL); 14851 allSticky = getStickiesLocked(action, filter, allSticky, 14852 UserHandle.getUserId(callingUid)); 14853 } 14854 } else { 14855 allSticky = getStickiesLocked(null, filter, allSticky, 14856 UserHandle.USER_ALL); 14857 allSticky = getStickiesLocked(null, filter, allSticky, 14858 UserHandle.getUserId(callingUid)); 14859 } 14860 14861 // The first sticky in the list is returned directly back to 14862 // the client. 14863 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14864 14865 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14866 + ": " + sticky); 14867 14868 if (receiver == null) { 14869 return sticky; 14870 } 14871 14872 ReceiverList rl 14873 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14874 if (rl == null) { 14875 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14876 userId, receiver); 14877 if (rl.app != null) { 14878 rl.app.receivers.add(rl); 14879 } else { 14880 try { 14881 receiver.asBinder().linkToDeath(rl, 0); 14882 } catch (RemoteException e) { 14883 return sticky; 14884 } 14885 rl.linkedToDeath = true; 14886 } 14887 mRegisteredReceivers.put(receiver.asBinder(), rl); 14888 } else if (rl.uid != callingUid) { 14889 throw new IllegalArgumentException( 14890 "Receiver requested to register for uid " + callingUid 14891 + " was previously registered for uid " + rl.uid); 14892 } else if (rl.pid != callingPid) { 14893 throw new IllegalArgumentException( 14894 "Receiver requested to register for pid " + callingPid 14895 + " was previously registered for pid " + rl.pid); 14896 } else if (rl.userId != userId) { 14897 throw new IllegalArgumentException( 14898 "Receiver requested to register for user " + userId 14899 + " was previously registered for user " + rl.userId); 14900 } 14901 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14902 permission, callingUid, userId); 14903 rl.add(bf); 14904 if (!bf.debugCheck()) { 14905 Slog.w(TAG, "==> For Dynamic broadast"); 14906 } 14907 mReceiverResolver.addFilter(bf); 14908 14909 // Enqueue broadcasts for all existing stickies that match 14910 // this filter. 14911 if (allSticky != null) { 14912 ArrayList receivers = new ArrayList(); 14913 receivers.add(bf); 14914 14915 int N = allSticky.size(); 14916 for (int i=0; i<N; i++) { 14917 Intent intent = (Intent)allSticky.get(i); 14918 BroadcastQueue queue = broadcastQueueForIntent(intent); 14919 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14920 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14921 null, null, false, true, true, -1); 14922 queue.enqueueParallelBroadcastLocked(r); 14923 queue.scheduleBroadcastsLocked(); 14924 } 14925 } 14926 14927 return sticky; 14928 } 14929 } 14930 14931 public void unregisterReceiver(IIntentReceiver receiver) { 14932 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14933 14934 final long origId = Binder.clearCallingIdentity(); 14935 try { 14936 boolean doTrim = false; 14937 14938 synchronized(this) { 14939 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14940 if (rl != null) { 14941 if (rl.curBroadcast != null) { 14942 BroadcastRecord r = rl.curBroadcast; 14943 final boolean doNext = finishReceiverLocked( 14944 receiver.asBinder(), r.resultCode, r.resultData, 14945 r.resultExtras, r.resultAbort); 14946 if (doNext) { 14947 doTrim = true; 14948 r.queue.processNextBroadcast(false); 14949 } 14950 } 14951 14952 if (rl.app != null) { 14953 rl.app.receivers.remove(rl); 14954 } 14955 removeReceiverLocked(rl); 14956 if (rl.linkedToDeath) { 14957 rl.linkedToDeath = false; 14958 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14959 } 14960 } 14961 } 14962 14963 // If we actually concluded any broadcasts, we might now be able 14964 // to trim the recipients' apps from our working set 14965 if (doTrim) { 14966 trimApplications(); 14967 return; 14968 } 14969 14970 } finally { 14971 Binder.restoreCallingIdentity(origId); 14972 } 14973 } 14974 14975 void removeReceiverLocked(ReceiverList rl) { 14976 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14977 int N = rl.size(); 14978 for (int i=0; i<N; i++) { 14979 mReceiverResolver.removeFilter(rl.get(i)); 14980 } 14981 } 14982 14983 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14984 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14985 ProcessRecord r = mLruProcesses.get(i); 14986 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14987 try { 14988 r.thread.dispatchPackageBroadcast(cmd, packages); 14989 } catch (RemoteException ex) { 14990 } 14991 } 14992 } 14993 } 14994 14995 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14996 int[] users) { 14997 List<ResolveInfo> receivers = null; 14998 try { 14999 HashSet<ComponentName> singleUserReceivers = null; 15000 boolean scannedFirstReceivers = false; 15001 for (int user : users) { 15002 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15003 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15004 if (user != 0 && newReceivers != null) { 15005 // If this is not the primary user, we need to check for 15006 // any receivers that should be filtered out. 15007 for (int i=0; i<newReceivers.size(); i++) { 15008 ResolveInfo ri = newReceivers.get(i); 15009 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15010 newReceivers.remove(i); 15011 i--; 15012 } 15013 } 15014 } 15015 if (newReceivers != null && newReceivers.size() == 0) { 15016 newReceivers = null; 15017 } 15018 if (receivers == null) { 15019 receivers = newReceivers; 15020 } else if (newReceivers != null) { 15021 // We need to concatenate the additional receivers 15022 // found with what we have do far. This would be easy, 15023 // but we also need to de-dup any receivers that are 15024 // singleUser. 15025 if (!scannedFirstReceivers) { 15026 // Collect any single user receivers we had already retrieved. 15027 scannedFirstReceivers = true; 15028 for (int i=0; i<receivers.size(); i++) { 15029 ResolveInfo ri = receivers.get(i); 15030 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15031 ComponentName cn = new ComponentName( 15032 ri.activityInfo.packageName, ri.activityInfo.name); 15033 if (singleUserReceivers == null) { 15034 singleUserReceivers = new HashSet<ComponentName>(); 15035 } 15036 singleUserReceivers.add(cn); 15037 } 15038 } 15039 } 15040 // Add the new results to the existing results, tracking 15041 // and de-dupping single user receivers. 15042 for (int i=0; i<newReceivers.size(); i++) { 15043 ResolveInfo ri = newReceivers.get(i); 15044 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15045 ComponentName cn = new ComponentName( 15046 ri.activityInfo.packageName, ri.activityInfo.name); 15047 if (singleUserReceivers == null) { 15048 singleUserReceivers = new HashSet<ComponentName>(); 15049 } 15050 if (!singleUserReceivers.contains(cn)) { 15051 singleUserReceivers.add(cn); 15052 receivers.add(ri); 15053 } 15054 } else { 15055 receivers.add(ri); 15056 } 15057 } 15058 } 15059 } 15060 } catch (RemoteException ex) { 15061 // pm is in same process, this will never happen. 15062 } 15063 return receivers; 15064 } 15065 15066 private final int broadcastIntentLocked(ProcessRecord callerApp, 15067 String callerPackage, Intent intent, String resolvedType, 15068 IIntentReceiver resultTo, int resultCode, String resultData, 15069 Bundle map, String requiredPermission, int appOp, 15070 boolean ordered, boolean sticky, int callingPid, int callingUid, 15071 int userId) { 15072 intent = new Intent(intent); 15073 15074 // By default broadcasts do not go to stopped apps. 15075 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15076 15077 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15078 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15079 + " ordered=" + ordered + " userid=" + userId); 15080 if ((resultTo != null) && !ordered) { 15081 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15082 } 15083 15084 userId = handleIncomingUser(callingPid, callingUid, userId, 15085 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15086 15087 // Make sure that the user who is receiving this broadcast is started. 15088 // If not, we will just skip it. 15089 15090 15091 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15092 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15093 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15094 Slog.w(TAG, "Skipping broadcast of " + intent 15095 + ": user " + userId + " is stopped"); 15096 return ActivityManager.BROADCAST_SUCCESS; 15097 } 15098 } 15099 15100 /* 15101 * Prevent non-system code (defined here to be non-persistent 15102 * processes) from sending protected broadcasts. 15103 */ 15104 int callingAppId = UserHandle.getAppId(callingUid); 15105 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15106 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15107 || callingAppId == Process.NFC_UID || callingUid == 0) { 15108 // Always okay. 15109 } else if (callerApp == null || !callerApp.persistent) { 15110 try { 15111 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15112 intent.getAction())) { 15113 String msg = "Permission Denial: not allowed to send broadcast " 15114 + intent.getAction() + " from pid=" 15115 + callingPid + ", uid=" + callingUid; 15116 Slog.w(TAG, msg); 15117 throw new SecurityException(msg); 15118 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15119 // Special case for compatibility: we don't want apps to send this, 15120 // but historically it has not been protected and apps may be using it 15121 // to poke their own app widget. So, instead of making it protected, 15122 // just limit it to the caller. 15123 if (callerApp == null) { 15124 String msg = "Permission Denial: not allowed to send broadcast " 15125 + intent.getAction() + " from unknown caller."; 15126 Slog.w(TAG, msg); 15127 throw new SecurityException(msg); 15128 } else if (intent.getComponent() != null) { 15129 // They are good enough to send to an explicit component... verify 15130 // it is being sent to the calling app. 15131 if (!intent.getComponent().getPackageName().equals( 15132 callerApp.info.packageName)) { 15133 String msg = "Permission Denial: not allowed to send broadcast " 15134 + intent.getAction() + " to " 15135 + intent.getComponent().getPackageName() + " from " 15136 + callerApp.info.packageName; 15137 Slog.w(TAG, msg); 15138 throw new SecurityException(msg); 15139 } 15140 } else { 15141 // Limit broadcast to their own package. 15142 intent.setPackage(callerApp.info.packageName); 15143 } 15144 } 15145 } catch (RemoteException e) { 15146 Slog.w(TAG, "Remote exception", e); 15147 return ActivityManager.BROADCAST_SUCCESS; 15148 } 15149 } 15150 15151 // Handle special intents: if this broadcast is from the package 15152 // manager about a package being removed, we need to remove all of 15153 // its activities from the history stack. 15154 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15155 intent.getAction()); 15156 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15157 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15158 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15159 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15160 || uidRemoved) { 15161 if (checkComponentPermission( 15162 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15163 callingPid, callingUid, -1, true) 15164 == PackageManager.PERMISSION_GRANTED) { 15165 if (uidRemoved) { 15166 final Bundle intentExtras = intent.getExtras(); 15167 final int uid = intentExtras != null 15168 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15169 if (uid >= 0) { 15170 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15171 synchronized (bs) { 15172 bs.removeUidStatsLocked(uid); 15173 } 15174 mAppOpsService.uidRemoved(uid); 15175 } 15176 } else { 15177 // If resources are unavailable just force stop all 15178 // those packages and flush the attribute cache as well. 15179 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15180 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15181 if (list != null && (list.length > 0)) { 15182 for (String pkg : list) { 15183 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15184 "storage unmount"); 15185 } 15186 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15187 sendPackageBroadcastLocked( 15188 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15189 } 15190 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15191 intent.getAction())) { 15192 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15193 } else { 15194 Uri data = intent.getData(); 15195 String ssp; 15196 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15197 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15198 intent.getAction()); 15199 boolean fullUninstall = removed && 15200 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15201 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15202 forceStopPackageLocked(ssp, UserHandle.getAppId( 15203 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15204 false, fullUninstall, userId, 15205 removed ? "pkg removed" : "pkg changed"); 15206 } 15207 if (removed) { 15208 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15209 new String[] {ssp}, userId); 15210 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15211 mAppOpsService.packageRemoved( 15212 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15213 15214 // Remove all permissions granted from/to this package 15215 removeUriPermissionsForPackageLocked(ssp, userId, true); 15216 } 15217 } 15218 } 15219 } 15220 } 15221 } else { 15222 String msg = "Permission Denial: " + intent.getAction() 15223 + " broadcast from " + callerPackage + " (pid=" + callingPid 15224 + ", uid=" + callingUid + ")" 15225 + " requires " 15226 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15227 Slog.w(TAG, msg); 15228 throw new SecurityException(msg); 15229 } 15230 15231 // Special case for adding a package: by default turn on compatibility 15232 // mode. 15233 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15234 Uri data = intent.getData(); 15235 String ssp; 15236 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15237 mCompatModePackages.handlePackageAddedLocked(ssp, 15238 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15239 } 15240 } 15241 15242 /* 15243 * If this is the time zone changed action, queue up a message that will reset the timezone 15244 * of all currently running processes. This message will get queued up before the broadcast 15245 * happens. 15246 */ 15247 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15248 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15249 } 15250 15251 /* 15252 * If the user set the time, let all running processes know. 15253 */ 15254 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15255 final int is24Hour = intent.getBooleanExtra( 15256 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15257 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15258 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15259 synchronized (stats) { 15260 stats.noteCurrentTimeChangedLocked(); 15261 } 15262 } 15263 15264 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15265 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15266 } 15267 15268 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15269 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15270 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15271 } 15272 15273 // Add to the sticky list if requested. 15274 if (sticky) { 15275 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15276 callingPid, callingUid) 15277 != PackageManager.PERMISSION_GRANTED) { 15278 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15279 + callingPid + ", uid=" + callingUid 15280 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15281 Slog.w(TAG, msg); 15282 throw new SecurityException(msg); 15283 } 15284 if (requiredPermission != null) { 15285 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15286 + " and enforce permission " + requiredPermission); 15287 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15288 } 15289 if (intent.getComponent() != null) { 15290 throw new SecurityException( 15291 "Sticky broadcasts can't target a specific component"); 15292 } 15293 // We use userId directly here, since the "all" target is maintained 15294 // as a separate set of sticky broadcasts. 15295 if (userId != UserHandle.USER_ALL) { 15296 // But first, if this is not a broadcast to all users, then 15297 // make sure it doesn't conflict with an existing broadcast to 15298 // all users. 15299 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15300 UserHandle.USER_ALL); 15301 if (stickies != null) { 15302 ArrayList<Intent> list = stickies.get(intent.getAction()); 15303 if (list != null) { 15304 int N = list.size(); 15305 int i; 15306 for (i=0; i<N; i++) { 15307 if (intent.filterEquals(list.get(i))) { 15308 throw new IllegalArgumentException( 15309 "Sticky broadcast " + intent + " for user " 15310 + userId + " conflicts with existing global broadcast"); 15311 } 15312 } 15313 } 15314 } 15315 } 15316 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15317 if (stickies == null) { 15318 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15319 mStickyBroadcasts.put(userId, stickies); 15320 } 15321 ArrayList<Intent> list = stickies.get(intent.getAction()); 15322 if (list == null) { 15323 list = new ArrayList<Intent>(); 15324 stickies.put(intent.getAction(), list); 15325 } 15326 int N = list.size(); 15327 int i; 15328 for (i=0; i<N; i++) { 15329 if (intent.filterEquals(list.get(i))) { 15330 // This sticky already exists, replace it. 15331 list.set(i, new Intent(intent)); 15332 break; 15333 } 15334 } 15335 if (i >= N) { 15336 list.add(new Intent(intent)); 15337 } 15338 } 15339 15340 int[] users; 15341 if (userId == UserHandle.USER_ALL) { 15342 // Caller wants broadcast to go to all started users. 15343 users = mStartedUserArray; 15344 } else { 15345 // Caller wants broadcast to go to one specific user. 15346 users = new int[] {userId}; 15347 } 15348 15349 // Figure out who all will receive this broadcast. 15350 List receivers = null; 15351 List<BroadcastFilter> registeredReceivers = null; 15352 // Need to resolve the intent to interested receivers... 15353 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15354 == 0) { 15355 receivers = collectReceiverComponents(intent, resolvedType, users); 15356 } 15357 if (intent.getComponent() == null) { 15358 registeredReceivers = mReceiverResolver.queryIntent(intent, 15359 resolvedType, false, userId); 15360 } 15361 15362 final boolean replacePending = 15363 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15364 15365 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15366 + " replacePending=" + replacePending); 15367 15368 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15369 if (!ordered && NR > 0) { 15370 // If we are not serializing this broadcast, then send the 15371 // registered receivers separately so they don't wait for the 15372 // components to be launched. 15373 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15374 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15375 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15376 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15377 ordered, sticky, false, userId); 15378 if (DEBUG_BROADCAST) Slog.v( 15379 TAG, "Enqueueing parallel broadcast " + r); 15380 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15381 if (!replaced) { 15382 queue.enqueueParallelBroadcastLocked(r); 15383 queue.scheduleBroadcastsLocked(); 15384 } 15385 registeredReceivers = null; 15386 NR = 0; 15387 } 15388 15389 // Merge into one list. 15390 int ir = 0; 15391 if (receivers != null) { 15392 // A special case for PACKAGE_ADDED: do not allow the package 15393 // being added to see this broadcast. This prevents them from 15394 // using this as a back door to get run as soon as they are 15395 // installed. Maybe in the future we want to have a special install 15396 // broadcast or such for apps, but we'd like to deliberately make 15397 // this decision. 15398 String skipPackages[] = null; 15399 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15400 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15401 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15402 Uri data = intent.getData(); 15403 if (data != null) { 15404 String pkgName = data.getSchemeSpecificPart(); 15405 if (pkgName != null) { 15406 skipPackages = new String[] { pkgName }; 15407 } 15408 } 15409 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15410 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15411 } 15412 if (skipPackages != null && (skipPackages.length > 0)) { 15413 for (String skipPackage : skipPackages) { 15414 if (skipPackage != null) { 15415 int NT = receivers.size(); 15416 for (int it=0; it<NT; it++) { 15417 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15418 if (curt.activityInfo.packageName.equals(skipPackage)) { 15419 receivers.remove(it); 15420 it--; 15421 NT--; 15422 } 15423 } 15424 } 15425 } 15426 } 15427 15428 int NT = receivers != null ? receivers.size() : 0; 15429 int it = 0; 15430 ResolveInfo curt = null; 15431 BroadcastFilter curr = null; 15432 while (it < NT && ir < NR) { 15433 if (curt == null) { 15434 curt = (ResolveInfo)receivers.get(it); 15435 } 15436 if (curr == null) { 15437 curr = registeredReceivers.get(ir); 15438 } 15439 if (curr.getPriority() >= curt.priority) { 15440 // Insert this broadcast record into the final list. 15441 receivers.add(it, curr); 15442 ir++; 15443 curr = null; 15444 it++; 15445 NT++; 15446 } else { 15447 // Skip to the next ResolveInfo in the final list. 15448 it++; 15449 curt = null; 15450 } 15451 } 15452 } 15453 while (ir < NR) { 15454 if (receivers == null) { 15455 receivers = new ArrayList(); 15456 } 15457 receivers.add(registeredReceivers.get(ir)); 15458 ir++; 15459 } 15460 15461 if ((receivers != null && receivers.size() > 0) 15462 || resultTo != null) { 15463 BroadcastQueue queue = broadcastQueueForIntent(intent); 15464 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15465 callerPackage, callingPid, callingUid, resolvedType, 15466 requiredPermission, appOp, receivers, resultTo, resultCode, 15467 resultData, map, ordered, sticky, false, userId); 15468 if (DEBUG_BROADCAST) Slog.v( 15469 TAG, "Enqueueing ordered broadcast " + r 15470 + ": prev had " + queue.mOrderedBroadcasts.size()); 15471 if (DEBUG_BROADCAST) { 15472 int seq = r.intent.getIntExtra("seq", -1); 15473 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15474 } 15475 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15476 if (!replaced) { 15477 queue.enqueueOrderedBroadcastLocked(r); 15478 queue.scheduleBroadcastsLocked(); 15479 } 15480 } 15481 15482 return ActivityManager.BROADCAST_SUCCESS; 15483 } 15484 15485 final Intent verifyBroadcastLocked(Intent intent) { 15486 // Refuse possible leaked file descriptors 15487 if (intent != null && intent.hasFileDescriptors() == true) { 15488 throw new IllegalArgumentException("File descriptors passed in Intent"); 15489 } 15490 15491 int flags = intent.getFlags(); 15492 15493 if (!mProcessesReady) { 15494 // if the caller really truly claims to know what they're doing, go 15495 // ahead and allow the broadcast without launching any receivers 15496 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15497 intent = new Intent(intent); 15498 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15499 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15500 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15501 + " before boot completion"); 15502 throw new IllegalStateException("Cannot broadcast before boot completed"); 15503 } 15504 } 15505 15506 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15507 throw new IllegalArgumentException( 15508 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15509 } 15510 15511 return intent; 15512 } 15513 15514 public final int broadcastIntent(IApplicationThread caller, 15515 Intent intent, String resolvedType, IIntentReceiver resultTo, 15516 int resultCode, String resultData, Bundle map, 15517 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15518 enforceNotIsolatedCaller("broadcastIntent"); 15519 synchronized(this) { 15520 intent = verifyBroadcastLocked(intent); 15521 15522 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15523 final int callingPid = Binder.getCallingPid(); 15524 final int callingUid = Binder.getCallingUid(); 15525 final long origId = Binder.clearCallingIdentity(); 15526 int res = broadcastIntentLocked(callerApp, 15527 callerApp != null ? callerApp.info.packageName : null, 15528 intent, resolvedType, resultTo, 15529 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15530 callingPid, callingUid, userId); 15531 Binder.restoreCallingIdentity(origId); 15532 return res; 15533 } 15534 } 15535 15536 int broadcastIntentInPackage(String packageName, int uid, 15537 Intent intent, String resolvedType, IIntentReceiver resultTo, 15538 int resultCode, String resultData, Bundle map, 15539 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15540 synchronized(this) { 15541 intent = verifyBroadcastLocked(intent); 15542 15543 final long origId = Binder.clearCallingIdentity(); 15544 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15545 resultTo, resultCode, resultData, map, requiredPermission, 15546 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15547 Binder.restoreCallingIdentity(origId); 15548 return res; 15549 } 15550 } 15551 15552 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15553 // Refuse possible leaked file descriptors 15554 if (intent != null && intent.hasFileDescriptors() == true) { 15555 throw new IllegalArgumentException("File descriptors passed in Intent"); 15556 } 15557 15558 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15559 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15560 15561 synchronized(this) { 15562 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15563 != PackageManager.PERMISSION_GRANTED) { 15564 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15565 + Binder.getCallingPid() 15566 + ", uid=" + Binder.getCallingUid() 15567 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15568 Slog.w(TAG, msg); 15569 throw new SecurityException(msg); 15570 } 15571 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15572 if (stickies != null) { 15573 ArrayList<Intent> list = stickies.get(intent.getAction()); 15574 if (list != null) { 15575 int N = list.size(); 15576 int i; 15577 for (i=0; i<N; i++) { 15578 if (intent.filterEquals(list.get(i))) { 15579 list.remove(i); 15580 break; 15581 } 15582 } 15583 if (list.size() <= 0) { 15584 stickies.remove(intent.getAction()); 15585 } 15586 } 15587 if (stickies.size() <= 0) { 15588 mStickyBroadcasts.remove(userId); 15589 } 15590 } 15591 } 15592 } 15593 15594 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15595 String resultData, Bundle resultExtras, boolean resultAbort) { 15596 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15597 if (r == null) { 15598 Slog.w(TAG, "finishReceiver called but not found on queue"); 15599 return false; 15600 } 15601 15602 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15603 } 15604 15605 void backgroundServicesFinishedLocked(int userId) { 15606 for (BroadcastQueue queue : mBroadcastQueues) { 15607 queue.backgroundServicesFinishedLocked(userId); 15608 } 15609 } 15610 15611 public void finishReceiver(IBinder who, int resultCode, String resultData, 15612 Bundle resultExtras, boolean resultAbort) { 15613 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15614 15615 // Refuse possible leaked file descriptors 15616 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15617 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15618 } 15619 15620 final long origId = Binder.clearCallingIdentity(); 15621 try { 15622 boolean doNext = false; 15623 BroadcastRecord r; 15624 15625 synchronized(this) { 15626 r = broadcastRecordForReceiverLocked(who); 15627 if (r != null) { 15628 doNext = r.queue.finishReceiverLocked(r, resultCode, 15629 resultData, resultExtras, resultAbort, true); 15630 } 15631 } 15632 15633 if (doNext) { 15634 r.queue.processNextBroadcast(false); 15635 } 15636 trimApplications(); 15637 } finally { 15638 Binder.restoreCallingIdentity(origId); 15639 } 15640 } 15641 15642 // ========================================================= 15643 // INSTRUMENTATION 15644 // ========================================================= 15645 15646 public boolean startInstrumentation(ComponentName className, 15647 String profileFile, int flags, Bundle arguments, 15648 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15649 int userId, String abiOverride) { 15650 enforceNotIsolatedCaller("startInstrumentation"); 15651 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15652 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15653 // Refuse possible leaked file descriptors 15654 if (arguments != null && arguments.hasFileDescriptors()) { 15655 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15656 } 15657 15658 synchronized(this) { 15659 InstrumentationInfo ii = null; 15660 ApplicationInfo ai = null; 15661 try { 15662 ii = mContext.getPackageManager().getInstrumentationInfo( 15663 className, STOCK_PM_FLAGS); 15664 ai = AppGlobals.getPackageManager().getApplicationInfo( 15665 ii.targetPackage, STOCK_PM_FLAGS, userId); 15666 } catch (PackageManager.NameNotFoundException e) { 15667 } catch (RemoteException e) { 15668 } 15669 if (ii == null) { 15670 reportStartInstrumentationFailure(watcher, className, 15671 "Unable to find instrumentation info for: " + className); 15672 return false; 15673 } 15674 if (ai == null) { 15675 reportStartInstrumentationFailure(watcher, className, 15676 "Unable to find instrumentation target package: " + ii.targetPackage); 15677 return false; 15678 } 15679 15680 int match = mContext.getPackageManager().checkSignatures( 15681 ii.targetPackage, ii.packageName); 15682 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15683 String msg = "Permission Denial: starting instrumentation " 15684 + className + " from pid=" 15685 + Binder.getCallingPid() 15686 + ", uid=" + Binder.getCallingPid() 15687 + " not allowed because package " + ii.packageName 15688 + " does not have a signature matching the target " 15689 + ii.targetPackage; 15690 reportStartInstrumentationFailure(watcher, className, msg); 15691 throw new SecurityException(msg); 15692 } 15693 15694 final long origId = Binder.clearCallingIdentity(); 15695 // Instrumentation can kill and relaunch even persistent processes 15696 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15697 "start instr"); 15698 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15699 app.instrumentationClass = className; 15700 app.instrumentationInfo = ai; 15701 app.instrumentationProfileFile = profileFile; 15702 app.instrumentationArguments = arguments; 15703 app.instrumentationWatcher = watcher; 15704 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15705 app.instrumentationResultClass = className; 15706 Binder.restoreCallingIdentity(origId); 15707 } 15708 15709 return true; 15710 } 15711 15712 /** 15713 * Report errors that occur while attempting to start Instrumentation. Always writes the 15714 * error to the logs, but if somebody is watching, send the report there too. This enables 15715 * the "am" command to report errors with more information. 15716 * 15717 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15718 * @param cn The component name of the instrumentation. 15719 * @param report The error report. 15720 */ 15721 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15722 ComponentName cn, String report) { 15723 Slog.w(TAG, report); 15724 try { 15725 if (watcher != null) { 15726 Bundle results = new Bundle(); 15727 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15728 results.putString("Error", report); 15729 watcher.instrumentationStatus(cn, -1, results); 15730 } 15731 } catch (RemoteException e) { 15732 Slog.w(TAG, e); 15733 } 15734 } 15735 15736 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15737 if (app.instrumentationWatcher != null) { 15738 try { 15739 // NOTE: IInstrumentationWatcher *must* be oneway here 15740 app.instrumentationWatcher.instrumentationFinished( 15741 app.instrumentationClass, 15742 resultCode, 15743 results); 15744 } catch (RemoteException e) { 15745 } 15746 } 15747 if (app.instrumentationUiAutomationConnection != null) { 15748 try { 15749 app.instrumentationUiAutomationConnection.shutdown(); 15750 } catch (RemoteException re) { 15751 /* ignore */ 15752 } 15753 // Only a UiAutomation can set this flag and now that 15754 // it is finished we make sure it is reset to its default. 15755 mUserIsMonkey = false; 15756 } 15757 app.instrumentationWatcher = null; 15758 app.instrumentationUiAutomationConnection = null; 15759 app.instrumentationClass = null; 15760 app.instrumentationInfo = null; 15761 app.instrumentationProfileFile = null; 15762 app.instrumentationArguments = null; 15763 15764 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15765 "finished inst"); 15766 } 15767 15768 public void finishInstrumentation(IApplicationThread target, 15769 int resultCode, Bundle results) { 15770 int userId = UserHandle.getCallingUserId(); 15771 // Refuse possible leaked file descriptors 15772 if (results != null && results.hasFileDescriptors()) { 15773 throw new IllegalArgumentException("File descriptors passed in Intent"); 15774 } 15775 15776 synchronized(this) { 15777 ProcessRecord app = getRecordForAppLocked(target); 15778 if (app == null) { 15779 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15780 return; 15781 } 15782 final long origId = Binder.clearCallingIdentity(); 15783 finishInstrumentationLocked(app, resultCode, results); 15784 Binder.restoreCallingIdentity(origId); 15785 } 15786 } 15787 15788 // ========================================================= 15789 // CONFIGURATION 15790 // ========================================================= 15791 15792 public ConfigurationInfo getDeviceConfigurationInfo() { 15793 ConfigurationInfo config = new ConfigurationInfo(); 15794 synchronized (this) { 15795 config.reqTouchScreen = mConfiguration.touchscreen; 15796 config.reqKeyboardType = mConfiguration.keyboard; 15797 config.reqNavigation = mConfiguration.navigation; 15798 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15799 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15800 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15801 } 15802 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15803 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15804 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15805 } 15806 config.reqGlEsVersion = GL_ES_VERSION; 15807 } 15808 return config; 15809 } 15810 15811 ActivityStack getFocusedStack() { 15812 return mStackSupervisor.getFocusedStack(); 15813 } 15814 15815 public Configuration getConfiguration() { 15816 Configuration ci; 15817 synchronized(this) { 15818 ci = new Configuration(mConfiguration); 15819 } 15820 return ci; 15821 } 15822 15823 public void updatePersistentConfiguration(Configuration values) { 15824 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15825 "updateConfiguration()"); 15826 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15827 "updateConfiguration()"); 15828 if (values == null) { 15829 throw new NullPointerException("Configuration must not be null"); 15830 } 15831 15832 synchronized(this) { 15833 final long origId = Binder.clearCallingIdentity(); 15834 updateConfigurationLocked(values, null, true, false); 15835 Binder.restoreCallingIdentity(origId); 15836 } 15837 } 15838 15839 public void updateConfiguration(Configuration values) { 15840 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15841 "updateConfiguration()"); 15842 15843 synchronized(this) { 15844 if (values == null && mWindowManager != null) { 15845 // sentinel: fetch the current configuration from the window manager 15846 values = mWindowManager.computeNewConfiguration(); 15847 } 15848 15849 if (mWindowManager != null) { 15850 mProcessList.applyDisplaySize(mWindowManager); 15851 } 15852 15853 final long origId = Binder.clearCallingIdentity(); 15854 if (values != null) { 15855 Settings.System.clearConfiguration(values); 15856 } 15857 updateConfigurationLocked(values, null, false, false); 15858 Binder.restoreCallingIdentity(origId); 15859 } 15860 } 15861 15862 /** 15863 * Do either or both things: (1) change the current configuration, and (2) 15864 * make sure the given activity is running with the (now) current 15865 * configuration. Returns true if the activity has been left running, or 15866 * false if <var>starting</var> is being destroyed to match the new 15867 * configuration. 15868 * @param persistent TODO 15869 */ 15870 boolean updateConfigurationLocked(Configuration values, 15871 ActivityRecord starting, boolean persistent, boolean initLocale) { 15872 int changes = 0; 15873 15874 if (values != null) { 15875 Configuration newConfig = new Configuration(mConfiguration); 15876 changes = newConfig.updateFrom(values); 15877 if (changes != 0) { 15878 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15879 Slog.i(TAG, "Updating configuration to: " + values); 15880 } 15881 15882 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15883 15884 if (values.locale != null && !initLocale) { 15885 saveLocaleLocked(values.locale, 15886 !values.locale.equals(mConfiguration.locale), 15887 values.userSetLocale); 15888 } 15889 15890 mConfigurationSeq++; 15891 if (mConfigurationSeq <= 0) { 15892 mConfigurationSeq = 1; 15893 } 15894 newConfig.seq = mConfigurationSeq; 15895 mConfiguration = newConfig; 15896 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15897 //mUsageStatsService.noteStartConfig(newConfig); 15898 15899 final Configuration configCopy = new Configuration(mConfiguration); 15900 15901 // TODO: If our config changes, should we auto dismiss any currently 15902 // showing dialogs? 15903 mShowDialogs = shouldShowDialogs(newConfig); 15904 15905 AttributeCache ac = AttributeCache.instance(); 15906 if (ac != null) { 15907 ac.updateConfiguration(configCopy); 15908 } 15909 15910 // Make sure all resources in our process are updated 15911 // right now, so that anyone who is going to retrieve 15912 // resource values after we return will be sure to get 15913 // the new ones. This is especially important during 15914 // boot, where the first config change needs to guarantee 15915 // all resources have that config before following boot 15916 // code is executed. 15917 mSystemThread.applyConfigurationToResources(configCopy); 15918 15919 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15920 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15921 msg.obj = new Configuration(configCopy); 15922 mHandler.sendMessage(msg); 15923 } 15924 15925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15926 ProcessRecord app = mLruProcesses.get(i); 15927 try { 15928 if (app.thread != null) { 15929 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15930 + app.processName + " new config " + mConfiguration); 15931 app.thread.scheduleConfigurationChanged(configCopy); 15932 } 15933 } catch (Exception e) { 15934 } 15935 } 15936 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15937 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15938 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15939 | Intent.FLAG_RECEIVER_FOREGROUND); 15940 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15941 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15942 Process.SYSTEM_UID, UserHandle.USER_ALL); 15943 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15944 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15945 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15946 broadcastIntentLocked(null, null, intent, 15947 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15948 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15949 } 15950 } 15951 } 15952 15953 boolean kept = true; 15954 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15955 // mainStack is null during startup. 15956 if (mainStack != null) { 15957 if (changes != 0 && starting == null) { 15958 // If the configuration changed, and the caller is not already 15959 // in the process of starting an activity, then find the top 15960 // activity to check if its configuration needs to change. 15961 starting = mainStack.topRunningActivityLocked(null); 15962 } 15963 15964 if (starting != null) { 15965 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15966 // And we need to make sure at this point that all other activities 15967 // are made visible with the correct configuration. 15968 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15969 } 15970 } 15971 15972 if (values != null && mWindowManager != null) { 15973 mWindowManager.setNewConfiguration(mConfiguration); 15974 } 15975 15976 return kept; 15977 } 15978 15979 /** 15980 * Decide based on the configuration whether we should shouw the ANR, 15981 * crash, etc dialogs. The idea is that if there is no affordnace to 15982 * press the on-screen buttons, we shouldn't show the dialog. 15983 * 15984 * A thought: SystemUI might also want to get told about this, the Power 15985 * dialog / global actions also might want different behaviors. 15986 */ 15987 private static final boolean shouldShowDialogs(Configuration config) { 15988 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15989 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15990 } 15991 15992 /** 15993 * Save the locale. You must be inside a synchronized (this) block. 15994 */ 15995 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15996 if(isDiff) { 15997 SystemProperties.set("user.language", l.getLanguage()); 15998 SystemProperties.set("user.region", l.getCountry()); 15999 } 16000 16001 if(isPersist) { 16002 SystemProperties.set("persist.sys.language", l.getLanguage()); 16003 SystemProperties.set("persist.sys.country", l.getCountry()); 16004 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16005 } 16006 } 16007 16008 @Override 16009 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16010 synchronized (this) { 16011 ActivityRecord srec = ActivityRecord.forToken(token); 16012 if (srec.task != null && srec.task.stack != null) { 16013 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16014 } 16015 } 16016 return false; 16017 } 16018 16019 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16020 Intent resultData) { 16021 16022 synchronized (this) { 16023 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16024 if (stack != null) { 16025 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16026 } 16027 return false; 16028 } 16029 } 16030 16031 public int getLaunchedFromUid(IBinder activityToken) { 16032 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16033 if (srec == null) { 16034 return -1; 16035 } 16036 return srec.launchedFromUid; 16037 } 16038 16039 public String getLaunchedFromPackage(IBinder activityToken) { 16040 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16041 if (srec == null) { 16042 return null; 16043 } 16044 return srec.launchedFromPackage; 16045 } 16046 16047 // ========================================================= 16048 // LIFETIME MANAGEMENT 16049 // ========================================================= 16050 16051 // Returns which broadcast queue the app is the current [or imminent] receiver 16052 // on, or 'null' if the app is not an active broadcast recipient. 16053 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16054 BroadcastRecord r = app.curReceiver; 16055 if (r != null) { 16056 return r.queue; 16057 } 16058 16059 // It's not the current receiver, but it might be starting up to become one 16060 synchronized (this) { 16061 for (BroadcastQueue queue : mBroadcastQueues) { 16062 r = queue.mPendingBroadcast; 16063 if (r != null && r.curApp == app) { 16064 // found it; report which queue it's in 16065 return queue; 16066 } 16067 } 16068 } 16069 16070 return null; 16071 } 16072 16073 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16074 boolean doingAll, long now) { 16075 if (mAdjSeq == app.adjSeq) { 16076 // This adjustment has already been computed. 16077 return app.curRawAdj; 16078 } 16079 16080 if (app.thread == null) { 16081 app.adjSeq = mAdjSeq; 16082 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16083 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16084 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16085 } 16086 16087 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16088 app.adjSource = null; 16089 app.adjTarget = null; 16090 app.empty = false; 16091 app.cached = false; 16092 16093 final int activitiesSize = app.activities.size(); 16094 16095 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16096 // The max adjustment doesn't allow this app to be anything 16097 // below foreground, so it is not worth doing work for it. 16098 app.adjType = "fixed"; 16099 app.adjSeq = mAdjSeq; 16100 app.curRawAdj = app.maxAdj; 16101 app.foregroundActivities = false; 16102 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16103 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16104 // System processes can do UI, and when they do we want to have 16105 // them trim their memory after the user leaves the UI. To 16106 // facilitate this, here we need to determine whether or not it 16107 // is currently showing UI. 16108 app.systemNoUi = true; 16109 if (app == TOP_APP) { 16110 app.systemNoUi = false; 16111 } else if (activitiesSize > 0) { 16112 for (int j = 0; j < activitiesSize; j++) { 16113 final ActivityRecord r = app.activities.get(j); 16114 if (r.visible) { 16115 app.systemNoUi = false; 16116 } 16117 } 16118 } 16119 if (!app.systemNoUi) { 16120 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16121 } 16122 return (app.curAdj=app.maxAdj); 16123 } 16124 16125 app.systemNoUi = false; 16126 16127 // Determine the importance of the process, starting with most 16128 // important to least, and assign an appropriate OOM adjustment. 16129 int adj; 16130 int schedGroup; 16131 int procState; 16132 boolean foregroundActivities = false; 16133 BroadcastQueue queue; 16134 if (app == TOP_APP) { 16135 // The last app on the list is the foreground app. 16136 adj = ProcessList.FOREGROUND_APP_ADJ; 16137 schedGroup = Process.THREAD_GROUP_DEFAULT; 16138 app.adjType = "top-activity"; 16139 foregroundActivities = true; 16140 procState = ActivityManager.PROCESS_STATE_TOP; 16141 } else if (app.instrumentationClass != null) { 16142 // Don't want to kill running instrumentation. 16143 adj = ProcessList.FOREGROUND_APP_ADJ; 16144 schedGroup = Process.THREAD_GROUP_DEFAULT; 16145 app.adjType = "instrumentation"; 16146 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16147 } else if ((queue = isReceivingBroadcast(app)) != null) { 16148 // An app that is currently receiving a broadcast also 16149 // counts as being in the foreground for OOM killer purposes. 16150 // It's placed in a sched group based on the nature of the 16151 // broadcast as reflected by which queue it's active in. 16152 adj = ProcessList.FOREGROUND_APP_ADJ; 16153 schedGroup = (queue == mFgBroadcastQueue) 16154 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16155 app.adjType = "broadcast"; 16156 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16157 } else if (app.executingServices.size() > 0) { 16158 // An app that is currently executing a service callback also 16159 // counts as being in the foreground. 16160 adj = ProcessList.FOREGROUND_APP_ADJ; 16161 schedGroup = app.execServicesFg ? 16162 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16163 app.adjType = "exec-service"; 16164 procState = ActivityManager.PROCESS_STATE_SERVICE; 16165 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16166 } else { 16167 // As far as we know the process is empty. We may change our mind later. 16168 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16169 // At this point we don't actually know the adjustment. Use the cached adj 16170 // value that the caller wants us to. 16171 adj = cachedAdj; 16172 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16173 app.cached = true; 16174 app.empty = true; 16175 app.adjType = "cch-empty"; 16176 } 16177 16178 // Examine all activities if not already foreground. 16179 if (!foregroundActivities && activitiesSize > 0) { 16180 for (int j = 0; j < activitiesSize; j++) { 16181 final ActivityRecord r = app.activities.get(j); 16182 if (r.app != app) { 16183 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16184 + app + "?!?"); 16185 continue; 16186 } 16187 if (r.visible) { 16188 // App has a visible activity; only upgrade adjustment. 16189 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16190 adj = ProcessList.VISIBLE_APP_ADJ; 16191 app.adjType = "visible"; 16192 } 16193 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16194 procState = ActivityManager.PROCESS_STATE_TOP; 16195 } 16196 schedGroup = Process.THREAD_GROUP_DEFAULT; 16197 app.cached = false; 16198 app.empty = false; 16199 foregroundActivities = true; 16200 break; 16201 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16202 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16203 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16204 app.adjType = "pausing"; 16205 } 16206 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16207 procState = ActivityManager.PROCESS_STATE_TOP; 16208 } 16209 schedGroup = Process.THREAD_GROUP_DEFAULT; 16210 app.cached = false; 16211 app.empty = false; 16212 foregroundActivities = true; 16213 } else if (r.state == ActivityState.STOPPING) { 16214 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16215 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16216 app.adjType = "stopping"; 16217 } 16218 // For the process state, we will at this point consider the 16219 // process to be cached. It will be cached either as an activity 16220 // or empty depending on whether the activity is finishing. We do 16221 // this so that we can treat the process as cached for purposes of 16222 // memory trimming (determing current memory level, trim command to 16223 // send to process) since there can be an arbitrary number of stopping 16224 // processes and they should soon all go into the cached state. 16225 if (!r.finishing) { 16226 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16227 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16228 } 16229 } 16230 app.cached = false; 16231 app.empty = false; 16232 foregroundActivities = true; 16233 } else { 16234 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16235 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16236 app.adjType = "cch-act"; 16237 } 16238 } 16239 } 16240 } 16241 16242 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16243 if (app.foregroundServices) { 16244 // The user is aware of this app, so make it visible. 16245 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16246 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16247 app.cached = false; 16248 app.adjType = "fg-service"; 16249 schedGroup = Process.THREAD_GROUP_DEFAULT; 16250 } else if (app.forcingToForeground != null) { 16251 // The user is aware of this app, so make it visible. 16252 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16253 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16254 app.cached = false; 16255 app.adjType = "force-fg"; 16256 app.adjSource = app.forcingToForeground; 16257 schedGroup = Process.THREAD_GROUP_DEFAULT; 16258 } 16259 } 16260 16261 if (app == mHeavyWeightProcess) { 16262 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16263 // We don't want to kill the current heavy-weight process. 16264 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16265 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16266 app.cached = false; 16267 app.adjType = "heavy"; 16268 } 16269 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16270 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16271 } 16272 } 16273 16274 if (app == mHomeProcess) { 16275 if (adj > ProcessList.HOME_APP_ADJ) { 16276 // This process is hosting what we currently consider to be the 16277 // home app, so we don't want to let it go into the background. 16278 adj = ProcessList.HOME_APP_ADJ; 16279 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16280 app.cached = false; 16281 app.adjType = "home"; 16282 } 16283 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16284 procState = ActivityManager.PROCESS_STATE_HOME; 16285 } 16286 } 16287 16288 if (app == mPreviousProcess && app.activities.size() > 0) { 16289 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16290 // This was the previous process that showed UI to the user. 16291 // We want to try to keep it around more aggressively, to give 16292 // a good experience around switching between two apps. 16293 adj = ProcessList.PREVIOUS_APP_ADJ; 16294 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16295 app.cached = false; 16296 app.adjType = "previous"; 16297 } 16298 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16299 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16300 } 16301 } 16302 16303 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16304 + " reason=" + app.adjType); 16305 16306 // By default, we use the computed adjustment. It may be changed if 16307 // there are applications dependent on our services or providers, but 16308 // this gives us a baseline and makes sure we don't get into an 16309 // infinite recursion. 16310 app.adjSeq = mAdjSeq; 16311 app.curRawAdj = adj; 16312 app.hasStartedServices = false; 16313 16314 if (mBackupTarget != null && app == mBackupTarget.app) { 16315 // If possible we want to avoid killing apps while they're being backed up 16316 if (adj > ProcessList.BACKUP_APP_ADJ) { 16317 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16318 adj = ProcessList.BACKUP_APP_ADJ; 16319 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16320 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16321 } 16322 app.adjType = "backup"; 16323 app.cached = false; 16324 } 16325 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16326 procState = ActivityManager.PROCESS_STATE_BACKUP; 16327 } 16328 } 16329 16330 boolean mayBeTop = false; 16331 16332 for (int is = app.services.size()-1; 16333 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16334 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16335 || procState > ActivityManager.PROCESS_STATE_TOP); 16336 is--) { 16337 ServiceRecord s = app.services.valueAt(is); 16338 if (s.startRequested) { 16339 app.hasStartedServices = true; 16340 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16341 procState = ActivityManager.PROCESS_STATE_SERVICE; 16342 } 16343 if (app.hasShownUi && app != mHomeProcess) { 16344 // If this process has shown some UI, let it immediately 16345 // go to the LRU list because it may be pretty heavy with 16346 // UI stuff. We'll tag it with a label just to help 16347 // debug and understand what is going on. 16348 if (adj > ProcessList.SERVICE_ADJ) { 16349 app.adjType = "cch-started-ui-services"; 16350 } 16351 } else { 16352 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16353 // This service has seen some activity within 16354 // recent memory, so we will keep its process ahead 16355 // of the background processes. 16356 if (adj > ProcessList.SERVICE_ADJ) { 16357 adj = ProcessList.SERVICE_ADJ; 16358 app.adjType = "started-services"; 16359 app.cached = false; 16360 } 16361 } 16362 // If we have let the service slide into the background 16363 // state, still have some text describing what it is doing 16364 // even though the service no longer has an impact. 16365 if (adj > ProcessList.SERVICE_ADJ) { 16366 app.adjType = "cch-started-services"; 16367 } 16368 } 16369 } 16370 for (int conni = s.connections.size()-1; 16371 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16372 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16373 || procState > ActivityManager.PROCESS_STATE_TOP); 16374 conni--) { 16375 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16376 for (int i = 0; 16377 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16378 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16379 || procState > ActivityManager.PROCESS_STATE_TOP); 16380 i++) { 16381 // XXX should compute this based on the max of 16382 // all connected clients. 16383 ConnectionRecord cr = clist.get(i); 16384 if (cr.binding.client == app) { 16385 // Binding to ourself is not interesting. 16386 continue; 16387 } 16388 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16389 ProcessRecord client = cr.binding.client; 16390 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16391 TOP_APP, doingAll, now); 16392 int clientProcState = client.curProcState; 16393 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16394 // If the other app is cached for any reason, for purposes here 16395 // we are going to consider it empty. The specific cached state 16396 // doesn't propagate except under certain conditions. 16397 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16398 } 16399 String adjType = null; 16400 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16401 // Not doing bind OOM management, so treat 16402 // this guy more like a started service. 16403 if (app.hasShownUi && app != mHomeProcess) { 16404 // If this process has shown some UI, let it immediately 16405 // go to the LRU list because it may be pretty heavy with 16406 // UI stuff. We'll tag it with a label just to help 16407 // debug and understand what is going on. 16408 if (adj > clientAdj) { 16409 adjType = "cch-bound-ui-services"; 16410 } 16411 app.cached = false; 16412 clientAdj = adj; 16413 clientProcState = procState; 16414 } else { 16415 if (now >= (s.lastActivity 16416 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16417 // This service has not seen activity within 16418 // recent memory, so allow it to drop to the 16419 // LRU list if there is no other reason to keep 16420 // it around. We'll also tag it with a label just 16421 // to help debug and undertand what is going on. 16422 if (adj > clientAdj) { 16423 adjType = "cch-bound-services"; 16424 } 16425 clientAdj = adj; 16426 } 16427 } 16428 } 16429 if (adj > clientAdj) { 16430 // If this process has recently shown UI, and 16431 // the process that is binding to it is less 16432 // important than being visible, then we don't 16433 // care about the binding as much as we care 16434 // about letting this process get into the LRU 16435 // list to be killed and restarted if needed for 16436 // memory. 16437 if (app.hasShownUi && app != mHomeProcess 16438 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16439 adjType = "cch-bound-ui-services"; 16440 } else { 16441 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16442 |Context.BIND_IMPORTANT)) != 0) { 16443 adj = clientAdj; 16444 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16445 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16446 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16447 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16448 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16449 adj = clientAdj; 16450 } else { 16451 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16452 adj = ProcessList.VISIBLE_APP_ADJ; 16453 } 16454 } 16455 if (!client.cached) { 16456 app.cached = false; 16457 } 16458 adjType = "service"; 16459 } 16460 } 16461 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16462 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16463 schedGroup = Process.THREAD_GROUP_DEFAULT; 16464 } 16465 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16466 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16467 // Special handling of clients who are in the top state. 16468 // We *may* want to consider this process to be in the 16469 // top state as well, but only if there is not another 16470 // reason for it to be running. Being on the top is a 16471 // special state, meaning you are specifically running 16472 // for the current top app. If the process is already 16473 // running in the background for some other reason, it 16474 // is more important to continue considering it to be 16475 // in the background state. 16476 mayBeTop = true; 16477 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16478 } else { 16479 // Special handling for above-top states (persistent 16480 // processes). These should not bring the current process 16481 // into the top state, since they are not on top. Instead 16482 // give them the best state after that. 16483 clientProcState = 16484 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16485 } 16486 } 16487 } else { 16488 if (clientProcState < 16489 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16490 clientProcState = 16491 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16492 } 16493 } 16494 if (procState > clientProcState) { 16495 procState = clientProcState; 16496 } 16497 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16498 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16499 app.pendingUiClean = true; 16500 } 16501 if (adjType != null) { 16502 app.adjType = adjType; 16503 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16504 .REASON_SERVICE_IN_USE; 16505 app.adjSource = cr.binding.client; 16506 app.adjSourceProcState = clientProcState; 16507 app.adjTarget = s.name; 16508 } 16509 } 16510 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16511 app.treatLikeActivity = true; 16512 } 16513 final ActivityRecord a = cr.activity; 16514 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16515 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16516 (a.visible || a.state == ActivityState.RESUMED 16517 || a.state == ActivityState.PAUSING)) { 16518 adj = ProcessList.FOREGROUND_APP_ADJ; 16519 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16520 schedGroup = Process.THREAD_GROUP_DEFAULT; 16521 } 16522 app.cached = false; 16523 app.adjType = "service"; 16524 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16525 .REASON_SERVICE_IN_USE; 16526 app.adjSource = a; 16527 app.adjSourceProcState = procState; 16528 app.adjTarget = s.name; 16529 } 16530 } 16531 } 16532 } 16533 } 16534 16535 for (int provi = app.pubProviders.size()-1; 16536 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16537 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16538 || procState > ActivityManager.PROCESS_STATE_TOP); 16539 provi--) { 16540 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16541 for (int i = cpr.connections.size()-1; 16542 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16543 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16544 || procState > ActivityManager.PROCESS_STATE_TOP); 16545 i--) { 16546 ContentProviderConnection conn = cpr.connections.get(i); 16547 ProcessRecord client = conn.client; 16548 if (client == app) { 16549 // Being our own client is not interesting. 16550 continue; 16551 } 16552 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16553 int clientProcState = client.curProcState; 16554 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16555 // If the other app is cached for any reason, for purposes here 16556 // we are going to consider it empty. 16557 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16558 } 16559 if (adj > clientAdj) { 16560 if (app.hasShownUi && app != mHomeProcess 16561 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16562 app.adjType = "cch-ui-provider"; 16563 } else { 16564 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16565 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16566 app.adjType = "provider"; 16567 } 16568 app.cached &= client.cached; 16569 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16570 .REASON_PROVIDER_IN_USE; 16571 app.adjSource = client; 16572 app.adjSourceProcState = clientProcState; 16573 app.adjTarget = cpr.name; 16574 } 16575 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16576 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16577 // Special handling of clients who are in the top state. 16578 // We *may* want to consider this process to be in the 16579 // top state as well, but only if there is not another 16580 // reason for it to be running. Being on the top is a 16581 // special state, meaning you are specifically running 16582 // for the current top app. If the process is already 16583 // running in the background for some other reason, it 16584 // is more important to continue considering it to be 16585 // in the background state. 16586 mayBeTop = true; 16587 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16588 } else { 16589 // Special handling for above-top states (persistent 16590 // processes). These should not bring the current process 16591 // into the top state, since they are not on top. Instead 16592 // give them the best state after that. 16593 clientProcState = 16594 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16595 } 16596 } 16597 if (procState > clientProcState) { 16598 procState = clientProcState; 16599 } 16600 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16601 schedGroup = Process.THREAD_GROUP_DEFAULT; 16602 } 16603 } 16604 // If the provider has external (non-framework) process 16605 // dependencies, ensure that its adjustment is at least 16606 // FOREGROUND_APP_ADJ. 16607 if (cpr.hasExternalProcessHandles()) { 16608 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16609 adj = ProcessList.FOREGROUND_APP_ADJ; 16610 schedGroup = Process.THREAD_GROUP_DEFAULT; 16611 app.cached = false; 16612 app.adjType = "provider"; 16613 app.adjTarget = cpr.name; 16614 } 16615 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16616 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16617 } 16618 } 16619 } 16620 16621 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16622 // A client of one of our services or providers is in the top state. We 16623 // *may* want to be in the top state, but not if we are already running in 16624 // the background for some other reason. For the decision here, we are going 16625 // to pick out a few specific states that we want to remain in when a client 16626 // is top (states that tend to be longer-term) and otherwise allow it to go 16627 // to the top state. 16628 switch (procState) { 16629 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16630 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16631 case ActivityManager.PROCESS_STATE_SERVICE: 16632 // These all are longer-term states, so pull them up to the top 16633 // of the background states, but not all the way to the top state. 16634 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16635 break; 16636 default: 16637 // Otherwise, top is a better choice, so take it. 16638 procState = ActivityManager.PROCESS_STATE_TOP; 16639 break; 16640 } 16641 } 16642 16643 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16644 if (app.hasClientActivities) { 16645 // This is a cached process, but with client activities. Mark it so. 16646 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16647 app.adjType = "cch-client-act"; 16648 } else if (app.treatLikeActivity) { 16649 // This is a cached process, but somebody wants us to treat it like it has 16650 // an activity, okay! 16651 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16652 app.adjType = "cch-as-act"; 16653 } 16654 } 16655 16656 if (adj == ProcessList.SERVICE_ADJ) { 16657 if (doingAll) { 16658 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16659 mNewNumServiceProcs++; 16660 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16661 if (!app.serviceb) { 16662 // This service isn't far enough down on the LRU list to 16663 // normally be a B service, but if we are low on RAM and it 16664 // is large we want to force it down since we would prefer to 16665 // keep launcher over it. 16666 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16667 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16668 app.serviceHighRam = true; 16669 app.serviceb = true; 16670 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16671 } else { 16672 mNewNumAServiceProcs++; 16673 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16674 } 16675 } else { 16676 app.serviceHighRam = false; 16677 } 16678 } 16679 if (app.serviceb) { 16680 adj = ProcessList.SERVICE_B_ADJ; 16681 } 16682 } 16683 16684 app.curRawAdj = adj; 16685 16686 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16687 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16688 if (adj > app.maxAdj) { 16689 adj = app.maxAdj; 16690 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16691 schedGroup = Process.THREAD_GROUP_DEFAULT; 16692 } 16693 } 16694 16695 // Do final modification to adj. Everything we do between here and applying 16696 // the final setAdj must be done in this function, because we will also use 16697 // it when computing the final cached adj later. Note that we don't need to 16698 // worry about this for max adj above, since max adj will always be used to 16699 // keep it out of the cached vaues. 16700 app.curAdj = app.modifyRawOomAdj(adj); 16701 app.curSchedGroup = schedGroup; 16702 app.curProcState = procState; 16703 app.foregroundActivities = foregroundActivities; 16704 16705 return app.curRawAdj; 16706 } 16707 16708 /** 16709 * Schedule PSS collection of a process. 16710 */ 16711 void requestPssLocked(ProcessRecord proc, int procState) { 16712 if (mPendingPssProcesses.contains(proc)) { 16713 return; 16714 } 16715 if (mPendingPssProcesses.size() == 0) { 16716 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16717 } 16718 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16719 proc.pssProcState = procState; 16720 mPendingPssProcesses.add(proc); 16721 } 16722 16723 /** 16724 * Schedule PSS collection of all processes. 16725 */ 16726 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16727 if (!always) { 16728 if (now < (mLastFullPssTime + 16729 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16730 return; 16731 } 16732 } 16733 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16734 mLastFullPssTime = now; 16735 mFullPssPending = true; 16736 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16737 mPendingPssProcesses.clear(); 16738 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16739 ProcessRecord app = mLruProcesses.get(i); 16740 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16741 app.pssProcState = app.setProcState; 16742 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16743 isSleeping(), now); 16744 mPendingPssProcesses.add(app); 16745 } 16746 } 16747 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16748 } 16749 16750 /** 16751 * Ask a given process to GC right now. 16752 */ 16753 final void performAppGcLocked(ProcessRecord app) { 16754 try { 16755 app.lastRequestedGc = SystemClock.uptimeMillis(); 16756 if (app.thread != null) { 16757 if (app.reportLowMemory) { 16758 app.reportLowMemory = false; 16759 app.thread.scheduleLowMemory(); 16760 } else { 16761 app.thread.processInBackground(); 16762 } 16763 } 16764 } catch (Exception e) { 16765 // whatever. 16766 } 16767 } 16768 16769 /** 16770 * Returns true if things are idle enough to perform GCs. 16771 */ 16772 private final boolean canGcNowLocked() { 16773 boolean processingBroadcasts = false; 16774 for (BroadcastQueue q : mBroadcastQueues) { 16775 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16776 processingBroadcasts = true; 16777 } 16778 } 16779 return !processingBroadcasts 16780 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16781 } 16782 16783 /** 16784 * Perform GCs on all processes that are waiting for it, but only 16785 * if things are idle. 16786 */ 16787 final void performAppGcsLocked() { 16788 final int N = mProcessesToGc.size(); 16789 if (N <= 0) { 16790 return; 16791 } 16792 if (canGcNowLocked()) { 16793 while (mProcessesToGc.size() > 0) { 16794 ProcessRecord proc = mProcessesToGc.remove(0); 16795 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16796 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16797 <= SystemClock.uptimeMillis()) { 16798 // To avoid spamming the system, we will GC processes one 16799 // at a time, waiting a few seconds between each. 16800 performAppGcLocked(proc); 16801 scheduleAppGcsLocked(); 16802 return; 16803 } else { 16804 // It hasn't been long enough since we last GCed this 16805 // process... put it in the list to wait for its time. 16806 addProcessToGcListLocked(proc); 16807 break; 16808 } 16809 } 16810 } 16811 16812 scheduleAppGcsLocked(); 16813 } 16814 } 16815 16816 /** 16817 * If all looks good, perform GCs on all processes waiting for them. 16818 */ 16819 final void performAppGcsIfAppropriateLocked() { 16820 if (canGcNowLocked()) { 16821 performAppGcsLocked(); 16822 return; 16823 } 16824 // Still not idle, wait some more. 16825 scheduleAppGcsLocked(); 16826 } 16827 16828 /** 16829 * Schedule the execution of all pending app GCs. 16830 */ 16831 final void scheduleAppGcsLocked() { 16832 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16833 16834 if (mProcessesToGc.size() > 0) { 16835 // Schedule a GC for the time to the next process. 16836 ProcessRecord proc = mProcessesToGc.get(0); 16837 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16838 16839 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16840 long now = SystemClock.uptimeMillis(); 16841 if (when < (now+GC_TIMEOUT)) { 16842 when = now + GC_TIMEOUT; 16843 } 16844 mHandler.sendMessageAtTime(msg, when); 16845 } 16846 } 16847 16848 /** 16849 * Add a process to the array of processes waiting to be GCed. Keeps the 16850 * list in sorted order by the last GC time. The process can't already be 16851 * on the list. 16852 */ 16853 final void addProcessToGcListLocked(ProcessRecord proc) { 16854 boolean added = false; 16855 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16856 if (mProcessesToGc.get(i).lastRequestedGc < 16857 proc.lastRequestedGc) { 16858 added = true; 16859 mProcessesToGc.add(i+1, proc); 16860 break; 16861 } 16862 } 16863 if (!added) { 16864 mProcessesToGc.add(0, proc); 16865 } 16866 } 16867 16868 /** 16869 * Set up to ask a process to GC itself. This will either do it 16870 * immediately, or put it on the list of processes to gc the next 16871 * time things are idle. 16872 */ 16873 final void scheduleAppGcLocked(ProcessRecord app) { 16874 long now = SystemClock.uptimeMillis(); 16875 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16876 return; 16877 } 16878 if (!mProcessesToGc.contains(app)) { 16879 addProcessToGcListLocked(app); 16880 scheduleAppGcsLocked(); 16881 } 16882 } 16883 16884 final void checkExcessivePowerUsageLocked(boolean doKills) { 16885 updateCpuStatsNow(); 16886 16887 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16888 boolean doWakeKills = doKills; 16889 boolean doCpuKills = doKills; 16890 if (mLastPowerCheckRealtime == 0) { 16891 doWakeKills = false; 16892 } 16893 if (mLastPowerCheckUptime == 0) { 16894 doCpuKills = false; 16895 } 16896 if (stats.isScreenOn()) { 16897 doWakeKills = false; 16898 } 16899 final long curRealtime = SystemClock.elapsedRealtime(); 16900 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16901 final long curUptime = SystemClock.uptimeMillis(); 16902 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16903 mLastPowerCheckRealtime = curRealtime; 16904 mLastPowerCheckUptime = curUptime; 16905 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16906 doWakeKills = false; 16907 } 16908 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16909 doCpuKills = false; 16910 } 16911 int i = mLruProcesses.size(); 16912 while (i > 0) { 16913 i--; 16914 ProcessRecord app = mLruProcesses.get(i); 16915 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16916 long wtime; 16917 synchronized (stats) { 16918 wtime = stats.getProcessWakeTime(app.info.uid, 16919 app.pid, curRealtime); 16920 } 16921 long wtimeUsed = wtime - app.lastWakeTime; 16922 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16923 if (DEBUG_POWER) { 16924 StringBuilder sb = new StringBuilder(128); 16925 sb.append("Wake for "); 16926 app.toShortString(sb); 16927 sb.append(": over "); 16928 TimeUtils.formatDuration(realtimeSince, sb); 16929 sb.append(" used "); 16930 TimeUtils.formatDuration(wtimeUsed, sb); 16931 sb.append(" ("); 16932 sb.append((wtimeUsed*100)/realtimeSince); 16933 sb.append("%)"); 16934 Slog.i(TAG, sb.toString()); 16935 sb.setLength(0); 16936 sb.append("CPU for "); 16937 app.toShortString(sb); 16938 sb.append(": over "); 16939 TimeUtils.formatDuration(uptimeSince, sb); 16940 sb.append(" used "); 16941 TimeUtils.formatDuration(cputimeUsed, sb); 16942 sb.append(" ("); 16943 sb.append((cputimeUsed*100)/uptimeSince); 16944 sb.append("%)"); 16945 Slog.i(TAG, sb.toString()); 16946 } 16947 // If a process has held a wake lock for more 16948 // than 50% of the time during this period, 16949 // that sounds bad. Kill! 16950 if (doWakeKills && realtimeSince > 0 16951 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16952 synchronized (stats) { 16953 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16954 realtimeSince, wtimeUsed); 16955 } 16956 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16957 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16958 } else if (doCpuKills && uptimeSince > 0 16959 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16960 synchronized (stats) { 16961 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16962 uptimeSince, cputimeUsed); 16963 } 16964 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16965 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16966 } else { 16967 app.lastWakeTime = wtime; 16968 app.lastCpuTime = app.curCpuTime; 16969 } 16970 } 16971 } 16972 } 16973 16974 private final boolean applyOomAdjLocked(ProcessRecord app, 16975 ProcessRecord TOP_APP, boolean doingAll, long now) { 16976 boolean success = true; 16977 16978 if (app.curRawAdj != app.setRawAdj) { 16979 app.setRawAdj = app.curRawAdj; 16980 } 16981 16982 int changes = 0; 16983 16984 if (app.curAdj != app.setAdj) { 16985 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16986 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16987 TAG, "Set " + app.pid + " " + app.processName + 16988 " adj " + app.curAdj + ": " + app.adjType); 16989 app.setAdj = app.curAdj; 16990 } 16991 16992 if (app.setSchedGroup != app.curSchedGroup) { 16993 app.setSchedGroup = app.curSchedGroup; 16994 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16995 "Setting process group of " + app.processName 16996 + " to " + app.curSchedGroup); 16997 if (app.waitingToKill != null && 16998 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16999 app.kill(app.waitingToKill, true); 17000 success = false; 17001 } else { 17002 if (true) { 17003 long oldId = Binder.clearCallingIdentity(); 17004 try { 17005 Process.setProcessGroup(app.pid, app.curSchedGroup); 17006 } catch (Exception e) { 17007 Slog.w(TAG, "Failed setting process group of " + app.pid 17008 + " to " + app.curSchedGroup); 17009 e.printStackTrace(); 17010 } finally { 17011 Binder.restoreCallingIdentity(oldId); 17012 } 17013 } else { 17014 if (app.thread != null) { 17015 try { 17016 app.thread.setSchedulingGroup(app.curSchedGroup); 17017 } catch (RemoteException e) { 17018 } 17019 } 17020 } 17021 Process.setSwappiness(app.pid, 17022 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17023 } 17024 } 17025 if (app.repForegroundActivities != app.foregroundActivities) { 17026 app.repForegroundActivities = app.foregroundActivities; 17027 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17028 } 17029 if (app.repProcState != app.curProcState) { 17030 app.repProcState = app.curProcState; 17031 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17032 if (app.thread != null) { 17033 try { 17034 if (false) { 17035 //RuntimeException h = new RuntimeException("here"); 17036 Slog.i(TAG, "Sending new process state " + app.repProcState 17037 + " to " + app /*, h*/); 17038 } 17039 app.thread.setProcessState(app.repProcState); 17040 } catch (RemoteException e) { 17041 } 17042 } 17043 } 17044 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17045 app.setProcState)) { 17046 app.lastStateTime = now; 17047 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17048 isSleeping(), now); 17049 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17050 + ProcessList.makeProcStateString(app.setProcState) + " to " 17051 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17052 + (app.nextPssTime-now) + ": " + app); 17053 } else { 17054 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17055 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17056 requestPssLocked(app, app.setProcState); 17057 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17058 isSleeping(), now); 17059 } else if (false && DEBUG_PSS) { 17060 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17061 } 17062 } 17063 if (app.setProcState != app.curProcState) { 17064 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17065 "Proc state change of " + app.processName 17066 + " to " + app.curProcState); 17067 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17068 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17069 if (setImportant && !curImportant) { 17070 // This app is no longer something we consider important enough to allow to 17071 // use arbitrary amounts of battery power. Note 17072 // its current wake lock time to later know to kill it if 17073 // it is not behaving well. 17074 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17075 synchronized (stats) { 17076 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17077 app.pid, SystemClock.elapsedRealtime()); 17078 } 17079 app.lastCpuTime = app.curCpuTime; 17080 17081 } 17082 app.setProcState = app.curProcState; 17083 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17084 app.notCachedSinceIdle = false; 17085 } 17086 if (!doingAll) { 17087 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17088 } else { 17089 app.procStateChanged = true; 17090 } 17091 } 17092 17093 if (changes != 0) { 17094 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17095 int i = mPendingProcessChanges.size()-1; 17096 ProcessChangeItem item = null; 17097 while (i >= 0) { 17098 item = mPendingProcessChanges.get(i); 17099 if (item.pid == app.pid) { 17100 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17101 break; 17102 } 17103 i--; 17104 } 17105 if (i < 0) { 17106 // No existing item in pending changes; need a new one. 17107 final int NA = mAvailProcessChanges.size(); 17108 if (NA > 0) { 17109 item = mAvailProcessChanges.remove(NA-1); 17110 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17111 } else { 17112 item = new ProcessChangeItem(); 17113 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17114 } 17115 item.changes = 0; 17116 item.pid = app.pid; 17117 item.uid = app.info.uid; 17118 if (mPendingProcessChanges.size() == 0) { 17119 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17120 "*** Enqueueing dispatch processes changed!"); 17121 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17122 } 17123 mPendingProcessChanges.add(item); 17124 } 17125 item.changes |= changes; 17126 item.processState = app.repProcState; 17127 item.foregroundActivities = app.repForegroundActivities; 17128 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17129 + Integer.toHexString(System.identityHashCode(item)) 17130 + " " + app.toShortString() + ": changes=" + item.changes 17131 + " procState=" + item.processState 17132 + " foreground=" + item.foregroundActivities 17133 + " type=" + app.adjType + " source=" + app.adjSource 17134 + " target=" + app.adjTarget); 17135 } 17136 17137 return success; 17138 } 17139 17140 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17141 if (proc.thread != null) { 17142 if (proc.baseProcessTracker != null) { 17143 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17144 } 17145 if (proc.repProcState >= 0) { 17146 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17147 proc.repProcState); 17148 } 17149 } 17150 } 17151 17152 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17153 ProcessRecord TOP_APP, boolean doingAll, long now) { 17154 if (app.thread == null) { 17155 return false; 17156 } 17157 17158 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17159 17160 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17161 } 17162 17163 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17164 boolean oomAdj) { 17165 if (isForeground != proc.foregroundServices) { 17166 proc.foregroundServices = isForeground; 17167 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17168 proc.info.uid); 17169 if (isForeground) { 17170 if (curProcs == null) { 17171 curProcs = new ArrayList<ProcessRecord>(); 17172 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17173 } 17174 if (!curProcs.contains(proc)) { 17175 curProcs.add(proc); 17176 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17177 proc.info.packageName, proc.info.uid); 17178 } 17179 } else { 17180 if (curProcs != null) { 17181 if (curProcs.remove(proc)) { 17182 mBatteryStatsService.noteEvent( 17183 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17184 proc.info.packageName, proc.info.uid); 17185 if (curProcs.size() <= 0) { 17186 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17187 } 17188 } 17189 } 17190 } 17191 if (oomAdj) { 17192 updateOomAdjLocked(); 17193 } 17194 } 17195 } 17196 17197 private final ActivityRecord resumedAppLocked() { 17198 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17199 String pkg; 17200 int uid; 17201 if (act != null) { 17202 pkg = act.packageName; 17203 uid = act.info.applicationInfo.uid; 17204 } else { 17205 pkg = null; 17206 uid = -1; 17207 } 17208 // Has the UID or resumed package name changed? 17209 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17210 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17211 if (mCurResumedPackage != null) { 17212 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17213 mCurResumedPackage, mCurResumedUid); 17214 } 17215 mCurResumedPackage = pkg; 17216 mCurResumedUid = uid; 17217 if (mCurResumedPackage != null) { 17218 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17219 mCurResumedPackage, mCurResumedUid); 17220 } 17221 } 17222 return act; 17223 } 17224 17225 final boolean updateOomAdjLocked(ProcessRecord app) { 17226 final ActivityRecord TOP_ACT = resumedAppLocked(); 17227 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17228 final boolean wasCached = app.cached; 17229 17230 mAdjSeq++; 17231 17232 // This is the desired cached adjusment we want to tell it to use. 17233 // If our app is currently cached, we know it, and that is it. Otherwise, 17234 // we don't know it yet, and it needs to now be cached we will then 17235 // need to do a complete oom adj. 17236 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17237 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17238 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17239 SystemClock.uptimeMillis()); 17240 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17241 // Changed to/from cached state, so apps after it in the LRU 17242 // list may also be changed. 17243 updateOomAdjLocked(); 17244 } 17245 return success; 17246 } 17247 17248 final void updateOomAdjLocked() { 17249 final ActivityRecord TOP_ACT = resumedAppLocked(); 17250 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17251 final long now = SystemClock.uptimeMillis(); 17252 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17253 final int N = mLruProcesses.size(); 17254 17255 if (false) { 17256 RuntimeException e = new RuntimeException(); 17257 e.fillInStackTrace(); 17258 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17259 } 17260 17261 mAdjSeq++; 17262 mNewNumServiceProcs = 0; 17263 mNewNumAServiceProcs = 0; 17264 17265 final int emptyProcessLimit; 17266 final int cachedProcessLimit; 17267 if (mProcessLimit <= 0) { 17268 emptyProcessLimit = cachedProcessLimit = 0; 17269 } else if (mProcessLimit == 1) { 17270 emptyProcessLimit = 1; 17271 cachedProcessLimit = 0; 17272 } else { 17273 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17274 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17275 } 17276 17277 // Let's determine how many processes we have running vs. 17278 // how many slots we have for background processes; we may want 17279 // to put multiple processes in a slot of there are enough of 17280 // them. 17281 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17282 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17283 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17284 if (numEmptyProcs > cachedProcessLimit) { 17285 // If there are more empty processes than our limit on cached 17286 // processes, then use the cached process limit for the factor. 17287 // This ensures that the really old empty processes get pushed 17288 // down to the bottom, so if we are running low on memory we will 17289 // have a better chance at keeping around more cached processes 17290 // instead of a gazillion empty processes. 17291 numEmptyProcs = cachedProcessLimit; 17292 } 17293 int emptyFactor = numEmptyProcs/numSlots; 17294 if (emptyFactor < 1) emptyFactor = 1; 17295 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17296 if (cachedFactor < 1) cachedFactor = 1; 17297 int stepCached = 0; 17298 int stepEmpty = 0; 17299 int numCached = 0; 17300 int numEmpty = 0; 17301 int numTrimming = 0; 17302 17303 mNumNonCachedProcs = 0; 17304 mNumCachedHiddenProcs = 0; 17305 17306 // First update the OOM adjustment for each of the 17307 // application processes based on their current state. 17308 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17309 int nextCachedAdj = curCachedAdj+1; 17310 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17311 int nextEmptyAdj = curEmptyAdj+2; 17312 for (int i=N-1; i>=0; i--) { 17313 ProcessRecord app = mLruProcesses.get(i); 17314 if (!app.killedByAm && app.thread != null) { 17315 app.procStateChanged = false; 17316 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17317 17318 // If we haven't yet assigned the final cached adj 17319 // to the process, do that now. 17320 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17321 switch (app.curProcState) { 17322 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17323 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17324 // This process is a cached process holding activities... 17325 // assign it the next cached value for that type, and then 17326 // step that cached level. 17327 app.curRawAdj = curCachedAdj; 17328 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17329 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17330 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17331 + ")"); 17332 if (curCachedAdj != nextCachedAdj) { 17333 stepCached++; 17334 if (stepCached >= cachedFactor) { 17335 stepCached = 0; 17336 curCachedAdj = nextCachedAdj; 17337 nextCachedAdj += 2; 17338 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17339 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17340 } 17341 } 17342 } 17343 break; 17344 default: 17345 // For everything else, assign next empty cached process 17346 // level and bump that up. Note that this means that 17347 // long-running services that have dropped down to the 17348 // cached level will be treated as empty (since their process 17349 // state is still as a service), which is what we want. 17350 app.curRawAdj = curEmptyAdj; 17351 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17352 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17353 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17354 + ")"); 17355 if (curEmptyAdj != nextEmptyAdj) { 17356 stepEmpty++; 17357 if (stepEmpty >= emptyFactor) { 17358 stepEmpty = 0; 17359 curEmptyAdj = nextEmptyAdj; 17360 nextEmptyAdj += 2; 17361 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17362 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17363 } 17364 } 17365 } 17366 break; 17367 } 17368 } 17369 17370 applyOomAdjLocked(app, TOP_APP, true, now); 17371 17372 // Count the number of process types. 17373 switch (app.curProcState) { 17374 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17375 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17376 mNumCachedHiddenProcs++; 17377 numCached++; 17378 if (numCached > cachedProcessLimit) { 17379 app.kill("cached #" + numCached, true); 17380 } 17381 break; 17382 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17383 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17384 && app.lastActivityTime < oldTime) { 17385 app.kill("empty for " 17386 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17387 / 1000) + "s", true); 17388 } else { 17389 numEmpty++; 17390 if (numEmpty > emptyProcessLimit) { 17391 app.kill("empty #" + numEmpty, true); 17392 } 17393 } 17394 break; 17395 default: 17396 mNumNonCachedProcs++; 17397 break; 17398 } 17399 17400 if (app.isolated && app.services.size() <= 0) { 17401 // If this is an isolated process, and there are no 17402 // services running in it, then the process is no longer 17403 // needed. We agressively kill these because we can by 17404 // definition not re-use the same process again, and it is 17405 // good to avoid having whatever code was running in them 17406 // left sitting around after no longer needed. 17407 app.kill("isolated not needed", true); 17408 } 17409 17410 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17411 && !app.killedByAm) { 17412 numTrimming++; 17413 } 17414 } 17415 } 17416 17417 mNumServiceProcs = mNewNumServiceProcs; 17418 17419 // Now determine the memory trimming level of background processes. 17420 // Unfortunately we need to start at the back of the list to do this 17421 // properly. We only do this if the number of background apps we 17422 // are managing to keep around is less than half the maximum we desire; 17423 // if we are keeping a good number around, we'll let them use whatever 17424 // memory they want. 17425 final int numCachedAndEmpty = numCached + numEmpty; 17426 int memFactor; 17427 if (numCached <= ProcessList.TRIM_CACHED_APPS 17428 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17429 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17430 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17431 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17432 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17433 } else { 17434 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17435 } 17436 } else { 17437 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17438 } 17439 // We always allow the memory level to go up (better). We only allow it to go 17440 // down if we are in a state where that is allowed, *and* the total number of processes 17441 // has gone down since last time. 17442 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17443 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17444 + " last=" + mLastNumProcesses); 17445 if (memFactor > mLastMemoryLevel) { 17446 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17447 memFactor = mLastMemoryLevel; 17448 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17449 } 17450 } 17451 mLastMemoryLevel = memFactor; 17452 mLastNumProcesses = mLruProcesses.size(); 17453 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17454 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17455 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17456 if (mLowRamStartTime == 0) { 17457 mLowRamStartTime = now; 17458 } 17459 int step = 0; 17460 int fgTrimLevel; 17461 switch (memFactor) { 17462 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17463 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17464 break; 17465 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17466 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17467 break; 17468 default: 17469 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17470 break; 17471 } 17472 int factor = numTrimming/3; 17473 int minFactor = 2; 17474 if (mHomeProcess != null) minFactor++; 17475 if (mPreviousProcess != null) minFactor++; 17476 if (factor < minFactor) factor = minFactor; 17477 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17478 for (int i=N-1; i>=0; i--) { 17479 ProcessRecord app = mLruProcesses.get(i); 17480 if (allChanged || app.procStateChanged) { 17481 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17482 app.procStateChanged = false; 17483 } 17484 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17485 && !app.killedByAm) { 17486 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17487 try { 17488 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17489 "Trimming memory of " + app.processName 17490 + " to " + curLevel); 17491 app.thread.scheduleTrimMemory(curLevel); 17492 } catch (RemoteException e) { 17493 } 17494 if (false) { 17495 // For now we won't do this; our memory trimming seems 17496 // to be good enough at this point that destroying 17497 // activities causes more harm than good. 17498 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17499 && app != mHomeProcess && app != mPreviousProcess) { 17500 // Need to do this on its own message because the stack may not 17501 // be in a consistent state at this point. 17502 // For these apps we will also finish their activities 17503 // to help them free memory. 17504 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17505 } 17506 } 17507 } 17508 app.trimMemoryLevel = curLevel; 17509 step++; 17510 if (step >= factor) { 17511 step = 0; 17512 switch (curLevel) { 17513 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17514 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17515 break; 17516 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17517 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17518 break; 17519 } 17520 } 17521 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17522 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17523 && app.thread != null) { 17524 try { 17525 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17526 "Trimming memory of heavy-weight " + app.processName 17527 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17528 app.thread.scheduleTrimMemory( 17529 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17530 } catch (RemoteException e) { 17531 } 17532 } 17533 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17534 } else { 17535 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17536 || app.systemNoUi) && app.pendingUiClean) { 17537 // If this application is now in the background and it 17538 // had done UI, then give it the special trim level to 17539 // have it free UI resources. 17540 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17541 if (app.trimMemoryLevel < level && app.thread != null) { 17542 try { 17543 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17544 "Trimming memory of bg-ui " + app.processName 17545 + " to " + level); 17546 app.thread.scheduleTrimMemory(level); 17547 } catch (RemoteException e) { 17548 } 17549 } 17550 app.pendingUiClean = false; 17551 } 17552 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17553 try { 17554 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17555 "Trimming memory of fg " + app.processName 17556 + " to " + fgTrimLevel); 17557 app.thread.scheduleTrimMemory(fgTrimLevel); 17558 } catch (RemoteException e) { 17559 } 17560 } 17561 app.trimMemoryLevel = fgTrimLevel; 17562 } 17563 } 17564 } else { 17565 if (mLowRamStartTime != 0) { 17566 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17567 mLowRamStartTime = 0; 17568 } 17569 for (int i=N-1; i>=0; i--) { 17570 ProcessRecord app = mLruProcesses.get(i); 17571 if (allChanged || app.procStateChanged) { 17572 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17573 app.procStateChanged = false; 17574 } 17575 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17576 || app.systemNoUi) && app.pendingUiClean) { 17577 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17578 && app.thread != null) { 17579 try { 17580 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17581 "Trimming memory of ui hidden " + app.processName 17582 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17583 app.thread.scheduleTrimMemory( 17584 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17585 } catch (RemoteException e) { 17586 } 17587 } 17588 app.pendingUiClean = false; 17589 } 17590 app.trimMemoryLevel = 0; 17591 } 17592 } 17593 17594 if (mAlwaysFinishActivities) { 17595 // Need to do this on its own message because the stack may not 17596 // be in a consistent state at this point. 17597 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17598 } 17599 17600 if (allChanged) { 17601 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17602 } 17603 17604 if (mProcessStats.shouldWriteNowLocked(now)) { 17605 mHandler.post(new Runnable() { 17606 @Override public void run() { 17607 synchronized (ActivityManagerService.this) { 17608 mProcessStats.writeStateAsyncLocked(); 17609 } 17610 } 17611 }); 17612 } 17613 17614 if (DEBUG_OOM_ADJ) { 17615 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17616 } 17617 } 17618 17619 final void trimApplications() { 17620 synchronized (this) { 17621 int i; 17622 17623 // First remove any unused application processes whose package 17624 // has been removed. 17625 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17626 final ProcessRecord app = mRemovedProcesses.get(i); 17627 if (app.activities.size() == 0 17628 && app.curReceiver == null && app.services.size() == 0) { 17629 Slog.i( 17630 TAG, "Exiting empty application process " 17631 + app.processName + " (" 17632 + (app.thread != null ? app.thread.asBinder() : null) 17633 + ")\n"); 17634 if (app.pid > 0 && app.pid != MY_PID) { 17635 app.kill("empty", false); 17636 } else { 17637 try { 17638 app.thread.scheduleExit(); 17639 } catch (Exception e) { 17640 // Ignore exceptions. 17641 } 17642 } 17643 cleanUpApplicationRecordLocked(app, false, true, -1); 17644 mRemovedProcesses.remove(i); 17645 17646 if (app.persistent) { 17647 addAppLocked(app.info, false, null /* ABI override */); 17648 } 17649 } 17650 } 17651 17652 // Now update the oom adj for all processes. 17653 updateOomAdjLocked(); 17654 } 17655 } 17656 17657 /** This method sends the specified signal to each of the persistent apps */ 17658 public void signalPersistentProcesses(int sig) throws RemoteException { 17659 if (sig != Process.SIGNAL_USR1) { 17660 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17661 } 17662 17663 synchronized (this) { 17664 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17665 != PackageManager.PERMISSION_GRANTED) { 17666 throw new SecurityException("Requires permission " 17667 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17668 } 17669 17670 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17671 ProcessRecord r = mLruProcesses.get(i); 17672 if (r.thread != null && r.persistent) { 17673 Process.sendSignal(r.pid, sig); 17674 } 17675 } 17676 } 17677 } 17678 17679 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17680 if (proc == null || proc == mProfileProc) { 17681 proc = mProfileProc; 17682 profileType = mProfileType; 17683 clearProfilerLocked(); 17684 } 17685 if (proc == null) { 17686 return; 17687 } 17688 try { 17689 proc.thread.profilerControl(false, null, profileType); 17690 } catch (RemoteException e) { 17691 throw new IllegalStateException("Process disappeared"); 17692 } 17693 } 17694 17695 private void clearProfilerLocked() { 17696 if (mProfileFd != null) { 17697 try { 17698 mProfileFd.close(); 17699 } catch (IOException e) { 17700 } 17701 } 17702 mProfileApp = null; 17703 mProfileProc = null; 17704 mProfileFile = null; 17705 mProfileType = 0; 17706 mAutoStopProfiler = false; 17707 mSamplingInterval = 0; 17708 } 17709 17710 public boolean profileControl(String process, int userId, boolean start, 17711 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17712 17713 try { 17714 synchronized (this) { 17715 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17716 // its own permission. 17717 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17718 != PackageManager.PERMISSION_GRANTED) { 17719 throw new SecurityException("Requires permission " 17720 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17721 } 17722 17723 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17724 throw new IllegalArgumentException("null profile info or fd"); 17725 } 17726 17727 ProcessRecord proc = null; 17728 if (process != null) { 17729 proc = findProcessLocked(process, userId, "profileControl"); 17730 } 17731 17732 if (start && (proc == null || proc.thread == null)) { 17733 throw new IllegalArgumentException("Unknown process: " + process); 17734 } 17735 17736 if (start) { 17737 stopProfilerLocked(null, 0); 17738 setProfileApp(proc.info, proc.processName, profilerInfo); 17739 mProfileProc = proc; 17740 mProfileType = profileType; 17741 ParcelFileDescriptor fd = profilerInfo.profileFd; 17742 try { 17743 fd = fd.dup(); 17744 } catch (IOException e) { 17745 fd = null; 17746 } 17747 profilerInfo.profileFd = fd; 17748 proc.thread.profilerControl(start, profilerInfo, profileType); 17749 fd = null; 17750 mProfileFd = null; 17751 } else { 17752 stopProfilerLocked(proc, profileType); 17753 if (profilerInfo != null && profilerInfo.profileFd != null) { 17754 try { 17755 profilerInfo.profileFd.close(); 17756 } catch (IOException e) { 17757 } 17758 } 17759 } 17760 17761 return true; 17762 } 17763 } catch (RemoteException e) { 17764 throw new IllegalStateException("Process disappeared"); 17765 } finally { 17766 if (profilerInfo != null && profilerInfo.profileFd != null) { 17767 try { 17768 profilerInfo.profileFd.close(); 17769 } catch (IOException e) { 17770 } 17771 } 17772 } 17773 } 17774 17775 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17776 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17777 userId, true, ALLOW_FULL_ONLY, callName, null); 17778 ProcessRecord proc = null; 17779 try { 17780 int pid = Integer.parseInt(process); 17781 synchronized (mPidsSelfLocked) { 17782 proc = mPidsSelfLocked.get(pid); 17783 } 17784 } catch (NumberFormatException e) { 17785 } 17786 17787 if (proc == null) { 17788 ArrayMap<String, SparseArray<ProcessRecord>> all 17789 = mProcessNames.getMap(); 17790 SparseArray<ProcessRecord> procs = all.get(process); 17791 if (procs != null && procs.size() > 0) { 17792 proc = procs.valueAt(0); 17793 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17794 for (int i=1; i<procs.size(); i++) { 17795 ProcessRecord thisProc = procs.valueAt(i); 17796 if (thisProc.userId == userId) { 17797 proc = thisProc; 17798 break; 17799 } 17800 } 17801 } 17802 } 17803 } 17804 17805 return proc; 17806 } 17807 17808 public boolean dumpHeap(String process, int userId, boolean managed, 17809 String path, ParcelFileDescriptor fd) throws RemoteException { 17810 17811 try { 17812 synchronized (this) { 17813 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17814 // its own permission (same as profileControl). 17815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17816 != PackageManager.PERMISSION_GRANTED) { 17817 throw new SecurityException("Requires permission " 17818 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17819 } 17820 17821 if (fd == null) { 17822 throw new IllegalArgumentException("null fd"); 17823 } 17824 17825 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17826 if (proc == null || proc.thread == null) { 17827 throw new IllegalArgumentException("Unknown process: " + process); 17828 } 17829 17830 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17831 if (!isDebuggable) { 17832 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17833 throw new SecurityException("Process not debuggable: " + proc); 17834 } 17835 } 17836 17837 proc.thread.dumpHeap(managed, path, fd); 17838 fd = null; 17839 return true; 17840 } 17841 } catch (RemoteException e) { 17842 throw new IllegalStateException("Process disappeared"); 17843 } finally { 17844 if (fd != null) { 17845 try { 17846 fd.close(); 17847 } catch (IOException e) { 17848 } 17849 } 17850 } 17851 } 17852 17853 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17854 public void monitor() { 17855 synchronized (this) { } 17856 } 17857 17858 void onCoreSettingsChange(Bundle settings) { 17859 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17860 ProcessRecord processRecord = mLruProcesses.get(i); 17861 try { 17862 if (processRecord.thread != null) { 17863 processRecord.thread.setCoreSettings(settings); 17864 } 17865 } catch (RemoteException re) { 17866 /* ignore */ 17867 } 17868 } 17869 } 17870 17871 // Multi-user methods 17872 17873 /** 17874 * Start user, if its not already running, but don't bring it to foreground. 17875 */ 17876 @Override 17877 public boolean startUserInBackground(final int userId) { 17878 return startUser(userId, /* foreground */ false); 17879 } 17880 17881 /** 17882 * Start user, if its not already running, and bring it to foreground. 17883 */ 17884 boolean startUserInForeground(final int userId, Dialog dlg) { 17885 boolean result = startUser(userId, /* foreground */ true); 17886 dlg.dismiss(); 17887 return result; 17888 } 17889 17890 /** 17891 * Refreshes the list of users related to the current user when either a 17892 * user switch happens or when a new related user is started in the 17893 * background. 17894 */ 17895 private void updateCurrentProfileIdsLocked() { 17896 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17897 mCurrentUserId, false /* enabledOnly */); 17898 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17899 for (int i = 0; i < currentProfileIds.length; i++) { 17900 currentProfileIds[i] = profiles.get(i).id; 17901 } 17902 mCurrentProfileIds = currentProfileIds; 17903 17904 synchronized (mUserProfileGroupIdsSelfLocked) { 17905 mUserProfileGroupIdsSelfLocked.clear(); 17906 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17907 for (int i = 0; i < users.size(); i++) { 17908 UserInfo user = users.get(i); 17909 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17910 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17911 } 17912 } 17913 } 17914 } 17915 17916 private Set getProfileIdsLocked(int userId) { 17917 Set userIds = new HashSet<Integer>(); 17918 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17919 userId, false /* enabledOnly */); 17920 for (UserInfo user : profiles) { 17921 userIds.add(Integer.valueOf(user.id)); 17922 } 17923 return userIds; 17924 } 17925 17926 @Override 17927 public boolean switchUser(final int userId) { 17928 String userName; 17929 synchronized (this) { 17930 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17931 if (userInfo == null) { 17932 Slog.w(TAG, "No user info for user #" + userId); 17933 return false; 17934 } 17935 if (userInfo.isManagedProfile()) { 17936 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17937 return false; 17938 } 17939 userName = userInfo.name; 17940 } 17941 mHandler.removeMessages(START_USER_SWITCH_MSG); 17942 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17943 return true; 17944 } 17945 17946 private void showUserSwitchDialog(int userId, String userName) { 17947 // The dialog will show and then initiate the user switch by calling startUserInForeground 17948 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17949 true /* above system */); 17950 d.show(); 17951 } 17952 17953 private boolean startUser(final int userId, final boolean foreground) { 17954 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17955 != PackageManager.PERMISSION_GRANTED) { 17956 String msg = "Permission Denial: switchUser() from pid=" 17957 + Binder.getCallingPid() 17958 + ", uid=" + Binder.getCallingUid() 17959 + " requires " + INTERACT_ACROSS_USERS_FULL; 17960 Slog.w(TAG, msg); 17961 throw new SecurityException(msg); 17962 } 17963 17964 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17965 17966 final long ident = Binder.clearCallingIdentity(); 17967 try { 17968 synchronized (this) { 17969 final int oldUserId = mCurrentUserId; 17970 if (oldUserId == userId) { 17971 return true; 17972 } 17973 17974 mStackSupervisor.setLockTaskModeLocked(null, false); 17975 17976 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17977 if (userInfo == null) { 17978 Slog.w(TAG, "No user info for user #" + userId); 17979 return false; 17980 } 17981 if (foreground && userInfo.isManagedProfile()) { 17982 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17983 return false; 17984 } 17985 17986 if (foreground) { 17987 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17988 R.anim.screen_user_enter); 17989 } 17990 17991 boolean needStart = false; 17992 17993 // If the user we are switching to is not currently started, then 17994 // we need to start it now. 17995 if (mStartedUsers.get(userId) == null) { 17996 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17997 updateStartedUserArrayLocked(); 17998 needStart = true; 17999 } 18000 18001 final Integer userIdInt = Integer.valueOf(userId); 18002 mUserLru.remove(userIdInt); 18003 mUserLru.add(userIdInt); 18004 18005 if (foreground) { 18006 mCurrentUserId = userId; 18007 updateCurrentProfileIdsLocked(); 18008 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18009 // Once the internal notion of the active user has switched, we lock the device 18010 // with the option to show the user switcher on the keyguard. 18011 mWindowManager.lockNow(null); 18012 } else { 18013 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18014 updateCurrentProfileIdsLocked(); 18015 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18016 mUserLru.remove(currentUserIdInt); 18017 mUserLru.add(currentUserIdInt); 18018 } 18019 18020 final UserStartedState uss = mStartedUsers.get(userId); 18021 18022 // Make sure user is in the started state. If it is currently 18023 // stopping, we need to knock that off. 18024 if (uss.mState == UserStartedState.STATE_STOPPING) { 18025 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18026 // so we can just fairly silently bring the user back from 18027 // the almost-dead. 18028 uss.mState = UserStartedState.STATE_RUNNING; 18029 updateStartedUserArrayLocked(); 18030 needStart = true; 18031 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18032 // This means ACTION_SHUTDOWN has been sent, so we will 18033 // need to treat this as a new boot of the user. 18034 uss.mState = UserStartedState.STATE_BOOTING; 18035 updateStartedUserArrayLocked(); 18036 needStart = true; 18037 } 18038 18039 if (uss.mState == UserStartedState.STATE_BOOTING) { 18040 // Booting up a new user, need to tell system services about it. 18041 // Note that this is on the same handler as scheduling of broadcasts, 18042 // which is important because it needs to go first. 18043 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18044 } 18045 18046 if (foreground) { 18047 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18048 oldUserId)); 18049 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18050 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18051 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18052 oldUserId, userId, uss)); 18053 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18054 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18055 } 18056 18057 if (needStart) { 18058 // Send USER_STARTED broadcast 18059 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18060 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18061 | Intent.FLAG_RECEIVER_FOREGROUND); 18062 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18063 broadcastIntentLocked(null, null, intent, 18064 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18065 false, false, MY_PID, Process.SYSTEM_UID, userId); 18066 } 18067 18068 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18069 if (userId != UserHandle.USER_OWNER) { 18070 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18071 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18072 broadcastIntentLocked(null, null, intent, null, 18073 new IIntentReceiver.Stub() { 18074 public void performReceive(Intent intent, int resultCode, 18075 String data, Bundle extras, boolean ordered, 18076 boolean sticky, int sendingUser) { 18077 onUserInitialized(uss, foreground, oldUserId, userId); 18078 } 18079 }, 0, null, null, null, AppOpsManager.OP_NONE, 18080 true, false, MY_PID, Process.SYSTEM_UID, 18081 userId); 18082 uss.initializing = true; 18083 } else { 18084 getUserManagerLocked().makeInitialized(userInfo.id); 18085 } 18086 } 18087 18088 if (foreground) { 18089 if (!uss.initializing) { 18090 moveUserToForeground(uss, oldUserId, userId); 18091 } 18092 } else { 18093 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18094 } 18095 18096 if (needStart) { 18097 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18098 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18099 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18100 broadcastIntentLocked(null, null, intent, 18101 null, new IIntentReceiver.Stub() { 18102 @Override 18103 public void performReceive(Intent intent, int resultCode, String data, 18104 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18105 throws RemoteException { 18106 } 18107 }, 0, null, null, 18108 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18109 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18110 } 18111 } 18112 } finally { 18113 Binder.restoreCallingIdentity(ident); 18114 } 18115 18116 return true; 18117 } 18118 18119 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18120 long ident = Binder.clearCallingIdentity(); 18121 try { 18122 Intent intent; 18123 if (oldUserId >= 0) { 18124 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18125 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18126 int count = profiles.size(); 18127 for (int i = 0; i < count; i++) { 18128 int profileUserId = profiles.get(i).id; 18129 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18130 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18131 | Intent.FLAG_RECEIVER_FOREGROUND); 18132 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18133 broadcastIntentLocked(null, null, intent, 18134 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18135 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18136 } 18137 } 18138 if (newUserId >= 0) { 18139 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18140 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18141 int count = profiles.size(); 18142 for (int i = 0; i < count; i++) { 18143 int profileUserId = profiles.get(i).id; 18144 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18145 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18146 | Intent.FLAG_RECEIVER_FOREGROUND); 18147 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18148 broadcastIntentLocked(null, null, intent, 18149 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18150 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18151 } 18152 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18154 | Intent.FLAG_RECEIVER_FOREGROUND); 18155 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18156 broadcastIntentLocked(null, null, intent, 18157 null, null, 0, null, null, 18158 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18159 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18160 } 18161 } finally { 18162 Binder.restoreCallingIdentity(ident); 18163 } 18164 } 18165 18166 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18167 final int newUserId) { 18168 final int N = mUserSwitchObservers.beginBroadcast(); 18169 if (N > 0) { 18170 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18171 int mCount = 0; 18172 @Override 18173 public void sendResult(Bundle data) throws RemoteException { 18174 synchronized (ActivityManagerService.this) { 18175 if (mCurUserSwitchCallback == this) { 18176 mCount++; 18177 if (mCount == N) { 18178 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18179 } 18180 } 18181 } 18182 } 18183 }; 18184 synchronized (this) { 18185 uss.switching = true; 18186 mCurUserSwitchCallback = callback; 18187 } 18188 for (int i=0; i<N; i++) { 18189 try { 18190 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18191 newUserId, callback); 18192 } catch (RemoteException e) { 18193 } 18194 } 18195 } else { 18196 synchronized (this) { 18197 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18198 } 18199 } 18200 mUserSwitchObservers.finishBroadcast(); 18201 } 18202 18203 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18204 synchronized (this) { 18205 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18206 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18207 } 18208 } 18209 18210 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18211 mCurUserSwitchCallback = null; 18212 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18213 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18214 oldUserId, newUserId, uss)); 18215 } 18216 18217 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18218 synchronized (this) { 18219 if (foreground) { 18220 moveUserToForeground(uss, oldUserId, newUserId); 18221 } 18222 } 18223 18224 completeSwitchAndInitalize(uss, newUserId, true, false); 18225 } 18226 18227 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18228 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18229 if (homeInFront) { 18230 startHomeActivityLocked(newUserId); 18231 } else { 18232 mStackSupervisor.resumeTopActivitiesLocked(); 18233 } 18234 EventLogTags.writeAmSwitchUser(newUserId); 18235 getUserManagerLocked().userForeground(newUserId); 18236 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18237 } 18238 18239 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18240 completeSwitchAndInitalize(uss, newUserId, false, true); 18241 } 18242 18243 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18244 boolean clearInitializing, boolean clearSwitching) { 18245 boolean unfrozen = false; 18246 synchronized (this) { 18247 if (clearInitializing) { 18248 uss.initializing = false; 18249 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18250 } 18251 if (clearSwitching) { 18252 uss.switching = false; 18253 } 18254 if (!uss.switching && !uss.initializing) { 18255 mWindowManager.stopFreezingScreen(); 18256 unfrozen = true; 18257 } 18258 } 18259 if (unfrozen) { 18260 final int N = mUserSwitchObservers.beginBroadcast(); 18261 for (int i=0; i<N; i++) { 18262 try { 18263 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18264 } catch (RemoteException e) { 18265 } 18266 } 18267 mUserSwitchObservers.finishBroadcast(); 18268 } 18269 } 18270 18271 void scheduleStartProfilesLocked() { 18272 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18273 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18274 DateUtils.SECOND_IN_MILLIS); 18275 } 18276 } 18277 18278 void startProfilesLocked() { 18279 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18280 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18281 mCurrentUserId, false /* enabledOnly */); 18282 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18283 for (UserInfo user : profiles) { 18284 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18285 && user.id != mCurrentUserId) { 18286 toStart.add(user); 18287 } 18288 } 18289 final int n = toStart.size(); 18290 int i = 0; 18291 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18292 startUserInBackground(toStart.get(i).id); 18293 } 18294 if (i < n) { 18295 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18296 } 18297 } 18298 18299 void finishUserBoot(UserStartedState uss) { 18300 synchronized (this) { 18301 if (uss.mState == UserStartedState.STATE_BOOTING 18302 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18303 uss.mState = UserStartedState.STATE_RUNNING; 18304 final int userId = uss.mHandle.getIdentifier(); 18305 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18306 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18307 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18308 broadcastIntentLocked(null, null, intent, 18309 null, null, 0, null, null, 18310 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18311 true, false, MY_PID, Process.SYSTEM_UID, userId); 18312 } 18313 } 18314 } 18315 18316 void finishUserSwitch(UserStartedState uss) { 18317 synchronized (this) { 18318 finishUserBoot(uss); 18319 18320 startProfilesLocked(); 18321 18322 int num = mUserLru.size(); 18323 int i = 0; 18324 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18325 Integer oldUserId = mUserLru.get(i); 18326 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18327 if (oldUss == null) { 18328 // Shouldn't happen, but be sane if it does. 18329 mUserLru.remove(i); 18330 num--; 18331 continue; 18332 } 18333 if (oldUss.mState == UserStartedState.STATE_STOPPING 18334 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18335 // This user is already stopping, doesn't count. 18336 num--; 18337 i++; 18338 continue; 18339 } 18340 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18341 // Owner and current can't be stopped, but count as running. 18342 i++; 18343 continue; 18344 } 18345 // This is a user to be stopped. 18346 stopUserLocked(oldUserId, null); 18347 num--; 18348 i++; 18349 } 18350 } 18351 } 18352 18353 @Override 18354 public int stopUser(final int userId, final IStopUserCallback callback) { 18355 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18356 != PackageManager.PERMISSION_GRANTED) { 18357 String msg = "Permission Denial: switchUser() from pid=" 18358 + Binder.getCallingPid() 18359 + ", uid=" + Binder.getCallingUid() 18360 + " requires " + INTERACT_ACROSS_USERS_FULL; 18361 Slog.w(TAG, msg); 18362 throw new SecurityException(msg); 18363 } 18364 if (userId <= 0) { 18365 throw new IllegalArgumentException("Can't stop primary user " + userId); 18366 } 18367 synchronized (this) { 18368 return stopUserLocked(userId, callback); 18369 } 18370 } 18371 18372 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18373 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18374 if (mCurrentUserId == userId) { 18375 return ActivityManager.USER_OP_IS_CURRENT; 18376 } 18377 18378 final UserStartedState uss = mStartedUsers.get(userId); 18379 if (uss == null) { 18380 // User is not started, nothing to do... but we do need to 18381 // callback if requested. 18382 if (callback != null) { 18383 mHandler.post(new Runnable() { 18384 @Override 18385 public void run() { 18386 try { 18387 callback.userStopped(userId); 18388 } catch (RemoteException e) { 18389 } 18390 } 18391 }); 18392 } 18393 return ActivityManager.USER_OP_SUCCESS; 18394 } 18395 18396 if (callback != null) { 18397 uss.mStopCallbacks.add(callback); 18398 } 18399 18400 if (uss.mState != UserStartedState.STATE_STOPPING 18401 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18402 uss.mState = UserStartedState.STATE_STOPPING; 18403 updateStartedUserArrayLocked(); 18404 18405 long ident = Binder.clearCallingIdentity(); 18406 try { 18407 // We are going to broadcast ACTION_USER_STOPPING and then 18408 // once that is done send a final ACTION_SHUTDOWN and then 18409 // stop the user. 18410 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18411 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18412 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18413 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18414 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18415 // This is the result receiver for the final shutdown broadcast. 18416 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18417 @Override 18418 public void performReceive(Intent intent, int resultCode, String data, 18419 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18420 finishUserStop(uss); 18421 } 18422 }; 18423 // This is the result receiver for the initial stopping broadcast. 18424 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18425 @Override 18426 public void performReceive(Intent intent, int resultCode, String data, 18427 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18428 // On to the next. 18429 synchronized (ActivityManagerService.this) { 18430 if (uss.mState != UserStartedState.STATE_STOPPING) { 18431 // Whoops, we are being started back up. Abort, abort! 18432 return; 18433 } 18434 uss.mState = UserStartedState.STATE_SHUTDOWN; 18435 } 18436 mBatteryStatsService.noteEvent( 18437 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18438 Integer.toString(userId), userId); 18439 mSystemServiceManager.stopUser(userId); 18440 broadcastIntentLocked(null, null, shutdownIntent, 18441 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18442 true, false, MY_PID, Process.SYSTEM_UID, userId); 18443 } 18444 }; 18445 // Kick things off. 18446 broadcastIntentLocked(null, null, stoppingIntent, 18447 null, stoppingReceiver, 0, null, null, 18448 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18449 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18450 } finally { 18451 Binder.restoreCallingIdentity(ident); 18452 } 18453 } 18454 18455 return ActivityManager.USER_OP_SUCCESS; 18456 } 18457 18458 void finishUserStop(UserStartedState uss) { 18459 final int userId = uss.mHandle.getIdentifier(); 18460 boolean stopped; 18461 ArrayList<IStopUserCallback> callbacks; 18462 synchronized (this) { 18463 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18464 if (mStartedUsers.get(userId) != uss) { 18465 stopped = false; 18466 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18467 stopped = false; 18468 } else { 18469 stopped = true; 18470 // User can no longer run. 18471 mStartedUsers.remove(userId); 18472 mUserLru.remove(Integer.valueOf(userId)); 18473 updateStartedUserArrayLocked(); 18474 18475 // Clean up all state and processes associated with the user. 18476 // Kill all the processes for the user. 18477 forceStopUserLocked(userId, "finish user"); 18478 } 18479 18480 // Explicitly remove the old information in mRecentTasks. 18481 removeRecentTasksForUserLocked(userId); 18482 } 18483 18484 for (int i=0; i<callbacks.size(); i++) { 18485 try { 18486 if (stopped) callbacks.get(i).userStopped(userId); 18487 else callbacks.get(i).userStopAborted(userId); 18488 } catch (RemoteException e) { 18489 } 18490 } 18491 18492 if (stopped) { 18493 mSystemServiceManager.cleanupUser(userId); 18494 synchronized (this) { 18495 mStackSupervisor.removeUserLocked(userId); 18496 } 18497 } 18498 } 18499 18500 @Override 18501 public UserInfo getCurrentUser() { 18502 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18503 != PackageManager.PERMISSION_GRANTED) && ( 18504 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18505 != PackageManager.PERMISSION_GRANTED)) { 18506 String msg = "Permission Denial: getCurrentUser() from pid=" 18507 + Binder.getCallingPid() 18508 + ", uid=" + Binder.getCallingUid() 18509 + " requires " + INTERACT_ACROSS_USERS; 18510 Slog.w(TAG, msg); 18511 throw new SecurityException(msg); 18512 } 18513 synchronized (this) { 18514 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18515 } 18516 } 18517 18518 int getCurrentUserIdLocked() { 18519 return mCurrentUserId; 18520 } 18521 18522 @Override 18523 public boolean isUserRunning(int userId, boolean orStopped) { 18524 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18525 != PackageManager.PERMISSION_GRANTED) { 18526 String msg = "Permission Denial: isUserRunning() from pid=" 18527 + Binder.getCallingPid() 18528 + ", uid=" + Binder.getCallingUid() 18529 + " requires " + INTERACT_ACROSS_USERS; 18530 Slog.w(TAG, msg); 18531 throw new SecurityException(msg); 18532 } 18533 synchronized (this) { 18534 return isUserRunningLocked(userId, orStopped); 18535 } 18536 } 18537 18538 boolean isUserRunningLocked(int userId, boolean orStopped) { 18539 UserStartedState state = mStartedUsers.get(userId); 18540 if (state == null) { 18541 return false; 18542 } 18543 if (orStopped) { 18544 return true; 18545 } 18546 return state.mState != UserStartedState.STATE_STOPPING 18547 && state.mState != UserStartedState.STATE_SHUTDOWN; 18548 } 18549 18550 @Override 18551 public int[] getRunningUserIds() { 18552 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18553 != PackageManager.PERMISSION_GRANTED) { 18554 String msg = "Permission Denial: isUserRunning() from pid=" 18555 + Binder.getCallingPid() 18556 + ", uid=" + Binder.getCallingUid() 18557 + " requires " + INTERACT_ACROSS_USERS; 18558 Slog.w(TAG, msg); 18559 throw new SecurityException(msg); 18560 } 18561 synchronized (this) { 18562 return mStartedUserArray; 18563 } 18564 } 18565 18566 private void updateStartedUserArrayLocked() { 18567 int num = 0; 18568 for (int i=0; i<mStartedUsers.size(); i++) { 18569 UserStartedState uss = mStartedUsers.valueAt(i); 18570 // This list does not include stopping users. 18571 if (uss.mState != UserStartedState.STATE_STOPPING 18572 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18573 num++; 18574 } 18575 } 18576 mStartedUserArray = new int[num]; 18577 num = 0; 18578 for (int i=0; i<mStartedUsers.size(); i++) { 18579 UserStartedState uss = mStartedUsers.valueAt(i); 18580 if (uss.mState != UserStartedState.STATE_STOPPING 18581 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18582 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18583 num++; 18584 } 18585 } 18586 } 18587 18588 @Override 18589 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18590 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18591 != PackageManager.PERMISSION_GRANTED) { 18592 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18593 + Binder.getCallingPid() 18594 + ", uid=" + Binder.getCallingUid() 18595 + " requires " + INTERACT_ACROSS_USERS_FULL; 18596 Slog.w(TAG, msg); 18597 throw new SecurityException(msg); 18598 } 18599 18600 mUserSwitchObservers.register(observer); 18601 } 18602 18603 @Override 18604 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18605 mUserSwitchObservers.unregister(observer); 18606 } 18607 18608 private boolean userExists(int userId) { 18609 if (userId == 0) { 18610 return true; 18611 } 18612 UserManagerService ums = getUserManagerLocked(); 18613 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18614 } 18615 18616 int[] getUsersLocked() { 18617 UserManagerService ums = getUserManagerLocked(); 18618 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18619 } 18620 18621 UserManagerService getUserManagerLocked() { 18622 if (mUserManager == null) { 18623 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18624 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18625 } 18626 return mUserManager; 18627 } 18628 18629 private int applyUserId(int uid, int userId) { 18630 return UserHandle.getUid(userId, uid); 18631 } 18632 18633 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18634 if (info == null) return null; 18635 ApplicationInfo newInfo = new ApplicationInfo(info); 18636 newInfo.uid = applyUserId(info.uid, userId); 18637 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18638 + info.packageName; 18639 return newInfo; 18640 } 18641 18642 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18643 if (aInfo == null 18644 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18645 return aInfo; 18646 } 18647 18648 ActivityInfo info = new ActivityInfo(aInfo); 18649 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18650 return info; 18651 } 18652 18653 private final class LocalService extends ActivityManagerInternal { 18654 @Override 18655 public void goingToSleep() { 18656 ActivityManagerService.this.goingToSleep(); 18657 } 18658 18659 @Override 18660 public void wakingUp() { 18661 ActivityManagerService.this.wakingUp(); 18662 } 18663 18664 @Override 18665 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18666 String processName, String abiOverride, int uid, Runnable crashHandler) { 18667 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18668 processName, abiOverride, uid, crashHandler); 18669 } 18670 } 18671 18672 /** 18673 * An implementation of IAppTask, that allows an app to manage its own tasks via 18674 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18675 * only the process that calls getAppTasks() can call the AppTask methods. 18676 */ 18677 class AppTaskImpl extends IAppTask.Stub { 18678 private int mTaskId; 18679 private int mCallingUid; 18680 18681 public AppTaskImpl(int taskId, int callingUid) { 18682 mTaskId = taskId; 18683 mCallingUid = callingUid; 18684 } 18685 18686 private void checkCaller() { 18687 if (mCallingUid != Binder.getCallingUid()) { 18688 throw new SecurityException("Caller " + mCallingUid 18689 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18690 } 18691 } 18692 18693 @Override 18694 public void finishAndRemoveTask() { 18695 checkCaller(); 18696 18697 synchronized (ActivityManagerService.this) { 18698 long origId = Binder.clearCallingIdentity(); 18699 try { 18700 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18701 if (tr == null) { 18702 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18703 } 18704 // Only kill the process if we are not a new document 18705 int flags = tr.getBaseIntent().getFlags(); 18706 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18707 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18708 removeTaskByIdLocked(mTaskId, 18709 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18710 } finally { 18711 Binder.restoreCallingIdentity(origId); 18712 } 18713 } 18714 } 18715 18716 @Override 18717 public ActivityManager.RecentTaskInfo getTaskInfo() { 18718 checkCaller(); 18719 18720 synchronized (ActivityManagerService.this) { 18721 long origId = Binder.clearCallingIdentity(); 18722 try { 18723 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18724 if (tr == null) { 18725 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18726 } 18727 return createRecentTaskInfoFromTaskRecord(tr); 18728 } finally { 18729 Binder.restoreCallingIdentity(origId); 18730 } 18731 } 18732 } 18733 18734 @Override 18735 public void moveToFront() { 18736 checkCaller(); 18737 18738 final TaskRecord tr; 18739 synchronized (ActivityManagerService.this) { 18740 tr = recentTaskForIdLocked(mTaskId); 18741 if (tr == null) { 18742 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18743 } 18744 if (tr.getRootActivity() != null) { 18745 long origId = Binder.clearCallingIdentity(); 18746 try { 18747 moveTaskToFrontLocked(tr.taskId, 0, null); 18748 return; 18749 } finally { 18750 Binder.restoreCallingIdentity(origId); 18751 } 18752 } 18753 } 18754 18755 startActivityFromRecentsInner(tr.taskId, null); 18756 } 18757 18758 @Override 18759 public int startActivity(IBinder whoThread, String callingPackage, 18760 Intent intent, String resolvedType, Bundle options) { 18761 checkCaller(); 18762 18763 int callingUser = UserHandle.getCallingUserId(); 18764 TaskRecord tr; 18765 IApplicationThread appThread; 18766 synchronized (ActivityManagerService.this) { 18767 tr = recentTaskForIdLocked(mTaskId); 18768 if (tr == null) { 18769 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18770 } 18771 appThread = ApplicationThreadNative.asInterface(whoThread); 18772 if (appThread == null) { 18773 throw new IllegalArgumentException("Bad app thread " + appThread); 18774 } 18775 } 18776 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18777 resolvedType, null, null, null, null, 0, 0, null, null, 18778 null, options, callingUser, null, tr); 18779 } 18780 18781 @Override 18782 public void setExcludeFromRecents(boolean exclude) { 18783 checkCaller(); 18784 18785 synchronized (ActivityManagerService.this) { 18786 long origId = Binder.clearCallingIdentity(); 18787 try { 18788 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18789 if (tr == null) { 18790 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18791 } 18792 Intent intent = tr.getBaseIntent(); 18793 if (exclude) { 18794 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18795 } else { 18796 intent.setFlags(intent.getFlags() 18797 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18798 } 18799 } finally { 18800 Binder.restoreCallingIdentity(origId); 18801 } 18802 } 18803 } 18804 } 18805} 18806