ActivityManagerService.java revision 13420f2311757554c314f620c83cb55153b67612
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.content.pm.PackageManager.PERMISSION_GRANTED; 22import static com.android.internal.util.XmlUtils.readBooleanAttribute; 23import static com.android.internal.util.XmlUtils.readIntAttribute; 24import static com.android.internal.util.XmlUtils.readLongAttribute; 25import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 26import static com.android.internal.util.XmlUtils.writeIntAttribute; 27import static com.android.internal.util.XmlUtils.writeLongAttribute; 28import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 29import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 30import static org.xmlpull.v1.XmlPullParser.START_TAG; 31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 32 33import android.Manifest; 34import android.app.AppOpsManager; 35import android.app.IActivityContainer; 36import android.app.IActivityContainerCallback; 37import android.app.IAppTask; 38import android.app.admin.DevicePolicyManager; 39import android.app.usage.UsageStats; 40import android.app.usage.UsageStatsManagerInternal; 41import android.appwidget.AppWidgetManager; 42import android.graphics.Rect; 43import android.os.BatteryStats; 44import android.os.PersistableBundle; 45import android.service.voice.IVoiceInteractionSession; 46import android.util.ArrayMap; 47import android.util.ArraySet; 48 49import android.util.SparseIntArray; 50import com.android.internal.R; 51import com.android.internal.annotations.GuardedBy; 52import com.android.internal.app.IAppOpsService; 53import com.android.internal.app.IVoiceInteractor; 54import com.android.internal.app.ProcessMap; 55import com.android.internal.app.ProcessStats; 56import com.android.internal.content.PackageMonitor; 57import com.android.internal.os.BackgroundThread; 58import com.android.internal.os.BatteryStatsImpl; 59import com.android.internal.os.ProcessCpuTracker; 60import com.android.internal.os.TransferPipe; 61import com.android.internal.os.Zygote; 62import com.android.internal.util.FastPrintWriter; 63import com.android.internal.util.FastXmlSerializer; 64import com.android.internal.util.MemInfoReader; 65import com.android.internal.util.Preconditions; 66import com.android.server.AppOpsService; 67import com.android.server.AttributeCache; 68import com.android.server.IntentResolver; 69import com.android.server.LocalServices; 70import com.android.server.ServiceThread; 71import com.android.server.SystemService; 72import com.android.server.SystemServiceManager; 73import com.android.server.Watchdog; 74import com.android.server.am.ActivityStack.ActivityState; 75import com.android.server.firewall.IntentFirewall; 76import com.android.server.pm.UserManagerService; 77import com.android.server.wm.AppTransition; 78import com.android.server.wm.WindowManagerService; 79import com.google.android.collect.Lists; 80import com.google.android.collect.Maps; 81 82import libcore.io.IoUtils; 83 84import org.xmlpull.v1.XmlPullParser; 85import org.xmlpull.v1.XmlPullParserException; 86import org.xmlpull.v1.XmlSerializer; 87 88import android.app.Activity; 89import android.app.ActivityManager; 90import android.app.ActivityManager.RunningTaskInfo; 91import android.app.ActivityManager.StackInfo; 92import android.app.ActivityManagerInternal; 93import android.app.ActivityManagerNative; 94import android.app.ActivityOptions; 95import android.app.ActivityThread; 96import android.app.AlertDialog; 97import android.app.AppGlobals; 98import android.app.ApplicationErrorReport; 99import android.app.Dialog; 100import android.app.IActivityController; 101import android.app.IApplicationThread; 102import android.app.IInstrumentationWatcher; 103import android.app.INotificationManager; 104import android.app.IProcessObserver; 105import android.app.IServiceConnection; 106import android.app.IStopUserCallback; 107import android.app.IUiAutomationConnection; 108import android.app.IUserSwitchObserver; 109import android.app.Instrumentation; 110import android.app.Notification; 111import android.app.NotificationManager; 112import android.app.PendingIntent; 113import android.app.backup.IBackupManager; 114import android.content.ActivityNotFoundException; 115import android.content.BroadcastReceiver; 116import android.content.ClipData; 117import android.content.ComponentCallbacks2; 118import android.content.ComponentName; 119import android.content.ContentProvider; 120import android.content.ContentResolver; 121import android.content.Context; 122import android.content.DialogInterface; 123import android.content.IContentProvider; 124import android.content.IIntentReceiver; 125import android.content.IIntentSender; 126import android.content.Intent; 127import android.content.IntentFilter; 128import android.content.IntentSender; 129import android.content.pm.ActivityInfo; 130import android.content.pm.ApplicationInfo; 131import android.content.pm.ConfigurationInfo; 132import android.content.pm.IPackageDataObserver; 133import android.content.pm.IPackageManager; 134import android.content.pm.InstrumentationInfo; 135import android.content.pm.PackageInfo; 136import android.content.pm.PackageManager; 137import android.content.pm.ParceledListSlice; 138import android.content.pm.UserInfo; 139import android.content.pm.PackageManager.NameNotFoundException; 140import android.content.pm.PathPermission; 141import android.content.pm.ProviderInfo; 142import android.content.pm.ResolveInfo; 143import android.content.pm.ServiceInfo; 144import android.content.res.CompatibilityInfo; 145import android.content.res.Configuration; 146import android.net.Proxy; 147import android.net.ProxyInfo; 148import android.net.Uri; 149import android.os.Binder; 150import android.os.Build; 151import android.os.Bundle; 152import android.os.Debug; 153import android.os.DropBoxManager; 154import android.os.Environment; 155import android.os.FactoryTest; 156import android.os.FileObserver; 157import android.os.FileUtils; 158import android.os.Handler; 159import android.os.IBinder; 160import android.os.IPermissionController; 161import android.os.IRemoteCallback; 162import android.os.IUserManager; 163import android.os.Looper; 164import android.os.Message; 165import android.os.Parcel; 166import android.os.ParcelFileDescriptor; 167import android.os.Process; 168import android.os.RemoteCallbackList; 169import android.os.RemoteException; 170import android.os.SELinux; 171import android.os.ServiceManager; 172import android.os.StrictMode; 173import android.os.SystemClock; 174import android.os.SystemProperties; 175import android.os.UpdateLock; 176import android.os.UserHandle; 177import android.provider.Settings; 178import android.text.format.DateUtils; 179import android.text.format.Time; 180import android.util.AtomicFile; 181import android.util.EventLog; 182import android.util.Log; 183import android.util.Pair; 184import android.util.PrintWriterPrinter; 185import android.util.Slog; 186import android.util.SparseArray; 187import android.util.TimeUtils; 188import android.util.Xml; 189import android.view.Gravity; 190import android.view.LayoutInflater; 191import android.view.View; 192import android.view.WindowManager; 193 194import java.io.BufferedInputStream; 195import java.io.BufferedOutputStream; 196import java.io.DataInputStream; 197import java.io.DataOutputStream; 198import java.io.File; 199import java.io.FileDescriptor; 200import java.io.FileInputStream; 201import java.io.FileNotFoundException; 202import java.io.FileOutputStream; 203import java.io.IOException; 204import java.io.InputStreamReader; 205import java.io.PrintWriter; 206import java.io.StringWriter; 207import java.lang.ref.WeakReference; 208import java.util.ArrayList; 209import java.util.Arrays; 210import java.util.Collections; 211import java.util.Comparator; 212import java.util.HashMap; 213import java.util.HashSet; 214import java.util.Iterator; 215import java.util.List; 216import java.util.Locale; 217import java.util.Map; 218import java.util.Set; 219import java.util.concurrent.atomic.AtomicBoolean; 220import java.util.concurrent.atomic.AtomicLong; 221 222public final class ActivityManagerService extends ActivityManagerNative 223 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 224 private static final String USER_DATA_DIR = "/data/user/"; 225 static final String TAG = "ActivityManager"; 226 static final String TAG_MU = "ActivityManagerServiceMU"; 227 static final boolean DEBUG = false; 228 static final boolean localLOGV = DEBUG; 229 static final boolean DEBUG_BACKUP = localLOGV || false; 230 static final boolean DEBUG_BROADCAST = localLOGV || false; 231 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 232 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 233 static final boolean DEBUG_CLEANUP = localLOGV || false; 234 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 235 static final boolean DEBUG_FOCUS = false; 236 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 237 static final boolean DEBUG_MU = localLOGV || false; 238 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 239 static final boolean DEBUG_LRU = localLOGV || false; 240 static final boolean DEBUG_PAUSE = localLOGV || false; 241 static final boolean DEBUG_POWER = localLOGV || false; 242 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 243 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 244 static final boolean DEBUG_PROCESSES = localLOGV || false; 245 static final boolean DEBUG_PROVIDER = localLOGV || false; 246 static final boolean DEBUG_RESULTS = localLOGV || false; 247 static final boolean DEBUG_SERVICE = localLOGV || false; 248 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 249 static final boolean DEBUG_STACK = localLOGV || false; 250 static final boolean DEBUG_SWITCH = localLOGV || false; 251 static final boolean DEBUG_TASKS = localLOGV || false; 252 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 253 static final boolean DEBUG_TRANSITION = localLOGV || false; 254 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 255 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 256 static final boolean DEBUG_VISBILITY = localLOGV || false; 257 static final boolean DEBUG_PSS = localLOGV || false; 258 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 259 static final boolean VALIDATE_TOKENS = false; 260 static final boolean SHOW_ACTIVITY_START_TIME = true; 261 262 // Control over CPU and battery monitoring. 263 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 264 static final boolean MONITOR_CPU_USAGE = true; 265 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 266 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 267 static final boolean MONITOR_THREAD_CPU_USAGE = false; 268 269 // The flags that are set for all calls we make to the package manager. 270 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 271 272 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 273 274 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 275 276 // Maximum number of recent tasks that we can remember. 277 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 278 279 // Maximum number recent bitmaps to keep in memory. 280 static final int MAX_RECENT_BITMAPS = 5; 281 282 // Amount of time after a call to stopAppSwitches() during which we will 283 // prevent further untrusted switches from happening. 284 static final long APP_SWITCH_DELAY_TIME = 5*1000; 285 286 // How long we wait for a launched process to attach to the activity manager 287 // before we decide it's never going to come up for real. 288 static final int PROC_START_TIMEOUT = 10*1000; 289 290 // How long we wait for a launched process to attach to the activity manager 291 // before we decide it's never going to come up for real, when the process was 292 // started with a wrapper for instrumentation (such as Valgrind) because it 293 // could take much longer than usual. 294 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 295 296 // How long to wait after going idle before forcing apps to GC. 297 static final int GC_TIMEOUT = 5*1000; 298 299 // The minimum amount of time between successive GC requests for a process. 300 static final int GC_MIN_INTERVAL = 60*1000; 301 302 // The minimum amount of time between successive PSS requests for a process. 303 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 304 305 // The minimum amount of time between successive PSS requests for a process 306 // when the request is due to the memory state being lowered. 307 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 308 309 // The rate at which we check for apps using excessive power -- 15 mins. 310 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 311 312 // The minimum sample duration we will allow before deciding we have 313 // enough data on wake locks to start killing things. 314 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 315 316 // The minimum sample duration we will allow before deciding we have 317 // enough data on CPU usage to start killing things. 318 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 319 320 // How long we allow a receiver to run before giving up on it. 321 static final int BROADCAST_FG_TIMEOUT = 10*1000; 322 static final int BROADCAST_BG_TIMEOUT = 60*1000; 323 324 // How long we wait until we timeout on key dispatching. 325 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 326 327 // How long we wait until we timeout on key dispatching during instrumentation. 328 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 329 330 // Amount of time we wait for observers to handle a user switch before 331 // giving up on them and unfreezing the screen. 332 static final int USER_SWITCH_TIMEOUT = 2*1000; 333 334 // Maximum number of users we allow to be running at a time. 335 static final int MAX_RUNNING_USERS = 3; 336 337 // How long to wait in getAssistContextExtras for the activity and foreground services 338 // to respond with the result. 339 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 340 341 // Maximum number of persisted Uri grants a package is allowed 342 static final int MAX_PERSISTED_URI_GRANTS = 128; 343 344 static final int MY_PID = Process.myPid(); 345 346 static final String[] EMPTY_STRING_ARRAY = new String[0]; 347 348 // How many bytes to write into the dropbox log before truncating 349 static final int DROPBOX_MAX_SIZE = 256 * 1024; 350 351 // Access modes for handleIncomingUser. 352 static final int ALLOW_NON_FULL = 0; 353 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 354 static final int ALLOW_FULL_ONLY = 2; 355 356 /** All system services */ 357 SystemServiceManager mSystemServiceManager; 358 359 /** Run all ActivityStacks through this */ 360 ActivityStackSupervisor mStackSupervisor; 361 362 public IntentFirewall mIntentFirewall; 363 364 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 365 // default actuion automatically. Important for devices without direct input 366 // devices. 367 private boolean mShowDialogs = true; 368 369 BroadcastQueue mFgBroadcastQueue; 370 BroadcastQueue mBgBroadcastQueue; 371 // Convenient for easy iteration over the queues. Foreground is first 372 // so that dispatch of foreground broadcasts gets precedence. 373 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 374 375 BroadcastQueue broadcastQueueForIntent(Intent intent) { 376 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 377 if (DEBUG_BACKGROUND_BROADCAST) { 378 Slog.i(TAG, "Broadcast intent " + intent + " on " 379 + (isFg ? "foreground" : "background") 380 + " queue"); 381 } 382 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 383 } 384 385 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 386 for (BroadcastQueue queue : mBroadcastQueues) { 387 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 388 if (r != null) { 389 return r; 390 } 391 } 392 return null; 393 } 394 395 /** 396 * Activity we have told the window manager to have key focus. 397 */ 398 ActivityRecord mFocusedActivity = null; 399 400 /** 401 * List of intents that were used to start the most recent tasks. 402 */ 403 ArrayList<TaskRecord> mRecentTasks; 404 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 405 406 public class PendingAssistExtras extends Binder implements Runnable { 407 public final ActivityRecord activity; 408 public boolean haveResult = false; 409 public Bundle result = null; 410 public PendingAssistExtras(ActivityRecord _activity) { 411 activity = _activity; 412 } 413 @Override 414 public void run() { 415 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 416 synchronized (this) { 417 haveResult = true; 418 notifyAll(); 419 } 420 } 421 } 422 423 final ArrayList<PendingAssistExtras> mPendingAssistExtras 424 = new ArrayList<PendingAssistExtras>(); 425 426 /** 427 * Process management. 428 */ 429 final ProcessList mProcessList = new ProcessList(); 430 431 /** 432 * All of the applications we currently have running organized by name. 433 * The keys are strings of the application package name (as 434 * returned by the package manager), and the keys are ApplicationRecord 435 * objects. 436 */ 437 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 438 439 /** 440 * Tracking long-term execution of processes to look for abuse and other 441 * bad app behavior. 442 */ 443 final ProcessStatsService mProcessStats; 444 445 /** 446 * The currently running isolated processes. 447 */ 448 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 449 450 /** 451 * Counter for assigning isolated process uids, to avoid frequently reusing the 452 * same ones. 453 */ 454 int mNextIsolatedProcessUid = 0; 455 456 /** 457 * The currently running heavy-weight process, if any. 458 */ 459 ProcessRecord mHeavyWeightProcess = null; 460 461 /** 462 * The last time that various processes have crashed. 463 */ 464 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 465 466 /** 467 * Information about a process that is currently marked as bad. 468 */ 469 static final class BadProcessInfo { 470 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 471 this.time = time; 472 this.shortMsg = shortMsg; 473 this.longMsg = longMsg; 474 this.stack = stack; 475 } 476 477 final long time; 478 final String shortMsg; 479 final String longMsg; 480 final String stack; 481 } 482 483 /** 484 * Set of applications that we consider to be bad, and will reject 485 * incoming broadcasts from (which the user has no control over). 486 * Processes are added to this set when they have crashed twice within 487 * a minimum amount of time; they are removed from it when they are 488 * later restarted (hopefully due to some user action). The value is the 489 * time it was added to the list. 490 */ 491 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 492 493 /** 494 * All of the processes we currently have running organized by pid. 495 * The keys are the pid running the application. 496 * 497 * <p>NOTE: This object is protected by its own lock, NOT the global 498 * activity manager lock! 499 */ 500 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 501 502 /** 503 * All of the processes that have been forced to be foreground. The key 504 * is the pid of the caller who requested it (we hold a death 505 * link on it). 506 */ 507 abstract class ForegroundToken implements IBinder.DeathRecipient { 508 int pid; 509 IBinder token; 510 } 511 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 512 513 /** 514 * List of records for processes that someone had tried to start before the 515 * system was ready. We don't start them at that point, but ensure they 516 * are started by the time booting is complete. 517 */ 518 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 519 520 /** 521 * List of persistent applications that are in the process 522 * of being started. 523 */ 524 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * Processes that are being forcibly torn down. 528 */ 529 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * List of running applications, sorted by recent usage. 533 * The first entry in the list is the least recently used. 534 */ 535 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * Where in mLruProcesses that the processes hosting activities start. 539 */ 540 int mLruProcessActivityStart = 0; 541 542 /** 543 * Where in mLruProcesses that the processes hosting services start. 544 * This is after (lower index) than mLruProcessesActivityStart. 545 */ 546 int mLruProcessServiceStart = 0; 547 548 /** 549 * List of processes that should gc as soon as things are idle. 550 */ 551 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes we want to collect PSS data from. 555 */ 556 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Last time we requested PSS data of all processes. 560 */ 561 long mLastFullPssTime = SystemClock.uptimeMillis(); 562 563 /** 564 * If set, the next time we collect PSS data we should do a full collection 565 * with data from native processes and the kernel. 566 */ 567 boolean mFullPssPending = false; 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 final ProviderMap mProviderMap; 707 708 /** 709 * List of content providers who have clients waiting for them. The 710 * application is currently being launched and the provider will be 711 * removed from this list once it is published. 712 */ 713 final ArrayList<ContentProviderRecord> mLaunchingProviders 714 = new ArrayList<ContentProviderRecord>(); 715 716 /** 717 * File storing persisted {@link #mGrantedUriPermissions}. 718 */ 719 private final AtomicFile mGrantFile; 720 721 /** XML constants used in {@link #mGrantFile} */ 722 private static final String TAG_URI_GRANTS = "uri-grants"; 723 private static final String TAG_URI_GRANT = "uri-grant"; 724 private static final String ATTR_USER_HANDLE = "userHandle"; 725 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 726 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 727 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 728 private static final String ATTR_TARGET_PKG = "targetPkg"; 729 private static final String ATTR_URI = "uri"; 730 private static final String ATTR_MODE_FLAGS = "modeFlags"; 731 private static final String ATTR_CREATED_TIME = "createdTime"; 732 private static final String ATTR_PREFIX = "prefix"; 733 734 /** 735 * Global set of specific {@link Uri} permissions that have been granted. 736 * This optimized lookup structure maps from {@link UriPermission#targetUid} 737 * to {@link UriPermission#uri} to {@link UriPermission}. 738 */ 739 @GuardedBy("this") 740 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 741 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 742 743 public static class GrantUri { 744 public final int sourceUserId; 745 public final Uri uri; 746 public boolean prefix; 747 748 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 749 this.sourceUserId = sourceUserId; 750 this.uri = uri; 751 this.prefix = prefix; 752 } 753 754 @Override 755 public int hashCode() { 756 return toString().hashCode(); 757 } 758 759 @Override 760 public boolean equals(Object o) { 761 if (o instanceof GrantUri) { 762 GrantUri other = (GrantUri) o; 763 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 764 && prefix == other.prefix; 765 } 766 return false; 767 } 768 769 @Override 770 public String toString() { 771 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 772 if (prefix) result += " [prefix]"; 773 return result; 774 } 775 776 public String toSafeString() { 777 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 778 if (prefix) result += " [prefix]"; 779 return result; 780 } 781 782 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 783 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 784 ContentProvider.getUriWithoutUserId(uri), false); 785 } 786 } 787 788 CoreSettingsObserver mCoreSettingsObserver; 789 790 /** 791 * Thread-local storage used to carry caller permissions over through 792 * indirect content-provider access. 793 */ 794 private class Identity { 795 public int pid; 796 public int uid; 797 798 Identity(int _pid, int _uid) { 799 pid = _pid; 800 uid = _uid; 801 } 802 } 803 804 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 805 806 /** 807 * All information we have collected about the runtime performance of 808 * any user id that can impact battery performance. 809 */ 810 final BatteryStatsService mBatteryStatsService; 811 812 /** 813 * Information about component usage 814 */ 815 UsageStatsManagerInternal mUsageStatsService; 816 817 /** 818 * Information about and control over application operations 819 */ 820 final AppOpsService mAppOpsService; 821 822 /** 823 * Save recent tasks information across reboots. 824 */ 825 final TaskPersister mTaskPersister; 826 827 /** 828 * Current configuration information. HistoryRecord objects are given 829 * a reference to this object to indicate which configuration they are 830 * currently running in, so this object must be kept immutable. 831 */ 832 Configuration mConfiguration = new Configuration(); 833 834 /** 835 * Current sequencing integer of the configuration, for skipping old 836 * configurations. 837 */ 838 int mConfigurationSeq = 0; 839 840 /** 841 * Hardware-reported OpenGLES version. 842 */ 843 final int GL_ES_VERSION; 844 845 /** 846 * List of initialization arguments to pass to all processes when binding applications to them. 847 * For example, references to the commonly used services. 848 */ 849 HashMap<String, IBinder> mAppBindArgs; 850 851 /** 852 * Temporary to avoid allocations. Protected by main lock. 853 */ 854 final StringBuilder mStringBuilder = new StringBuilder(256); 855 856 /** 857 * Used to control how we initialize the service. 858 */ 859 ComponentName mTopComponent; 860 String mTopAction = Intent.ACTION_MAIN; 861 String mTopData; 862 boolean mProcessesReady = false; 863 boolean mSystemReady = false; 864 boolean mBooting = false; 865 boolean mWaitingUpdate = false; 866 boolean mDidUpdate = false; 867 boolean mOnBattery = false; 868 boolean mLaunchWarningShown = false; 869 870 Context mContext; 871 872 int mFactoryTest; 873 874 boolean mCheckedForSetup; 875 876 /** 877 * The time at which we will allow normal application switches again, 878 * after a call to {@link #stopAppSwitches()}. 879 */ 880 long mAppSwitchesAllowedTime; 881 882 /** 883 * This is set to true after the first switch after mAppSwitchesAllowedTime 884 * is set; any switches after that will clear the time. 885 */ 886 boolean mDidAppSwitch; 887 888 /** 889 * Last time (in realtime) at which we checked for power usage. 890 */ 891 long mLastPowerCheckRealtime; 892 893 /** 894 * Last time (in uptime) at which we checked for power usage. 895 */ 896 long mLastPowerCheckUptime; 897 898 /** 899 * Set while we are wanting to sleep, to prevent any 900 * activities from being started/resumed. 901 */ 902 private boolean mSleeping = false; 903 904 /** 905 * Set while we are running a voice interaction. This overrides 906 * sleeping while it is active. 907 */ 908 private boolean mRunningVoice = false; 909 910 /** 911 * State of external calls telling us if the device is asleep. 912 */ 913 private boolean mWentToSleep = false; 914 915 /** 916 * State of external call telling us if the lock screen is shown. 917 */ 918 private boolean mLockScreenShown = false; 919 920 /** 921 * Set if we are shutting down the system, similar to sleeping. 922 */ 923 boolean mShuttingDown = false; 924 925 /** 926 * Current sequence id for oom_adj computation traversal. 927 */ 928 int mAdjSeq = 0; 929 930 /** 931 * Current sequence id for process LRU updating. 932 */ 933 int mLruSeq = 0; 934 935 /** 936 * Keep track of the non-cached/empty process we last found, to help 937 * determine how to distribute cached/empty processes next time. 938 */ 939 int mNumNonCachedProcs = 0; 940 941 /** 942 * Keep track of the number of cached hidden procs, to balance oom adj 943 * distribution between those and empty procs. 944 */ 945 int mNumCachedHiddenProcs = 0; 946 947 /** 948 * Keep track of the number of service processes we last found, to 949 * determine on the next iteration which should be B services. 950 */ 951 int mNumServiceProcs = 0; 952 int mNewNumAServiceProcs = 0; 953 int mNewNumServiceProcs = 0; 954 955 /** 956 * Allow the current computed overall memory level of the system to go down? 957 * This is set to false when we are killing processes for reasons other than 958 * memory management, so that the now smaller process list will not be taken as 959 * an indication that memory is tighter. 960 */ 961 boolean mAllowLowerMemLevel = false; 962 963 /** 964 * The last computed memory level, for holding when we are in a state that 965 * processes are going away for other reasons. 966 */ 967 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 968 969 /** 970 * The last total number of process we have, to determine if changes actually look 971 * like a shrinking number of process due to lower RAM. 972 */ 973 int mLastNumProcesses; 974 975 /** 976 * The uptime of the last time we performed idle maintenance. 977 */ 978 long mLastIdleTime = SystemClock.uptimeMillis(); 979 980 /** 981 * Total time spent with RAM that has been added in the past since the last idle time. 982 */ 983 long mLowRamTimeSinceLastIdle = 0; 984 985 /** 986 * If RAM is currently low, when that horrible situation started. 987 */ 988 long mLowRamStartTime = 0; 989 990 /** 991 * For reporting to battery stats the current top application. 992 */ 993 private String mCurResumedPackage = null; 994 private int mCurResumedUid = -1; 995 996 /** 997 * For reporting to battery stats the apps currently running foreground 998 * service. The ProcessMap is package/uid tuples; each of these contain 999 * an array of the currently foreground processes. 1000 */ 1001 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1002 = new ProcessMap<ArrayList<ProcessRecord>>(); 1003 1004 /** 1005 * This is set if we had to do a delayed dexopt of an app before launching 1006 * it, to increase the ANR timeouts in that case. 1007 */ 1008 boolean mDidDexOpt; 1009 1010 /** 1011 * Set if the systemServer made a call to enterSafeMode. 1012 */ 1013 boolean mSafeMode; 1014 1015 String mDebugApp = null; 1016 boolean mWaitForDebugger = false; 1017 boolean mDebugTransient = false; 1018 String mOrigDebugApp = null; 1019 boolean mOrigWaitForDebugger = false; 1020 boolean mAlwaysFinishActivities = false; 1021 IActivityController mController = null; 1022 String mProfileApp = null; 1023 ProcessRecord mProfileProc = null; 1024 String mProfileFile; 1025 ParcelFileDescriptor mProfileFd; 1026 int mProfileType = 0; 1027 boolean mAutoStopProfiler = false; 1028 String mOpenGlTraceApp = null; 1029 1030 static class ProcessChangeItem { 1031 static final int CHANGE_ACTIVITIES = 1<<0; 1032 static final int CHANGE_PROCESS_STATE = 1<<1; 1033 int changes; 1034 int uid; 1035 int pid; 1036 int processState; 1037 boolean foregroundActivities; 1038 } 1039 1040 final RemoteCallbackList<IProcessObserver> mProcessObservers 1041 = new RemoteCallbackList<IProcessObserver>(); 1042 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1043 1044 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1045 = new ArrayList<ProcessChangeItem>(); 1046 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1047 = new ArrayList<ProcessChangeItem>(); 1048 1049 /** 1050 * Runtime CPU use collection thread. This object's lock is used to 1051 * protect all related state. 1052 */ 1053 final Thread mProcessCpuThread; 1054 1055 /** 1056 * Used to collect process stats when showing not responding dialog. 1057 * Protected by mProcessCpuThread. 1058 */ 1059 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1060 MONITOR_THREAD_CPU_USAGE); 1061 final AtomicLong mLastCpuTime = new AtomicLong(0); 1062 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1063 1064 long mLastWriteTime = 0; 1065 1066 /** 1067 * Used to retain an update lock when the foreground activity is in 1068 * immersive mode. 1069 */ 1070 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1071 1072 /** 1073 * Set to true after the system has finished booting. 1074 */ 1075 boolean mBooted = false; 1076 1077 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1078 int mProcessLimitOverride = -1; 1079 1080 WindowManagerService mWindowManager; 1081 1082 final ActivityThread mSystemThread; 1083 1084 int mCurrentUserId = 0; 1085 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1086 1087 /** 1088 * Mapping from each known user ID to the profile group ID it is associated with. 1089 */ 1090 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1091 1092 private UserManagerService mUserManager; 1093 1094 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1095 final ProcessRecord mApp; 1096 final int mPid; 1097 final IApplicationThread mAppThread; 1098 1099 AppDeathRecipient(ProcessRecord app, int pid, 1100 IApplicationThread thread) { 1101 if (localLOGV) Slog.v( 1102 TAG, "New death recipient " + this 1103 + " for thread " + thread.asBinder()); 1104 mApp = app; 1105 mPid = pid; 1106 mAppThread = thread; 1107 } 1108 1109 @Override 1110 public void binderDied() { 1111 if (localLOGV) Slog.v( 1112 TAG, "Death received in " + this 1113 + " for thread " + mAppThread.asBinder()); 1114 synchronized(ActivityManagerService.this) { 1115 appDiedLocked(mApp, mPid, mAppThread); 1116 } 1117 } 1118 } 1119 1120 static final int SHOW_ERROR_MSG = 1; 1121 static final int SHOW_NOT_RESPONDING_MSG = 2; 1122 static final int SHOW_FACTORY_ERROR_MSG = 3; 1123 static final int UPDATE_CONFIGURATION_MSG = 4; 1124 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1125 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1126 static final int SERVICE_TIMEOUT_MSG = 12; 1127 static final int UPDATE_TIME_ZONE = 13; 1128 static final int SHOW_UID_ERROR_MSG = 14; 1129 static final int IM_FEELING_LUCKY_MSG = 15; 1130 static final int PROC_START_TIMEOUT_MSG = 20; 1131 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1132 static final int KILL_APPLICATION_MSG = 22; 1133 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1134 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1135 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1136 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1137 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1138 static final int CLEAR_DNS_CACHE_MSG = 28; 1139 static final int UPDATE_HTTP_PROXY_MSG = 29; 1140 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1141 static final int DISPATCH_PROCESSES_CHANGED = 31; 1142 static final int DISPATCH_PROCESS_DIED = 32; 1143 static final int REPORT_MEM_USAGE_MSG = 33; 1144 static final int REPORT_USER_SWITCH_MSG = 34; 1145 static final int CONTINUE_USER_SWITCH_MSG = 35; 1146 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1147 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1148 static final int PERSIST_URI_GRANTS_MSG = 38; 1149 static final int REQUEST_ALL_PSS_MSG = 39; 1150 static final int START_PROFILES_MSG = 40; 1151 static final int UPDATE_TIME = 41; 1152 static final int SYSTEM_USER_START_MSG = 42; 1153 static final int SYSTEM_USER_CURRENT_MSG = 43; 1154 1155 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1156 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1157 static final int FIRST_COMPAT_MODE_MSG = 300; 1158 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1159 1160 AlertDialog mUidAlert; 1161 CompatModeDialog mCompatModeDialog; 1162 long mLastMemUsageReportTime = 0; 1163 1164 private LockToAppRequestDialog mLockToAppRequest; 1165 1166 /** 1167 * Flag whether the current user is a "monkey", i.e. whether 1168 * the UI is driven by a UI automation tool. 1169 */ 1170 private boolean mUserIsMonkey; 1171 1172 /** Flag whether the device has a recents UI */ 1173 final boolean mHasRecents; 1174 1175 final ServiceThread mHandlerThread; 1176 final MainHandler mHandler; 1177 1178 final class MainHandler extends Handler { 1179 public MainHandler(Looper looper) { 1180 super(looper, null, true); 1181 } 1182 1183 @Override 1184 public void handleMessage(Message msg) { 1185 switch (msg.what) { 1186 case SHOW_ERROR_MSG: { 1187 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1188 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1189 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1190 synchronized (ActivityManagerService.this) { 1191 ProcessRecord proc = (ProcessRecord)data.get("app"); 1192 AppErrorResult res = (AppErrorResult) data.get("result"); 1193 if (proc != null && proc.crashDialog != null) { 1194 Slog.e(TAG, "App already has crash dialog: " + proc); 1195 if (res != null) { 1196 res.set(0); 1197 } 1198 return; 1199 } 1200 if (!showBackground && UserHandle.getAppId(proc.uid) 1201 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1202 && proc.pid != MY_PID) { 1203 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1204 if (res != null) { 1205 res.set(0); 1206 } 1207 return; 1208 } 1209 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1210 Dialog d = new AppErrorDialog(mContext, 1211 ActivityManagerService.this, res, proc); 1212 d.show(); 1213 proc.crashDialog = d; 1214 } else { 1215 // The device is asleep, so just pretend that the user 1216 // saw a crash dialog and hit "force quit". 1217 if (res != null) { 1218 res.set(0); 1219 } 1220 } 1221 } 1222 1223 ensureBootCompleted(); 1224 } break; 1225 case SHOW_NOT_RESPONDING_MSG: { 1226 synchronized (ActivityManagerService.this) { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 ProcessRecord proc = (ProcessRecord)data.get("app"); 1229 if (proc != null && proc.anrDialog != null) { 1230 Slog.e(TAG, "App already has anr dialog: " + proc); 1231 return; 1232 } 1233 1234 Intent intent = new Intent("android.intent.action.ANR"); 1235 if (!mProcessesReady) { 1236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1237 | Intent.FLAG_RECEIVER_FOREGROUND); 1238 } 1239 broadcastIntentLocked(null, null, intent, 1240 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1241 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1242 1243 if (mShowDialogs) { 1244 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1245 mContext, proc, (ActivityRecord)data.get("activity"), 1246 msg.arg1 != 0); 1247 d.show(); 1248 proc.anrDialog = d; 1249 } else { 1250 // Just kill the app if there is no dialog to be shown. 1251 killAppAtUsersRequest(proc, null); 1252 } 1253 } 1254 1255 ensureBootCompleted(); 1256 } break; 1257 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1258 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1259 synchronized (ActivityManagerService.this) { 1260 ProcessRecord proc = (ProcessRecord) data.get("app"); 1261 if (proc == null) { 1262 Slog.e(TAG, "App not found when showing strict mode dialog."); 1263 break; 1264 } 1265 if (proc.crashDialog != null) { 1266 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1267 return; 1268 } 1269 AppErrorResult res = (AppErrorResult) data.get("result"); 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new StrictModeViolationDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 res.set(0); 1279 } 1280 } 1281 ensureBootCompleted(); 1282 } break; 1283 case SHOW_FACTORY_ERROR_MSG: { 1284 Dialog d = new FactoryErrorDialog( 1285 mContext, msg.getData().getCharSequence("msg")); 1286 d.show(); 1287 ensureBootCompleted(); 1288 } break; 1289 case UPDATE_CONFIGURATION_MSG: { 1290 final ContentResolver resolver = mContext.getContentResolver(); 1291 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1292 } break; 1293 case GC_BACKGROUND_PROCESSES_MSG: { 1294 synchronized (ActivityManagerService.this) { 1295 performAppGcsIfAppropriateLocked(); 1296 } 1297 } break; 1298 case WAIT_FOR_DEBUGGER_MSG: { 1299 synchronized (ActivityManagerService.this) { 1300 ProcessRecord app = (ProcessRecord)msg.obj; 1301 if (msg.arg1 != 0) { 1302 if (!app.waitedForDebugger) { 1303 Dialog d = new AppWaitingForDebuggerDialog( 1304 ActivityManagerService.this, 1305 mContext, app); 1306 app.waitDialog = d; 1307 app.waitedForDebugger = true; 1308 d.show(); 1309 } 1310 } else { 1311 if (app.waitDialog != null) { 1312 app.waitDialog.dismiss(); 1313 app.waitDialog = null; 1314 } 1315 } 1316 } 1317 } break; 1318 case SERVICE_TIMEOUT_MSG: { 1319 if (mDidDexOpt) { 1320 mDidDexOpt = false; 1321 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1322 nmsg.obj = msg.obj; 1323 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1324 return; 1325 } 1326 mServices.serviceTimeout((ProcessRecord)msg.obj); 1327 } break; 1328 case UPDATE_TIME_ZONE: { 1329 synchronized (ActivityManagerService.this) { 1330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1331 ProcessRecord r = mLruProcesses.get(i); 1332 if (r.thread != null) { 1333 try { 1334 r.thread.updateTimeZone(); 1335 } catch (RemoteException ex) { 1336 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1337 } 1338 } 1339 } 1340 } 1341 } break; 1342 case CLEAR_DNS_CACHE_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1345 ProcessRecord r = mLruProcesses.get(i); 1346 if (r.thread != null) { 1347 try { 1348 r.thread.clearDnsCache(); 1349 } catch (RemoteException ex) { 1350 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1351 } 1352 } 1353 } 1354 } 1355 } break; 1356 case UPDATE_HTTP_PROXY_MSG: { 1357 ProxyInfo proxy = (ProxyInfo)msg.obj; 1358 String host = ""; 1359 String port = ""; 1360 String exclList = ""; 1361 Uri pacFileUrl = Uri.EMPTY; 1362 if (proxy != null) { 1363 host = proxy.getHost(); 1364 port = Integer.toString(proxy.getPort()); 1365 exclList = proxy.getExclusionListAsString(); 1366 pacFileUrl = proxy.getPacFileUrl(); 1367 } 1368 synchronized (ActivityManagerService.this) { 1369 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1370 ProcessRecord r = mLruProcesses.get(i); 1371 if (r.thread != null) { 1372 try { 1373 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1374 } catch (RemoteException ex) { 1375 Slog.w(TAG, "Failed to update http proxy for: " + 1376 r.info.processName); 1377 } 1378 } 1379 } 1380 } 1381 } break; 1382 case SHOW_UID_ERROR_MSG: { 1383 String title = "System UIDs Inconsistent"; 1384 String text = "UIDs on the system are inconsistent, you need to wipe your" 1385 + " data partition or your device will be unstable."; 1386 Log.e(TAG, title + ": " + text); 1387 if (mShowDialogs) { 1388 // XXX This is a temporary dialog, no need to localize. 1389 AlertDialog d = new BaseErrorDialog(mContext); 1390 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1391 d.setCancelable(false); 1392 d.setTitle(title); 1393 d.setMessage(text); 1394 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1395 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1396 mUidAlert = d; 1397 d.show(); 1398 } 1399 } break; 1400 case IM_FEELING_LUCKY_MSG: { 1401 if (mUidAlert != null) { 1402 mUidAlert.dismiss(); 1403 mUidAlert = null; 1404 } 1405 } break; 1406 case PROC_START_TIMEOUT_MSG: { 1407 if (mDidDexOpt) { 1408 mDidDexOpt = false; 1409 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1410 nmsg.obj = msg.obj; 1411 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1412 return; 1413 } 1414 ProcessRecord app = (ProcessRecord)msg.obj; 1415 synchronized (ActivityManagerService.this) { 1416 processStartTimedOutLocked(app); 1417 } 1418 } break; 1419 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1420 synchronized (ActivityManagerService.this) { 1421 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1422 } 1423 } break; 1424 case KILL_APPLICATION_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 int appid = msg.arg1; 1427 boolean restart = (msg.arg2 == 1); 1428 Bundle bundle = (Bundle)msg.obj; 1429 String pkg = bundle.getString("pkg"); 1430 String reason = bundle.getString("reason"); 1431 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1432 false, UserHandle.USER_ALL, reason); 1433 } 1434 } break; 1435 case FINALIZE_PENDING_INTENT_MSG: { 1436 ((PendingIntentRecord)msg.obj).completeFinalize(); 1437 } break; 1438 case POST_HEAVY_NOTIFICATION_MSG: { 1439 INotificationManager inm = NotificationManager.getService(); 1440 if (inm == null) { 1441 return; 1442 } 1443 1444 ActivityRecord root = (ActivityRecord)msg.obj; 1445 ProcessRecord process = root.app; 1446 if (process == null) { 1447 return; 1448 } 1449 1450 try { 1451 Context context = mContext.createPackageContext(process.info.packageName, 0); 1452 String text = mContext.getString(R.string.heavy_weight_notification, 1453 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1454 Notification notification = new Notification(); 1455 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1456 notification.when = 0; 1457 notification.flags = Notification.FLAG_ONGOING_EVENT; 1458 notification.tickerText = text; 1459 notification.defaults = 0; // please be quiet 1460 notification.sound = null; 1461 notification.vibrate = null; 1462 notification.setLatestEventInfo(context, text, 1463 mContext.getText(R.string.heavy_weight_notification_detail), 1464 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1465 PendingIntent.FLAG_CANCEL_CURRENT, null, 1466 new UserHandle(root.userId))); 1467 1468 try { 1469 int[] outId = new int[1]; 1470 inm.enqueueNotificationWithTag("android", "android", null, 1471 R.string.heavy_weight_notification, 1472 notification, outId, root.userId); 1473 } catch (RuntimeException e) { 1474 Slog.w(ActivityManagerService.TAG, 1475 "Error showing notification for heavy-weight app", e); 1476 } catch (RemoteException e) { 1477 } 1478 } catch (NameNotFoundException e) { 1479 Slog.w(TAG, "Unable to create context for heavy notification", e); 1480 } 1481 } break; 1482 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1483 INotificationManager inm = NotificationManager.getService(); 1484 if (inm == null) { 1485 return; 1486 } 1487 try { 1488 inm.cancelNotificationWithTag("android", null, 1489 R.string.heavy_weight_notification, msg.arg1); 1490 } catch (RuntimeException e) { 1491 Slog.w(ActivityManagerService.TAG, 1492 "Error canceling notification for service", e); 1493 } catch (RemoteException e) { 1494 } 1495 } break; 1496 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1497 synchronized (ActivityManagerService.this) { 1498 checkExcessivePowerUsageLocked(true); 1499 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1500 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1501 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1502 } 1503 } break; 1504 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1505 synchronized (ActivityManagerService.this) { 1506 ActivityRecord ar = (ActivityRecord)msg.obj; 1507 if (mCompatModeDialog != null) { 1508 if (mCompatModeDialog.mAppInfo.packageName.equals( 1509 ar.info.applicationInfo.packageName)) { 1510 return; 1511 } 1512 mCompatModeDialog.dismiss(); 1513 mCompatModeDialog = null; 1514 } 1515 if (ar != null && false) { 1516 if (mCompatModePackages.getPackageAskCompatModeLocked( 1517 ar.packageName)) { 1518 int mode = mCompatModePackages.computeCompatModeLocked( 1519 ar.info.applicationInfo); 1520 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1521 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1522 mCompatModeDialog = new CompatModeDialog( 1523 ActivityManagerService.this, mContext, 1524 ar.info.applicationInfo); 1525 mCompatModeDialog.show(); 1526 } 1527 } 1528 } 1529 } 1530 break; 1531 } 1532 case DISPATCH_PROCESSES_CHANGED: { 1533 dispatchProcessesChanged(); 1534 break; 1535 } 1536 case DISPATCH_PROCESS_DIED: { 1537 final int pid = msg.arg1; 1538 final int uid = msg.arg2; 1539 dispatchProcessDied(pid, uid); 1540 break; 1541 } 1542 case REPORT_MEM_USAGE_MSG: { 1543 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1544 Thread thread = new Thread() { 1545 @Override public void run() { 1546 final SparseArray<ProcessMemInfo> infoMap 1547 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1548 for (int i=0, N=memInfos.size(); i<N; i++) { 1549 ProcessMemInfo mi = memInfos.get(i); 1550 infoMap.put(mi.pid, mi); 1551 } 1552 updateCpuStatsNow(); 1553 synchronized (mProcessCpuThread) { 1554 final int N = mProcessCpuTracker.countStats(); 1555 for (int i=0; i<N; i++) { 1556 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1557 if (st.vsize > 0) { 1558 long pss = Debug.getPss(st.pid, null); 1559 if (pss > 0) { 1560 if (infoMap.indexOfKey(st.pid) < 0) { 1561 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1562 ProcessList.NATIVE_ADJ, -1, "native", null); 1563 mi.pss = pss; 1564 memInfos.add(mi); 1565 } 1566 } 1567 } 1568 } 1569 } 1570 1571 long totalPss = 0; 1572 for (int i=0, N=memInfos.size(); i<N; i++) { 1573 ProcessMemInfo mi = memInfos.get(i); 1574 if (mi.pss == 0) { 1575 mi.pss = Debug.getPss(mi.pid, null); 1576 } 1577 totalPss += mi.pss; 1578 } 1579 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1580 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1581 if (lhs.oomAdj != rhs.oomAdj) { 1582 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1583 } 1584 if (lhs.pss != rhs.pss) { 1585 return lhs.pss < rhs.pss ? 1 : -1; 1586 } 1587 return 0; 1588 } 1589 }); 1590 1591 StringBuilder tag = new StringBuilder(128); 1592 StringBuilder stack = new StringBuilder(128); 1593 tag.append("Low on memory -- "); 1594 appendMemBucket(tag, totalPss, "total", false); 1595 appendMemBucket(stack, totalPss, "total", true); 1596 1597 StringBuilder logBuilder = new StringBuilder(1024); 1598 logBuilder.append("Low on memory:\n"); 1599 1600 boolean firstLine = true; 1601 int lastOomAdj = Integer.MIN_VALUE; 1602 for (int i=0, N=memInfos.size(); i<N; i++) { 1603 ProcessMemInfo mi = memInfos.get(i); 1604 1605 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1606 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1607 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1608 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1609 if (lastOomAdj != mi.oomAdj) { 1610 lastOomAdj = mi.oomAdj; 1611 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1612 tag.append(" / "); 1613 } 1614 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1615 if (firstLine) { 1616 stack.append(":"); 1617 firstLine = false; 1618 } 1619 stack.append("\n\t at "); 1620 } else { 1621 stack.append("$"); 1622 } 1623 } else { 1624 tag.append(" "); 1625 stack.append("$"); 1626 } 1627 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1628 appendMemBucket(tag, mi.pss, mi.name, false); 1629 } 1630 appendMemBucket(stack, mi.pss, mi.name, true); 1631 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1632 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1633 stack.append("("); 1634 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1635 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1636 stack.append(DUMP_MEM_OOM_LABEL[k]); 1637 stack.append(":"); 1638 stack.append(DUMP_MEM_OOM_ADJ[k]); 1639 } 1640 } 1641 stack.append(")"); 1642 } 1643 } 1644 1645 logBuilder.append(" "); 1646 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1647 logBuilder.append(' '); 1648 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1649 logBuilder.append(' '); 1650 ProcessList.appendRamKb(logBuilder, mi.pss); 1651 logBuilder.append(" kB: "); 1652 logBuilder.append(mi.name); 1653 logBuilder.append(" ("); 1654 logBuilder.append(mi.pid); 1655 logBuilder.append(") "); 1656 logBuilder.append(mi.adjType); 1657 logBuilder.append('\n'); 1658 if (mi.adjReason != null) { 1659 logBuilder.append(" "); 1660 logBuilder.append(mi.adjReason); 1661 logBuilder.append('\n'); 1662 } 1663 } 1664 1665 logBuilder.append(" "); 1666 ProcessList.appendRamKb(logBuilder, totalPss); 1667 logBuilder.append(" kB: TOTAL\n"); 1668 1669 long[] infos = new long[Debug.MEMINFO_COUNT]; 1670 Debug.getMemInfo(infos); 1671 logBuilder.append(" MemInfo: "); 1672 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1673 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1674 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1675 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1676 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1677 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1678 logBuilder.append(" ZRAM: "); 1679 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1680 logBuilder.append(" kB RAM, "); 1681 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1682 logBuilder.append(" kB swap total, "); 1683 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1684 logBuilder.append(" kB swap free\n"); 1685 } 1686 Slog.i(TAG, logBuilder.toString()); 1687 1688 StringBuilder dropBuilder = new StringBuilder(1024); 1689 /* 1690 StringWriter oomSw = new StringWriter(); 1691 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1692 StringWriter catSw = new StringWriter(); 1693 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1694 String[] emptyArgs = new String[] { }; 1695 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1696 oomPw.flush(); 1697 String oomString = oomSw.toString(); 1698 */ 1699 dropBuilder.append(stack); 1700 dropBuilder.append('\n'); 1701 dropBuilder.append('\n'); 1702 dropBuilder.append(logBuilder); 1703 dropBuilder.append('\n'); 1704 /* 1705 dropBuilder.append(oomString); 1706 dropBuilder.append('\n'); 1707 */ 1708 StringWriter catSw = new StringWriter(); 1709 synchronized (ActivityManagerService.this) { 1710 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1711 String[] emptyArgs = new String[] { }; 1712 catPw.println(); 1713 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1714 catPw.println(); 1715 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1716 false, false, null); 1717 catPw.println(); 1718 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1719 catPw.flush(); 1720 } 1721 dropBuilder.append(catSw.toString()); 1722 addErrorToDropBox("lowmem", null, "system_server", null, 1723 null, tag.toString(), dropBuilder.toString(), null, null); 1724 //Slog.i(TAG, "Sent to dropbox:"); 1725 //Slog.i(TAG, dropBuilder.toString()); 1726 synchronized (ActivityManagerService.this) { 1727 long now = SystemClock.uptimeMillis(); 1728 if (mLastMemUsageReportTime < now) { 1729 mLastMemUsageReportTime = now; 1730 } 1731 } 1732 } 1733 }; 1734 thread.start(); 1735 break; 1736 } 1737 case REPORT_USER_SWITCH_MSG: { 1738 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1739 break; 1740 } 1741 case CONTINUE_USER_SWITCH_MSG: { 1742 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1743 break; 1744 } 1745 case USER_SWITCH_TIMEOUT_MSG: { 1746 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1747 break; 1748 } 1749 case IMMERSIVE_MODE_LOCK_MSG: { 1750 final boolean nextState = (msg.arg1 != 0); 1751 if (mUpdateLock.isHeld() != nextState) { 1752 if (DEBUG_IMMERSIVE) { 1753 final ActivityRecord r = (ActivityRecord) msg.obj; 1754 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1755 } 1756 if (nextState) { 1757 mUpdateLock.acquire(); 1758 } else { 1759 mUpdateLock.release(); 1760 } 1761 } 1762 break; 1763 } 1764 case PERSIST_URI_GRANTS_MSG: { 1765 writeGrantedUriPermissions(); 1766 break; 1767 } 1768 case REQUEST_ALL_PSS_MSG: { 1769 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1770 break; 1771 } 1772 case START_PROFILES_MSG: { 1773 synchronized (ActivityManagerService.this) { 1774 startProfilesLocked(); 1775 } 1776 break; 1777 } 1778 case UPDATE_TIME: { 1779 synchronized (ActivityManagerService.this) { 1780 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1781 ProcessRecord r = mLruProcesses.get(i); 1782 if (r.thread != null) { 1783 try { 1784 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1785 } catch (RemoteException ex) { 1786 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1787 } 1788 } 1789 } 1790 } 1791 break; 1792 } 1793 case SYSTEM_USER_START_MSG: { 1794 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1795 Integer.toString(msg.arg1), msg.arg1); 1796 mSystemServiceManager.startUser(msg.arg1); 1797 break; 1798 } 1799 case SYSTEM_USER_CURRENT_MSG: { 1800 mBatteryStatsService.noteEvent( 1801 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1802 Integer.toString(msg.arg2), msg.arg2); 1803 mBatteryStatsService.noteEvent( 1804 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1805 Integer.toString(msg.arg1), msg.arg1); 1806 mSystemServiceManager.switchUser(msg.arg1); 1807 break; 1808 } 1809 } 1810 } 1811 }; 1812 1813 static final int COLLECT_PSS_BG_MSG = 1; 1814 1815 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1816 @Override 1817 public void handleMessage(Message msg) { 1818 switch (msg.what) { 1819 case COLLECT_PSS_BG_MSG: { 1820 long start = SystemClock.uptimeMillis(); 1821 MemInfoReader memInfo = null; 1822 synchronized (ActivityManagerService.this) { 1823 if (mFullPssPending) { 1824 mFullPssPending = false; 1825 memInfo = new MemInfoReader(); 1826 } 1827 } 1828 if (memInfo != null) { 1829 updateCpuStatsNow(); 1830 long nativeTotalPss = 0; 1831 synchronized (mProcessCpuThread) { 1832 final int N = mProcessCpuTracker.countStats(); 1833 for (int j=0; j<N; j++) { 1834 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1835 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1836 // This is definitely an application process; skip it. 1837 continue; 1838 } 1839 synchronized (mPidsSelfLocked) { 1840 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1841 // This is one of our own processes; skip it. 1842 continue; 1843 } 1844 } 1845 nativeTotalPss += Debug.getPss(st.pid, null); 1846 } 1847 } 1848 memInfo.readMemInfo(); 1849 synchronized (this) { 1850 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1851 + (SystemClock.uptimeMillis()-start) + "ms"); 1852 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1853 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1854 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1855 +memInfo.getSlabSizeKb(), 1856 nativeTotalPss); 1857 } 1858 } 1859 1860 int i=0, num=0; 1861 long[] tmp = new long[1]; 1862 do { 1863 ProcessRecord proc; 1864 int procState; 1865 int pid; 1866 synchronized (ActivityManagerService.this) { 1867 if (i >= mPendingPssProcesses.size()) { 1868 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1869 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1870 mPendingPssProcesses.clear(); 1871 return; 1872 } 1873 proc = mPendingPssProcesses.get(i); 1874 procState = proc.pssProcState; 1875 if (proc.thread != null && procState == proc.setProcState) { 1876 pid = proc.pid; 1877 } else { 1878 proc = null; 1879 pid = 0; 1880 } 1881 i++; 1882 } 1883 if (proc != null) { 1884 long pss = Debug.getPss(pid, tmp); 1885 synchronized (ActivityManagerService.this) { 1886 if (proc.thread != null && proc.setProcState == procState 1887 && proc.pid == pid) { 1888 num++; 1889 proc.lastPssTime = SystemClock.uptimeMillis(); 1890 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1891 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1892 + ": " + pss + " lastPss=" + proc.lastPss 1893 + " state=" + ProcessList.makeProcStateString(procState)); 1894 if (proc.initialIdlePss == 0) { 1895 proc.initialIdlePss = pss; 1896 } 1897 proc.lastPss = pss; 1898 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1899 proc.lastCachedPss = pss; 1900 } 1901 } 1902 } 1903 } 1904 } while (true); 1905 } 1906 } 1907 } 1908 }; 1909 1910 /** 1911 * Monitor for package changes and update our internal state. 1912 */ 1913 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1914 @Override 1915 public void onPackageRemoved(String packageName, int uid) { 1916 // Remove all tasks with activities in the specified package from the list of recent tasks 1917 synchronized (ActivityManagerService.this) { 1918 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1919 TaskRecord tr = mRecentTasks.get(i); 1920 ComponentName cn = tr.intent.getComponent(); 1921 if (cn != null && cn.getPackageName().equals(packageName)) { 1922 // If the package name matches, remove the task and kill the process 1923 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1924 } 1925 } 1926 } 1927 } 1928 1929 @Override 1930 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1931 onPackageModified(packageName); 1932 return true; 1933 } 1934 1935 @Override 1936 public void onPackageModified(String packageName) { 1937 final PackageManager pm = mContext.getPackageManager(); 1938 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1939 new ArrayList<Pair<Intent, Integer>>(); 1940 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1941 // Copy the list of recent tasks so that we don't hold onto the lock on 1942 // ActivityManagerService for long periods while checking if components exist. 1943 synchronized (ActivityManagerService.this) { 1944 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1945 TaskRecord tr = mRecentTasks.get(i); 1946 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1947 } 1948 } 1949 // Check the recent tasks and filter out all tasks with components that no longer exist. 1950 Intent tmpI = new Intent(); 1951 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1952 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1953 ComponentName cn = p.first.getComponent(); 1954 if (cn != null && cn.getPackageName().equals(packageName)) { 1955 try { 1956 // Add the task to the list to remove if the component no longer exists 1957 tmpI.setComponent(cn); 1958 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1959 tasksToRemove.add(p.second); 1960 } 1961 } catch (Exception e) {} 1962 } 1963 } 1964 // Prune all the tasks with removed components from the list of recent tasks 1965 synchronized (ActivityManagerService.this) { 1966 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1967 // Remove the task but don't kill the process (since other components in that 1968 // package may still be running and in the background) 1969 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1970 } 1971 } 1972 } 1973 1974 @Override 1975 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1976 // Force stop the specified packages 1977 if (packages != null) { 1978 for (String pkg : packages) { 1979 synchronized (ActivityManagerService.this) { 1980 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1981 "finished booting")) { 1982 return true; 1983 } 1984 } 1985 } 1986 } 1987 return false; 1988 } 1989 }; 1990 1991 public void setSystemProcess() { 1992 try { 1993 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1994 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1995 ServiceManager.addService("meminfo", new MemBinder(this)); 1996 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1997 ServiceManager.addService("dbinfo", new DbBinder(this)); 1998 if (MONITOR_CPU_USAGE) { 1999 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2000 } 2001 ServiceManager.addService("permission", new PermissionController(this)); 2002 2003 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2004 "android", STOCK_PM_FLAGS); 2005 mSystemThread.installSystemApplicationInfo(info); 2006 2007 synchronized (this) { 2008 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2009 app.persistent = true; 2010 app.pid = MY_PID; 2011 app.maxAdj = ProcessList.SYSTEM_ADJ; 2012 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2013 mProcessNames.put(app.processName, app.uid, app); 2014 synchronized (mPidsSelfLocked) { 2015 mPidsSelfLocked.put(app.pid, app); 2016 } 2017 updateLruProcessLocked(app, false, null); 2018 updateOomAdjLocked(); 2019 } 2020 } catch (PackageManager.NameNotFoundException e) { 2021 throw new RuntimeException( 2022 "Unable to find android system package", e); 2023 } 2024 } 2025 2026 public void setWindowManager(WindowManagerService wm) { 2027 mWindowManager = wm; 2028 mStackSupervisor.setWindowManager(wm); 2029 } 2030 2031 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2032 mUsageStatsService = usageStatsManager; 2033 } 2034 2035 public void startObservingNativeCrashes() { 2036 final NativeCrashListener ncl = new NativeCrashListener(this); 2037 ncl.start(); 2038 } 2039 2040 public IAppOpsService getAppOpsService() { 2041 return mAppOpsService; 2042 } 2043 2044 static class MemBinder extends Binder { 2045 ActivityManagerService mActivityManagerService; 2046 MemBinder(ActivityManagerService activityManagerService) { 2047 mActivityManagerService = activityManagerService; 2048 } 2049 2050 @Override 2051 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2052 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2053 != PackageManager.PERMISSION_GRANTED) { 2054 pw.println("Permission Denial: can't dump meminfo from from pid=" 2055 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2056 + " without permission " + android.Manifest.permission.DUMP); 2057 return; 2058 } 2059 2060 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2061 } 2062 } 2063 2064 static class GraphicsBinder extends Binder { 2065 ActivityManagerService mActivityManagerService; 2066 GraphicsBinder(ActivityManagerService activityManagerService) { 2067 mActivityManagerService = activityManagerService; 2068 } 2069 2070 @Override 2071 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2072 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2073 != PackageManager.PERMISSION_GRANTED) { 2074 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2075 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2076 + " without permission " + android.Manifest.permission.DUMP); 2077 return; 2078 } 2079 2080 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2081 } 2082 } 2083 2084 static class DbBinder extends Binder { 2085 ActivityManagerService mActivityManagerService; 2086 DbBinder(ActivityManagerService activityManagerService) { 2087 mActivityManagerService = activityManagerService; 2088 } 2089 2090 @Override 2091 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2092 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2093 != PackageManager.PERMISSION_GRANTED) { 2094 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2095 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2096 + " without permission " + android.Manifest.permission.DUMP); 2097 return; 2098 } 2099 2100 mActivityManagerService.dumpDbInfo(fd, pw, args); 2101 } 2102 } 2103 2104 static class CpuBinder extends Binder { 2105 ActivityManagerService mActivityManagerService; 2106 CpuBinder(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 cpuinfo from from pid=" 2115 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2116 + " without permission " + android.Manifest.permission.DUMP); 2117 return; 2118 } 2119 2120 synchronized (mActivityManagerService.mProcessCpuThread) { 2121 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2122 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2123 SystemClock.uptimeMillis())); 2124 } 2125 } 2126 } 2127 2128 public static final class Lifecycle extends SystemService { 2129 private final ActivityManagerService mService; 2130 2131 public Lifecycle(Context context) { 2132 super(context); 2133 mService = new ActivityManagerService(context); 2134 } 2135 2136 @Override 2137 public void onStart() { 2138 mService.start(); 2139 } 2140 2141 public ActivityManagerService getService() { 2142 return mService; 2143 } 2144 } 2145 2146 // Note: This method is invoked on the main thread but may need to attach various 2147 // handlers to other threads. So take care to be explicit about the looper. 2148 public ActivityManagerService(Context systemContext) { 2149 mContext = systemContext; 2150 mFactoryTest = FactoryTest.getMode(); 2151 mSystemThread = ActivityThread.currentActivityThread(); 2152 2153 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2154 2155 mHandlerThread = new ServiceThread(TAG, 2156 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2157 mHandlerThread.start(); 2158 mHandler = new MainHandler(mHandlerThread.getLooper()); 2159 2160 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2161 "foreground", BROADCAST_FG_TIMEOUT, false); 2162 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2163 "background", BROADCAST_BG_TIMEOUT, true); 2164 mBroadcastQueues[0] = mFgBroadcastQueue; 2165 mBroadcastQueues[1] = mBgBroadcastQueue; 2166 2167 mServices = new ActiveServices(this); 2168 mProviderMap = new ProviderMap(this); 2169 2170 // TODO: Move creation of battery stats service outside of activity manager service. 2171 File dataDir = Environment.getDataDirectory(); 2172 File systemDir = new File(dataDir, "system"); 2173 systemDir.mkdirs(); 2174 mBatteryStatsService = new BatteryStatsService(new File( 2175 systemDir, "batterystats.bin").toString(), mHandler); 2176 mBatteryStatsService.getActiveStatistics().readLocked(); 2177 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2178 mOnBattery = DEBUG_POWER ? true 2179 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2180 mBatteryStatsService.getActiveStatistics().setCallback(this); 2181 2182 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2183 2184 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2185 2186 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2187 2188 // User 0 is the first and only user that runs at boot. 2189 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2190 mUserLru.add(Integer.valueOf(0)); 2191 updateStartedUserArrayLocked(); 2192 2193 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2194 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2195 2196 mConfiguration.setToDefaults(); 2197 mConfiguration.setLocale(Locale.getDefault()); 2198 2199 mConfigurationSeq = mConfiguration.seq = 1; 2200 mProcessCpuTracker.init(); 2201 2202 mHasRecents = mContext.getResources().getBoolean( 2203 com.android.internal.R.bool.config_hasRecents); 2204 2205 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2206 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2207 mStackSupervisor = new ActivityStackSupervisor(this); 2208 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2209 2210 mProcessCpuThread = new Thread("CpuTracker") { 2211 @Override 2212 public void run() { 2213 while (true) { 2214 try { 2215 try { 2216 synchronized(this) { 2217 final long now = SystemClock.uptimeMillis(); 2218 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2219 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2220 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2221 // + ", write delay=" + nextWriteDelay); 2222 if (nextWriteDelay < nextCpuDelay) { 2223 nextCpuDelay = nextWriteDelay; 2224 } 2225 if (nextCpuDelay > 0) { 2226 mProcessCpuMutexFree.set(true); 2227 this.wait(nextCpuDelay); 2228 } 2229 } 2230 } catch (InterruptedException e) { 2231 } 2232 updateCpuStatsNow(); 2233 } catch (Exception e) { 2234 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2235 } 2236 } 2237 } 2238 }; 2239 2240 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2241 2242 Watchdog.getInstance().addMonitor(this); 2243 Watchdog.getInstance().addThread(mHandler); 2244 } 2245 2246 public void setSystemServiceManager(SystemServiceManager mgr) { 2247 mSystemServiceManager = mgr; 2248 } 2249 2250 private void start() { 2251 Process.removeAllProcessGroups(); 2252 mProcessCpuThread.start(); 2253 2254 mBatteryStatsService.publish(mContext); 2255 mAppOpsService.publish(mContext); 2256 Slog.d("AppOps", "AppOpsService published"); 2257 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2258 } 2259 2260 public void initPowerManagement() { 2261 mStackSupervisor.initPowerManagement(); 2262 mBatteryStatsService.initPowerManagement(); 2263 } 2264 2265 @Override 2266 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2267 throws RemoteException { 2268 if (code == SYSPROPS_TRANSACTION) { 2269 // We need to tell all apps about the system property change. 2270 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2271 synchronized(this) { 2272 final int NP = mProcessNames.getMap().size(); 2273 for (int ip=0; ip<NP; ip++) { 2274 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2275 final int NA = apps.size(); 2276 for (int ia=0; ia<NA; ia++) { 2277 ProcessRecord app = apps.valueAt(ia); 2278 if (app.thread != null) { 2279 procs.add(app.thread.asBinder()); 2280 } 2281 } 2282 } 2283 } 2284 2285 int N = procs.size(); 2286 for (int i=0; i<N; i++) { 2287 Parcel data2 = Parcel.obtain(); 2288 try { 2289 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2290 } catch (RemoteException e) { 2291 } 2292 data2.recycle(); 2293 } 2294 } 2295 try { 2296 return super.onTransact(code, data, reply, flags); 2297 } catch (RuntimeException e) { 2298 // The activity manager only throws security exceptions, so let's 2299 // log all others. 2300 if (!(e instanceof SecurityException)) { 2301 Slog.wtf(TAG, "Activity Manager Crash", e); 2302 } 2303 throw e; 2304 } 2305 } 2306 2307 void updateCpuStats() { 2308 final long now = SystemClock.uptimeMillis(); 2309 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2310 return; 2311 } 2312 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2313 synchronized (mProcessCpuThread) { 2314 mProcessCpuThread.notify(); 2315 } 2316 } 2317 } 2318 2319 void updateCpuStatsNow() { 2320 synchronized (mProcessCpuThread) { 2321 mProcessCpuMutexFree.set(false); 2322 final long now = SystemClock.uptimeMillis(); 2323 boolean haveNewCpuStats = false; 2324 2325 if (MONITOR_CPU_USAGE && 2326 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2327 mLastCpuTime.set(now); 2328 haveNewCpuStats = true; 2329 mProcessCpuTracker.update(); 2330 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2331 //Slog.i(TAG, "Total CPU usage: " 2332 // + mProcessCpu.getTotalCpuPercent() + "%"); 2333 2334 // Slog the cpu usage if the property is set. 2335 if ("true".equals(SystemProperties.get("events.cpu"))) { 2336 int user = mProcessCpuTracker.getLastUserTime(); 2337 int system = mProcessCpuTracker.getLastSystemTime(); 2338 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2339 int irq = mProcessCpuTracker.getLastIrqTime(); 2340 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2341 int idle = mProcessCpuTracker.getLastIdleTime(); 2342 2343 int total = user + system + iowait + irq + softIrq + idle; 2344 if (total == 0) total = 1; 2345 2346 EventLog.writeEvent(EventLogTags.CPU, 2347 ((user+system+iowait+irq+softIrq) * 100) / total, 2348 (user * 100) / total, 2349 (system * 100) / total, 2350 (iowait * 100) / total, 2351 (irq * 100) / total, 2352 (softIrq * 100) / total); 2353 } 2354 } 2355 2356 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2357 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2358 synchronized(bstats) { 2359 synchronized(mPidsSelfLocked) { 2360 if (haveNewCpuStats) { 2361 if (mOnBattery) { 2362 int perc = bstats.startAddingCpuLocked(); 2363 int totalUTime = 0; 2364 int totalSTime = 0; 2365 final int N = mProcessCpuTracker.countStats(); 2366 for (int i=0; i<N; i++) { 2367 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2368 if (!st.working) { 2369 continue; 2370 } 2371 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2372 int otherUTime = (st.rel_utime*perc)/100; 2373 int otherSTime = (st.rel_stime*perc)/100; 2374 totalUTime += otherUTime; 2375 totalSTime += otherSTime; 2376 if (pr != null) { 2377 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2378 if (ps == null || !ps.isActive()) { 2379 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2380 pr.info.uid, pr.processName); 2381 } 2382 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2383 st.rel_stime-otherSTime); 2384 ps.addSpeedStepTimes(cpuSpeedTimes); 2385 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2386 } else { 2387 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2388 if (ps == null || !ps.isActive()) { 2389 st.batteryStats = ps = bstats.getProcessStatsLocked( 2390 bstats.mapUid(st.uid), st.name); 2391 } 2392 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2393 st.rel_stime-otherSTime); 2394 ps.addSpeedStepTimes(cpuSpeedTimes); 2395 } 2396 } 2397 bstats.finishAddingCpuLocked(perc, totalUTime, 2398 totalSTime, cpuSpeedTimes); 2399 } 2400 } 2401 } 2402 2403 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2404 mLastWriteTime = now; 2405 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2406 } 2407 } 2408 } 2409 } 2410 2411 @Override 2412 public void batteryNeedsCpuUpdate() { 2413 updateCpuStatsNow(); 2414 } 2415 2416 @Override 2417 public void batteryPowerChanged(boolean onBattery) { 2418 // When plugging in, update the CPU stats first before changing 2419 // the plug state. 2420 updateCpuStatsNow(); 2421 synchronized (this) { 2422 synchronized(mPidsSelfLocked) { 2423 mOnBattery = DEBUG_POWER ? true : onBattery; 2424 } 2425 } 2426 } 2427 2428 /** 2429 * Initialize the application bind args. These are passed to each 2430 * process when the bindApplication() IPC is sent to the process. They're 2431 * lazily setup to make sure the services are running when they're asked for. 2432 */ 2433 private HashMap<String, IBinder> getCommonServicesLocked() { 2434 if (mAppBindArgs == null) { 2435 mAppBindArgs = new HashMap<String, IBinder>(); 2436 2437 // Setup the application init args 2438 mAppBindArgs.put("package", ServiceManager.getService("package")); 2439 mAppBindArgs.put("window", ServiceManager.getService("window")); 2440 mAppBindArgs.put(Context.ALARM_SERVICE, 2441 ServiceManager.getService(Context.ALARM_SERVICE)); 2442 } 2443 return mAppBindArgs; 2444 } 2445 2446 final void setFocusedActivityLocked(ActivityRecord r) { 2447 if (mFocusedActivity != r) { 2448 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2449 mFocusedActivity = r; 2450 if (r.task != null && r.task.voiceInteractor != null) { 2451 startRunningVoiceLocked(); 2452 } else { 2453 finishRunningVoiceLocked(); 2454 } 2455 mStackSupervisor.setFocusedStack(r); 2456 if (r != null) { 2457 mWindowManager.setFocusedApp(r.appToken, true); 2458 } 2459 applyUpdateLockStateLocked(r); 2460 } 2461 } 2462 2463 final void clearFocusedActivity(ActivityRecord r) { 2464 if (mFocusedActivity == r) { 2465 mFocusedActivity = null; 2466 } 2467 } 2468 2469 @Override 2470 public void setFocusedStack(int stackId) { 2471 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2472 synchronized (ActivityManagerService.this) { 2473 ActivityStack stack = mStackSupervisor.getStack(stackId); 2474 if (stack != null) { 2475 ActivityRecord r = stack.topRunningActivityLocked(null); 2476 if (r != null) { 2477 setFocusedActivityLocked(r); 2478 } 2479 } 2480 } 2481 } 2482 2483 @Override 2484 public void notifyActivityDrawn(IBinder token) { 2485 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2486 synchronized (this) { 2487 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2488 if (r != null) { 2489 r.task.stack.notifyActivityDrawnLocked(r); 2490 } 2491 } 2492 } 2493 2494 final void applyUpdateLockStateLocked(ActivityRecord r) { 2495 // Modifications to the UpdateLock state are done on our handler, outside 2496 // the activity manager's locks. The new state is determined based on the 2497 // state *now* of the relevant activity record. The object is passed to 2498 // the handler solely for logging detail, not to be consulted/modified. 2499 final boolean nextState = r != null && r.immersive; 2500 mHandler.sendMessage( 2501 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2502 } 2503 2504 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2505 Message msg = Message.obtain(); 2506 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2507 msg.obj = r.task.askedCompatMode ? null : r; 2508 mHandler.sendMessage(msg); 2509 } 2510 2511 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2512 String what, Object obj, ProcessRecord srcApp) { 2513 app.lastActivityTime = now; 2514 2515 if (app.activities.size() > 0) { 2516 // Don't want to touch dependent processes that are hosting activities. 2517 return index; 2518 } 2519 2520 int lrui = mLruProcesses.lastIndexOf(app); 2521 if (lrui < 0) { 2522 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2523 + what + " " + obj + " from " + srcApp); 2524 return index; 2525 } 2526 2527 if (lrui >= index) { 2528 // Don't want to cause this to move dependent processes *back* in the 2529 // list as if they were less frequently used. 2530 return index; 2531 } 2532 2533 if (lrui >= mLruProcessActivityStart) { 2534 // Don't want to touch dependent processes that are hosting activities. 2535 return index; 2536 } 2537 2538 mLruProcesses.remove(lrui); 2539 if (index > 0) { 2540 index--; 2541 } 2542 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2543 + " in LRU list: " + app); 2544 mLruProcesses.add(index, app); 2545 return index; 2546 } 2547 2548 final void removeLruProcessLocked(ProcessRecord app) { 2549 int lrui = mLruProcesses.lastIndexOf(app); 2550 if (lrui >= 0) { 2551 if (lrui <= mLruProcessActivityStart) { 2552 mLruProcessActivityStart--; 2553 } 2554 if (lrui <= mLruProcessServiceStart) { 2555 mLruProcessServiceStart--; 2556 } 2557 mLruProcesses.remove(lrui); 2558 } 2559 } 2560 2561 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2562 ProcessRecord client) { 2563 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2564 || app.treatLikeActivity; 2565 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2566 if (!activityChange && hasActivity) { 2567 // The process has activities, so we are only allowing activity-based adjustments 2568 // to move it. It should be kept in the front of the list with other 2569 // processes that have activities, and we don't want those to change their 2570 // order except due to activity operations. 2571 return; 2572 } 2573 2574 mLruSeq++; 2575 final long now = SystemClock.uptimeMillis(); 2576 app.lastActivityTime = now; 2577 2578 // First a quick reject: if the app is already at the position we will 2579 // put it, then there is nothing to do. 2580 if (hasActivity) { 2581 final int N = mLruProcesses.size(); 2582 if (N > 0 && mLruProcesses.get(N-1) == app) { 2583 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2584 return; 2585 } 2586 } else { 2587 if (mLruProcessServiceStart > 0 2588 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2589 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2590 return; 2591 } 2592 } 2593 2594 int lrui = mLruProcesses.lastIndexOf(app); 2595 2596 if (app.persistent && lrui >= 0) { 2597 // We don't care about the position of persistent processes, as long as 2598 // they are in the list. 2599 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2600 return; 2601 } 2602 2603 /* In progress: compute new position first, so we can avoid doing work 2604 if the process is not actually going to move. Not yet working. 2605 int addIndex; 2606 int nextIndex; 2607 boolean inActivity = false, inService = false; 2608 if (hasActivity) { 2609 // Process has activities, put it at the very tipsy-top. 2610 addIndex = mLruProcesses.size(); 2611 nextIndex = mLruProcessServiceStart; 2612 inActivity = true; 2613 } else if (hasService) { 2614 // Process has services, put it at the top of the service list. 2615 addIndex = mLruProcessActivityStart; 2616 nextIndex = mLruProcessServiceStart; 2617 inActivity = true; 2618 inService = true; 2619 } else { 2620 // Process not otherwise of interest, it goes to the top of the non-service area. 2621 addIndex = mLruProcessServiceStart; 2622 if (client != null) { 2623 int clientIndex = mLruProcesses.lastIndexOf(client); 2624 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2625 + app); 2626 if (clientIndex >= 0 && addIndex > clientIndex) { 2627 addIndex = clientIndex; 2628 } 2629 } 2630 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2631 } 2632 2633 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2634 + mLruProcessActivityStart + "): " + app); 2635 */ 2636 2637 if (lrui >= 0) { 2638 if (lrui < mLruProcessActivityStart) { 2639 mLruProcessActivityStart--; 2640 } 2641 if (lrui < mLruProcessServiceStart) { 2642 mLruProcessServiceStart--; 2643 } 2644 /* 2645 if (addIndex > lrui) { 2646 addIndex--; 2647 } 2648 if (nextIndex > lrui) { 2649 nextIndex--; 2650 } 2651 */ 2652 mLruProcesses.remove(lrui); 2653 } 2654 2655 /* 2656 mLruProcesses.add(addIndex, app); 2657 if (inActivity) { 2658 mLruProcessActivityStart++; 2659 } 2660 if (inService) { 2661 mLruProcessActivityStart++; 2662 } 2663 */ 2664 2665 int nextIndex; 2666 if (hasActivity) { 2667 final int N = mLruProcesses.size(); 2668 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2669 // Process doesn't have activities, but has clients with 2670 // activities... move it up, but one below the top (the top 2671 // should always have a real activity). 2672 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2673 mLruProcesses.add(N-1, app); 2674 // To keep it from spamming the LRU list (by making a bunch of clients), 2675 // we will push down any other entries owned by the app. 2676 final int uid = app.info.uid; 2677 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2678 ProcessRecord subProc = mLruProcesses.get(i); 2679 if (subProc.info.uid == uid) { 2680 // We want to push this one down the list. If the process after 2681 // it is for the same uid, however, don't do so, because we don't 2682 // want them internally to be re-ordered. 2683 if (mLruProcesses.get(i-1).info.uid != uid) { 2684 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2685 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2686 ProcessRecord tmp = mLruProcesses.get(i); 2687 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2688 mLruProcesses.set(i-1, tmp); 2689 i--; 2690 } 2691 } else { 2692 // A gap, we can stop here. 2693 break; 2694 } 2695 } 2696 } else { 2697 // Process has activities, put it at the very tipsy-top. 2698 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2699 mLruProcesses.add(app); 2700 } 2701 nextIndex = mLruProcessServiceStart; 2702 } else if (hasService) { 2703 // Process has services, put it at the top of the service list. 2704 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2705 mLruProcesses.add(mLruProcessActivityStart, app); 2706 nextIndex = mLruProcessServiceStart; 2707 mLruProcessActivityStart++; 2708 } else { 2709 // Process not otherwise of interest, it goes to the top of the non-service area. 2710 int index = mLruProcessServiceStart; 2711 if (client != null) { 2712 // If there is a client, don't allow the process to be moved up higher 2713 // in the list than that client. 2714 int clientIndex = mLruProcesses.lastIndexOf(client); 2715 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2716 + " when updating " + app); 2717 if (clientIndex <= lrui) { 2718 // Don't allow the client index restriction to push it down farther in the 2719 // list than it already is. 2720 clientIndex = lrui; 2721 } 2722 if (clientIndex >= 0 && index > clientIndex) { 2723 index = clientIndex; 2724 } 2725 } 2726 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2727 mLruProcesses.add(index, app); 2728 nextIndex = index-1; 2729 mLruProcessActivityStart++; 2730 mLruProcessServiceStart++; 2731 } 2732 2733 // If the app is currently using a content provider or service, 2734 // bump those processes as well. 2735 for (int j=app.connections.size()-1; j>=0; j--) { 2736 ConnectionRecord cr = app.connections.valueAt(j); 2737 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2738 && cr.binding.service.app != null 2739 && cr.binding.service.app.lruSeq != mLruSeq 2740 && !cr.binding.service.app.persistent) { 2741 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2742 "service connection", cr, app); 2743 } 2744 } 2745 for (int j=app.conProviders.size()-1; j>=0; j--) { 2746 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2747 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2748 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2749 "provider reference", cpr, app); 2750 } 2751 } 2752 } 2753 2754 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2755 if (uid == Process.SYSTEM_UID) { 2756 // The system gets to run in any process. If there are multiple 2757 // processes with the same uid, just pick the first (this 2758 // should never happen). 2759 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2760 if (procs == null) return null; 2761 final int N = procs.size(); 2762 for (int i = 0; i < N; i++) { 2763 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2764 } 2765 } 2766 ProcessRecord proc = mProcessNames.get(processName, uid); 2767 if (false && proc != null && !keepIfLarge 2768 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2769 && proc.lastCachedPss >= 4000) { 2770 // Turn this condition on to cause killing to happen regularly, for testing. 2771 if (proc.baseProcessTracker != null) { 2772 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2773 } 2774 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2775 + "k from cached"); 2776 } else if (proc != null && !keepIfLarge 2777 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2778 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2779 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2780 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2781 if (proc.baseProcessTracker != null) { 2782 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2783 } 2784 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2785 + "k from cached"); 2786 } 2787 } 2788 return proc; 2789 } 2790 2791 void ensurePackageDexOpt(String packageName) { 2792 IPackageManager pm = AppGlobals.getPackageManager(); 2793 try { 2794 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2795 mDidDexOpt = true; 2796 } 2797 } catch (RemoteException e) { 2798 } 2799 } 2800 2801 boolean isNextTransitionForward() { 2802 int transit = mWindowManager.getPendingAppTransition(); 2803 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2804 || transit == AppTransition.TRANSIT_TASK_OPEN 2805 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2806 } 2807 2808 final ProcessRecord startProcessLocked(String processName, 2809 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2810 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2811 boolean isolated, boolean keepIfLarge) { 2812 ProcessRecord app; 2813 if (!isolated) { 2814 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2815 } else { 2816 // If this is an isolated process, it can't re-use an existing process. 2817 app = null; 2818 } 2819 // We don't have to do anything more if: 2820 // (1) There is an existing application record; and 2821 // (2) The caller doesn't think it is dead, OR there is no thread 2822 // object attached to it so we know it couldn't have crashed; and 2823 // (3) There is a pid assigned to it, so it is either starting or 2824 // already running. 2825 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2826 + " app=" + app + " knownToBeDead=" + knownToBeDead 2827 + " thread=" + (app != null ? app.thread : null) 2828 + " pid=" + (app != null ? app.pid : -1)); 2829 if (app != null && app.pid > 0) { 2830 if (!knownToBeDead || app.thread == null) { 2831 // We already have the app running, or are waiting for it to 2832 // come up (we have a pid but not yet its thread), so keep it. 2833 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2834 // If this is a new package in the process, add the package to the list 2835 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2836 return app; 2837 } 2838 2839 // An application record is attached to a previous process, 2840 // clean it up now. 2841 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2842 Process.killProcessGroup(app.info.uid, app.pid); 2843 handleAppDiedLocked(app, true, true); 2844 } 2845 2846 String hostingNameStr = hostingName != null 2847 ? hostingName.flattenToShortString() : null; 2848 2849 if (!isolated) { 2850 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2851 // If we are in the background, then check to see if this process 2852 // is bad. If so, we will just silently fail. 2853 if (mBadProcesses.get(info.processName, info.uid) != null) { 2854 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2855 + "/" + info.processName); 2856 return null; 2857 } 2858 } else { 2859 // When the user is explicitly starting a process, then clear its 2860 // crash count so that we won't make it bad until they see at 2861 // least one crash dialog again, and make the process good again 2862 // if it had been bad. 2863 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2864 + "/" + info.processName); 2865 mProcessCrashTimes.remove(info.processName, info.uid); 2866 if (mBadProcesses.get(info.processName, info.uid) != null) { 2867 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2868 UserHandle.getUserId(info.uid), info.uid, 2869 info.processName); 2870 mBadProcesses.remove(info.processName, info.uid); 2871 if (app != null) { 2872 app.bad = false; 2873 } 2874 } 2875 } 2876 } 2877 2878 if (app == null) { 2879 app = newProcessRecordLocked(info, processName, isolated); 2880 if (app == null) { 2881 Slog.w(TAG, "Failed making new process record for " 2882 + processName + "/" + info.uid + " isolated=" + isolated); 2883 return null; 2884 } 2885 mProcessNames.put(processName, app.uid, app); 2886 if (isolated) { 2887 mIsolatedProcesses.put(app.uid, app); 2888 } 2889 } else { 2890 // If this is a new package in the process, add the package to the list 2891 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2892 } 2893 2894 // If the system is not ready yet, then hold off on starting this 2895 // process until it is. 2896 if (!mProcessesReady 2897 && !isAllowedWhileBooting(info) 2898 && !allowWhileBooting) { 2899 if (!mProcessesOnHold.contains(app)) { 2900 mProcessesOnHold.add(app); 2901 } 2902 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2903 return app; 2904 } 2905 2906 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2907 return (app.pid != 0) ? app : null; 2908 } 2909 2910 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2911 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2912 } 2913 2914 private final void startProcessLocked(ProcessRecord app, 2915 String hostingType, String hostingNameStr, String abiOverride) { 2916 if (app.pid > 0 && app.pid != MY_PID) { 2917 synchronized (mPidsSelfLocked) { 2918 mPidsSelfLocked.remove(app.pid); 2919 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2920 } 2921 app.setPid(0); 2922 } 2923 2924 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2925 "startProcessLocked removing on hold: " + app); 2926 mProcessesOnHold.remove(app); 2927 2928 updateCpuStats(); 2929 2930 try { 2931 int uid = app.uid; 2932 2933 int[] gids = null; 2934 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2935 if (!app.isolated) { 2936 int[] permGids = null; 2937 try { 2938 final PackageManager pm = mContext.getPackageManager(); 2939 permGids = pm.getPackageGids(app.info.packageName); 2940 2941 if (Environment.isExternalStorageEmulated()) { 2942 if (pm.checkPermission( 2943 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2944 app.info.packageName) == PERMISSION_GRANTED) { 2945 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2946 } else { 2947 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2948 } 2949 } 2950 } catch (PackageManager.NameNotFoundException e) { 2951 Slog.w(TAG, "Unable to retrieve gids", e); 2952 } 2953 2954 /* 2955 * Add shared application and profile GIDs so applications can share some 2956 * resources like shared libraries and access user-wide resources 2957 */ 2958 if (permGids == null) { 2959 gids = new int[2]; 2960 } else { 2961 gids = new int[permGids.length + 2]; 2962 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2963 } 2964 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2965 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2966 } 2967 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2968 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2969 && mTopComponent != null 2970 && app.processName.equals(mTopComponent.getPackageName())) { 2971 uid = 0; 2972 } 2973 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2974 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2975 uid = 0; 2976 } 2977 } 2978 int debugFlags = 0; 2979 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2981 // Also turn on CheckJNI for debuggable apps. It's quite 2982 // awkward to turn on otherwise. 2983 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2984 } 2985 // Run the app in safe mode if its manifest requests so or the 2986 // system is booted in safe mode. 2987 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2988 mSafeMode == true) { 2989 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2990 } 2991 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2992 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2993 } 2994 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2995 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2996 } 2997 if ("1".equals(SystemProperties.get("debug.assert"))) { 2998 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2999 } 3000 3001 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3002 if (requiredAbi == null) { 3003 requiredAbi = Build.SUPPORTED_ABIS[0]; 3004 } 3005 3006 // Start the process. It will either succeed and return a result containing 3007 // the PID of the new process, or else throw a RuntimeException. 3008 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 3009 app.processName, uid, uid, gids, debugFlags, mountExternal, 3010 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3011 3012 if (app.isolated) { 3013 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3014 } 3015 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3016 3017 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3018 UserHandle.getUserId(uid), startResult.pid, uid, 3019 app.processName, hostingType, 3020 hostingNameStr != null ? hostingNameStr : ""); 3021 3022 if (app.persistent) { 3023 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3024 } 3025 3026 StringBuilder buf = mStringBuilder; 3027 buf.setLength(0); 3028 buf.append("Start proc "); 3029 buf.append(app.processName); 3030 buf.append(" for "); 3031 buf.append(hostingType); 3032 if (hostingNameStr != null) { 3033 buf.append(" "); 3034 buf.append(hostingNameStr); 3035 } 3036 buf.append(": pid="); 3037 buf.append(startResult.pid); 3038 buf.append(" uid="); 3039 buf.append(uid); 3040 buf.append(" gids={"); 3041 if (gids != null) { 3042 for (int gi=0; gi<gids.length; gi++) { 3043 if (gi != 0) buf.append(", "); 3044 buf.append(gids[gi]); 3045 3046 } 3047 } 3048 buf.append("}"); 3049 if (requiredAbi != null) { 3050 buf.append(" abi="); 3051 buf.append(requiredAbi); 3052 } 3053 Slog.i(TAG, buf.toString()); 3054 app.setPid(startResult.pid); 3055 app.usingWrapper = startResult.usingWrapper; 3056 app.removed = false; 3057 app.killedByAm = false; 3058 synchronized (mPidsSelfLocked) { 3059 this.mPidsSelfLocked.put(startResult.pid, app); 3060 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3061 msg.obj = app; 3062 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3063 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3064 } 3065 } catch (RuntimeException e) { 3066 // XXX do better error recovery. 3067 app.setPid(0); 3068 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3069 if (app.isolated) { 3070 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3071 } 3072 Slog.e(TAG, "Failure starting process " + app.processName, e); 3073 } 3074 } 3075 3076 void updateUsageStats(ActivityRecord component, boolean resumed) { 3077 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3078 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3079 if (resumed) { 3080 if (mUsageStatsService != null) { 3081 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3082 UsageStats.Event.MOVE_TO_FOREGROUND); 3083 } 3084 synchronized (stats) { 3085 stats.noteActivityResumedLocked(component.app.uid); 3086 } 3087 } else { 3088 if (mUsageStatsService != null) { 3089 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3090 UsageStats.Event.MOVE_TO_BACKGROUND); 3091 } 3092 synchronized (stats) { 3093 stats.noteActivityPausedLocked(component.app.uid); 3094 } 3095 } 3096 } 3097 3098 Intent getHomeIntent() { 3099 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3100 intent.setComponent(mTopComponent); 3101 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3102 intent.addCategory(Intent.CATEGORY_HOME); 3103 } 3104 return intent; 3105 } 3106 3107 boolean startHomeActivityLocked(int userId) { 3108 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3109 && mTopAction == null) { 3110 // We are running in factory test mode, but unable to find 3111 // the factory test app, so just sit around displaying the 3112 // error message and don't try to start anything. 3113 return false; 3114 } 3115 Intent intent = getHomeIntent(); 3116 ActivityInfo aInfo = 3117 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3118 if (aInfo != null) { 3119 intent.setComponent(new ComponentName( 3120 aInfo.applicationInfo.packageName, aInfo.name)); 3121 // Don't do this if the home app is currently being 3122 // instrumented. 3123 aInfo = new ActivityInfo(aInfo); 3124 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3125 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3126 aInfo.applicationInfo.uid, true); 3127 if (app == null || app.instrumentationClass == null) { 3128 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3129 mStackSupervisor.startHomeActivity(intent, aInfo); 3130 } 3131 } 3132 3133 return true; 3134 } 3135 3136 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3137 ActivityInfo ai = null; 3138 ComponentName comp = intent.getComponent(); 3139 try { 3140 if (comp != null) { 3141 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3142 } else { 3143 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3144 intent, 3145 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3146 flags, userId); 3147 3148 if (info != null) { 3149 ai = info.activityInfo; 3150 } 3151 } 3152 } catch (RemoteException e) { 3153 // ignore 3154 } 3155 3156 return ai; 3157 } 3158 3159 /** 3160 * Starts the "new version setup screen" if appropriate. 3161 */ 3162 void startSetupActivityLocked() { 3163 // Only do this once per boot. 3164 if (mCheckedForSetup) { 3165 return; 3166 } 3167 3168 // We will show this screen if the current one is a different 3169 // version than the last one shown, and we are not running in 3170 // low-level factory test mode. 3171 final ContentResolver resolver = mContext.getContentResolver(); 3172 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3173 Settings.Global.getInt(resolver, 3174 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3175 mCheckedForSetup = true; 3176 3177 // See if we should be showing the platform update setup UI. 3178 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3179 List<ResolveInfo> ris = mContext.getPackageManager() 3180 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3181 3182 // We don't allow third party apps to replace this. 3183 ResolveInfo ri = null; 3184 for (int i=0; ris != null && i<ris.size(); i++) { 3185 if ((ris.get(i).activityInfo.applicationInfo.flags 3186 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3187 ri = ris.get(i); 3188 break; 3189 } 3190 } 3191 3192 if (ri != null) { 3193 String vers = ri.activityInfo.metaData != null 3194 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3195 : null; 3196 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3197 vers = ri.activityInfo.applicationInfo.metaData.getString( 3198 Intent.METADATA_SETUP_VERSION); 3199 } 3200 String lastVers = Settings.Secure.getString( 3201 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3202 if (vers != null && !vers.equals(lastVers)) { 3203 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3204 intent.setComponent(new ComponentName( 3205 ri.activityInfo.packageName, ri.activityInfo.name)); 3206 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3207 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3208 } 3209 } 3210 } 3211 } 3212 3213 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3214 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3215 } 3216 3217 void enforceNotIsolatedCaller(String caller) { 3218 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3219 throw new SecurityException("Isolated process not allowed to call " + caller); 3220 } 3221 } 3222 3223 @Override 3224 public int getFrontActivityScreenCompatMode() { 3225 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3226 synchronized (this) { 3227 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3228 } 3229 } 3230 3231 @Override 3232 public void setFrontActivityScreenCompatMode(int mode) { 3233 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3234 "setFrontActivityScreenCompatMode"); 3235 synchronized (this) { 3236 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3237 } 3238 } 3239 3240 @Override 3241 public int getPackageScreenCompatMode(String packageName) { 3242 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3243 synchronized (this) { 3244 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3245 } 3246 } 3247 3248 @Override 3249 public void setPackageScreenCompatMode(String packageName, int mode) { 3250 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3251 "setPackageScreenCompatMode"); 3252 synchronized (this) { 3253 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3254 } 3255 } 3256 3257 @Override 3258 public boolean getPackageAskScreenCompat(String packageName) { 3259 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3260 synchronized (this) { 3261 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3262 } 3263 } 3264 3265 @Override 3266 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3267 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3268 "setPackageAskScreenCompat"); 3269 synchronized (this) { 3270 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3271 } 3272 } 3273 3274 private void dispatchProcessesChanged() { 3275 int N; 3276 synchronized (this) { 3277 N = mPendingProcessChanges.size(); 3278 if (mActiveProcessChanges.length < N) { 3279 mActiveProcessChanges = new ProcessChangeItem[N]; 3280 } 3281 mPendingProcessChanges.toArray(mActiveProcessChanges); 3282 mAvailProcessChanges.addAll(mPendingProcessChanges); 3283 mPendingProcessChanges.clear(); 3284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3285 } 3286 3287 int i = mProcessObservers.beginBroadcast(); 3288 while (i > 0) { 3289 i--; 3290 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3291 if (observer != null) { 3292 try { 3293 for (int j=0; j<N; j++) { 3294 ProcessChangeItem item = mActiveProcessChanges[j]; 3295 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3296 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3297 + item.pid + " uid=" + item.uid + ": " 3298 + item.foregroundActivities); 3299 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3300 item.foregroundActivities); 3301 } 3302 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3303 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3304 + item.pid + " uid=" + item.uid + ": " + item.processState); 3305 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3306 } 3307 } 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 private void dispatchProcessDied(int pid, int uid) { 3316 int i = mProcessObservers.beginBroadcast(); 3317 while (i > 0) { 3318 i--; 3319 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3320 if (observer != null) { 3321 try { 3322 observer.onProcessDied(pid, uid); 3323 } catch (RemoteException e) { 3324 } 3325 } 3326 } 3327 mProcessObservers.finishBroadcast(); 3328 } 3329 3330 @Override 3331 public final int startActivity(IApplicationThread caller, String callingPackage, 3332 Intent intent, String resolvedType, IBinder resultTo, 3333 String resultWho, int requestCode, int startFlags, 3334 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3335 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3336 resultWho, requestCode, 3337 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3338 } 3339 3340 @Override 3341 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3342 Intent intent, String resolvedType, IBinder resultTo, 3343 String resultWho, int requestCode, int startFlags, 3344 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3345 enforceNotIsolatedCaller("startActivity"); 3346 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3347 false, ALLOW_FULL_ONLY, "startActivity", null); 3348 // TODO: Switch to user app stacks here. 3349 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3350 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3351 null, null, options, userId, null); 3352 } 3353 3354 @Override 3355 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3356 Intent intent, String resolvedType, IBinder resultTo, 3357 String resultWho, int requestCode, int startFlags, String profileFile, 3358 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3359 enforceNotIsolatedCaller("startActivityAndWait"); 3360 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3361 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3362 WaitResult res = new WaitResult(); 3363 // TODO: Switch to user app stacks here. 3364 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3365 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3366 res, null, options, userId, null); 3367 return res; 3368 } 3369 3370 @Override 3371 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3372 Intent intent, String resolvedType, IBinder resultTo, 3373 String resultWho, int requestCode, int startFlags, Configuration config, 3374 Bundle options, int userId) { 3375 enforceNotIsolatedCaller("startActivityWithConfig"); 3376 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3377 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3378 // TODO: Switch to user app stacks here. 3379 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3380 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3381 null, null, null, config, options, userId, null); 3382 return ret; 3383 } 3384 3385 @Override 3386 public int startActivityIntentSender(IApplicationThread caller, 3387 IntentSender intent, Intent fillInIntent, String resolvedType, 3388 IBinder resultTo, String resultWho, int requestCode, 3389 int flagsMask, int flagsValues, Bundle options) { 3390 enforceNotIsolatedCaller("startActivityIntentSender"); 3391 // Refuse possible leaked file descriptors 3392 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3393 throw new IllegalArgumentException("File descriptors passed in Intent"); 3394 } 3395 3396 IIntentSender sender = intent.getTarget(); 3397 if (!(sender instanceof PendingIntentRecord)) { 3398 throw new IllegalArgumentException("Bad PendingIntent object"); 3399 } 3400 3401 PendingIntentRecord pir = (PendingIntentRecord)sender; 3402 3403 synchronized (this) { 3404 // If this is coming from the currently resumed activity, it is 3405 // effectively saying that app switches are allowed at this point. 3406 final ActivityStack stack = getFocusedStack(); 3407 if (stack.mResumedActivity != null && 3408 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3409 mAppSwitchesAllowedTime = 0; 3410 } 3411 } 3412 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3413 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3414 return ret; 3415 } 3416 3417 @Override 3418 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3419 Intent intent, String resolvedType, IVoiceInteractionSession session, 3420 IVoiceInteractor interactor, int startFlags, String profileFile, 3421 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3422 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3423 != PackageManager.PERMISSION_GRANTED) { 3424 String msg = "Permission Denial: startVoiceActivity() from pid=" 3425 + Binder.getCallingPid() 3426 + ", uid=" + Binder.getCallingUid() 3427 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3428 Slog.w(TAG, msg); 3429 throw new SecurityException(msg); 3430 } 3431 if (session == null || interactor == null) { 3432 throw new NullPointerException("null session or interactor"); 3433 } 3434 userId = handleIncomingUser(callingPid, callingUid, userId, 3435 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3436 // TODO: Switch to user app stacks here. 3437 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3438 resolvedType, session, interactor, null, null, 0, startFlags, 3439 profileFile, profileFd, null, null, options, userId, null); 3440 } 3441 3442 @Override 3443 public boolean startNextMatchingActivity(IBinder callingActivity, 3444 Intent intent, Bundle options) { 3445 // Refuse possible leaked file descriptors 3446 if (intent != null && intent.hasFileDescriptors() == true) { 3447 throw new IllegalArgumentException("File descriptors passed in Intent"); 3448 } 3449 3450 synchronized (this) { 3451 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3452 if (r == null) { 3453 ActivityOptions.abort(options); 3454 return false; 3455 } 3456 if (r.app == null || r.app.thread == null) { 3457 // The caller is not running... d'oh! 3458 ActivityOptions.abort(options); 3459 return false; 3460 } 3461 intent = new Intent(intent); 3462 // The caller is not allowed to change the data. 3463 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3464 // And we are resetting to find the next component... 3465 intent.setComponent(null); 3466 3467 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3468 3469 ActivityInfo aInfo = null; 3470 try { 3471 List<ResolveInfo> resolves = 3472 AppGlobals.getPackageManager().queryIntentActivities( 3473 intent, r.resolvedType, 3474 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3475 UserHandle.getCallingUserId()); 3476 3477 // Look for the original activity in the list... 3478 final int N = resolves != null ? resolves.size() : 0; 3479 for (int i=0; i<N; i++) { 3480 ResolveInfo rInfo = resolves.get(i); 3481 if (rInfo.activityInfo.packageName.equals(r.packageName) 3482 && rInfo.activityInfo.name.equals(r.info.name)) { 3483 // We found the current one... the next matching is 3484 // after it. 3485 i++; 3486 if (i<N) { 3487 aInfo = resolves.get(i).activityInfo; 3488 } 3489 if (debug) { 3490 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3491 + "/" + r.info.name); 3492 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3493 + "/" + aInfo.name); 3494 } 3495 break; 3496 } 3497 } 3498 } catch (RemoteException e) { 3499 } 3500 3501 if (aInfo == null) { 3502 // Nobody who is next! 3503 ActivityOptions.abort(options); 3504 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3505 return false; 3506 } 3507 3508 intent.setComponent(new ComponentName( 3509 aInfo.applicationInfo.packageName, aInfo.name)); 3510 intent.setFlags(intent.getFlags()&~( 3511 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3512 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3513 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3514 Intent.FLAG_ACTIVITY_NEW_TASK)); 3515 3516 // Okay now we need to start the new activity, replacing the 3517 // currently running activity. This is a little tricky because 3518 // we want to start the new one as if the current one is finished, 3519 // but not finish the current one first so that there is no flicker. 3520 // And thus... 3521 final boolean wasFinishing = r.finishing; 3522 r.finishing = true; 3523 3524 // Propagate reply information over to the new activity. 3525 final ActivityRecord resultTo = r.resultTo; 3526 final String resultWho = r.resultWho; 3527 final int requestCode = r.requestCode; 3528 r.resultTo = null; 3529 if (resultTo != null) { 3530 resultTo.removeResultsLocked(r, resultWho, requestCode); 3531 } 3532 3533 final long origId = Binder.clearCallingIdentity(); 3534 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3535 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3536 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3537 options, false, null, null); 3538 Binder.restoreCallingIdentity(origId); 3539 3540 r.finishing = wasFinishing; 3541 if (res != ActivityManager.START_SUCCESS) { 3542 return false; 3543 } 3544 return true; 3545 } 3546 } 3547 3548 final int startActivityInPackage(int uid, String callingPackage, 3549 Intent intent, String resolvedType, IBinder resultTo, 3550 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3551 IActivityContainer container) { 3552 3553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3554 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3555 3556 // TODO: Switch to user app stacks here. 3557 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3558 null, null, resultTo, resultWho, requestCode, startFlags, 3559 null, null, null, null, options, userId, container); 3560 return ret; 3561 } 3562 3563 @Override 3564 public final int startActivities(IApplicationThread caller, String callingPackage, 3565 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3566 int userId) { 3567 enforceNotIsolatedCaller("startActivities"); 3568 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3569 false, ALLOW_FULL_ONLY, "startActivity", null); 3570 // TODO: Switch to user app stacks here. 3571 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3572 resolvedTypes, resultTo, options, userId); 3573 return ret; 3574 } 3575 3576 final int startActivitiesInPackage(int uid, String callingPackage, 3577 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3578 Bundle options, int userId) { 3579 3580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3581 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3582 // TODO: Switch to user app stacks here. 3583 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3584 resultTo, options, userId); 3585 return ret; 3586 } 3587 3588 final void addRecentTaskLocked(TaskRecord task) { 3589 int N = mRecentTasks.size(); 3590 // Quick case: check if the top-most recent task is the same. 3591 if (N > 0 && mRecentTasks.get(0) == task) { 3592 return; 3593 } 3594 // Another quick case: never add voice sessions. 3595 if (task.voiceSession != null) { 3596 return; 3597 } 3598 // Remove any existing entries that are the same kind of task. 3599 final Intent intent = task.intent; 3600 final boolean document = intent != null && intent.isDocument(); 3601 final ComponentName comp = intent.getComponent(); 3602 3603 int maxRecents = task.maxRecents - 1; 3604 for (int i=0; i<N; i++) { 3605 final TaskRecord tr = mRecentTasks.get(i); 3606 if (task != tr) { 3607 if (task.userId != tr.userId) { 3608 continue; 3609 } 3610 if (i > MAX_RECENT_BITMAPS) { 3611 tr.freeLastThumbnail(); 3612 } 3613 final Intent trIntent = tr.intent; 3614 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3615 (intent == null || !intent.filterEquals(trIntent))) { 3616 continue; 3617 } 3618 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3619 if (document && trIsDocument) { 3620 // These are the same document activity (not necessarily the same doc). 3621 if (maxRecents > 0) { 3622 --maxRecents; 3623 continue; 3624 } 3625 // Hit the maximum number of documents for this task. Fall through 3626 // and remove this document from recents. 3627 } else if (document || trIsDocument) { 3628 // Only one of these is a document. Not the droid we're looking for. 3629 continue; 3630 } 3631 } 3632 3633 // Either task and tr are the same or, their affinities match or their intents match 3634 // and neither of them is a document, or they are documents using the same activity 3635 // and their maxRecents has been reached. 3636 tr.disposeThumbnail(); 3637 mRecentTasks.remove(i); 3638 if (task != tr) { 3639 tr.closeRecentsChain(); 3640 } 3641 i--; 3642 N--; 3643 if (task.intent == null) { 3644 // If the new recent task we are adding is not fully 3645 // specified, then replace it with the existing recent task. 3646 task = tr; 3647 } 3648 mTaskPersister.notify(tr, false); 3649 } 3650 if (N >= MAX_RECENT_TASKS) { 3651 final TaskRecord tr = mRecentTasks.remove(N - 1); 3652 tr.disposeThumbnail(); 3653 tr.closeRecentsChain(); 3654 } 3655 mRecentTasks.add(0, task); 3656 } 3657 3658 @Override 3659 public void reportActivityFullyDrawn(IBinder token) { 3660 synchronized (this) { 3661 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3662 if (r == null) { 3663 return; 3664 } 3665 r.reportFullyDrawnLocked(); 3666 } 3667 } 3668 3669 @Override 3670 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3671 synchronized (this) { 3672 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3673 if (r == null) { 3674 return; 3675 } 3676 final long origId = Binder.clearCallingIdentity(); 3677 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3678 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3679 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3680 if (config != null) { 3681 r.frozenBeforeDestroy = true; 3682 if (!updateConfigurationLocked(config, r, false, false)) { 3683 mStackSupervisor.resumeTopActivitiesLocked(); 3684 } 3685 } 3686 Binder.restoreCallingIdentity(origId); 3687 } 3688 } 3689 3690 @Override 3691 public int getRequestedOrientation(IBinder token) { 3692 synchronized (this) { 3693 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3694 if (r == null) { 3695 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3696 } 3697 return mWindowManager.getAppOrientation(r.appToken); 3698 } 3699 } 3700 3701 /** 3702 * This is the internal entry point for handling Activity.finish(). 3703 * 3704 * @param token The Binder token referencing the Activity we want to finish. 3705 * @param resultCode Result code, if any, from this Activity. 3706 * @param resultData Result data (Intent), if any, from this Activity. 3707 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3708 * the root Activity in the task. 3709 * 3710 * @return Returns true if the activity successfully finished, or false if it is still running. 3711 */ 3712 @Override 3713 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3714 boolean finishTask) { 3715 // Refuse possible leaked file descriptors 3716 if (resultData != null && resultData.hasFileDescriptors() == true) { 3717 throw new IllegalArgumentException("File descriptors passed in Intent"); 3718 } 3719 3720 synchronized(this) { 3721 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3722 if (r == null) { 3723 return true; 3724 } 3725 // Keep track of the root activity of the task before we finish it 3726 TaskRecord tr = r.task; 3727 ActivityRecord rootR = tr.getRootActivity(); 3728 // Do not allow task to finish in Lock Task mode. 3729 if (tr == mStackSupervisor.mLockTaskModeTask) { 3730 if (rootR == r) { 3731 mStackSupervisor.showLockTaskToast(); 3732 return false; 3733 } 3734 } 3735 if (mController != null) { 3736 // Find the first activity that is not finishing. 3737 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3738 if (next != null) { 3739 // ask watcher if this is allowed 3740 boolean resumeOK = true; 3741 try { 3742 resumeOK = mController.activityResuming(next.packageName); 3743 } catch (RemoteException e) { 3744 mController = null; 3745 Watchdog.getInstance().setActivityController(null); 3746 } 3747 3748 if (!resumeOK) { 3749 return false; 3750 } 3751 } 3752 } 3753 final long origId = Binder.clearCallingIdentity(); 3754 try { 3755 boolean res; 3756 if (finishTask && r == rootR) { 3757 // If requested, remove the task that is associated to this activity only if it 3758 // was the root activity in the task. The result code and data is ignored because 3759 // we don't support returning them across task boundaries. 3760 res = removeTaskByIdLocked(tr.taskId, 0); 3761 } else { 3762 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3763 resultData, "app-request", true); 3764 } 3765 return res; 3766 } finally { 3767 Binder.restoreCallingIdentity(origId); 3768 } 3769 } 3770 } 3771 3772 @Override 3773 public final void finishHeavyWeightApp() { 3774 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3775 != PackageManager.PERMISSION_GRANTED) { 3776 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3777 + Binder.getCallingPid() 3778 + ", uid=" + Binder.getCallingUid() 3779 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3780 Slog.w(TAG, msg); 3781 throw new SecurityException(msg); 3782 } 3783 3784 synchronized(this) { 3785 if (mHeavyWeightProcess == null) { 3786 return; 3787 } 3788 3789 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3790 mHeavyWeightProcess.activities); 3791 for (int i=0; i<activities.size(); i++) { 3792 ActivityRecord r = activities.get(i); 3793 if (!r.finishing) { 3794 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3795 null, "finish-heavy", true); 3796 } 3797 } 3798 3799 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3800 mHeavyWeightProcess.userId, 0)); 3801 mHeavyWeightProcess = null; 3802 } 3803 } 3804 3805 @Override 3806 public void crashApplication(int uid, int initialPid, String packageName, 3807 String message) { 3808 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3809 != PackageManager.PERMISSION_GRANTED) { 3810 String msg = "Permission Denial: crashApplication() from pid=" 3811 + Binder.getCallingPid() 3812 + ", uid=" + Binder.getCallingUid() 3813 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3814 Slog.w(TAG, msg); 3815 throw new SecurityException(msg); 3816 } 3817 3818 synchronized(this) { 3819 ProcessRecord proc = null; 3820 3821 // Figure out which process to kill. We don't trust that initialPid 3822 // still has any relation to current pids, so must scan through the 3823 // list. 3824 synchronized (mPidsSelfLocked) { 3825 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3826 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3827 if (p.uid != uid) { 3828 continue; 3829 } 3830 if (p.pid == initialPid) { 3831 proc = p; 3832 break; 3833 } 3834 if (p.pkgList.containsKey(packageName)) { 3835 proc = p; 3836 } 3837 } 3838 } 3839 3840 if (proc == null) { 3841 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3842 + " initialPid=" + initialPid 3843 + " packageName=" + packageName); 3844 return; 3845 } 3846 3847 if (proc.thread != null) { 3848 if (proc.pid == Process.myPid()) { 3849 Log.w(TAG, "crashApplication: trying to crash self!"); 3850 return; 3851 } 3852 long ident = Binder.clearCallingIdentity(); 3853 try { 3854 proc.thread.scheduleCrash(message); 3855 } catch (RemoteException e) { 3856 } 3857 Binder.restoreCallingIdentity(ident); 3858 } 3859 } 3860 } 3861 3862 @Override 3863 public final void finishSubActivity(IBinder token, String resultWho, 3864 int requestCode) { 3865 synchronized(this) { 3866 final long origId = Binder.clearCallingIdentity(); 3867 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3868 if (r != null) { 3869 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3870 } 3871 Binder.restoreCallingIdentity(origId); 3872 } 3873 } 3874 3875 @Override 3876 public boolean finishActivityAffinity(IBinder token) { 3877 synchronized(this) { 3878 final long origId = Binder.clearCallingIdentity(); 3879 try { 3880 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3881 3882 ActivityRecord rootR = r.task.getRootActivity(); 3883 // Do not allow task to finish in Lock Task mode. 3884 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3885 if (rootR == r) { 3886 mStackSupervisor.showLockTaskToast(); 3887 return false; 3888 } 3889 } 3890 boolean res = false; 3891 if (r != null) { 3892 res = r.task.stack.finishActivityAffinityLocked(r); 3893 } 3894 return res; 3895 } finally { 3896 Binder.restoreCallingIdentity(origId); 3897 } 3898 } 3899 } 3900 3901 @Override 3902 public void finishVoiceTask(IVoiceInteractionSession session) { 3903 synchronized(this) { 3904 final long origId = Binder.clearCallingIdentity(); 3905 try { 3906 mStackSupervisor.finishVoiceTask(session); 3907 } finally { 3908 Binder.restoreCallingIdentity(origId); 3909 } 3910 } 3911 3912 } 3913 3914 @Override 3915 public boolean willActivityBeVisible(IBinder token) { 3916 synchronized(this) { 3917 ActivityStack stack = ActivityRecord.getStackLocked(token); 3918 if (stack != null) { 3919 return stack.willActivityBeVisibleLocked(token); 3920 } 3921 return false; 3922 } 3923 } 3924 3925 @Override 3926 public void overridePendingTransition(IBinder token, String packageName, 3927 int enterAnim, int exitAnim) { 3928 synchronized(this) { 3929 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3930 if (self == null) { 3931 return; 3932 } 3933 3934 final long origId = Binder.clearCallingIdentity(); 3935 3936 if (self.state == ActivityState.RESUMED 3937 || self.state == ActivityState.PAUSING) { 3938 mWindowManager.overridePendingAppTransition(packageName, 3939 enterAnim, exitAnim, null); 3940 } 3941 3942 Binder.restoreCallingIdentity(origId); 3943 } 3944 } 3945 3946 /** 3947 * Main function for removing an existing process from the activity manager 3948 * as a result of that process going away. Clears out all connections 3949 * to the process. 3950 */ 3951 private final void handleAppDiedLocked(ProcessRecord app, 3952 boolean restarting, boolean allowRestart) { 3953 int pid = app.pid; 3954 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3955 if (!restarting) { 3956 removeLruProcessLocked(app); 3957 if (pid > 0) { 3958 ProcessList.remove(pid); 3959 } 3960 } 3961 3962 if (mProfileProc == app) { 3963 clearProfilerLocked(); 3964 } 3965 3966 // Remove this application's activities from active lists. 3967 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3968 3969 app.activities.clear(); 3970 3971 if (app.instrumentationClass != null) { 3972 Slog.w(TAG, "Crash of app " + app.processName 3973 + " running instrumentation " + app.instrumentationClass); 3974 Bundle info = new Bundle(); 3975 info.putString("shortMsg", "Process crashed."); 3976 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3977 } 3978 3979 if (!restarting) { 3980 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3981 // If there was nothing to resume, and we are not already 3982 // restarting this process, but there is a visible activity that 3983 // is hosted by the process... then make sure all visible 3984 // activities are running, taking care of restarting this 3985 // process. 3986 if (hasVisibleActivities) { 3987 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3988 } 3989 } 3990 } 3991 } 3992 3993 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3994 IBinder threadBinder = thread.asBinder(); 3995 // Find the application record. 3996 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3997 ProcessRecord rec = mLruProcesses.get(i); 3998 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3999 return i; 4000 } 4001 } 4002 return -1; 4003 } 4004 4005 final ProcessRecord getRecordForAppLocked( 4006 IApplicationThread thread) { 4007 if (thread == null) { 4008 return null; 4009 } 4010 4011 int appIndex = getLRURecordIndexForAppLocked(thread); 4012 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4013 } 4014 4015 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4016 // If there are no longer any background processes running, 4017 // and the app that died was not running instrumentation, 4018 // then tell everyone we are now low on memory. 4019 boolean haveBg = false; 4020 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4021 ProcessRecord rec = mLruProcesses.get(i); 4022 if (rec.thread != null 4023 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4024 haveBg = true; 4025 break; 4026 } 4027 } 4028 4029 if (!haveBg) { 4030 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4031 if (doReport) { 4032 long now = SystemClock.uptimeMillis(); 4033 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4034 doReport = false; 4035 } else { 4036 mLastMemUsageReportTime = now; 4037 } 4038 } 4039 final ArrayList<ProcessMemInfo> memInfos 4040 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4041 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4042 long now = SystemClock.uptimeMillis(); 4043 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4044 ProcessRecord rec = mLruProcesses.get(i); 4045 if (rec == dyingProc || rec.thread == null) { 4046 continue; 4047 } 4048 if (doReport) { 4049 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4050 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4051 } 4052 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4053 // The low memory report is overriding any current 4054 // state for a GC request. Make sure to do 4055 // heavy/important/visible/foreground processes first. 4056 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4057 rec.lastRequestedGc = 0; 4058 } else { 4059 rec.lastRequestedGc = rec.lastLowMemory; 4060 } 4061 rec.reportLowMemory = true; 4062 rec.lastLowMemory = now; 4063 mProcessesToGc.remove(rec); 4064 addProcessToGcListLocked(rec); 4065 } 4066 } 4067 if (doReport) { 4068 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4069 mHandler.sendMessage(msg); 4070 } 4071 scheduleAppGcsLocked(); 4072 } 4073 } 4074 4075 final void appDiedLocked(ProcessRecord app, int pid, 4076 IApplicationThread thread) { 4077 4078 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4079 synchronized (stats) { 4080 stats.noteProcessDiedLocked(app.info.uid, pid); 4081 } 4082 4083 Process.killProcessGroup(app.info.uid, pid); 4084 4085 // Clean up already done if the process has been re-started. 4086 if (app.pid == pid && app.thread != null && 4087 app.thread.asBinder() == thread.asBinder()) { 4088 boolean doLowMem = app.instrumentationClass == null; 4089 boolean doOomAdj = doLowMem; 4090 if (!app.killedByAm) { 4091 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4092 + ") has died."); 4093 mAllowLowerMemLevel = true; 4094 } else { 4095 // Note that we always want to do oom adj to update our state with the 4096 // new number of procs. 4097 mAllowLowerMemLevel = false; 4098 doLowMem = false; 4099 } 4100 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4101 if (DEBUG_CLEANUP) Slog.v( 4102 TAG, "Dying app: " + app + ", pid: " + pid 4103 + ", thread: " + thread.asBinder()); 4104 handleAppDiedLocked(app, false, true); 4105 4106 if (doOomAdj) { 4107 updateOomAdjLocked(); 4108 } 4109 if (doLowMem) { 4110 doLowMemReportIfNeededLocked(app); 4111 } 4112 } else if (app.pid != pid) { 4113 // A new process has already been started. 4114 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4115 + ") has died and restarted (pid " + app.pid + ")."); 4116 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4117 } else if (DEBUG_PROCESSES) { 4118 Slog.d(TAG, "Received spurious death notification for thread " 4119 + thread.asBinder()); 4120 } 4121 } 4122 4123 /** 4124 * If a stack trace dump file is configured, dump process stack traces. 4125 * @param clearTraces causes the dump file to be erased prior to the new 4126 * traces being written, if true; when false, the new traces will be 4127 * appended to any existing file content. 4128 * @param firstPids of dalvik VM processes to dump stack traces for first 4129 * @param lastPids of dalvik VM processes to dump stack traces for last 4130 * @param nativeProcs optional list of native process names to dump stack crawls 4131 * @return file containing stack traces, or null if no dump file is configured 4132 */ 4133 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4134 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4135 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4136 if (tracesPath == null || tracesPath.length() == 0) { 4137 return null; 4138 } 4139 4140 File tracesFile = new File(tracesPath); 4141 try { 4142 File tracesDir = tracesFile.getParentFile(); 4143 if (!tracesDir.exists()) { 4144 tracesFile.mkdirs(); 4145 if (!SELinux.restorecon(tracesDir)) { 4146 return null; 4147 } 4148 } 4149 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4150 4151 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4152 tracesFile.createNewFile(); 4153 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4154 } catch (IOException e) { 4155 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4156 return null; 4157 } 4158 4159 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4160 return tracesFile; 4161 } 4162 4163 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4164 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4165 // Use a FileObserver to detect when traces finish writing. 4166 // The order of traces is considered important to maintain for legibility. 4167 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4168 @Override 4169 public synchronized void onEvent(int event, String path) { notify(); } 4170 }; 4171 4172 try { 4173 observer.startWatching(); 4174 4175 // First collect all of the stacks of the most important pids. 4176 if (firstPids != null) { 4177 try { 4178 int num = firstPids.size(); 4179 for (int i = 0; i < num; i++) { 4180 synchronized (observer) { 4181 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4182 observer.wait(200); // Wait for write-close, give up after 200msec 4183 } 4184 } 4185 } catch (InterruptedException e) { 4186 Log.wtf(TAG, e); 4187 } 4188 } 4189 4190 // Next collect the stacks of the native pids 4191 if (nativeProcs != null) { 4192 int[] pids = Process.getPidsForCommands(nativeProcs); 4193 if (pids != null) { 4194 for (int pid : pids) { 4195 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4196 } 4197 } 4198 } 4199 4200 // Lastly, measure CPU usage. 4201 if (processCpuTracker != null) { 4202 processCpuTracker.init(); 4203 System.gc(); 4204 processCpuTracker.update(); 4205 try { 4206 synchronized (processCpuTracker) { 4207 processCpuTracker.wait(500); // measure over 1/2 second. 4208 } 4209 } catch (InterruptedException e) { 4210 } 4211 processCpuTracker.update(); 4212 4213 // We'll take the stack crawls of just the top apps using CPU. 4214 final int N = processCpuTracker.countWorkingStats(); 4215 int numProcs = 0; 4216 for (int i=0; i<N && numProcs<5; i++) { 4217 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4218 if (lastPids.indexOfKey(stats.pid) >= 0) { 4219 numProcs++; 4220 try { 4221 synchronized (observer) { 4222 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4223 observer.wait(200); // Wait for write-close, give up after 200msec 4224 } 4225 } catch (InterruptedException e) { 4226 Log.wtf(TAG, e); 4227 } 4228 4229 } 4230 } 4231 } 4232 } finally { 4233 observer.stopWatching(); 4234 } 4235 } 4236 4237 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4238 if (true || IS_USER_BUILD) { 4239 return; 4240 } 4241 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4242 if (tracesPath == null || tracesPath.length() == 0) { 4243 return; 4244 } 4245 4246 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4247 StrictMode.allowThreadDiskWrites(); 4248 try { 4249 final File tracesFile = new File(tracesPath); 4250 final File tracesDir = tracesFile.getParentFile(); 4251 final File tracesTmp = new File(tracesDir, "__tmp__"); 4252 try { 4253 if (!tracesDir.exists()) { 4254 tracesFile.mkdirs(); 4255 if (!SELinux.restorecon(tracesDir.getPath())) { 4256 return; 4257 } 4258 } 4259 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4260 4261 if (tracesFile.exists()) { 4262 tracesTmp.delete(); 4263 tracesFile.renameTo(tracesTmp); 4264 } 4265 StringBuilder sb = new StringBuilder(); 4266 Time tobj = new Time(); 4267 tobj.set(System.currentTimeMillis()); 4268 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4269 sb.append(": "); 4270 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4271 sb.append(" since "); 4272 sb.append(msg); 4273 FileOutputStream fos = new FileOutputStream(tracesFile); 4274 fos.write(sb.toString().getBytes()); 4275 if (app == null) { 4276 fos.write("\n*** No application process!".getBytes()); 4277 } 4278 fos.close(); 4279 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4280 } catch (IOException e) { 4281 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4282 return; 4283 } 4284 4285 if (app != null) { 4286 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4287 firstPids.add(app.pid); 4288 dumpStackTraces(tracesPath, firstPids, null, null, null); 4289 } 4290 4291 File lastTracesFile = null; 4292 File curTracesFile = null; 4293 for (int i=9; i>=0; i--) { 4294 String name = String.format(Locale.US, "slow%02d.txt", i); 4295 curTracesFile = new File(tracesDir, name); 4296 if (curTracesFile.exists()) { 4297 if (lastTracesFile != null) { 4298 curTracesFile.renameTo(lastTracesFile); 4299 } else { 4300 curTracesFile.delete(); 4301 } 4302 } 4303 lastTracesFile = curTracesFile; 4304 } 4305 tracesFile.renameTo(curTracesFile); 4306 if (tracesTmp.exists()) { 4307 tracesTmp.renameTo(tracesFile); 4308 } 4309 } finally { 4310 StrictMode.setThreadPolicy(oldPolicy); 4311 } 4312 } 4313 4314 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4315 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4316 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4317 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4318 4319 if (mController != null) { 4320 try { 4321 // 0 == continue, -1 = kill process immediately 4322 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4323 if (res < 0 && app.pid != MY_PID) { 4324 Process.killProcess(app.pid); 4325 Process.killProcessGroup(app.info.uid, app.pid); 4326 } 4327 } catch (RemoteException e) { 4328 mController = null; 4329 Watchdog.getInstance().setActivityController(null); 4330 } 4331 } 4332 4333 long anrTime = SystemClock.uptimeMillis(); 4334 if (MONITOR_CPU_USAGE) { 4335 updateCpuStatsNow(); 4336 } 4337 4338 synchronized (this) { 4339 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4340 if (mShuttingDown) { 4341 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4342 return; 4343 } else if (app.notResponding) { 4344 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4345 return; 4346 } else if (app.crashing) { 4347 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4348 return; 4349 } 4350 4351 // In case we come through here for the same app before completing 4352 // this one, mark as anring now so we will bail out. 4353 app.notResponding = true; 4354 4355 // Log the ANR to the event log. 4356 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4357 app.processName, app.info.flags, annotation); 4358 4359 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4360 firstPids.add(app.pid); 4361 4362 int parentPid = app.pid; 4363 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4364 if (parentPid != app.pid) firstPids.add(parentPid); 4365 4366 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4367 4368 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4369 ProcessRecord r = mLruProcesses.get(i); 4370 if (r != null && r.thread != null) { 4371 int pid = r.pid; 4372 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4373 if (r.persistent) { 4374 firstPids.add(pid); 4375 } else { 4376 lastPids.put(pid, Boolean.TRUE); 4377 } 4378 } 4379 } 4380 } 4381 } 4382 4383 // Log the ANR to the main log. 4384 StringBuilder info = new StringBuilder(); 4385 info.setLength(0); 4386 info.append("ANR in ").append(app.processName); 4387 if (activity != null && activity.shortComponentName != null) { 4388 info.append(" (").append(activity.shortComponentName).append(")"); 4389 } 4390 info.append("\n"); 4391 info.append("PID: ").append(app.pid).append("\n"); 4392 if (annotation != null) { 4393 info.append("Reason: ").append(annotation).append("\n"); 4394 } 4395 if (parent != null && parent != activity) { 4396 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4397 } 4398 4399 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4400 4401 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4402 NATIVE_STACKS_OF_INTEREST); 4403 4404 String cpuInfo = null; 4405 if (MONITOR_CPU_USAGE) { 4406 updateCpuStatsNow(); 4407 synchronized (mProcessCpuThread) { 4408 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4409 } 4410 info.append(processCpuTracker.printCurrentLoad()); 4411 info.append(cpuInfo); 4412 } 4413 4414 info.append(processCpuTracker.printCurrentState(anrTime)); 4415 4416 Slog.e(TAG, info.toString()); 4417 if (tracesFile == null) { 4418 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4419 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4420 } 4421 4422 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4423 cpuInfo, tracesFile, null); 4424 4425 if (mController != null) { 4426 try { 4427 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4428 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4429 if (res != 0) { 4430 if (res < 0 && app.pid != MY_PID) { 4431 Process.killProcess(app.pid); 4432 Process.killProcessGroup(app.info.uid, app.pid); 4433 } else { 4434 synchronized (this) { 4435 mServices.scheduleServiceTimeoutLocked(app); 4436 } 4437 } 4438 return; 4439 } 4440 } catch (RemoteException e) { 4441 mController = null; 4442 Watchdog.getInstance().setActivityController(null); 4443 } 4444 } 4445 4446 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4447 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4448 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4449 4450 synchronized (this) { 4451 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4452 killUnneededProcessLocked(app, "background ANR"); 4453 return; 4454 } 4455 4456 // Set the app's notResponding state, and look up the errorReportReceiver 4457 makeAppNotRespondingLocked(app, 4458 activity != null ? activity.shortComponentName : null, 4459 annotation != null ? "ANR " + annotation : "ANR", 4460 info.toString()); 4461 4462 // Bring up the infamous App Not Responding dialog 4463 Message msg = Message.obtain(); 4464 HashMap<String, Object> map = new HashMap<String, Object>(); 4465 msg.what = SHOW_NOT_RESPONDING_MSG; 4466 msg.obj = map; 4467 msg.arg1 = aboveSystem ? 1 : 0; 4468 map.put("app", app); 4469 if (activity != null) { 4470 map.put("activity", activity); 4471 } 4472 4473 mHandler.sendMessage(msg); 4474 } 4475 } 4476 4477 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4478 if (!mLaunchWarningShown) { 4479 mLaunchWarningShown = true; 4480 mHandler.post(new Runnable() { 4481 @Override 4482 public void run() { 4483 synchronized (ActivityManagerService.this) { 4484 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4485 d.show(); 4486 mHandler.postDelayed(new Runnable() { 4487 @Override 4488 public void run() { 4489 synchronized (ActivityManagerService.this) { 4490 d.dismiss(); 4491 mLaunchWarningShown = false; 4492 } 4493 } 4494 }, 4000); 4495 } 4496 } 4497 }); 4498 } 4499 } 4500 4501 @Override 4502 public boolean clearApplicationUserData(final String packageName, 4503 final IPackageDataObserver observer, int userId) { 4504 enforceNotIsolatedCaller("clearApplicationUserData"); 4505 int uid = Binder.getCallingUid(); 4506 int pid = Binder.getCallingPid(); 4507 userId = handleIncomingUser(pid, uid, 4508 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4509 long callingId = Binder.clearCallingIdentity(); 4510 try { 4511 IPackageManager pm = AppGlobals.getPackageManager(); 4512 int pkgUid = -1; 4513 synchronized(this) { 4514 try { 4515 pkgUid = pm.getPackageUid(packageName, userId); 4516 } catch (RemoteException e) { 4517 } 4518 if (pkgUid == -1) { 4519 Slog.w(TAG, "Invalid packageName: " + packageName); 4520 if (observer != null) { 4521 try { 4522 observer.onRemoveCompleted(packageName, false); 4523 } catch (RemoteException e) { 4524 Slog.i(TAG, "Observer no longer exists."); 4525 } 4526 } 4527 return false; 4528 } 4529 if (uid == pkgUid || checkComponentPermission( 4530 android.Manifest.permission.CLEAR_APP_USER_DATA, 4531 pid, uid, -1, true) 4532 == PackageManager.PERMISSION_GRANTED) { 4533 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4534 } else { 4535 throw new SecurityException("PID " + pid + " does not have permission " 4536 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4537 + " of package " + packageName); 4538 } 4539 } 4540 4541 try { 4542 // Clear application user data 4543 pm.clearApplicationUserData(packageName, observer, userId); 4544 4545 // Remove all permissions granted from/to this package 4546 removeUriPermissionsForPackageLocked(packageName, userId, true); 4547 4548 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4549 Uri.fromParts("package", packageName, null)); 4550 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4551 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4552 null, null, 0, null, null, null, false, false, userId); 4553 } catch (RemoteException e) { 4554 } 4555 } finally { 4556 Binder.restoreCallingIdentity(callingId); 4557 } 4558 return true; 4559 } 4560 4561 @Override 4562 public void killBackgroundProcesses(final String packageName, int userId) { 4563 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4564 != PackageManager.PERMISSION_GRANTED && 4565 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4566 != PackageManager.PERMISSION_GRANTED) { 4567 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4568 + Binder.getCallingPid() 4569 + ", uid=" + Binder.getCallingUid() 4570 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4571 Slog.w(TAG, msg); 4572 throw new SecurityException(msg); 4573 } 4574 4575 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4576 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4577 long callingId = Binder.clearCallingIdentity(); 4578 try { 4579 IPackageManager pm = AppGlobals.getPackageManager(); 4580 synchronized(this) { 4581 int appId = -1; 4582 try { 4583 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4584 } catch (RemoteException e) { 4585 } 4586 if (appId == -1) { 4587 Slog.w(TAG, "Invalid packageName: " + packageName); 4588 return; 4589 } 4590 killPackageProcessesLocked(packageName, appId, userId, 4591 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4592 } 4593 } finally { 4594 Binder.restoreCallingIdentity(callingId); 4595 } 4596 } 4597 4598 @Override 4599 public void killAllBackgroundProcesses() { 4600 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4601 != PackageManager.PERMISSION_GRANTED) { 4602 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4603 + Binder.getCallingPid() 4604 + ", uid=" + Binder.getCallingUid() 4605 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4606 Slog.w(TAG, msg); 4607 throw new SecurityException(msg); 4608 } 4609 4610 long callingId = Binder.clearCallingIdentity(); 4611 try { 4612 synchronized(this) { 4613 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4614 final int NP = mProcessNames.getMap().size(); 4615 for (int ip=0; ip<NP; ip++) { 4616 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4617 final int NA = apps.size(); 4618 for (int ia=0; ia<NA; ia++) { 4619 ProcessRecord app = apps.valueAt(ia); 4620 if (app.persistent) { 4621 // we don't kill persistent processes 4622 continue; 4623 } 4624 if (app.removed) { 4625 procs.add(app); 4626 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4627 app.removed = true; 4628 procs.add(app); 4629 } 4630 } 4631 } 4632 4633 int N = procs.size(); 4634 for (int i=0; i<N; i++) { 4635 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4636 } 4637 mAllowLowerMemLevel = true; 4638 updateOomAdjLocked(); 4639 doLowMemReportIfNeededLocked(null); 4640 } 4641 } finally { 4642 Binder.restoreCallingIdentity(callingId); 4643 } 4644 } 4645 4646 @Override 4647 public void forceStopPackage(final String packageName, int userId) { 4648 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4649 != PackageManager.PERMISSION_GRANTED) { 4650 String msg = "Permission Denial: forceStopPackage() from pid=" 4651 + Binder.getCallingPid() 4652 + ", uid=" + Binder.getCallingUid() 4653 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4654 Slog.w(TAG, msg); 4655 throw new SecurityException(msg); 4656 } 4657 final int callingPid = Binder.getCallingPid(); 4658 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4659 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4660 long callingId = Binder.clearCallingIdentity(); 4661 try { 4662 IPackageManager pm = AppGlobals.getPackageManager(); 4663 synchronized(this) { 4664 int[] users = userId == UserHandle.USER_ALL 4665 ? getUsersLocked() : new int[] { userId }; 4666 for (int user : users) { 4667 int pkgUid = -1; 4668 try { 4669 pkgUid = pm.getPackageUid(packageName, user); 4670 } catch (RemoteException e) { 4671 } 4672 if (pkgUid == -1) { 4673 Slog.w(TAG, "Invalid packageName: " + packageName); 4674 continue; 4675 } 4676 try { 4677 pm.setPackageStoppedState(packageName, true, user); 4678 } catch (RemoteException e) { 4679 } catch (IllegalArgumentException e) { 4680 Slog.w(TAG, "Failed trying to unstop package " 4681 + packageName + ": " + e); 4682 } 4683 if (isUserRunningLocked(user, false)) { 4684 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4685 } 4686 } 4687 } 4688 } finally { 4689 Binder.restoreCallingIdentity(callingId); 4690 } 4691 } 4692 4693 @Override 4694 public void addPackageDependency(String packageName) { 4695 synchronized (this) { 4696 int callingPid = Binder.getCallingPid(); 4697 if (callingPid == Process.myPid()) { 4698 // Yeah, um, no. 4699 Slog.w(TAG, "Can't addPackageDependency on system process"); 4700 return; 4701 } 4702 ProcessRecord proc; 4703 synchronized (mPidsSelfLocked) { 4704 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4705 } 4706 if (proc != null) { 4707 if (proc.pkgDeps == null) { 4708 proc.pkgDeps = new ArraySet<String>(1); 4709 } 4710 proc.pkgDeps.add(packageName); 4711 } 4712 } 4713 } 4714 4715 /* 4716 * The pkg name and app id have to be specified. 4717 */ 4718 @Override 4719 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4720 if (pkg == null) { 4721 return; 4722 } 4723 // Make sure the uid is valid. 4724 if (appid < 0) { 4725 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4726 return; 4727 } 4728 int callerUid = Binder.getCallingUid(); 4729 // Only the system server can kill an application 4730 if (callerUid == Process.SYSTEM_UID) { 4731 // Post an aysnc message to kill the application 4732 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4733 msg.arg1 = appid; 4734 msg.arg2 = 0; 4735 Bundle bundle = new Bundle(); 4736 bundle.putString("pkg", pkg); 4737 bundle.putString("reason", reason); 4738 msg.obj = bundle; 4739 mHandler.sendMessage(msg); 4740 } else { 4741 throw new SecurityException(callerUid + " cannot kill pkg: " + 4742 pkg); 4743 } 4744 } 4745 4746 @Override 4747 public void closeSystemDialogs(String reason) { 4748 enforceNotIsolatedCaller("closeSystemDialogs"); 4749 4750 final int pid = Binder.getCallingPid(); 4751 final int uid = Binder.getCallingUid(); 4752 final long origId = Binder.clearCallingIdentity(); 4753 try { 4754 synchronized (this) { 4755 // Only allow this from foreground processes, so that background 4756 // applications can't abuse it to prevent system UI from being shown. 4757 if (uid >= Process.FIRST_APPLICATION_UID) { 4758 ProcessRecord proc; 4759 synchronized (mPidsSelfLocked) { 4760 proc = mPidsSelfLocked.get(pid); 4761 } 4762 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4763 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4764 + " from background process " + proc); 4765 return; 4766 } 4767 } 4768 closeSystemDialogsLocked(reason); 4769 } 4770 } finally { 4771 Binder.restoreCallingIdentity(origId); 4772 } 4773 } 4774 4775 void closeSystemDialogsLocked(String reason) { 4776 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4777 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4778 | Intent.FLAG_RECEIVER_FOREGROUND); 4779 if (reason != null) { 4780 intent.putExtra("reason", reason); 4781 } 4782 mWindowManager.closeSystemDialogs(reason); 4783 4784 mStackSupervisor.closeSystemDialogsLocked(); 4785 4786 broadcastIntentLocked(null, null, intent, null, 4787 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4788 Process.SYSTEM_UID, UserHandle.USER_ALL); 4789 } 4790 4791 @Override 4792 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4793 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4794 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4795 for (int i=pids.length-1; i>=0; i--) { 4796 ProcessRecord proc; 4797 int oomAdj; 4798 synchronized (this) { 4799 synchronized (mPidsSelfLocked) { 4800 proc = mPidsSelfLocked.get(pids[i]); 4801 oomAdj = proc != null ? proc.setAdj : 0; 4802 } 4803 } 4804 infos[i] = new Debug.MemoryInfo(); 4805 Debug.getMemoryInfo(pids[i], infos[i]); 4806 if (proc != null) { 4807 synchronized (this) { 4808 if (proc.thread != null && proc.setAdj == oomAdj) { 4809 // Record this for posterity if the process has been stable. 4810 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4811 infos[i].getTotalUss(), false, proc.pkgList); 4812 } 4813 } 4814 } 4815 } 4816 return infos; 4817 } 4818 4819 @Override 4820 public long[] getProcessPss(int[] pids) { 4821 enforceNotIsolatedCaller("getProcessPss"); 4822 long[] pss = new long[pids.length]; 4823 for (int i=pids.length-1; i>=0; i--) { 4824 ProcessRecord proc; 4825 int oomAdj; 4826 synchronized (this) { 4827 synchronized (mPidsSelfLocked) { 4828 proc = mPidsSelfLocked.get(pids[i]); 4829 oomAdj = proc != null ? proc.setAdj : 0; 4830 } 4831 } 4832 long[] tmpUss = new long[1]; 4833 pss[i] = Debug.getPss(pids[i], tmpUss); 4834 if (proc != null) { 4835 synchronized (this) { 4836 if (proc.thread != null && proc.setAdj == oomAdj) { 4837 // Record this for posterity if the process has been stable. 4838 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4839 } 4840 } 4841 } 4842 } 4843 return pss; 4844 } 4845 4846 @Override 4847 public void killApplicationProcess(String processName, int uid) { 4848 if (processName == null) { 4849 return; 4850 } 4851 4852 int callerUid = Binder.getCallingUid(); 4853 // Only the system server can kill an application 4854 if (callerUid == Process.SYSTEM_UID) { 4855 synchronized (this) { 4856 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4857 if (app != null && app.thread != null) { 4858 try { 4859 app.thread.scheduleSuicide(); 4860 } catch (RemoteException e) { 4861 // If the other end already died, then our work here is done. 4862 } 4863 } else { 4864 Slog.w(TAG, "Process/uid not found attempting kill of " 4865 + processName + " / " + uid); 4866 } 4867 } 4868 } else { 4869 throw new SecurityException(callerUid + " cannot kill app process: " + 4870 processName); 4871 } 4872 } 4873 4874 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4875 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4876 false, true, false, false, UserHandle.getUserId(uid), reason); 4877 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4878 Uri.fromParts("package", packageName, null)); 4879 if (!mProcessesReady) { 4880 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4881 | Intent.FLAG_RECEIVER_FOREGROUND); 4882 } 4883 intent.putExtra(Intent.EXTRA_UID, uid); 4884 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4885 broadcastIntentLocked(null, null, intent, 4886 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4887 false, false, 4888 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4889 } 4890 4891 private void forceStopUserLocked(int userId, String reason) { 4892 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4893 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4894 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4895 | Intent.FLAG_RECEIVER_FOREGROUND); 4896 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4897 broadcastIntentLocked(null, null, intent, 4898 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4899 false, false, 4900 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4901 } 4902 4903 private final boolean killPackageProcessesLocked(String packageName, int appId, 4904 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4905 boolean doit, boolean evenPersistent, String reason) { 4906 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4907 4908 // Remove all processes this package may have touched: all with the 4909 // same UID (except for the system or root user), and all whose name 4910 // matches the package name. 4911 final int NP = mProcessNames.getMap().size(); 4912 for (int ip=0; ip<NP; ip++) { 4913 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4914 final int NA = apps.size(); 4915 for (int ia=0; ia<NA; ia++) { 4916 ProcessRecord app = apps.valueAt(ia); 4917 if (app.persistent && !evenPersistent) { 4918 // we don't kill persistent processes 4919 continue; 4920 } 4921 if (app.removed) { 4922 if (doit) { 4923 procs.add(app); 4924 } 4925 continue; 4926 } 4927 4928 // Skip process if it doesn't meet our oom adj requirement. 4929 if (app.setAdj < minOomAdj) { 4930 continue; 4931 } 4932 4933 // If no package is specified, we call all processes under the 4934 // give user id. 4935 if (packageName == null) { 4936 if (app.userId != userId) { 4937 continue; 4938 } 4939 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4940 continue; 4941 } 4942 // Package has been specified, we want to hit all processes 4943 // that match it. We need to qualify this by the processes 4944 // that are running under the specified app and user ID. 4945 } else { 4946 final boolean isDep = app.pkgDeps != null 4947 && app.pkgDeps.contains(packageName); 4948 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 4949 continue; 4950 } 4951 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4952 continue; 4953 } 4954 if (!app.pkgList.containsKey(packageName) && !isDep) { 4955 continue; 4956 } 4957 } 4958 4959 // Process has passed all conditions, kill it! 4960 if (!doit) { 4961 return true; 4962 } 4963 app.removed = true; 4964 procs.add(app); 4965 } 4966 } 4967 4968 int N = procs.size(); 4969 for (int i=0; i<N; i++) { 4970 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4971 } 4972 updateOomAdjLocked(); 4973 return N > 0; 4974 } 4975 4976 private final boolean forceStopPackageLocked(String name, int appId, 4977 boolean callerWillRestart, boolean purgeCache, boolean doit, 4978 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4979 int i; 4980 int N; 4981 4982 if (userId == UserHandle.USER_ALL && name == null) { 4983 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4984 } 4985 4986 if (appId < 0 && name != null) { 4987 try { 4988 appId = UserHandle.getAppId( 4989 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4990 } catch (RemoteException e) { 4991 } 4992 } 4993 4994 if (doit) { 4995 if (name != null) { 4996 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4997 + " user=" + userId + ": " + reason); 4998 } else { 4999 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5000 } 5001 5002 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5003 for (int ip=pmap.size()-1; ip>=0; ip--) { 5004 SparseArray<Long> ba = pmap.valueAt(ip); 5005 for (i=ba.size()-1; i>=0; i--) { 5006 boolean remove = false; 5007 final int entUid = ba.keyAt(i); 5008 if (name != null) { 5009 if (userId == UserHandle.USER_ALL) { 5010 if (UserHandle.getAppId(entUid) == appId) { 5011 remove = true; 5012 } 5013 } else { 5014 if (entUid == UserHandle.getUid(userId, appId)) { 5015 remove = true; 5016 } 5017 } 5018 } else if (UserHandle.getUserId(entUid) == userId) { 5019 remove = true; 5020 } 5021 if (remove) { 5022 ba.removeAt(i); 5023 } 5024 } 5025 if (ba.size() == 0) { 5026 pmap.removeAt(ip); 5027 } 5028 } 5029 } 5030 5031 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5032 -100, callerWillRestart, true, doit, evenPersistent, 5033 name == null ? ("stop user " + userId) : ("stop " + name)); 5034 5035 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5036 if (!doit) { 5037 return true; 5038 } 5039 didSomething = true; 5040 } 5041 5042 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5043 if (!doit) { 5044 return true; 5045 } 5046 didSomething = true; 5047 } 5048 5049 if (name == null) { 5050 // Remove all sticky broadcasts from this user. 5051 mStickyBroadcasts.remove(userId); 5052 } 5053 5054 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5055 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5056 userId, providers)) { 5057 if (!doit) { 5058 return true; 5059 } 5060 didSomething = true; 5061 } 5062 N = providers.size(); 5063 for (i=0; i<N; i++) { 5064 removeDyingProviderLocked(null, providers.get(i), true); 5065 } 5066 5067 // Remove transient permissions granted from/to this package/user 5068 removeUriPermissionsForPackageLocked(name, userId, false); 5069 5070 if (name == null || uninstalling) { 5071 // Remove pending intents. For now we only do this when force 5072 // stopping users, because we have some problems when doing this 5073 // for packages -- app widgets are not currently cleaned up for 5074 // such packages, so they can be left with bad pending intents. 5075 if (mIntentSenderRecords.size() > 0) { 5076 Iterator<WeakReference<PendingIntentRecord>> it 5077 = mIntentSenderRecords.values().iterator(); 5078 while (it.hasNext()) { 5079 WeakReference<PendingIntentRecord> wpir = it.next(); 5080 if (wpir == null) { 5081 it.remove(); 5082 continue; 5083 } 5084 PendingIntentRecord pir = wpir.get(); 5085 if (pir == null) { 5086 it.remove(); 5087 continue; 5088 } 5089 if (name == null) { 5090 // Stopping user, remove all objects for the user. 5091 if (pir.key.userId != userId) { 5092 // Not the same user, skip it. 5093 continue; 5094 } 5095 } else { 5096 if (UserHandle.getAppId(pir.uid) != appId) { 5097 // Different app id, skip it. 5098 continue; 5099 } 5100 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5101 // Different user, skip it. 5102 continue; 5103 } 5104 if (!pir.key.packageName.equals(name)) { 5105 // Different package, skip it. 5106 continue; 5107 } 5108 } 5109 if (!doit) { 5110 return true; 5111 } 5112 didSomething = true; 5113 it.remove(); 5114 pir.canceled = true; 5115 if (pir.key.activity != null) { 5116 pir.key.activity.pendingResults.remove(pir.ref); 5117 } 5118 } 5119 } 5120 } 5121 5122 if (doit) { 5123 if (purgeCache && name != null) { 5124 AttributeCache ac = AttributeCache.instance(); 5125 if (ac != null) { 5126 ac.removePackage(name); 5127 } 5128 } 5129 if (mBooted) { 5130 mStackSupervisor.resumeTopActivitiesLocked(); 5131 mStackSupervisor.scheduleIdleLocked(); 5132 } 5133 } 5134 5135 return didSomething; 5136 } 5137 5138 private final boolean removeProcessLocked(ProcessRecord app, 5139 boolean callerWillRestart, boolean allowRestart, String reason) { 5140 final String name = app.processName; 5141 final int uid = app.uid; 5142 if (DEBUG_PROCESSES) Slog.d( 5143 TAG, "Force removing proc " + app.toShortString() + " (" + name 5144 + "/" + uid + ")"); 5145 5146 mProcessNames.remove(name, uid); 5147 mIsolatedProcesses.remove(app.uid); 5148 if (mHeavyWeightProcess == app) { 5149 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5150 mHeavyWeightProcess.userId, 0)); 5151 mHeavyWeightProcess = null; 5152 } 5153 boolean needRestart = false; 5154 if (app.pid > 0 && app.pid != MY_PID) { 5155 int pid = app.pid; 5156 synchronized (mPidsSelfLocked) { 5157 mPidsSelfLocked.remove(pid); 5158 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5159 } 5160 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5161 if (app.isolated) { 5162 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5163 } 5164 killUnneededProcessLocked(app, reason); 5165 Process.killProcessGroup(app.info.uid, app.pid); 5166 handleAppDiedLocked(app, true, allowRestart); 5167 removeLruProcessLocked(app); 5168 5169 if (app.persistent && !app.isolated) { 5170 if (!callerWillRestart) { 5171 addAppLocked(app.info, false, null /* ABI override */); 5172 } else { 5173 needRestart = true; 5174 } 5175 } 5176 } else { 5177 mRemovedProcesses.add(app); 5178 } 5179 5180 return needRestart; 5181 } 5182 5183 private final void processStartTimedOutLocked(ProcessRecord app) { 5184 final int pid = app.pid; 5185 boolean gone = false; 5186 synchronized (mPidsSelfLocked) { 5187 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5188 if (knownApp != null && knownApp.thread == null) { 5189 mPidsSelfLocked.remove(pid); 5190 gone = true; 5191 } 5192 } 5193 5194 if (gone) { 5195 Slog.w(TAG, "Process " + app + " failed to attach"); 5196 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5197 pid, app.uid, app.processName); 5198 mProcessNames.remove(app.processName, app.uid); 5199 mIsolatedProcesses.remove(app.uid); 5200 if (mHeavyWeightProcess == app) { 5201 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5202 mHeavyWeightProcess.userId, 0)); 5203 mHeavyWeightProcess = null; 5204 } 5205 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5206 if (app.isolated) { 5207 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5208 } 5209 // Take care of any launching providers waiting for this process. 5210 checkAppInLaunchingProvidersLocked(app, true); 5211 // Take care of any services that are waiting for the process. 5212 mServices.processStartTimedOutLocked(app); 5213 killUnneededProcessLocked(app, "start timeout"); 5214 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5215 Slog.w(TAG, "Unattached app died before backup, skipping"); 5216 try { 5217 IBackupManager bm = IBackupManager.Stub.asInterface( 5218 ServiceManager.getService(Context.BACKUP_SERVICE)); 5219 bm.agentDisconnected(app.info.packageName); 5220 } catch (RemoteException e) { 5221 // Can't happen; the backup manager is local 5222 } 5223 } 5224 if (isPendingBroadcastProcessLocked(pid)) { 5225 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5226 skipPendingBroadcastLocked(pid); 5227 } 5228 } else { 5229 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5230 } 5231 } 5232 5233 private final boolean attachApplicationLocked(IApplicationThread thread, 5234 int pid) { 5235 5236 // Find the application record that is being attached... either via 5237 // the pid if we are running in multiple processes, or just pull the 5238 // next app record if we are emulating process with anonymous threads. 5239 ProcessRecord app; 5240 if (pid != MY_PID && pid >= 0) { 5241 synchronized (mPidsSelfLocked) { 5242 app = mPidsSelfLocked.get(pid); 5243 } 5244 } else { 5245 app = null; 5246 } 5247 5248 if (app == null) { 5249 Slog.w(TAG, "No pending application record for pid " + pid 5250 + " (IApplicationThread " + thread + "); dropping process"); 5251 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5252 if (pid > 0 && pid != MY_PID) { 5253 Process.killProcessQuiet(pid); 5254 //TODO: Process.killProcessGroup(app.info.uid, pid); 5255 } else { 5256 try { 5257 thread.scheduleExit(); 5258 } catch (Exception e) { 5259 // Ignore exceptions. 5260 } 5261 } 5262 return false; 5263 } 5264 5265 // If this application record is still attached to a previous 5266 // process, clean it up now. 5267 if (app.thread != null) { 5268 handleAppDiedLocked(app, true, true); 5269 } 5270 5271 // Tell the process all about itself. 5272 5273 if (localLOGV) Slog.v( 5274 TAG, "Binding process pid " + pid + " to record " + app); 5275 5276 final String processName = app.processName; 5277 try { 5278 AppDeathRecipient adr = new AppDeathRecipient( 5279 app, pid, thread); 5280 thread.asBinder().linkToDeath(adr, 0); 5281 app.deathRecipient = adr; 5282 } catch (RemoteException e) { 5283 app.resetPackageList(mProcessStats); 5284 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5285 return false; 5286 } 5287 5288 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5289 5290 app.makeActive(thread, mProcessStats); 5291 app.curAdj = app.setAdj = -100; 5292 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5293 app.forcingToForeground = null; 5294 updateProcessForegroundLocked(app, false, false); 5295 app.hasShownUi = false; 5296 app.debugging = false; 5297 app.cached = false; 5298 5299 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5300 5301 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5302 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5303 5304 if (!normalMode) { 5305 Slog.i(TAG, "Launching preboot mode app: " + app); 5306 } 5307 5308 if (localLOGV) Slog.v( 5309 TAG, "New app record " + app 5310 + " thread=" + thread.asBinder() + " pid=" + pid); 5311 try { 5312 int testMode = IApplicationThread.DEBUG_OFF; 5313 if (mDebugApp != null && mDebugApp.equals(processName)) { 5314 testMode = mWaitForDebugger 5315 ? IApplicationThread.DEBUG_WAIT 5316 : IApplicationThread.DEBUG_ON; 5317 app.debugging = true; 5318 if (mDebugTransient) { 5319 mDebugApp = mOrigDebugApp; 5320 mWaitForDebugger = mOrigWaitForDebugger; 5321 } 5322 } 5323 String profileFile = app.instrumentationProfileFile; 5324 ParcelFileDescriptor profileFd = null; 5325 boolean profileAutoStop = false; 5326 if (mProfileApp != null && mProfileApp.equals(processName)) { 5327 mProfileProc = app; 5328 profileFile = mProfileFile; 5329 profileFd = mProfileFd; 5330 profileAutoStop = mAutoStopProfiler; 5331 } 5332 boolean enableOpenGlTrace = false; 5333 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5334 enableOpenGlTrace = true; 5335 mOpenGlTraceApp = null; 5336 } 5337 5338 // If the app is being launched for restore or full backup, set it up specially 5339 boolean isRestrictedBackupMode = false; 5340 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5341 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5342 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5343 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5344 } 5345 5346 ensurePackageDexOpt(app.instrumentationInfo != null 5347 ? app.instrumentationInfo.packageName 5348 : app.info.packageName); 5349 if (app.instrumentationClass != null) { 5350 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5351 } 5352 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5353 + processName + " with config " + mConfiguration); 5354 ApplicationInfo appInfo = app.instrumentationInfo != null 5355 ? app.instrumentationInfo : app.info; 5356 app.compat = compatibilityInfoForPackageLocked(appInfo); 5357 if (profileFd != null) { 5358 profileFd = profileFd.dup(); 5359 } 5360 thread.bindApplication(processName, appInfo, providers, 5361 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5362 app.instrumentationArguments, app.instrumentationWatcher, 5363 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5364 isRestrictedBackupMode || !normalMode, app.persistent, 5365 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5366 mCoreSettingsObserver.getCoreSettingsLocked()); 5367 updateLruProcessLocked(app, false, null); 5368 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5369 } catch (Exception e) { 5370 // todo: Yikes! What should we do? For now we will try to 5371 // start another process, but that could easily get us in 5372 // an infinite loop of restarting processes... 5373 Slog.w(TAG, "Exception thrown during bind!", e); 5374 5375 app.resetPackageList(mProcessStats); 5376 app.unlinkDeathRecipient(); 5377 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5378 return false; 5379 } 5380 5381 // Remove this record from the list of starting applications. 5382 mPersistentStartingProcesses.remove(app); 5383 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5384 "Attach application locked removing on hold: " + app); 5385 mProcessesOnHold.remove(app); 5386 5387 boolean badApp = false; 5388 boolean didSomething = false; 5389 5390 // See if the top visible activity is waiting to run in this process... 5391 if (normalMode) { 5392 try { 5393 if (mStackSupervisor.attachApplicationLocked(app)) { 5394 didSomething = true; 5395 } 5396 } catch (Exception e) { 5397 badApp = true; 5398 } 5399 } 5400 5401 // Find any services that should be running in this process... 5402 if (!badApp) { 5403 try { 5404 didSomething |= mServices.attachApplicationLocked(app, processName); 5405 } catch (Exception e) { 5406 badApp = true; 5407 } 5408 } 5409 5410 // Check if a next-broadcast receiver is in this process... 5411 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5412 try { 5413 didSomething |= sendPendingBroadcastsLocked(app); 5414 } catch (Exception e) { 5415 // If the app died trying to launch the receiver we declare it 'bad' 5416 badApp = true; 5417 } 5418 } 5419 5420 // Check whether the next backup agent is in this process... 5421 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5422 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5423 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5424 try { 5425 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5426 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5427 mBackupTarget.backupMode); 5428 } catch (Exception e) { 5429 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5430 e.printStackTrace(); 5431 } 5432 } 5433 5434 if (badApp) { 5435 // todo: Also need to kill application to deal with all 5436 // kinds of exceptions. 5437 handleAppDiedLocked(app, false, true); 5438 return false; 5439 } 5440 5441 if (!didSomething) { 5442 updateOomAdjLocked(); 5443 } 5444 5445 return true; 5446 } 5447 5448 @Override 5449 public final void attachApplication(IApplicationThread thread) { 5450 synchronized (this) { 5451 int callingPid = Binder.getCallingPid(); 5452 final long origId = Binder.clearCallingIdentity(); 5453 attachApplicationLocked(thread, callingPid); 5454 Binder.restoreCallingIdentity(origId); 5455 } 5456 } 5457 5458 @Override 5459 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5460 final long origId = Binder.clearCallingIdentity(); 5461 synchronized (this) { 5462 ActivityStack stack = ActivityRecord.getStackLocked(token); 5463 if (stack != null) { 5464 ActivityRecord r = 5465 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5466 if (stopProfiling) { 5467 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5468 try { 5469 mProfileFd.close(); 5470 } catch (IOException e) { 5471 } 5472 clearProfilerLocked(); 5473 } 5474 } 5475 } 5476 } 5477 Binder.restoreCallingIdentity(origId); 5478 } 5479 5480 void enableScreenAfterBoot() { 5481 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5482 SystemClock.uptimeMillis()); 5483 mWindowManager.enableScreenAfterBoot(); 5484 5485 synchronized (this) { 5486 updateEventDispatchingLocked(); 5487 } 5488 } 5489 5490 @Override 5491 public void showBootMessage(final CharSequence msg, final boolean always) { 5492 enforceNotIsolatedCaller("showBootMessage"); 5493 mWindowManager.showBootMessage(msg, always); 5494 } 5495 5496 @Override 5497 public void dismissKeyguardOnNextActivity() { 5498 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5499 final long token = Binder.clearCallingIdentity(); 5500 try { 5501 synchronized (this) { 5502 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5503 if (mLockScreenShown) { 5504 mLockScreenShown = false; 5505 comeOutOfSleepIfNeededLocked(); 5506 } 5507 mStackSupervisor.setDismissKeyguard(true); 5508 } 5509 } finally { 5510 Binder.restoreCallingIdentity(token); 5511 } 5512 } 5513 5514 final void finishBooting() { 5515 // Register receivers to handle package update events 5516 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5517 5518 synchronized (this) { 5519 // Ensure that any processes we had put on hold are now started 5520 // up. 5521 final int NP = mProcessesOnHold.size(); 5522 if (NP > 0) { 5523 ArrayList<ProcessRecord> procs = 5524 new ArrayList<ProcessRecord>(mProcessesOnHold); 5525 for (int ip=0; ip<NP; ip++) { 5526 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5527 + procs.get(ip)); 5528 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5529 } 5530 } 5531 5532 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5533 // Start looking for apps that are abusing wake locks. 5534 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5535 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5536 // Tell anyone interested that we are done booting! 5537 SystemProperties.set("sys.boot_completed", "1"); 5538 SystemProperties.set("dev.bootcomplete", "1"); 5539 for (int i=0; i<mStartedUsers.size(); i++) { 5540 UserStartedState uss = mStartedUsers.valueAt(i); 5541 if (uss.mState == UserStartedState.STATE_BOOTING) { 5542 uss.mState = UserStartedState.STATE_RUNNING; 5543 final int userId = mStartedUsers.keyAt(i); 5544 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5545 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5546 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5547 broadcastIntentLocked(null, null, intent, null, 5548 new IIntentReceiver.Stub() { 5549 @Override 5550 public void performReceive(Intent intent, int resultCode, 5551 String data, Bundle extras, boolean ordered, 5552 boolean sticky, int sendingUser) { 5553 synchronized (ActivityManagerService.this) { 5554 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5555 true, false); 5556 } 5557 } 5558 }, 5559 0, null, null, 5560 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5561 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5562 userId); 5563 } 5564 } 5565 scheduleStartProfilesLocked(); 5566 } 5567 } 5568 } 5569 5570 final void ensureBootCompleted() { 5571 boolean booting; 5572 boolean enableScreen; 5573 synchronized (this) { 5574 booting = mBooting; 5575 mBooting = false; 5576 enableScreen = !mBooted; 5577 mBooted = true; 5578 } 5579 5580 if (booting) { 5581 finishBooting(); 5582 } 5583 5584 if (enableScreen) { 5585 enableScreenAfterBoot(); 5586 } 5587 } 5588 5589 @Override 5590 public final void activityResumed(IBinder token) { 5591 final long origId = Binder.clearCallingIdentity(); 5592 synchronized(this) { 5593 ActivityStack stack = ActivityRecord.getStackLocked(token); 5594 if (stack != null) { 5595 ActivityRecord.activityResumedLocked(token); 5596 } 5597 } 5598 Binder.restoreCallingIdentity(origId); 5599 } 5600 5601 @Override 5602 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5603 final long origId = Binder.clearCallingIdentity(); 5604 synchronized(this) { 5605 ActivityStack stack = ActivityRecord.getStackLocked(token); 5606 if (stack != null) { 5607 stack.activityPausedLocked(token, false, persistentState); 5608 } 5609 } 5610 Binder.restoreCallingIdentity(origId); 5611 } 5612 5613 @Override 5614 public final void activityStopped(IBinder token, Bundle icicle, 5615 PersistableBundle persistentState, CharSequence description) { 5616 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5617 5618 // Refuse possible leaked file descriptors 5619 if (icicle != null && icicle.hasFileDescriptors()) { 5620 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5621 } 5622 5623 final long origId = Binder.clearCallingIdentity(); 5624 5625 synchronized (this) { 5626 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5627 if (r != null) { 5628 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5629 } 5630 } 5631 5632 trimApplications(); 5633 5634 Binder.restoreCallingIdentity(origId); 5635 } 5636 5637 @Override 5638 public final void activityDestroyed(IBinder token) { 5639 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5640 synchronized (this) { 5641 ActivityStack stack = ActivityRecord.getStackLocked(token); 5642 if (stack != null) { 5643 stack.activityDestroyedLocked(token); 5644 } 5645 } 5646 } 5647 5648 @Override 5649 public final void mediaResourcesReleased(IBinder token) { 5650 final long origId = Binder.clearCallingIdentity(); 5651 try { 5652 synchronized (this) { 5653 ActivityStack stack = ActivityRecord.getStackLocked(token); 5654 if (stack != null) { 5655 stack.mediaResourcesReleased(token); 5656 } 5657 } 5658 } finally { 5659 Binder.restoreCallingIdentity(origId); 5660 } 5661 } 5662 5663 @Override 5664 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5665 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5666 } 5667 5668 @Override 5669 public String getCallingPackage(IBinder token) { 5670 synchronized (this) { 5671 ActivityRecord r = getCallingRecordLocked(token); 5672 return r != null ? r.info.packageName : null; 5673 } 5674 } 5675 5676 @Override 5677 public ComponentName getCallingActivity(IBinder token) { 5678 synchronized (this) { 5679 ActivityRecord r = getCallingRecordLocked(token); 5680 return r != null ? r.intent.getComponent() : null; 5681 } 5682 } 5683 5684 private ActivityRecord getCallingRecordLocked(IBinder token) { 5685 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5686 if (r == null) { 5687 return null; 5688 } 5689 return r.resultTo; 5690 } 5691 5692 @Override 5693 public ComponentName getActivityClassForToken(IBinder token) { 5694 synchronized(this) { 5695 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5696 if (r == null) { 5697 return null; 5698 } 5699 return r.intent.getComponent(); 5700 } 5701 } 5702 5703 @Override 5704 public String getPackageForToken(IBinder token) { 5705 synchronized(this) { 5706 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5707 if (r == null) { 5708 return null; 5709 } 5710 return r.packageName; 5711 } 5712 } 5713 5714 @Override 5715 public IIntentSender getIntentSender(int type, 5716 String packageName, IBinder token, String resultWho, 5717 int requestCode, Intent[] intents, String[] resolvedTypes, 5718 int flags, Bundle options, int userId) { 5719 enforceNotIsolatedCaller("getIntentSender"); 5720 // Refuse possible leaked file descriptors 5721 if (intents != null) { 5722 if (intents.length < 1) { 5723 throw new IllegalArgumentException("Intents array length must be >= 1"); 5724 } 5725 for (int i=0; i<intents.length; i++) { 5726 Intent intent = intents[i]; 5727 if (intent != null) { 5728 if (intent.hasFileDescriptors()) { 5729 throw new IllegalArgumentException("File descriptors passed in Intent"); 5730 } 5731 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5732 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5733 throw new IllegalArgumentException( 5734 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5735 } 5736 intents[i] = new Intent(intent); 5737 } 5738 } 5739 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5740 throw new IllegalArgumentException( 5741 "Intent array length does not match resolvedTypes length"); 5742 } 5743 } 5744 if (options != null) { 5745 if (options.hasFileDescriptors()) { 5746 throw new IllegalArgumentException("File descriptors passed in options"); 5747 } 5748 } 5749 5750 synchronized(this) { 5751 int callingUid = Binder.getCallingUid(); 5752 int origUserId = userId; 5753 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5754 type == ActivityManager.INTENT_SENDER_BROADCAST, 5755 ALLOW_NON_FULL, "getIntentSender", null); 5756 if (origUserId == UserHandle.USER_CURRENT) { 5757 // We don't want to evaluate this until the pending intent is 5758 // actually executed. However, we do want to always do the 5759 // security checking for it above. 5760 userId = UserHandle.USER_CURRENT; 5761 } 5762 try { 5763 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5764 int uid = AppGlobals.getPackageManager() 5765 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5766 if (!UserHandle.isSameApp(callingUid, uid)) { 5767 String msg = "Permission Denial: getIntentSender() from pid=" 5768 + Binder.getCallingPid() 5769 + ", uid=" + Binder.getCallingUid() 5770 + ", (need uid=" + uid + ")" 5771 + " is not allowed to send as package " + packageName; 5772 Slog.w(TAG, msg); 5773 throw new SecurityException(msg); 5774 } 5775 } 5776 5777 return getIntentSenderLocked(type, packageName, callingUid, userId, 5778 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5779 5780 } catch (RemoteException e) { 5781 throw new SecurityException(e); 5782 } 5783 } 5784 } 5785 5786 IIntentSender getIntentSenderLocked(int type, String packageName, 5787 int callingUid, int userId, IBinder token, String resultWho, 5788 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5789 Bundle options) { 5790 if (DEBUG_MU) 5791 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5792 ActivityRecord activity = null; 5793 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5794 activity = ActivityRecord.isInStackLocked(token); 5795 if (activity == null) { 5796 return null; 5797 } 5798 if (activity.finishing) { 5799 return null; 5800 } 5801 } 5802 5803 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5804 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5805 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5806 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5807 |PendingIntent.FLAG_UPDATE_CURRENT); 5808 5809 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5810 type, packageName, activity, resultWho, 5811 requestCode, intents, resolvedTypes, flags, options, userId); 5812 WeakReference<PendingIntentRecord> ref; 5813 ref = mIntentSenderRecords.get(key); 5814 PendingIntentRecord rec = ref != null ? ref.get() : null; 5815 if (rec != null) { 5816 if (!cancelCurrent) { 5817 if (updateCurrent) { 5818 if (rec.key.requestIntent != null) { 5819 rec.key.requestIntent.replaceExtras(intents != null ? 5820 intents[intents.length - 1] : null); 5821 } 5822 if (intents != null) { 5823 intents[intents.length-1] = rec.key.requestIntent; 5824 rec.key.allIntents = intents; 5825 rec.key.allResolvedTypes = resolvedTypes; 5826 } else { 5827 rec.key.allIntents = null; 5828 rec.key.allResolvedTypes = null; 5829 } 5830 } 5831 return rec; 5832 } 5833 rec.canceled = true; 5834 mIntentSenderRecords.remove(key); 5835 } 5836 if (noCreate) { 5837 return rec; 5838 } 5839 rec = new PendingIntentRecord(this, key, callingUid); 5840 mIntentSenderRecords.put(key, rec.ref); 5841 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5842 if (activity.pendingResults == null) { 5843 activity.pendingResults 5844 = new HashSet<WeakReference<PendingIntentRecord>>(); 5845 } 5846 activity.pendingResults.add(rec.ref); 5847 } 5848 return rec; 5849 } 5850 5851 @Override 5852 public void cancelIntentSender(IIntentSender sender) { 5853 if (!(sender instanceof PendingIntentRecord)) { 5854 return; 5855 } 5856 synchronized(this) { 5857 PendingIntentRecord rec = (PendingIntentRecord)sender; 5858 try { 5859 int uid = AppGlobals.getPackageManager() 5860 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5861 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5862 String msg = "Permission Denial: cancelIntentSender() from pid=" 5863 + Binder.getCallingPid() 5864 + ", uid=" + Binder.getCallingUid() 5865 + " is not allowed to cancel packges " 5866 + rec.key.packageName; 5867 Slog.w(TAG, msg); 5868 throw new SecurityException(msg); 5869 } 5870 } catch (RemoteException e) { 5871 throw new SecurityException(e); 5872 } 5873 cancelIntentSenderLocked(rec, true); 5874 } 5875 } 5876 5877 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5878 rec.canceled = true; 5879 mIntentSenderRecords.remove(rec.key); 5880 if (cleanActivity && rec.key.activity != null) { 5881 rec.key.activity.pendingResults.remove(rec.ref); 5882 } 5883 } 5884 5885 @Override 5886 public String getPackageForIntentSender(IIntentSender pendingResult) { 5887 if (!(pendingResult instanceof PendingIntentRecord)) { 5888 return null; 5889 } 5890 try { 5891 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5892 return res.key.packageName; 5893 } catch (ClassCastException e) { 5894 } 5895 return null; 5896 } 5897 5898 @Override 5899 public int getUidForIntentSender(IIntentSender sender) { 5900 if (sender instanceof PendingIntentRecord) { 5901 try { 5902 PendingIntentRecord res = (PendingIntentRecord)sender; 5903 return res.uid; 5904 } catch (ClassCastException e) { 5905 } 5906 } 5907 return -1; 5908 } 5909 5910 @Override 5911 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5912 if (!(pendingResult instanceof PendingIntentRecord)) { 5913 return false; 5914 } 5915 try { 5916 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5917 if (res.key.allIntents == null) { 5918 return false; 5919 } 5920 for (int i=0; i<res.key.allIntents.length; i++) { 5921 Intent intent = res.key.allIntents[i]; 5922 if (intent.getPackage() != null && intent.getComponent() != null) { 5923 return false; 5924 } 5925 } 5926 return true; 5927 } catch (ClassCastException e) { 5928 } 5929 return false; 5930 } 5931 5932 @Override 5933 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5934 if (!(pendingResult instanceof PendingIntentRecord)) { 5935 return false; 5936 } 5937 try { 5938 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5939 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5940 return true; 5941 } 5942 return false; 5943 } catch (ClassCastException e) { 5944 } 5945 return false; 5946 } 5947 5948 @Override 5949 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5950 if (!(pendingResult instanceof PendingIntentRecord)) { 5951 return null; 5952 } 5953 try { 5954 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5955 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5956 } catch (ClassCastException e) { 5957 } 5958 return null; 5959 } 5960 5961 @Override 5962 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5963 if (!(pendingResult instanceof PendingIntentRecord)) { 5964 return null; 5965 } 5966 try { 5967 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5968 Intent intent = res.key.requestIntent; 5969 if (intent != null) { 5970 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5971 || res.lastTagPrefix.equals(prefix))) { 5972 return res.lastTag; 5973 } 5974 res.lastTagPrefix = prefix; 5975 StringBuilder sb = new StringBuilder(128); 5976 if (prefix != null) { 5977 sb.append(prefix); 5978 } 5979 if (intent.getAction() != null) { 5980 sb.append(intent.getAction()); 5981 } else if (intent.getComponent() != null) { 5982 intent.getComponent().appendShortString(sb); 5983 } else { 5984 sb.append("?"); 5985 } 5986 return res.lastTag = sb.toString(); 5987 } 5988 } catch (ClassCastException e) { 5989 } 5990 return null; 5991 } 5992 5993 @Override 5994 public void setProcessLimit(int max) { 5995 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5996 "setProcessLimit()"); 5997 synchronized (this) { 5998 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5999 mProcessLimitOverride = max; 6000 } 6001 trimApplications(); 6002 } 6003 6004 @Override 6005 public int getProcessLimit() { 6006 synchronized (this) { 6007 return mProcessLimitOverride; 6008 } 6009 } 6010 6011 void foregroundTokenDied(ForegroundToken token) { 6012 synchronized (ActivityManagerService.this) { 6013 synchronized (mPidsSelfLocked) { 6014 ForegroundToken cur 6015 = mForegroundProcesses.get(token.pid); 6016 if (cur != token) { 6017 return; 6018 } 6019 mForegroundProcesses.remove(token.pid); 6020 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6021 if (pr == null) { 6022 return; 6023 } 6024 pr.forcingToForeground = null; 6025 updateProcessForegroundLocked(pr, false, false); 6026 } 6027 updateOomAdjLocked(); 6028 } 6029 } 6030 6031 @Override 6032 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6033 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6034 "setProcessForeground()"); 6035 synchronized(this) { 6036 boolean changed = false; 6037 6038 synchronized (mPidsSelfLocked) { 6039 ProcessRecord pr = mPidsSelfLocked.get(pid); 6040 if (pr == null && isForeground) { 6041 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6042 return; 6043 } 6044 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6045 if (oldToken != null) { 6046 oldToken.token.unlinkToDeath(oldToken, 0); 6047 mForegroundProcesses.remove(pid); 6048 if (pr != null) { 6049 pr.forcingToForeground = null; 6050 } 6051 changed = true; 6052 } 6053 if (isForeground && token != null) { 6054 ForegroundToken newToken = new ForegroundToken() { 6055 @Override 6056 public void binderDied() { 6057 foregroundTokenDied(this); 6058 } 6059 }; 6060 newToken.pid = pid; 6061 newToken.token = token; 6062 try { 6063 token.linkToDeath(newToken, 0); 6064 mForegroundProcesses.put(pid, newToken); 6065 pr.forcingToForeground = token; 6066 changed = true; 6067 } catch (RemoteException e) { 6068 // If the process died while doing this, we will later 6069 // do the cleanup with the process death link. 6070 } 6071 } 6072 } 6073 6074 if (changed) { 6075 updateOomAdjLocked(); 6076 } 6077 } 6078 } 6079 6080 // ========================================================= 6081 // PERMISSIONS 6082 // ========================================================= 6083 6084 static class PermissionController extends IPermissionController.Stub { 6085 ActivityManagerService mActivityManagerService; 6086 PermissionController(ActivityManagerService activityManagerService) { 6087 mActivityManagerService = activityManagerService; 6088 } 6089 6090 @Override 6091 public boolean checkPermission(String permission, int pid, int uid) { 6092 return mActivityManagerService.checkPermission(permission, pid, 6093 uid) == PackageManager.PERMISSION_GRANTED; 6094 } 6095 } 6096 6097 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6098 @Override 6099 public int checkComponentPermission(String permission, int pid, int uid, 6100 int owningUid, boolean exported) { 6101 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6102 owningUid, exported); 6103 } 6104 6105 @Override 6106 public Object getAMSLock() { 6107 return ActivityManagerService.this; 6108 } 6109 } 6110 6111 /** 6112 * This can be called with or without the global lock held. 6113 */ 6114 int checkComponentPermission(String permission, int pid, int uid, 6115 int owningUid, boolean exported) { 6116 // We might be performing an operation on behalf of an indirect binder 6117 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6118 // client identity accordingly before proceeding. 6119 Identity tlsIdentity = sCallerIdentity.get(); 6120 if (tlsIdentity != null) { 6121 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6122 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6123 uid = tlsIdentity.uid; 6124 pid = tlsIdentity.pid; 6125 } 6126 6127 if (pid == MY_PID) { 6128 return PackageManager.PERMISSION_GRANTED; 6129 } 6130 6131 return ActivityManager.checkComponentPermission(permission, uid, 6132 owningUid, exported); 6133 } 6134 6135 /** 6136 * As the only public entry point for permissions checking, this method 6137 * can enforce the semantic that requesting a check on a null global 6138 * permission is automatically denied. (Internally a null permission 6139 * string is used when calling {@link #checkComponentPermission} in cases 6140 * when only uid-based security is needed.) 6141 * 6142 * This can be called with or without the global lock held. 6143 */ 6144 @Override 6145 public int checkPermission(String permission, int pid, int uid) { 6146 if (permission == null) { 6147 return PackageManager.PERMISSION_DENIED; 6148 } 6149 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6150 } 6151 6152 /** 6153 * Binder IPC calls go through the public entry point. 6154 * This can be called with or without the global lock held. 6155 */ 6156 int checkCallingPermission(String permission) { 6157 return checkPermission(permission, 6158 Binder.getCallingPid(), 6159 UserHandle.getAppId(Binder.getCallingUid())); 6160 } 6161 6162 /** 6163 * This can be called with or without the global lock held. 6164 */ 6165 void enforceCallingPermission(String permission, String func) { 6166 if (checkCallingPermission(permission) 6167 == PackageManager.PERMISSION_GRANTED) { 6168 return; 6169 } 6170 6171 String msg = "Permission Denial: " + func + " from pid=" 6172 + Binder.getCallingPid() 6173 + ", uid=" + Binder.getCallingUid() 6174 + " requires " + permission; 6175 Slog.w(TAG, msg); 6176 throw new SecurityException(msg); 6177 } 6178 6179 /** 6180 * Determine if UID is holding permissions required to access {@link Uri} in 6181 * the given {@link ProviderInfo}. Final permission checking is always done 6182 * in {@link ContentProvider}. 6183 */ 6184 private final boolean checkHoldingPermissionsLocked( 6185 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6187 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6188 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6189 return false; 6190 } 6191 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6192 } 6193 6194 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6195 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6196 if (pi.applicationInfo.uid == uid) { 6197 return true; 6198 } else if (!pi.exported) { 6199 return false; 6200 } 6201 6202 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6203 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6204 try { 6205 // check if target holds top-level <provider> permissions 6206 if (!readMet && pi.readPermission != null && considerUidPermissions 6207 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6208 readMet = true; 6209 } 6210 if (!writeMet && pi.writePermission != null && considerUidPermissions 6211 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6212 writeMet = true; 6213 } 6214 6215 // track if unprotected read/write is allowed; any denied 6216 // <path-permission> below removes this ability 6217 boolean allowDefaultRead = pi.readPermission == null; 6218 boolean allowDefaultWrite = pi.writePermission == null; 6219 6220 // check if target holds any <path-permission> that match uri 6221 final PathPermission[] pps = pi.pathPermissions; 6222 if (pps != null) { 6223 final String path = grantUri.uri.getPath(); 6224 int i = pps.length; 6225 while (i > 0 && (!readMet || !writeMet)) { 6226 i--; 6227 PathPermission pp = pps[i]; 6228 if (pp.match(path)) { 6229 if (!readMet) { 6230 final String pprperm = pp.getReadPermission(); 6231 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6232 + pprperm + " for " + pp.getPath() 6233 + ": match=" + pp.match(path) 6234 + " check=" + pm.checkUidPermission(pprperm, uid)); 6235 if (pprperm != null) { 6236 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6237 == PERMISSION_GRANTED) { 6238 readMet = true; 6239 } else { 6240 allowDefaultRead = false; 6241 } 6242 } 6243 } 6244 if (!writeMet) { 6245 final String ppwperm = pp.getWritePermission(); 6246 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6247 + ppwperm + " for " + pp.getPath() 6248 + ": match=" + pp.match(path) 6249 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6250 if (ppwperm != null) { 6251 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6252 == PERMISSION_GRANTED) { 6253 writeMet = true; 6254 } else { 6255 allowDefaultWrite = false; 6256 } 6257 } 6258 } 6259 } 6260 } 6261 } 6262 6263 // grant unprotected <provider> read/write, if not blocked by 6264 // <path-permission> above 6265 if (allowDefaultRead) readMet = true; 6266 if (allowDefaultWrite) writeMet = true; 6267 6268 } catch (RemoteException e) { 6269 return false; 6270 } 6271 6272 return readMet && writeMet; 6273 } 6274 6275 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6276 ProviderInfo pi = null; 6277 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6278 if (cpr != null) { 6279 pi = cpr.info; 6280 } else { 6281 try { 6282 pi = AppGlobals.getPackageManager().resolveContentProvider( 6283 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6284 } catch (RemoteException ex) { 6285 } 6286 } 6287 return pi; 6288 } 6289 6290 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6291 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6292 if (targetUris != null) { 6293 return targetUris.get(grantUri); 6294 } 6295 return null; 6296 } 6297 6298 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6299 String targetPkg, int targetUid, GrantUri grantUri) { 6300 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6301 if (targetUris == null) { 6302 targetUris = Maps.newArrayMap(); 6303 mGrantedUriPermissions.put(targetUid, targetUris); 6304 } 6305 6306 UriPermission perm = targetUris.get(grantUri); 6307 if (perm == null) { 6308 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6309 targetUris.put(grantUri, perm); 6310 } 6311 6312 return perm; 6313 } 6314 6315 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6316 final int modeFlags) { 6317 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6318 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6319 : UriPermission.STRENGTH_OWNED; 6320 6321 // Root gets to do everything. 6322 if (uid == 0) { 6323 return true; 6324 } 6325 6326 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6327 if (perms == null) return false; 6328 6329 // First look for exact match 6330 final UriPermission exactPerm = perms.get(grantUri); 6331 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6332 return true; 6333 } 6334 6335 // No exact match, look for prefixes 6336 final int N = perms.size(); 6337 for (int i = 0; i < N; i++) { 6338 final UriPermission perm = perms.valueAt(i); 6339 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6340 && perm.getStrength(modeFlags) >= minStrength) { 6341 return true; 6342 } 6343 } 6344 6345 return false; 6346 } 6347 6348 @Override 6349 public int checkUriPermission(Uri uri, int pid, int uid, 6350 final int modeFlags, int userId) { 6351 enforceNotIsolatedCaller("checkUriPermission"); 6352 6353 // Another redirected-binder-call permissions check as in 6354 // {@link checkComponentPermission}. 6355 Identity tlsIdentity = sCallerIdentity.get(); 6356 if (tlsIdentity != null) { 6357 uid = tlsIdentity.uid; 6358 pid = tlsIdentity.pid; 6359 } 6360 6361 // Our own process gets to do everything. 6362 if (pid == MY_PID) { 6363 return PackageManager.PERMISSION_GRANTED; 6364 } 6365 synchronized (this) { 6366 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6367 ? PackageManager.PERMISSION_GRANTED 6368 : PackageManager.PERMISSION_DENIED; 6369 } 6370 } 6371 6372 /** 6373 * Check if the targetPkg can be granted permission to access uri by 6374 * the callingUid using the given modeFlags. Throws a security exception 6375 * if callingUid is not allowed to do this. Returns the uid of the target 6376 * if the URI permission grant should be performed; returns -1 if it is not 6377 * needed (for example targetPkg already has permission to access the URI). 6378 * If you already know the uid of the target, you can supply it in 6379 * lastTargetUid else set that to -1. 6380 */ 6381 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6382 final int modeFlags, int lastTargetUid) { 6383 if (!Intent.isAccessUriMode(modeFlags)) { 6384 return -1; 6385 } 6386 6387 if (targetPkg != null) { 6388 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6389 "Checking grant " + targetPkg + " permission to " + grantUri); 6390 } 6391 6392 final IPackageManager pm = AppGlobals.getPackageManager(); 6393 6394 // If this is not a content: uri, we can't do anything with it. 6395 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6396 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6397 "Can't grant URI permission for non-content URI: " + grantUri); 6398 return -1; 6399 } 6400 6401 final String authority = grantUri.uri.getAuthority(); 6402 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6403 if (pi == null) { 6404 Slog.w(TAG, "No content provider found for permission check: " + 6405 grantUri.uri.toSafeString()); 6406 return -1; 6407 } 6408 6409 int targetUid = lastTargetUid; 6410 if (targetUid < 0 && targetPkg != null) { 6411 try { 6412 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6413 if (targetUid < 0) { 6414 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6415 "Can't grant URI permission no uid for: " + targetPkg); 6416 return -1; 6417 } 6418 } catch (RemoteException ex) { 6419 return -1; 6420 } 6421 } 6422 6423 if (targetUid >= 0) { 6424 // First... does the target actually need this permission? 6425 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6426 // No need to grant the target this permission. 6427 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6428 "Target " + targetPkg + " already has full permission to " + grantUri); 6429 return -1; 6430 } 6431 } else { 6432 // First... there is no target package, so can anyone access it? 6433 boolean allowed = pi.exported; 6434 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6435 if (pi.readPermission != null) { 6436 allowed = false; 6437 } 6438 } 6439 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6440 if (pi.writePermission != null) { 6441 allowed = false; 6442 } 6443 } 6444 if (allowed) { 6445 return -1; 6446 } 6447 } 6448 6449 /* There is a special cross user grant if: 6450 * - The target is on another user. 6451 * - Apps on the current user can access the uri without any uid permissions. 6452 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6453 * grant uri permissions. 6454 */ 6455 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6456 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6457 modeFlags, false /*without considering the uid permissions*/); 6458 6459 // Second... is the provider allowing granting of URI permissions? 6460 if (!specialCrossUserGrant) { 6461 if (!pi.grantUriPermissions) { 6462 throw new SecurityException("Provider " + pi.packageName 6463 + "/" + pi.name 6464 + " does not allow granting of Uri permissions (uri " 6465 + grantUri + ")"); 6466 } 6467 if (pi.uriPermissionPatterns != null) { 6468 final int N = pi.uriPermissionPatterns.length; 6469 boolean allowed = false; 6470 for (int i=0; i<N; i++) { 6471 if (pi.uriPermissionPatterns[i] != null 6472 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6473 allowed = true; 6474 break; 6475 } 6476 } 6477 if (!allowed) { 6478 throw new SecurityException("Provider " + pi.packageName 6479 + "/" + pi.name 6480 + " does not allow granting of permission to path of Uri " 6481 + grantUri); 6482 } 6483 } 6484 } 6485 6486 // Third... does the caller itself have permission to access 6487 // this uri? 6488 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6489 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6490 // Require they hold a strong enough Uri permission 6491 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6492 throw new SecurityException("Uid " + callingUid 6493 + " does not have permission to uri " + grantUri); 6494 } 6495 } 6496 } 6497 return targetUid; 6498 } 6499 6500 @Override 6501 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6502 final int modeFlags, int userId) { 6503 enforceNotIsolatedCaller("checkGrantUriPermission"); 6504 synchronized(this) { 6505 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6506 new GrantUri(userId, uri, false), modeFlags, -1); 6507 } 6508 } 6509 6510 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6511 final int modeFlags, UriPermissionOwner owner) { 6512 if (!Intent.isAccessUriMode(modeFlags)) { 6513 return; 6514 } 6515 6516 // So here we are: the caller has the assumed permission 6517 // to the uri, and the target doesn't. Let's now give this to 6518 // the target. 6519 6520 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6521 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6522 6523 final String authority = grantUri.uri.getAuthority(); 6524 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6525 if (pi == null) { 6526 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6527 return; 6528 } 6529 6530 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6531 grantUri.prefix = true; 6532 } 6533 final UriPermission perm = findOrCreateUriPermissionLocked( 6534 pi.packageName, targetPkg, targetUid, grantUri); 6535 perm.grantModes(modeFlags, owner); 6536 } 6537 6538 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6539 final int modeFlags, UriPermissionOwner owner) { 6540 if (targetPkg == null) { 6541 throw new NullPointerException("targetPkg"); 6542 } 6543 6544 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6545 -1); 6546 if (targetUid < 0) { 6547 return; 6548 } 6549 6550 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6551 owner); 6552 } 6553 6554 static class NeededUriGrants extends ArrayList<GrantUri> { 6555 final String targetPkg; 6556 final int targetUid; 6557 final int flags; 6558 6559 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6560 this.targetPkg = targetPkg; 6561 this.targetUid = targetUid; 6562 this.flags = flags; 6563 } 6564 } 6565 6566 /** 6567 * Like checkGrantUriPermissionLocked, but takes an Intent. 6568 */ 6569 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6570 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6571 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6572 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6573 + " clip=" + (intent != null ? intent.getClipData() : null) 6574 + " from " + intent + "; flags=0x" 6575 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6576 6577 if (targetPkg == null) { 6578 throw new NullPointerException("targetPkg"); 6579 } 6580 6581 if (intent == null) { 6582 return null; 6583 } 6584 Uri data = intent.getData(); 6585 ClipData clip = intent.getClipData(); 6586 if (data == null && clip == null) { 6587 return null; 6588 } 6589 final IPackageManager pm = AppGlobals.getPackageManager(); 6590 int targetUid; 6591 if (needed != null) { 6592 targetUid = needed.targetUid; 6593 } else { 6594 try { 6595 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6596 } catch (RemoteException ex) { 6597 return null; 6598 } 6599 if (targetUid < 0) { 6600 if (DEBUG_URI_PERMISSION) { 6601 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6602 + " on user " + targetUserId); 6603 } 6604 return null; 6605 } 6606 } 6607 if (data != null) { 6608 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6609 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6610 targetUid); 6611 if (targetUid > 0) { 6612 if (needed == null) { 6613 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6614 } 6615 needed.add(grantUri); 6616 } 6617 } 6618 if (clip != null) { 6619 for (int i=0; i<clip.getItemCount(); i++) { 6620 Uri uri = clip.getItemAt(i).getUri(); 6621 if (uri != null) { 6622 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6623 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6624 targetUid); 6625 if (targetUid > 0) { 6626 if (needed == null) { 6627 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6628 } 6629 needed.add(grantUri); 6630 } 6631 } else { 6632 Intent clipIntent = clip.getItemAt(i).getIntent(); 6633 if (clipIntent != null) { 6634 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6635 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6636 if (newNeeded != null) { 6637 needed = newNeeded; 6638 } 6639 } 6640 } 6641 } 6642 } 6643 6644 return needed; 6645 } 6646 6647 /** 6648 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6649 */ 6650 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6651 UriPermissionOwner owner) { 6652 if (needed != null) { 6653 for (int i=0; i<needed.size(); i++) { 6654 GrantUri grantUri = needed.get(i); 6655 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6656 grantUri, needed.flags, owner); 6657 } 6658 } 6659 } 6660 6661 void grantUriPermissionFromIntentLocked(int callingUid, 6662 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6663 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6664 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6665 if (needed == null) { 6666 return; 6667 } 6668 6669 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6670 } 6671 6672 @Override 6673 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6674 final int modeFlags, int userId) { 6675 enforceNotIsolatedCaller("grantUriPermission"); 6676 GrantUri grantUri = new GrantUri(userId, uri, false); 6677 synchronized(this) { 6678 final ProcessRecord r = getRecordForAppLocked(caller); 6679 if (r == null) { 6680 throw new SecurityException("Unable to find app for caller " 6681 + caller 6682 + " when granting permission to uri " + grantUri); 6683 } 6684 if (targetPkg == null) { 6685 throw new IllegalArgumentException("null target"); 6686 } 6687 if (grantUri == null) { 6688 throw new IllegalArgumentException("null uri"); 6689 } 6690 6691 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6692 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6693 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6694 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6695 6696 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6697 } 6698 } 6699 6700 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6701 if (perm.modeFlags == 0) { 6702 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6703 perm.targetUid); 6704 if (perms != null) { 6705 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6706 "Removing " + perm.targetUid + " permission to " + perm.uri); 6707 6708 perms.remove(perm.uri); 6709 if (perms.isEmpty()) { 6710 mGrantedUriPermissions.remove(perm.targetUid); 6711 } 6712 } 6713 } 6714 } 6715 6716 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6717 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6718 6719 final IPackageManager pm = AppGlobals.getPackageManager(); 6720 final String authority = grantUri.uri.getAuthority(); 6721 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6722 if (pi == null) { 6723 Slog.w(TAG, "No content provider found for permission revoke: " 6724 + grantUri.toSafeString()); 6725 return; 6726 } 6727 6728 // Does the caller have this permission on the URI? 6729 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6730 // Right now, if you are not the original owner of the permission, 6731 // you are not allowed to revoke it. 6732 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6733 throw new SecurityException("Uid " + callingUid 6734 + " does not have permission to uri " + grantUri); 6735 //} 6736 } 6737 6738 boolean persistChanged = false; 6739 6740 // Go through all of the permissions and remove any that match. 6741 int N = mGrantedUriPermissions.size(); 6742 for (int i = 0; i < N; i++) { 6743 final int targetUid = mGrantedUriPermissions.keyAt(i); 6744 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6745 6746 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6747 final UriPermission perm = it.next(); 6748 if (perm.uri.sourceUserId == grantUri.sourceUserId 6749 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6750 if (DEBUG_URI_PERMISSION) 6751 Slog.v(TAG, 6752 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6753 persistChanged |= perm.revokeModes( 6754 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6755 if (perm.modeFlags == 0) { 6756 it.remove(); 6757 } 6758 } 6759 } 6760 6761 if (perms.isEmpty()) { 6762 mGrantedUriPermissions.remove(targetUid); 6763 N--; 6764 i--; 6765 } 6766 } 6767 6768 if (persistChanged) { 6769 schedulePersistUriGrants(); 6770 } 6771 } 6772 6773 @Override 6774 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6775 int userId) { 6776 enforceNotIsolatedCaller("revokeUriPermission"); 6777 synchronized(this) { 6778 final ProcessRecord r = getRecordForAppLocked(caller); 6779 if (r == null) { 6780 throw new SecurityException("Unable to find app for caller " 6781 + caller 6782 + " when revoking permission to uri " + uri); 6783 } 6784 if (uri == null) { 6785 Slog.w(TAG, "revokeUriPermission: null uri"); 6786 return; 6787 } 6788 6789 if (!Intent.isAccessUriMode(modeFlags)) { 6790 return; 6791 } 6792 6793 final IPackageManager pm = AppGlobals.getPackageManager(); 6794 final String authority = uri.getAuthority(); 6795 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6796 if (pi == null) { 6797 Slog.w(TAG, "No content provider found for permission revoke: " 6798 + uri.toSafeString()); 6799 return; 6800 } 6801 6802 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6803 } 6804 } 6805 6806 /** 6807 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6808 * given package. 6809 * 6810 * @param packageName Package name to match, or {@code null} to apply to all 6811 * packages. 6812 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6813 * to all users. 6814 * @param persistable If persistable grants should be removed. 6815 */ 6816 private void removeUriPermissionsForPackageLocked( 6817 String packageName, int userHandle, boolean persistable) { 6818 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6819 throw new IllegalArgumentException("Must narrow by either package or user"); 6820 } 6821 6822 boolean persistChanged = false; 6823 6824 int N = mGrantedUriPermissions.size(); 6825 for (int i = 0; i < N; i++) { 6826 final int targetUid = mGrantedUriPermissions.keyAt(i); 6827 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6828 6829 // Only inspect grants matching user 6830 if (userHandle == UserHandle.USER_ALL 6831 || userHandle == UserHandle.getUserId(targetUid)) { 6832 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6833 final UriPermission perm = it.next(); 6834 6835 // Only inspect grants matching package 6836 if (packageName == null || perm.sourcePkg.equals(packageName) 6837 || perm.targetPkg.equals(packageName)) { 6838 persistChanged |= perm.revokeModes( 6839 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6840 6841 // Only remove when no modes remain; any persisted grants 6842 // will keep this alive. 6843 if (perm.modeFlags == 0) { 6844 it.remove(); 6845 } 6846 } 6847 } 6848 6849 if (perms.isEmpty()) { 6850 mGrantedUriPermissions.remove(targetUid); 6851 N--; 6852 i--; 6853 } 6854 } 6855 } 6856 6857 if (persistChanged) { 6858 schedulePersistUriGrants(); 6859 } 6860 } 6861 6862 @Override 6863 public IBinder newUriPermissionOwner(String name) { 6864 enforceNotIsolatedCaller("newUriPermissionOwner"); 6865 synchronized(this) { 6866 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6867 return owner.getExternalTokenLocked(); 6868 } 6869 } 6870 6871 @Override 6872 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6873 final int modeFlags, int userId) { 6874 synchronized(this) { 6875 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6876 if (owner == null) { 6877 throw new IllegalArgumentException("Unknown owner: " + token); 6878 } 6879 if (fromUid != Binder.getCallingUid()) { 6880 if (Binder.getCallingUid() != Process.myUid()) { 6881 // Only system code can grant URI permissions on behalf 6882 // of other users. 6883 throw new SecurityException("nice try"); 6884 } 6885 } 6886 if (targetPkg == null) { 6887 throw new IllegalArgumentException("null target"); 6888 } 6889 if (uri == null) { 6890 throw new IllegalArgumentException("null uri"); 6891 } 6892 6893 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6894 modeFlags, owner); 6895 } 6896 } 6897 6898 @Override 6899 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6900 synchronized(this) { 6901 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6902 if (owner == null) { 6903 throw new IllegalArgumentException("Unknown owner: " + token); 6904 } 6905 6906 if (uri == null) { 6907 owner.removeUriPermissionsLocked(mode); 6908 } else { 6909 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6910 } 6911 } 6912 } 6913 6914 private void schedulePersistUriGrants() { 6915 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6916 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6917 10 * DateUtils.SECOND_IN_MILLIS); 6918 } 6919 } 6920 6921 private void writeGrantedUriPermissions() { 6922 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6923 6924 // Snapshot permissions so we can persist without lock 6925 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6926 synchronized (this) { 6927 final int size = mGrantedUriPermissions.size(); 6928 for (int i = 0; i < size; i++) { 6929 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6930 for (UriPermission perm : perms.values()) { 6931 if (perm.persistedModeFlags != 0) { 6932 persist.add(perm.snapshot()); 6933 } 6934 } 6935 } 6936 } 6937 6938 FileOutputStream fos = null; 6939 try { 6940 fos = mGrantFile.startWrite(); 6941 6942 XmlSerializer out = new FastXmlSerializer(); 6943 out.setOutput(fos, "utf-8"); 6944 out.startDocument(null, true); 6945 out.startTag(null, TAG_URI_GRANTS); 6946 for (UriPermission.Snapshot perm : persist) { 6947 out.startTag(null, TAG_URI_GRANT); 6948 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6949 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6950 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6951 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6952 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6953 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6954 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6955 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6956 out.endTag(null, TAG_URI_GRANT); 6957 } 6958 out.endTag(null, TAG_URI_GRANTS); 6959 out.endDocument(); 6960 6961 mGrantFile.finishWrite(fos); 6962 } catch (IOException e) { 6963 if (fos != null) { 6964 mGrantFile.failWrite(fos); 6965 } 6966 } 6967 } 6968 6969 private void readGrantedUriPermissionsLocked() { 6970 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6971 6972 final long now = System.currentTimeMillis(); 6973 6974 FileInputStream fis = null; 6975 try { 6976 fis = mGrantFile.openRead(); 6977 final XmlPullParser in = Xml.newPullParser(); 6978 in.setInput(fis, null); 6979 6980 int type; 6981 while ((type = in.next()) != END_DOCUMENT) { 6982 final String tag = in.getName(); 6983 if (type == START_TAG) { 6984 if (TAG_URI_GRANT.equals(tag)) { 6985 final int sourceUserId; 6986 final int targetUserId; 6987 final int userHandle = readIntAttribute(in, 6988 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6989 if (userHandle != UserHandle.USER_NULL) { 6990 // For backwards compatibility. 6991 sourceUserId = userHandle; 6992 targetUserId = userHandle; 6993 } else { 6994 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6995 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6996 } 6997 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6998 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6999 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7000 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7001 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7002 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7003 7004 // Sanity check that provider still belongs to source package 7005 final ProviderInfo pi = getProviderInfoLocked( 7006 uri.getAuthority(), sourceUserId); 7007 if (pi != null && sourcePkg.equals(pi.packageName)) { 7008 int targetUid = -1; 7009 try { 7010 targetUid = AppGlobals.getPackageManager() 7011 .getPackageUid(targetPkg, targetUserId); 7012 } catch (RemoteException e) { 7013 } 7014 if (targetUid != -1) { 7015 final UriPermission perm = findOrCreateUriPermissionLocked( 7016 sourcePkg, targetPkg, targetUid, 7017 new GrantUri(sourceUserId, uri, prefix)); 7018 perm.initPersistedModes(modeFlags, createdTime); 7019 } 7020 } else { 7021 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7022 + " but instead found " + pi); 7023 } 7024 } 7025 } 7026 } 7027 } catch (FileNotFoundException e) { 7028 // Missing grants is okay 7029 } catch (IOException e) { 7030 Log.wtf(TAG, "Failed reading Uri grants", e); 7031 } catch (XmlPullParserException e) { 7032 Log.wtf(TAG, "Failed reading Uri grants", e); 7033 } finally { 7034 IoUtils.closeQuietly(fis); 7035 } 7036 } 7037 7038 @Override 7039 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7040 enforceNotIsolatedCaller("takePersistableUriPermission"); 7041 7042 Preconditions.checkFlagsArgument(modeFlags, 7043 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7044 7045 synchronized (this) { 7046 final int callingUid = Binder.getCallingUid(); 7047 boolean persistChanged = false; 7048 GrantUri grantUri = new GrantUri(userId, uri, false); 7049 7050 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7051 new GrantUri(userId, uri, false)); 7052 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7053 new GrantUri(userId, uri, true)); 7054 7055 final boolean exactValid = (exactPerm != null) 7056 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7057 final boolean prefixValid = (prefixPerm != null) 7058 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7059 7060 if (!(exactValid || prefixValid)) { 7061 throw new SecurityException("No persistable permission grants found for UID " 7062 + callingUid + " and Uri " + grantUri.toSafeString()); 7063 } 7064 7065 if (exactValid) { 7066 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7067 } 7068 if (prefixValid) { 7069 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7070 } 7071 7072 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7073 7074 if (persistChanged) { 7075 schedulePersistUriGrants(); 7076 } 7077 } 7078 } 7079 7080 @Override 7081 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7082 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7083 7084 Preconditions.checkFlagsArgument(modeFlags, 7085 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7086 7087 synchronized (this) { 7088 final int callingUid = Binder.getCallingUid(); 7089 boolean persistChanged = false; 7090 7091 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7092 new GrantUri(userId, uri, false)); 7093 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7094 new GrantUri(userId, uri, true)); 7095 if (exactPerm == null && prefixPerm == null) { 7096 throw new SecurityException("No permission grants found for UID " + callingUid 7097 + " and Uri " + uri.toSafeString()); 7098 } 7099 7100 if (exactPerm != null) { 7101 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7102 removeUriPermissionIfNeededLocked(exactPerm); 7103 } 7104 if (prefixPerm != null) { 7105 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7106 removeUriPermissionIfNeededLocked(prefixPerm); 7107 } 7108 7109 if (persistChanged) { 7110 schedulePersistUriGrants(); 7111 } 7112 } 7113 } 7114 7115 /** 7116 * Prune any older {@link UriPermission} for the given UID until outstanding 7117 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7118 * 7119 * @return if any mutations occured that require persisting. 7120 */ 7121 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7122 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7123 if (perms == null) return false; 7124 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7125 7126 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7127 for (UriPermission perm : perms.values()) { 7128 if (perm.persistedModeFlags != 0) { 7129 persisted.add(perm); 7130 } 7131 } 7132 7133 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7134 if (trimCount <= 0) return false; 7135 7136 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7137 for (int i = 0; i < trimCount; i++) { 7138 final UriPermission perm = persisted.get(i); 7139 7140 if (DEBUG_URI_PERMISSION) { 7141 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7142 } 7143 7144 perm.releasePersistableModes(~0); 7145 removeUriPermissionIfNeededLocked(perm); 7146 } 7147 7148 return true; 7149 } 7150 7151 @Override 7152 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7153 String packageName, boolean incoming) { 7154 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7155 Preconditions.checkNotNull(packageName, "packageName"); 7156 7157 final int callingUid = Binder.getCallingUid(); 7158 final IPackageManager pm = AppGlobals.getPackageManager(); 7159 try { 7160 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7161 if (packageUid != callingUid) { 7162 throw new SecurityException( 7163 "Package " + packageName + " does not belong to calling UID " + callingUid); 7164 } 7165 } catch (RemoteException e) { 7166 throw new SecurityException("Failed to verify package name ownership"); 7167 } 7168 7169 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7170 synchronized (this) { 7171 if (incoming) { 7172 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7173 callingUid); 7174 if (perms == null) { 7175 Slog.w(TAG, "No permission grants found for " + packageName); 7176 } else { 7177 for (UriPermission perm : perms.values()) { 7178 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7179 result.add(perm.buildPersistedPublicApiObject()); 7180 } 7181 } 7182 } 7183 } else { 7184 final int size = mGrantedUriPermissions.size(); 7185 for (int i = 0; i < size; i++) { 7186 final ArrayMap<GrantUri, UriPermission> perms = 7187 mGrantedUriPermissions.valueAt(i); 7188 for (UriPermission perm : perms.values()) { 7189 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7190 result.add(perm.buildPersistedPublicApiObject()); 7191 } 7192 } 7193 } 7194 } 7195 } 7196 return new ParceledListSlice<android.content.UriPermission>(result); 7197 } 7198 7199 @Override 7200 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7201 synchronized (this) { 7202 ProcessRecord app = 7203 who != null ? getRecordForAppLocked(who) : null; 7204 if (app == null) return; 7205 7206 Message msg = Message.obtain(); 7207 msg.what = WAIT_FOR_DEBUGGER_MSG; 7208 msg.obj = app; 7209 msg.arg1 = waiting ? 1 : 0; 7210 mHandler.sendMessage(msg); 7211 } 7212 } 7213 7214 @Override 7215 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7216 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7217 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7218 outInfo.availMem = Process.getFreeMemory(); 7219 outInfo.totalMem = Process.getTotalMemory(); 7220 outInfo.threshold = homeAppMem; 7221 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7222 outInfo.hiddenAppThreshold = cachedAppMem; 7223 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7224 ProcessList.SERVICE_ADJ); 7225 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7226 ProcessList.VISIBLE_APP_ADJ); 7227 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7228 ProcessList.FOREGROUND_APP_ADJ); 7229 } 7230 7231 // ========================================================= 7232 // TASK MANAGEMENT 7233 // ========================================================= 7234 7235 @Override 7236 public List<IAppTask> getAppTasks() { 7237 final PackageManager pm = mContext.getPackageManager(); 7238 int callingUid = Binder.getCallingUid(); 7239 long ident = Binder.clearCallingIdentity(); 7240 7241 // Compose the list of packages for this id to test against 7242 HashSet<String> packages = new HashSet<String>(); 7243 String[] uidPackages = pm.getPackagesForUid(callingUid); 7244 for (int i = 0; i < uidPackages.length; i++) { 7245 packages.add(uidPackages[i]); 7246 } 7247 7248 synchronized(this) { 7249 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7250 try { 7251 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7252 7253 final int N = mRecentTasks.size(); 7254 for (int i = 0; i < N; i++) { 7255 TaskRecord tr = mRecentTasks.get(i); 7256 // Skip tasks that are not created by the caller 7257 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7258 ActivityManager.RecentTaskInfo taskInfo = 7259 createRecentTaskInfoFromTaskRecord(tr); 7260 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7261 list.add(taskImpl); 7262 } 7263 } 7264 } finally { 7265 Binder.restoreCallingIdentity(ident); 7266 } 7267 return list; 7268 } 7269 } 7270 7271 @Override 7272 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7273 final int callingUid = Binder.getCallingUid(); 7274 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7275 7276 synchronized(this) { 7277 if (localLOGV) Slog.v( 7278 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7279 7280 final boolean allowed = checkCallingPermission( 7281 android.Manifest.permission.GET_TASKS) 7282 == PackageManager.PERMISSION_GRANTED; 7283 if (!allowed) { 7284 Slog.w(TAG, "getTasks: caller " + callingUid 7285 + " does not hold GET_TASKS; limiting output"); 7286 } 7287 7288 // TODO: Improve with MRU list from all ActivityStacks. 7289 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7290 } 7291 7292 return list; 7293 } 7294 7295 TaskRecord getMostRecentTask() { 7296 return mRecentTasks.get(0); 7297 } 7298 7299 /** 7300 * Creates a new RecentTaskInfo from a TaskRecord. 7301 */ 7302 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7303 // Update the task description to reflect any changes in the task stack 7304 tr.updateTaskDescription(); 7305 7306 // Compose the recent task info 7307 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7308 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7309 rti.persistentId = tr.taskId; 7310 rti.baseIntent = new Intent(tr.getBaseIntent()); 7311 rti.origActivity = tr.origActivity; 7312 rti.description = tr.lastDescription; 7313 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7314 rti.userId = tr.userId; 7315 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7316 rti.firstActiveTime = tr.firstActiveTime; 7317 rti.lastActiveTime = tr.lastActiveTime; 7318 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7319 return rti; 7320 } 7321 7322 @Override 7323 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7324 final int callingUid = Binder.getCallingUid(); 7325 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7326 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7327 7328 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7329 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7330 synchronized (this) { 7331 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7332 == PackageManager.PERMISSION_GRANTED; 7333 if (!allowed) { 7334 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7335 + " does not hold GET_TASKS; limiting output"); 7336 } 7337 final boolean detailed = checkCallingPermission( 7338 android.Manifest.permission.GET_DETAILED_TASKS) 7339 == PackageManager.PERMISSION_GRANTED; 7340 7341 IPackageManager pm = AppGlobals.getPackageManager(); 7342 7343 final int N = mRecentTasks.size(); 7344 ArrayList<ActivityManager.RecentTaskInfo> res 7345 = new ArrayList<ActivityManager.RecentTaskInfo>( 7346 maxNum < N ? maxNum : N); 7347 7348 final Set<Integer> includedUsers; 7349 if (includeProfiles) { 7350 includedUsers = getProfileIdsLocked(userId); 7351 } else { 7352 includedUsers = new HashSet<Integer>(); 7353 } 7354 includedUsers.add(Integer.valueOf(userId)); 7355 7356 // Regroup affiliated tasks together. 7357 for (int i = 0; i < N; ) { 7358 TaskRecord task = mRecentTasks.remove(i); 7359 if (mTmpRecents.contains(task)) { 7360 continue; 7361 } 7362 int affiliatedTaskId = task.mAffiliatedTaskId; 7363 while (true) { 7364 TaskRecord next = task.mNextAffiliate; 7365 if (next == null) { 7366 break; 7367 } 7368 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7369 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7370 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7371 task.setNextAffiliate(null); 7372 if (next.mPrevAffiliate == task) { 7373 next.setPrevAffiliate(null); 7374 } 7375 break; 7376 } 7377 if (next.mPrevAffiliate != task) { 7378 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7379 next.mPrevAffiliate + " task=" + task); 7380 next.setPrevAffiliate(null); 7381 break; 7382 } 7383 if (!mRecentTasks.contains(next)) { 7384 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7385 task.setNextAffiliate(null); 7386 if (next.mPrevAffiliate == task) { 7387 next.setPrevAffiliate(null); 7388 } 7389 break; 7390 } 7391 task = next; 7392 } 7393 // task is now the end of the list 7394 do { 7395 mRecentTasks.remove(task); 7396 mRecentTasks.add(i++, task); 7397 mTmpRecents.add(task); 7398 } while ((task = task.mPrevAffiliate) != null); 7399 } 7400 mTmpRecents.clear(); 7401 // mRecentTasks is now in sorted, affiliated order. 7402 7403 for (int i=0; i<N && maxNum > 0; i++) { 7404 TaskRecord tr = mRecentTasks.get(i); 7405 // Only add calling user or related users recent tasks 7406 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7407 7408 // Return the entry if desired by the caller. We always return 7409 // the first entry, because callers always expect this to be the 7410 // foreground app. We may filter others if the caller has 7411 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7412 // we should exclude the entry. 7413 7414 if (i == 0 7415 || withExcluded 7416 || (tr.intent == null) 7417 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7418 == 0)) { 7419 if (!allowed) { 7420 // If the caller doesn't have the GET_TASKS permission, then only 7421 // allow them to see a small subset of tasks -- their own and home. 7422 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7423 continue; 7424 } 7425 } 7426 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7427 // Don't include auto remove tasks that are finished or finishing. 7428 continue; 7429 } 7430 7431 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7432 if (!detailed) { 7433 rti.baseIntent.replaceExtras((Bundle)null); 7434 } 7435 7436 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7437 // Check whether this activity is currently available. 7438 try { 7439 if (rti.origActivity != null) { 7440 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7441 == null) { 7442 continue; 7443 } 7444 } else if (rti.baseIntent != null) { 7445 if (pm.queryIntentActivities(rti.baseIntent, 7446 null, 0, userId) == null) { 7447 continue; 7448 } 7449 } 7450 } catch (RemoteException e) { 7451 // Will never happen. 7452 } 7453 } 7454 7455 res.add(rti); 7456 maxNum--; 7457 } 7458 } 7459 return res; 7460 } 7461 } 7462 7463 private TaskRecord recentTaskForIdLocked(int id) { 7464 final int N = mRecentTasks.size(); 7465 for (int i=0; i<N; i++) { 7466 TaskRecord tr = mRecentTasks.get(i); 7467 if (tr.taskId == id) { 7468 return tr; 7469 } 7470 } 7471 return null; 7472 } 7473 7474 @Override 7475 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7476 synchronized (this) { 7477 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7478 "getTaskThumbnail()"); 7479 TaskRecord tr = recentTaskForIdLocked(id); 7480 if (tr != null) { 7481 return tr.getTaskThumbnailLocked(); 7482 } 7483 } 7484 return null; 7485 } 7486 7487 @Override 7488 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7489 synchronized (this) { 7490 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7491 if (r != null) { 7492 r.taskDescription = td; 7493 r.task.updateTaskDescription(); 7494 } 7495 } 7496 } 7497 7498 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7499 if (!pr.killedByAm) { 7500 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7501 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7502 pr.processName, pr.setAdj, reason); 7503 pr.killedByAm = true; 7504 Process.killProcessQuiet(pr.pid); 7505 Process.killProcessGroup(pr.info.uid, pr.pid); 7506 } 7507 } 7508 7509 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7510 tr.disposeThumbnail(); 7511 mRecentTasks.remove(tr); 7512 tr.closeRecentsChain(); 7513 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7514 Intent baseIntent = new Intent( 7515 tr.intent != null ? tr.intent : tr.affinityIntent); 7516 ComponentName component = baseIntent.getComponent(); 7517 if (component == null) { 7518 Slog.w(TAG, "Now component for base intent of task: " + tr); 7519 return; 7520 } 7521 7522 // Find any running services associated with this app. 7523 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7524 7525 if (killProcesses) { 7526 // Find any running processes associated with this app. 7527 final String pkg = component.getPackageName(); 7528 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7529 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7530 for (int i=0; i<pmap.size(); i++) { 7531 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7532 for (int j=0; j<uids.size(); j++) { 7533 ProcessRecord proc = uids.valueAt(j); 7534 if (proc.userId != tr.userId) { 7535 continue; 7536 } 7537 if (!proc.pkgList.containsKey(pkg)) { 7538 continue; 7539 } 7540 procs.add(proc); 7541 } 7542 } 7543 7544 // Kill the running processes. 7545 for (int i=0; i<procs.size(); i++) { 7546 ProcessRecord pr = procs.get(i); 7547 if (pr == mHomeProcess) { 7548 // Don't kill the home process along with tasks from the same package. 7549 continue; 7550 } 7551 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7552 killUnneededProcessLocked(pr, "remove task"); 7553 } else { 7554 pr.waitingToKill = "remove task"; 7555 } 7556 } 7557 } 7558 } 7559 7560 /** 7561 * Removes the task with the specified task id. 7562 * 7563 * @param taskId Identifier of the task to be removed. 7564 * @param flags Additional operational flags. May be 0 or 7565 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7566 * @return Returns true if the given task was found and removed. 7567 */ 7568 private boolean removeTaskByIdLocked(int taskId, int flags) { 7569 TaskRecord tr = recentTaskForIdLocked(taskId); 7570 if (tr != null) { 7571 tr.removeTaskActivitiesLocked(); 7572 cleanUpRemovedTaskLocked(tr, flags); 7573 if (tr.isPersistable) { 7574 notifyTaskPersisterLocked(tr, true); 7575 } 7576 return true; 7577 } 7578 return false; 7579 } 7580 7581 @Override 7582 public boolean removeTask(int taskId, int flags) { 7583 synchronized (this) { 7584 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7585 "removeTask()"); 7586 long ident = Binder.clearCallingIdentity(); 7587 try { 7588 return removeTaskByIdLocked(taskId, flags); 7589 } finally { 7590 Binder.restoreCallingIdentity(ident); 7591 } 7592 } 7593 } 7594 7595 /** 7596 * TODO: Add mController hook 7597 */ 7598 @Override 7599 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7600 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7601 "moveTaskToFront()"); 7602 7603 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7604 synchronized(this) { 7605 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7606 Binder.getCallingUid(), "Task to front")) { 7607 ActivityOptions.abort(options); 7608 return; 7609 } 7610 final long origId = Binder.clearCallingIdentity(); 7611 try { 7612 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7613 if (task == null) { 7614 return; 7615 } 7616 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7617 mStackSupervisor.showLockTaskToast(); 7618 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7619 return; 7620 } 7621 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7622 if (prev != null && prev.isRecentsActivity()) { 7623 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7624 } 7625 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7626 } finally { 7627 Binder.restoreCallingIdentity(origId); 7628 } 7629 ActivityOptions.abort(options); 7630 } 7631 } 7632 7633 @Override 7634 public void moveTaskToBack(int taskId) { 7635 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7636 "moveTaskToBack()"); 7637 7638 synchronized(this) { 7639 TaskRecord tr = recentTaskForIdLocked(taskId); 7640 if (tr != null) { 7641 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7642 ActivityStack stack = tr.stack; 7643 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7644 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7645 Binder.getCallingUid(), "Task to back")) { 7646 return; 7647 } 7648 } 7649 final long origId = Binder.clearCallingIdentity(); 7650 try { 7651 stack.moveTaskToBackLocked(taskId, null); 7652 } finally { 7653 Binder.restoreCallingIdentity(origId); 7654 } 7655 } 7656 } 7657 } 7658 7659 /** 7660 * Moves an activity, and all of the other activities within the same task, to the bottom 7661 * of the history stack. The activity's order within the task is unchanged. 7662 * 7663 * @param token A reference to the activity we wish to move 7664 * @param nonRoot If false then this only works if the activity is the root 7665 * of a task; if true it will work for any activity in a task. 7666 * @return Returns true if the move completed, false if not. 7667 */ 7668 @Override 7669 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7670 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7671 synchronized(this) { 7672 final long origId = Binder.clearCallingIdentity(); 7673 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7674 if (taskId >= 0) { 7675 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7676 } 7677 Binder.restoreCallingIdentity(origId); 7678 } 7679 return false; 7680 } 7681 7682 @Override 7683 public void moveTaskBackwards(int task) { 7684 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7685 "moveTaskBackwards()"); 7686 7687 synchronized(this) { 7688 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7689 Binder.getCallingUid(), "Task backwards")) { 7690 return; 7691 } 7692 final long origId = Binder.clearCallingIdentity(); 7693 moveTaskBackwardsLocked(task); 7694 Binder.restoreCallingIdentity(origId); 7695 } 7696 } 7697 7698 private final void moveTaskBackwardsLocked(int task) { 7699 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7700 } 7701 7702 @Override 7703 public IBinder getHomeActivityToken() throws RemoteException { 7704 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7705 "getHomeActivityToken()"); 7706 synchronized (this) { 7707 return mStackSupervisor.getHomeActivityToken(); 7708 } 7709 } 7710 7711 @Override 7712 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7713 IActivityContainerCallback callback) throws RemoteException { 7714 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7715 "createActivityContainer()"); 7716 synchronized (this) { 7717 if (parentActivityToken == null) { 7718 throw new IllegalArgumentException("parent token must not be null"); 7719 } 7720 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7721 if (r == null) { 7722 return null; 7723 } 7724 if (callback == null) { 7725 throw new IllegalArgumentException("callback must not be null"); 7726 } 7727 return mStackSupervisor.createActivityContainer(r, callback); 7728 } 7729 } 7730 7731 @Override 7732 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7733 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7734 "deleteActivityContainer()"); 7735 synchronized (this) { 7736 mStackSupervisor.deleteActivityContainer(container); 7737 } 7738 } 7739 7740 @Override 7741 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7742 throws RemoteException { 7743 synchronized (this) { 7744 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7745 if (stack != null) { 7746 return stack.mActivityContainer; 7747 } 7748 return null; 7749 } 7750 } 7751 7752 @Override 7753 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7754 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7755 "moveTaskToStack()"); 7756 if (stackId == HOME_STACK_ID) { 7757 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7758 new RuntimeException("here").fillInStackTrace()); 7759 } 7760 synchronized (this) { 7761 long ident = Binder.clearCallingIdentity(); 7762 try { 7763 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7764 + stackId + " toTop=" + toTop); 7765 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7766 } finally { 7767 Binder.restoreCallingIdentity(ident); 7768 } 7769 } 7770 } 7771 7772 @Override 7773 public void resizeStack(int stackBoxId, Rect bounds) { 7774 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7775 "resizeStackBox()"); 7776 long ident = Binder.clearCallingIdentity(); 7777 try { 7778 mWindowManager.resizeStack(stackBoxId, bounds); 7779 } finally { 7780 Binder.restoreCallingIdentity(ident); 7781 } 7782 } 7783 7784 @Override 7785 public List<StackInfo> getAllStackInfos() { 7786 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7787 "getAllStackInfos()"); 7788 long ident = Binder.clearCallingIdentity(); 7789 try { 7790 synchronized (this) { 7791 return mStackSupervisor.getAllStackInfosLocked(); 7792 } 7793 } finally { 7794 Binder.restoreCallingIdentity(ident); 7795 } 7796 } 7797 7798 @Override 7799 public StackInfo getStackInfo(int stackId) { 7800 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7801 "getStackInfo()"); 7802 long ident = Binder.clearCallingIdentity(); 7803 try { 7804 synchronized (this) { 7805 return mStackSupervisor.getStackInfoLocked(stackId); 7806 } 7807 } finally { 7808 Binder.restoreCallingIdentity(ident); 7809 } 7810 } 7811 7812 @Override 7813 public boolean isInHomeStack(int taskId) { 7814 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7815 "getStackInfo()"); 7816 long ident = Binder.clearCallingIdentity(); 7817 try { 7818 synchronized (this) { 7819 TaskRecord tr = recentTaskForIdLocked(taskId); 7820 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7821 } 7822 } finally { 7823 Binder.restoreCallingIdentity(ident); 7824 } 7825 } 7826 7827 @Override 7828 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7829 synchronized(this) { 7830 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7831 } 7832 } 7833 7834 private boolean isLockTaskAuthorized(String pkg) { 7835 final DevicePolicyManager dpm = (DevicePolicyManager) 7836 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7837 try { 7838 int uid = mContext.getPackageManager().getPackageUid(pkg, 7839 Binder.getCallingUserHandle().getIdentifier()); 7840 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7841 } catch (NameNotFoundException e) { 7842 return false; 7843 } 7844 } 7845 7846 void startLockTaskMode(TaskRecord task) { 7847 final String pkg; 7848 synchronized (this) { 7849 pkg = task.intent.getComponent().getPackageName(); 7850 } 7851 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7852 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7853 final TaskRecord taskRecord = task; 7854 mHandler.post(new Runnable() { 7855 @Override 7856 public void run() { 7857 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7858 } 7859 }); 7860 return; 7861 } 7862 long ident = Binder.clearCallingIdentity(); 7863 try { 7864 synchronized (this) { 7865 // Since we lost lock on task, make sure it is still there. 7866 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7867 if (task != null) { 7868 if (!isSystemInitiated 7869 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7870 throw new IllegalArgumentException("Invalid task, not in foreground"); 7871 } 7872 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7873 } 7874 } 7875 } finally { 7876 Binder.restoreCallingIdentity(ident); 7877 } 7878 } 7879 7880 @Override 7881 public void startLockTaskMode(int taskId) { 7882 final TaskRecord task; 7883 long ident = Binder.clearCallingIdentity(); 7884 try { 7885 synchronized (this) { 7886 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7887 } 7888 } finally { 7889 Binder.restoreCallingIdentity(ident); 7890 } 7891 if (task != null) { 7892 startLockTaskMode(task); 7893 } 7894 } 7895 7896 @Override 7897 public void startLockTaskMode(IBinder token) { 7898 final TaskRecord task; 7899 long ident = Binder.clearCallingIdentity(); 7900 try { 7901 synchronized (this) { 7902 final ActivityRecord r = ActivityRecord.forToken(token); 7903 if (r == null) { 7904 return; 7905 } 7906 task = r.task; 7907 } 7908 } finally { 7909 Binder.restoreCallingIdentity(ident); 7910 } 7911 if (task != null) { 7912 startLockTaskMode(task); 7913 } 7914 } 7915 7916 @Override 7917 public void startLockTaskModeOnCurrent() throws RemoteException { 7918 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7919 ActivityRecord r = null; 7920 synchronized (this) { 7921 r = mStackSupervisor.topRunningActivityLocked(); 7922 } 7923 startLockTaskMode(r.task); 7924 } 7925 7926 @Override 7927 public void stopLockTaskMode() { 7928 // Verify that the user matches the package of the intent for the TaskRecord 7929 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7930 // and stopLockTaskMode. 7931 final int callingUid = Binder.getCallingUid(); 7932 if (callingUid != Process.SYSTEM_UID) { 7933 try { 7934 String pkg = 7935 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7936 int uid = mContext.getPackageManager().getPackageUid(pkg, 7937 Binder.getCallingUserHandle().getIdentifier()); 7938 if (uid != callingUid) { 7939 throw new SecurityException("Invalid uid, expected " + uid); 7940 } 7941 } catch (NameNotFoundException e) { 7942 Log.d(TAG, "stopLockTaskMode " + e); 7943 return; 7944 } 7945 } 7946 long ident = Binder.clearCallingIdentity(); 7947 try { 7948 Log.d(TAG, "stopLockTaskMode"); 7949 // Stop lock task 7950 synchronized (this) { 7951 mStackSupervisor.setLockTaskModeLocked(null, false); 7952 } 7953 } finally { 7954 Binder.restoreCallingIdentity(ident); 7955 } 7956 } 7957 7958 @Override 7959 public void stopLockTaskModeOnCurrent() throws RemoteException { 7960 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7961 long ident = Binder.clearCallingIdentity(); 7962 try { 7963 stopLockTaskMode(); 7964 } finally { 7965 Binder.restoreCallingIdentity(ident); 7966 } 7967 } 7968 7969 @Override 7970 public boolean isInLockTaskMode() { 7971 synchronized (this) { 7972 return mStackSupervisor.isInLockTaskMode(); 7973 } 7974 } 7975 7976 // ========================================================= 7977 // CONTENT PROVIDERS 7978 // ========================================================= 7979 7980 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7981 List<ProviderInfo> providers = null; 7982 try { 7983 providers = AppGlobals.getPackageManager(). 7984 queryContentProviders(app.processName, app.uid, 7985 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7986 } catch (RemoteException ex) { 7987 } 7988 if (DEBUG_MU) 7989 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7990 int userId = app.userId; 7991 if (providers != null) { 7992 int N = providers.size(); 7993 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7994 for (int i=0; i<N; i++) { 7995 ProviderInfo cpi = 7996 (ProviderInfo)providers.get(i); 7997 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7998 cpi.name, cpi.flags); 7999 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8000 // This is a singleton provider, but a user besides the 8001 // default user is asking to initialize a process it runs 8002 // in... well, no, it doesn't actually run in this process, 8003 // it runs in the process of the default user. Get rid of it. 8004 providers.remove(i); 8005 N--; 8006 i--; 8007 continue; 8008 } 8009 8010 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8011 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8012 if (cpr == null) { 8013 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8014 mProviderMap.putProviderByClass(comp, cpr); 8015 } 8016 if (DEBUG_MU) 8017 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8018 app.pubProviders.put(cpi.name, cpr); 8019 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8020 // Don't add this if it is a platform component that is marked 8021 // to run in multiple processes, because this is actually 8022 // part of the framework so doesn't make sense to track as a 8023 // separate apk in the process. 8024 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8025 mProcessStats); 8026 } 8027 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8028 } 8029 } 8030 return providers; 8031 } 8032 8033 /** 8034 * Check if {@link ProcessRecord} has a possible chance at accessing the 8035 * given {@link ProviderInfo}. Final permission checking is always done 8036 * in {@link ContentProvider}. 8037 */ 8038 private final String checkContentProviderPermissionLocked( 8039 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8040 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8041 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8042 boolean checkedGrants = false; 8043 if (checkUser) { 8044 // Looking for cross-user grants before enforcing the typical cross-users permissions 8045 int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid)); 8046 if (tmpTargetUserId != userId) { 8047 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8048 return null; 8049 } 8050 checkedGrants = true; 8051 } 8052 userId = handleIncomingUser(callingPid, callingUid, userId, 8053 false, ALLOW_NON_FULL, 8054 "checkContentProviderPermissionLocked " + cpi.authority, null); 8055 if (userId != tmpTargetUserId) { 8056 // When we actually went to determine the final targer user ID, this ended 8057 // up different than our initial check for the authority. This is because 8058 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8059 // SELF. So we need to re-check the grants again. 8060 checkedGrants = false; 8061 } 8062 } 8063 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8064 cpi.applicationInfo.uid, cpi.exported) 8065 == PackageManager.PERMISSION_GRANTED) { 8066 return null; 8067 } 8068 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8069 cpi.applicationInfo.uid, cpi.exported) 8070 == PackageManager.PERMISSION_GRANTED) { 8071 return null; 8072 } 8073 8074 PathPermission[] pps = cpi.pathPermissions; 8075 if (pps != null) { 8076 int i = pps.length; 8077 while (i > 0) { 8078 i--; 8079 PathPermission pp = pps[i]; 8080 String pprperm = pp.getReadPermission(); 8081 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8082 cpi.applicationInfo.uid, cpi.exported) 8083 == PackageManager.PERMISSION_GRANTED) { 8084 return null; 8085 } 8086 String ppwperm = pp.getWritePermission(); 8087 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8088 cpi.applicationInfo.uid, cpi.exported) 8089 == PackageManager.PERMISSION_GRANTED) { 8090 return null; 8091 } 8092 } 8093 } 8094 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8095 return null; 8096 } 8097 8098 String msg; 8099 if (!cpi.exported) { 8100 msg = "Permission Denial: opening provider " + cpi.name 8101 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8102 + ", uid=" + callingUid + ") that is not exported from uid " 8103 + cpi.applicationInfo.uid; 8104 } else { 8105 msg = "Permission Denial: opening provider " + cpi.name 8106 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8107 + ", uid=" + callingUid + ") requires " 8108 + cpi.readPermission + " or " + cpi.writePermission; 8109 } 8110 Slog.w(TAG, msg); 8111 return msg; 8112 } 8113 8114 /** 8115 * Returns if the ContentProvider has granted a uri to callingUid 8116 */ 8117 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8118 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8119 if (perms != null) { 8120 for (int i=perms.size()-1; i>=0; i--) { 8121 GrantUri grantUri = perms.keyAt(i); 8122 if (grantUri.sourceUserId == userId || !checkUser) { 8123 if (matchesProvider(grantUri.uri, cpi)) { 8124 return true; 8125 } 8126 } 8127 } 8128 } 8129 return false; 8130 } 8131 8132 /** 8133 * Returns true if the uri authority is one of the authorities specified in the provider. 8134 */ 8135 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8136 String uriAuth = uri.getAuthority(); 8137 String cpiAuth = cpi.authority; 8138 if (cpiAuth.indexOf(';') == -1) { 8139 return cpiAuth.equals(uriAuth); 8140 } 8141 String[] cpiAuths = cpiAuth.split(";"); 8142 int length = cpiAuths.length; 8143 for (int i = 0; i < length; i++) { 8144 if (cpiAuths[i].equals(uriAuth)) return true; 8145 } 8146 return false; 8147 } 8148 8149 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8150 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8151 if (r != null) { 8152 for (int i=0; i<r.conProviders.size(); i++) { 8153 ContentProviderConnection conn = r.conProviders.get(i); 8154 if (conn.provider == cpr) { 8155 if (DEBUG_PROVIDER) Slog.v(TAG, 8156 "Adding provider requested by " 8157 + r.processName + " from process " 8158 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8159 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8160 if (stable) { 8161 conn.stableCount++; 8162 conn.numStableIncs++; 8163 } else { 8164 conn.unstableCount++; 8165 conn.numUnstableIncs++; 8166 } 8167 return conn; 8168 } 8169 } 8170 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8171 if (stable) { 8172 conn.stableCount = 1; 8173 conn.numStableIncs = 1; 8174 } else { 8175 conn.unstableCount = 1; 8176 conn.numUnstableIncs = 1; 8177 } 8178 cpr.connections.add(conn); 8179 r.conProviders.add(conn); 8180 return conn; 8181 } 8182 cpr.addExternalProcessHandleLocked(externalProcessToken); 8183 return null; 8184 } 8185 8186 boolean decProviderCountLocked(ContentProviderConnection conn, 8187 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8188 if (conn != null) { 8189 cpr = conn.provider; 8190 if (DEBUG_PROVIDER) Slog.v(TAG, 8191 "Removing provider requested by " 8192 + conn.client.processName + " from process " 8193 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8194 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8195 if (stable) { 8196 conn.stableCount--; 8197 } else { 8198 conn.unstableCount--; 8199 } 8200 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8201 cpr.connections.remove(conn); 8202 conn.client.conProviders.remove(conn); 8203 return true; 8204 } 8205 return false; 8206 } 8207 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8208 return false; 8209 } 8210 8211 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8212 String name, IBinder token, boolean stable, int userId) { 8213 ContentProviderRecord cpr; 8214 ContentProviderConnection conn = null; 8215 ProviderInfo cpi = null; 8216 8217 synchronized(this) { 8218 ProcessRecord r = null; 8219 if (caller != null) { 8220 r = getRecordForAppLocked(caller); 8221 if (r == null) { 8222 throw new SecurityException( 8223 "Unable to find app for caller " + caller 8224 + " (pid=" + Binder.getCallingPid() 8225 + ") when getting content provider " + name); 8226 } 8227 } 8228 8229 boolean checkCrossUser = true; 8230 8231 // First check if this content provider has been published... 8232 cpr = mProviderMap.getProviderByName(name, userId); 8233 // If that didn't work, check if it exists for user 0 and then 8234 // verify that it's a singleton provider before using it. 8235 if (cpr == null && userId != UserHandle.USER_OWNER) { 8236 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8237 if (cpr != null) { 8238 cpi = cpr.info; 8239 if (isSingleton(cpi.processName, cpi.applicationInfo, 8240 cpi.name, cpi.flags) 8241 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8242 userId = UserHandle.USER_OWNER; 8243 checkCrossUser = false; 8244 } else { 8245 cpr = null; 8246 cpi = null; 8247 } 8248 } 8249 } 8250 8251 boolean providerRunning = cpr != null; 8252 if (providerRunning) { 8253 cpi = cpr.info; 8254 String msg; 8255 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8256 != null) { 8257 throw new SecurityException(msg); 8258 } 8259 8260 if (r != null && cpr.canRunHere(r)) { 8261 // This provider has been published or is in the process 8262 // of being published... but it is also allowed to run 8263 // in the caller's process, so don't make a connection 8264 // and just let the caller instantiate its own instance. 8265 ContentProviderHolder holder = cpr.newHolder(null); 8266 // don't give caller the provider object, it needs 8267 // to make its own. 8268 holder.provider = null; 8269 return holder; 8270 } 8271 8272 final long origId = Binder.clearCallingIdentity(); 8273 8274 // In this case the provider instance already exists, so we can 8275 // return it right away. 8276 conn = incProviderCountLocked(r, cpr, token, stable); 8277 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8278 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8279 // If this is a perceptible app accessing the provider, 8280 // make sure to count it as being accessed and thus 8281 // back up on the LRU list. This is good because 8282 // content providers are often expensive to start. 8283 updateLruProcessLocked(cpr.proc, false, null); 8284 } 8285 } 8286 8287 if (cpr.proc != null) { 8288 if (false) { 8289 if (cpr.name.flattenToShortString().equals( 8290 "com.android.providers.calendar/.CalendarProvider2")) { 8291 Slog.v(TAG, "****************** KILLING " 8292 + cpr.name.flattenToShortString()); 8293 Process.killProcess(cpr.proc.pid); 8294 } 8295 } 8296 boolean success = updateOomAdjLocked(cpr.proc); 8297 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8298 // NOTE: there is still a race here where a signal could be 8299 // pending on the process even though we managed to update its 8300 // adj level. Not sure what to do about this, but at least 8301 // the race is now smaller. 8302 if (!success) { 8303 // Uh oh... it looks like the provider's process 8304 // has been killed on us. We need to wait for a new 8305 // process to be started, and make sure its death 8306 // doesn't kill our process. 8307 Slog.i(TAG, 8308 "Existing provider " + cpr.name.flattenToShortString() 8309 + " is crashing; detaching " + r); 8310 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8311 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8312 if (!lastRef) { 8313 // This wasn't the last ref our process had on 8314 // the provider... we have now been killed, bail. 8315 return null; 8316 } 8317 providerRunning = false; 8318 conn = null; 8319 } 8320 } 8321 8322 Binder.restoreCallingIdentity(origId); 8323 } 8324 8325 boolean singleton; 8326 if (!providerRunning) { 8327 try { 8328 cpi = AppGlobals.getPackageManager(). 8329 resolveContentProvider(name, 8330 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8331 } catch (RemoteException ex) { 8332 } 8333 if (cpi == null) { 8334 return null; 8335 } 8336 // If the provider is a singleton AND 8337 // (it's a call within the same user || the provider is a 8338 // privileged app) 8339 // Then allow connecting to the singleton provider 8340 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8341 cpi.name, cpi.flags) 8342 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8343 if (singleton) { 8344 userId = UserHandle.USER_OWNER; 8345 } 8346 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8347 8348 String msg; 8349 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8350 != null) { 8351 throw new SecurityException(msg); 8352 } 8353 8354 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8355 && !cpi.processName.equals("system")) { 8356 // If this content provider does not run in the system 8357 // process, and the system is not yet ready to run other 8358 // processes, then fail fast instead of hanging. 8359 throw new IllegalArgumentException( 8360 "Attempt to launch content provider before system ready"); 8361 } 8362 8363 // Make sure that the user who owns this provider is started. If not, 8364 // we don't want to allow it to run. 8365 if (mStartedUsers.get(userId) == null) { 8366 Slog.w(TAG, "Unable to launch app " 8367 + cpi.applicationInfo.packageName + "/" 8368 + cpi.applicationInfo.uid + " for provider " 8369 + name + ": user " + userId + " is stopped"); 8370 return null; 8371 } 8372 8373 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8374 cpr = mProviderMap.getProviderByClass(comp, userId); 8375 final boolean firstClass = cpr == null; 8376 if (firstClass) { 8377 try { 8378 ApplicationInfo ai = 8379 AppGlobals.getPackageManager(). 8380 getApplicationInfo( 8381 cpi.applicationInfo.packageName, 8382 STOCK_PM_FLAGS, userId); 8383 if (ai == null) { 8384 Slog.w(TAG, "No package info for content provider " 8385 + cpi.name); 8386 return null; 8387 } 8388 ai = getAppInfoForUser(ai, userId); 8389 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8390 } catch (RemoteException ex) { 8391 // pm is in same process, this will never happen. 8392 } 8393 } 8394 8395 if (r != null && cpr.canRunHere(r)) { 8396 // If this is a multiprocess provider, then just return its 8397 // info and allow the caller to instantiate it. Only do 8398 // this if the provider is the same user as the caller's 8399 // process, or can run as root (so can be in any process). 8400 return cpr.newHolder(null); 8401 } 8402 8403 if (DEBUG_PROVIDER) { 8404 RuntimeException e = new RuntimeException("here"); 8405 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8406 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8407 } 8408 8409 // This is single process, and our app is now connecting to it. 8410 // See if we are already in the process of launching this 8411 // provider. 8412 final int N = mLaunchingProviders.size(); 8413 int i; 8414 for (i=0; i<N; i++) { 8415 if (mLaunchingProviders.get(i) == cpr) { 8416 break; 8417 } 8418 } 8419 8420 // If the provider is not already being launched, then get it 8421 // started. 8422 if (i >= N) { 8423 final long origId = Binder.clearCallingIdentity(); 8424 8425 try { 8426 // Content provider is now in use, its package can't be stopped. 8427 try { 8428 AppGlobals.getPackageManager().setPackageStoppedState( 8429 cpr.appInfo.packageName, false, userId); 8430 } catch (RemoteException e) { 8431 } catch (IllegalArgumentException e) { 8432 Slog.w(TAG, "Failed trying to unstop package " 8433 + cpr.appInfo.packageName + ": " + e); 8434 } 8435 8436 // Use existing process if already started 8437 ProcessRecord proc = getProcessRecordLocked( 8438 cpi.processName, cpr.appInfo.uid, false); 8439 if (proc != null && proc.thread != null) { 8440 if (DEBUG_PROVIDER) { 8441 Slog.d(TAG, "Installing in existing process " + proc); 8442 } 8443 proc.pubProviders.put(cpi.name, cpr); 8444 try { 8445 proc.thread.scheduleInstallProvider(cpi); 8446 } catch (RemoteException e) { 8447 } 8448 } else { 8449 proc = startProcessLocked(cpi.processName, 8450 cpr.appInfo, false, 0, "content provider", 8451 new ComponentName(cpi.applicationInfo.packageName, 8452 cpi.name), false, false, false); 8453 if (proc == null) { 8454 Slog.w(TAG, "Unable to launch app " 8455 + cpi.applicationInfo.packageName + "/" 8456 + cpi.applicationInfo.uid + " for provider " 8457 + name + ": process is bad"); 8458 return null; 8459 } 8460 } 8461 cpr.launchingApp = proc; 8462 mLaunchingProviders.add(cpr); 8463 } finally { 8464 Binder.restoreCallingIdentity(origId); 8465 } 8466 } 8467 8468 // Make sure the provider is published (the same provider class 8469 // may be published under multiple names). 8470 if (firstClass) { 8471 mProviderMap.putProviderByClass(comp, cpr); 8472 } 8473 8474 mProviderMap.putProviderByName(name, cpr); 8475 conn = incProviderCountLocked(r, cpr, token, stable); 8476 if (conn != null) { 8477 conn.waiting = true; 8478 } 8479 } 8480 } 8481 8482 // Wait for the provider to be published... 8483 synchronized (cpr) { 8484 while (cpr.provider == null) { 8485 if (cpr.launchingApp == null) { 8486 Slog.w(TAG, "Unable to launch app " 8487 + cpi.applicationInfo.packageName + "/" 8488 + cpi.applicationInfo.uid + " for provider " 8489 + name + ": launching app became null"); 8490 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8491 UserHandle.getUserId(cpi.applicationInfo.uid), 8492 cpi.applicationInfo.packageName, 8493 cpi.applicationInfo.uid, name); 8494 return null; 8495 } 8496 try { 8497 if (DEBUG_MU) { 8498 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8499 + cpr.launchingApp); 8500 } 8501 if (conn != null) { 8502 conn.waiting = true; 8503 } 8504 cpr.wait(); 8505 } catch (InterruptedException ex) { 8506 } finally { 8507 if (conn != null) { 8508 conn.waiting = false; 8509 } 8510 } 8511 } 8512 } 8513 return cpr != null ? cpr.newHolder(conn) : null; 8514 } 8515 8516 @Override 8517 public final ContentProviderHolder getContentProvider( 8518 IApplicationThread caller, String name, int userId, boolean stable) { 8519 enforceNotIsolatedCaller("getContentProvider"); 8520 if (caller == null) { 8521 String msg = "null IApplicationThread when getting content provider " 8522 + name; 8523 Slog.w(TAG, msg); 8524 throw new SecurityException(msg); 8525 } 8526 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8527 // with cross-user grant. 8528 return getContentProviderImpl(caller, name, null, stable, userId); 8529 } 8530 8531 public ContentProviderHolder getContentProviderExternal( 8532 String name, int userId, IBinder token) { 8533 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8534 "Do not have permission in call getContentProviderExternal()"); 8535 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8536 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8537 return getContentProviderExternalUnchecked(name, token, userId); 8538 } 8539 8540 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8541 IBinder token, int userId) { 8542 return getContentProviderImpl(null, name, token, true, userId); 8543 } 8544 8545 /** 8546 * Drop a content provider from a ProcessRecord's bookkeeping 8547 */ 8548 public void removeContentProvider(IBinder connection, boolean stable) { 8549 enforceNotIsolatedCaller("removeContentProvider"); 8550 long ident = Binder.clearCallingIdentity(); 8551 try { 8552 synchronized (this) { 8553 ContentProviderConnection conn; 8554 try { 8555 conn = (ContentProviderConnection)connection; 8556 } catch (ClassCastException e) { 8557 String msg ="removeContentProvider: " + connection 8558 + " not a ContentProviderConnection"; 8559 Slog.w(TAG, msg); 8560 throw new IllegalArgumentException(msg); 8561 } 8562 if (conn == null) { 8563 throw new NullPointerException("connection is null"); 8564 } 8565 if (decProviderCountLocked(conn, null, null, stable)) { 8566 updateOomAdjLocked(); 8567 } 8568 } 8569 } finally { 8570 Binder.restoreCallingIdentity(ident); 8571 } 8572 } 8573 8574 public void removeContentProviderExternal(String name, IBinder token) { 8575 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8576 "Do not have permission in call removeContentProviderExternal()"); 8577 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8578 } 8579 8580 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8581 synchronized (this) { 8582 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8583 if(cpr == null) { 8584 //remove from mProvidersByClass 8585 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8586 return; 8587 } 8588 8589 //update content provider record entry info 8590 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8591 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8592 if (localCpr.hasExternalProcessHandles()) { 8593 if (localCpr.removeExternalProcessHandleLocked(token)) { 8594 updateOomAdjLocked(); 8595 } else { 8596 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8597 + " with no external reference for token: " 8598 + token + "."); 8599 } 8600 } else { 8601 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8602 + " with no external references."); 8603 } 8604 } 8605 } 8606 8607 public final void publishContentProviders(IApplicationThread caller, 8608 List<ContentProviderHolder> providers) { 8609 if (providers == null) { 8610 return; 8611 } 8612 8613 enforceNotIsolatedCaller("publishContentProviders"); 8614 synchronized (this) { 8615 final ProcessRecord r = getRecordForAppLocked(caller); 8616 if (DEBUG_MU) 8617 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8618 if (r == null) { 8619 throw new SecurityException( 8620 "Unable to find app for caller " + caller 8621 + " (pid=" + Binder.getCallingPid() 8622 + ") when publishing content providers"); 8623 } 8624 8625 final long origId = Binder.clearCallingIdentity(); 8626 8627 final int N = providers.size(); 8628 for (int i=0; i<N; i++) { 8629 ContentProviderHolder src = providers.get(i); 8630 if (src == null || src.info == null || src.provider == null) { 8631 continue; 8632 } 8633 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8634 if (DEBUG_MU) 8635 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8636 if (dst != null) { 8637 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8638 mProviderMap.putProviderByClass(comp, dst); 8639 String names[] = dst.info.authority.split(";"); 8640 for (int j = 0; j < names.length; j++) { 8641 mProviderMap.putProviderByName(names[j], dst); 8642 } 8643 8644 int NL = mLaunchingProviders.size(); 8645 int j; 8646 for (j=0; j<NL; j++) { 8647 if (mLaunchingProviders.get(j) == dst) { 8648 mLaunchingProviders.remove(j); 8649 j--; 8650 NL--; 8651 } 8652 } 8653 synchronized (dst) { 8654 dst.provider = src.provider; 8655 dst.proc = r; 8656 dst.notifyAll(); 8657 } 8658 updateOomAdjLocked(r); 8659 } 8660 } 8661 8662 Binder.restoreCallingIdentity(origId); 8663 } 8664 } 8665 8666 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8667 ContentProviderConnection conn; 8668 try { 8669 conn = (ContentProviderConnection)connection; 8670 } catch (ClassCastException e) { 8671 String msg ="refContentProvider: " + connection 8672 + " not a ContentProviderConnection"; 8673 Slog.w(TAG, msg); 8674 throw new IllegalArgumentException(msg); 8675 } 8676 if (conn == null) { 8677 throw new NullPointerException("connection is null"); 8678 } 8679 8680 synchronized (this) { 8681 if (stable > 0) { 8682 conn.numStableIncs += stable; 8683 } 8684 stable = conn.stableCount + stable; 8685 if (stable < 0) { 8686 throw new IllegalStateException("stableCount < 0: " + stable); 8687 } 8688 8689 if (unstable > 0) { 8690 conn.numUnstableIncs += unstable; 8691 } 8692 unstable = conn.unstableCount + unstable; 8693 if (unstable < 0) { 8694 throw new IllegalStateException("unstableCount < 0: " + unstable); 8695 } 8696 8697 if ((stable+unstable) <= 0) { 8698 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8699 + stable + " unstable=" + unstable); 8700 } 8701 conn.stableCount = stable; 8702 conn.unstableCount = unstable; 8703 return !conn.dead; 8704 } 8705 } 8706 8707 public void unstableProviderDied(IBinder connection) { 8708 ContentProviderConnection conn; 8709 try { 8710 conn = (ContentProviderConnection)connection; 8711 } catch (ClassCastException e) { 8712 String msg ="refContentProvider: " + connection 8713 + " not a ContentProviderConnection"; 8714 Slog.w(TAG, msg); 8715 throw new IllegalArgumentException(msg); 8716 } 8717 if (conn == null) { 8718 throw new NullPointerException("connection is null"); 8719 } 8720 8721 // Safely retrieve the content provider associated with the connection. 8722 IContentProvider provider; 8723 synchronized (this) { 8724 provider = conn.provider.provider; 8725 } 8726 8727 if (provider == null) { 8728 // Um, yeah, we're way ahead of you. 8729 return; 8730 } 8731 8732 // Make sure the caller is being honest with us. 8733 if (provider.asBinder().pingBinder()) { 8734 // Er, no, still looks good to us. 8735 synchronized (this) { 8736 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8737 + " says " + conn + " died, but we don't agree"); 8738 return; 8739 } 8740 } 8741 8742 // Well look at that! It's dead! 8743 synchronized (this) { 8744 if (conn.provider.provider != provider) { 8745 // But something changed... good enough. 8746 return; 8747 } 8748 8749 ProcessRecord proc = conn.provider.proc; 8750 if (proc == null || proc.thread == null) { 8751 // Seems like the process is already cleaned up. 8752 return; 8753 } 8754 8755 // As far as we're concerned, this is just like receiving a 8756 // death notification... just a bit prematurely. 8757 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8758 + ") early provider death"); 8759 final long ident = Binder.clearCallingIdentity(); 8760 try { 8761 appDiedLocked(proc, proc.pid, proc.thread); 8762 } finally { 8763 Binder.restoreCallingIdentity(ident); 8764 } 8765 } 8766 } 8767 8768 @Override 8769 public void appNotRespondingViaProvider(IBinder connection) { 8770 enforceCallingPermission( 8771 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8772 8773 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8774 if (conn == null) { 8775 Slog.w(TAG, "ContentProviderConnection is null"); 8776 return; 8777 } 8778 8779 final ProcessRecord host = conn.provider.proc; 8780 if (host == null) { 8781 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8782 return; 8783 } 8784 8785 final long token = Binder.clearCallingIdentity(); 8786 try { 8787 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8788 } finally { 8789 Binder.restoreCallingIdentity(token); 8790 } 8791 } 8792 8793 public final void installSystemProviders() { 8794 List<ProviderInfo> providers; 8795 synchronized (this) { 8796 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8797 providers = generateApplicationProvidersLocked(app); 8798 if (providers != null) { 8799 for (int i=providers.size()-1; i>=0; i--) { 8800 ProviderInfo pi = (ProviderInfo)providers.get(i); 8801 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8802 Slog.w(TAG, "Not installing system proc provider " + pi.name 8803 + ": not system .apk"); 8804 providers.remove(i); 8805 } 8806 } 8807 } 8808 } 8809 if (providers != null) { 8810 mSystemThread.installSystemProviders(providers); 8811 } 8812 8813 mCoreSettingsObserver = new CoreSettingsObserver(this); 8814 8815 //mUsageStatsService.monitorPackages(); 8816 } 8817 8818 /** 8819 * Allows app to retrieve the MIME type of a URI without having permission 8820 * to access its content provider. 8821 * 8822 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8823 * 8824 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8825 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8826 */ 8827 public String getProviderMimeType(Uri uri, int userId) { 8828 enforceNotIsolatedCaller("getProviderMimeType"); 8829 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8830 userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null); 8831 final String name = uri.getAuthority(); 8832 final long ident = Binder.clearCallingIdentity(); 8833 ContentProviderHolder holder = null; 8834 8835 try { 8836 holder = getContentProviderExternalUnchecked(name, null, userId); 8837 if (holder != null) { 8838 return holder.provider.getType(uri); 8839 } 8840 } catch (RemoteException e) { 8841 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8842 return null; 8843 } finally { 8844 if (holder != null) { 8845 removeContentProviderExternalUnchecked(name, null, userId); 8846 } 8847 Binder.restoreCallingIdentity(ident); 8848 } 8849 8850 return null; 8851 } 8852 8853 // ========================================================= 8854 // GLOBAL MANAGEMENT 8855 // ========================================================= 8856 8857 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8858 boolean isolated) { 8859 String proc = customProcess != null ? customProcess : info.processName; 8860 BatteryStatsImpl.Uid.Proc ps = null; 8861 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8862 int uid = info.uid; 8863 if (isolated) { 8864 int userId = UserHandle.getUserId(uid); 8865 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8866 while (true) { 8867 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8868 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8869 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8870 } 8871 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8872 mNextIsolatedProcessUid++; 8873 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8874 // No process for this uid, use it. 8875 break; 8876 } 8877 stepsLeft--; 8878 if (stepsLeft <= 0) { 8879 return null; 8880 } 8881 } 8882 } 8883 return new ProcessRecord(stats, info, proc, uid); 8884 } 8885 8886 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8887 String abiOverride) { 8888 ProcessRecord app; 8889 if (!isolated) { 8890 app = getProcessRecordLocked(info.processName, info.uid, true); 8891 } else { 8892 app = null; 8893 } 8894 8895 if (app == null) { 8896 app = newProcessRecordLocked(info, null, isolated); 8897 mProcessNames.put(info.processName, app.uid, app); 8898 if (isolated) { 8899 mIsolatedProcesses.put(app.uid, app); 8900 } 8901 updateLruProcessLocked(app, false, null); 8902 updateOomAdjLocked(); 8903 } 8904 8905 // This package really, really can not be stopped. 8906 try { 8907 AppGlobals.getPackageManager().setPackageStoppedState( 8908 info.packageName, false, UserHandle.getUserId(app.uid)); 8909 } catch (RemoteException e) { 8910 } catch (IllegalArgumentException e) { 8911 Slog.w(TAG, "Failed trying to unstop package " 8912 + info.packageName + ": " + e); 8913 } 8914 8915 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8916 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8917 app.persistent = true; 8918 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8919 } 8920 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8921 mPersistentStartingProcesses.add(app); 8922 startProcessLocked(app, "added application", app.processName, 8923 abiOverride); 8924 } 8925 8926 return app; 8927 } 8928 8929 public void unhandledBack() { 8930 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8931 "unhandledBack()"); 8932 8933 synchronized(this) { 8934 final long origId = Binder.clearCallingIdentity(); 8935 try { 8936 getFocusedStack().unhandledBackLocked(); 8937 } finally { 8938 Binder.restoreCallingIdentity(origId); 8939 } 8940 } 8941 } 8942 8943 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8944 enforceNotIsolatedCaller("openContentUri"); 8945 final int userId = UserHandle.getCallingUserId(); 8946 String name = uri.getAuthority(); 8947 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8948 ParcelFileDescriptor pfd = null; 8949 if (cph != null) { 8950 // We record the binder invoker's uid in thread-local storage before 8951 // going to the content provider to open the file. Later, in the code 8952 // that handles all permissions checks, we look for this uid and use 8953 // that rather than the Activity Manager's own uid. The effect is that 8954 // we do the check against the caller's permissions even though it looks 8955 // to the content provider like the Activity Manager itself is making 8956 // the request. 8957 sCallerIdentity.set(new Identity( 8958 Binder.getCallingPid(), Binder.getCallingUid())); 8959 try { 8960 pfd = cph.provider.openFile(null, uri, "r", null); 8961 } catch (FileNotFoundException e) { 8962 // do nothing; pfd will be returned null 8963 } finally { 8964 // Ensure that whatever happens, we clean up the identity state 8965 sCallerIdentity.remove(); 8966 } 8967 8968 // We've got the fd now, so we're done with the provider. 8969 removeContentProviderExternalUnchecked(name, null, userId); 8970 } else { 8971 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8972 } 8973 return pfd; 8974 } 8975 8976 // Actually is sleeping or shutting down or whatever else in the future 8977 // is an inactive state. 8978 public boolean isSleepingOrShuttingDown() { 8979 return mSleeping || mShuttingDown; 8980 } 8981 8982 public boolean isSleeping() { 8983 return mSleeping; 8984 } 8985 8986 void goingToSleep() { 8987 synchronized(this) { 8988 mWentToSleep = true; 8989 updateEventDispatchingLocked(); 8990 goToSleepIfNeededLocked(); 8991 } 8992 } 8993 8994 void finishRunningVoiceLocked() { 8995 if (mRunningVoice) { 8996 mRunningVoice = false; 8997 goToSleepIfNeededLocked(); 8998 } 8999 } 9000 9001 void goToSleepIfNeededLocked() { 9002 if (mWentToSleep && !mRunningVoice) { 9003 if (!mSleeping) { 9004 mSleeping = true; 9005 mStackSupervisor.goingToSleepLocked(); 9006 9007 // Initialize the wake times of all processes. 9008 checkExcessivePowerUsageLocked(false); 9009 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9010 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9011 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9012 } 9013 } 9014 } 9015 9016 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9017 mTaskPersister.notify(task, flush); 9018 } 9019 9020 @Override 9021 public boolean shutdown(int timeout) { 9022 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9023 != PackageManager.PERMISSION_GRANTED) { 9024 throw new SecurityException("Requires permission " 9025 + android.Manifest.permission.SHUTDOWN); 9026 } 9027 9028 boolean timedout = false; 9029 9030 synchronized(this) { 9031 mShuttingDown = true; 9032 updateEventDispatchingLocked(); 9033 timedout = mStackSupervisor.shutdownLocked(timeout); 9034 } 9035 9036 mAppOpsService.shutdown(); 9037 if (mUsageStatsService != null) { 9038 mUsageStatsService.prepareShutdown(); 9039 } 9040 mBatteryStatsService.shutdown(); 9041 synchronized (this) { 9042 mProcessStats.shutdownLocked(); 9043 } 9044 notifyTaskPersisterLocked(null, true); 9045 9046 return timedout; 9047 } 9048 9049 public final void activitySlept(IBinder token) { 9050 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9051 9052 final long origId = Binder.clearCallingIdentity(); 9053 9054 synchronized (this) { 9055 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9056 if (r != null) { 9057 mStackSupervisor.activitySleptLocked(r); 9058 } 9059 } 9060 9061 Binder.restoreCallingIdentity(origId); 9062 } 9063 9064 void logLockScreen(String msg) { 9065 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9066 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9067 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 9068 mStackSupervisor.mDismissKeyguardOnNextActivity); 9069 } 9070 9071 private void comeOutOfSleepIfNeededLocked() { 9072 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9073 if (mSleeping) { 9074 mSleeping = false; 9075 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9076 } 9077 } 9078 } 9079 9080 void wakingUp() { 9081 synchronized(this) { 9082 mWentToSleep = false; 9083 updateEventDispatchingLocked(); 9084 comeOutOfSleepIfNeededLocked(); 9085 } 9086 } 9087 9088 void startRunningVoiceLocked() { 9089 if (!mRunningVoice) { 9090 mRunningVoice = true; 9091 comeOutOfSleepIfNeededLocked(); 9092 } 9093 } 9094 9095 private void updateEventDispatchingLocked() { 9096 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9097 } 9098 9099 public void setLockScreenShown(boolean shown) { 9100 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9101 != PackageManager.PERMISSION_GRANTED) { 9102 throw new SecurityException("Requires permission " 9103 + android.Manifest.permission.DEVICE_POWER); 9104 } 9105 9106 synchronized(this) { 9107 long ident = Binder.clearCallingIdentity(); 9108 try { 9109 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9110 mLockScreenShown = shown; 9111 comeOutOfSleepIfNeededLocked(); 9112 } finally { 9113 Binder.restoreCallingIdentity(ident); 9114 } 9115 } 9116 } 9117 9118 @Override 9119 public void stopAppSwitches() { 9120 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9121 != PackageManager.PERMISSION_GRANTED) { 9122 throw new SecurityException("Requires permission " 9123 + android.Manifest.permission.STOP_APP_SWITCHES); 9124 } 9125 9126 synchronized(this) { 9127 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9128 + APP_SWITCH_DELAY_TIME; 9129 mDidAppSwitch = false; 9130 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9131 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9132 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9133 } 9134 } 9135 9136 public void resumeAppSwitches() { 9137 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9138 != PackageManager.PERMISSION_GRANTED) { 9139 throw new SecurityException("Requires permission " 9140 + android.Manifest.permission.STOP_APP_SWITCHES); 9141 } 9142 9143 synchronized(this) { 9144 // Note that we don't execute any pending app switches... we will 9145 // let those wait until either the timeout, or the next start 9146 // activity request. 9147 mAppSwitchesAllowedTime = 0; 9148 } 9149 } 9150 9151 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9152 String name) { 9153 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9154 return true; 9155 } 9156 9157 final int perm = checkComponentPermission( 9158 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9159 callingUid, -1, true); 9160 if (perm == PackageManager.PERMISSION_GRANTED) { 9161 return true; 9162 } 9163 9164 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9165 return false; 9166 } 9167 9168 public void setDebugApp(String packageName, boolean waitForDebugger, 9169 boolean persistent) { 9170 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9171 "setDebugApp()"); 9172 9173 long ident = Binder.clearCallingIdentity(); 9174 try { 9175 // Note that this is not really thread safe if there are multiple 9176 // callers into it at the same time, but that's not a situation we 9177 // care about. 9178 if (persistent) { 9179 final ContentResolver resolver = mContext.getContentResolver(); 9180 Settings.Global.putString( 9181 resolver, Settings.Global.DEBUG_APP, 9182 packageName); 9183 Settings.Global.putInt( 9184 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9185 waitForDebugger ? 1 : 0); 9186 } 9187 9188 synchronized (this) { 9189 if (!persistent) { 9190 mOrigDebugApp = mDebugApp; 9191 mOrigWaitForDebugger = mWaitForDebugger; 9192 } 9193 mDebugApp = packageName; 9194 mWaitForDebugger = waitForDebugger; 9195 mDebugTransient = !persistent; 9196 if (packageName != null) { 9197 forceStopPackageLocked(packageName, -1, false, false, true, true, 9198 false, UserHandle.USER_ALL, "set debug app"); 9199 } 9200 } 9201 } finally { 9202 Binder.restoreCallingIdentity(ident); 9203 } 9204 } 9205 9206 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9207 synchronized (this) { 9208 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9209 if (!isDebuggable) { 9210 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9211 throw new SecurityException("Process not debuggable: " + app.packageName); 9212 } 9213 } 9214 9215 mOpenGlTraceApp = processName; 9216 } 9217 } 9218 9219 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9220 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9221 synchronized (this) { 9222 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9223 if (!isDebuggable) { 9224 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9225 throw new SecurityException("Process not debuggable: " + app.packageName); 9226 } 9227 } 9228 mProfileApp = processName; 9229 mProfileFile = profileFile; 9230 if (mProfileFd != null) { 9231 try { 9232 mProfileFd.close(); 9233 } catch (IOException e) { 9234 } 9235 mProfileFd = null; 9236 } 9237 mProfileFd = profileFd; 9238 mProfileType = 0; 9239 mAutoStopProfiler = autoStopProfiler; 9240 } 9241 } 9242 9243 @Override 9244 public void setAlwaysFinish(boolean enabled) { 9245 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9246 "setAlwaysFinish()"); 9247 9248 Settings.Global.putInt( 9249 mContext.getContentResolver(), 9250 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9251 9252 synchronized (this) { 9253 mAlwaysFinishActivities = enabled; 9254 } 9255 } 9256 9257 @Override 9258 public void setActivityController(IActivityController controller) { 9259 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9260 "setActivityController()"); 9261 synchronized (this) { 9262 mController = controller; 9263 Watchdog.getInstance().setActivityController(controller); 9264 } 9265 } 9266 9267 @Override 9268 public void setUserIsMonkey(boolean userIsMonkey) { 9269 synchronized (this) { 9270 synchronized (mPidsSelfLocked) { 9271 final int callingPid = Binder.getCallingPid(); 9272 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9273 if (precessRecord == null) { 9274 throw new SecurityException("Unknown process: " + callingPid); 9275 } 9276 if (precessRecord.instrumentationUiAutomationConnection == null) { 9277 throw new SecurityException("Only an instrumentation process " 9278 + "with a UiAutomation can call setUserIsMonkey"); 9279 } 9280 } 9281 mUserIsMonkey = userIsMonkey; 9282 } 9283 } 9284 9285 @Override 9286 public boolean isUserAMonkey() { 9287 synchronized (this) { 9288 // If there is a controller also implies the user is a monkey. 9289 return (mUserIsMonkey || mController != null); 9290 } 9291 } 9292 9293 public void requestBugReport() { 9294 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9295 SystemProperties.set("ctl.start", "bugreport"); 9296 } 9297 9298 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9299 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9300 } 9301 9302 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9303 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9304 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9305 } 9306 return KEY_DISPATCHING_TIMEOUT; 9307 } 9308 9309 @Override 9310 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9311 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9312 != PackageManager.PERMISSION_GRANTED) { 9313 throw new SecurityException("Requires permission " 9314 + android.Manifest.permission.FILTER_EVENTS); 9315 } 9316 ProcessRecord proc; 9317 long timeout; 9318 synchronized (this) { 9319 synchronized (mPidsSelfLocked) { 9320 proc = mPidsSelfLocked.get(pid); 9321 } 9322 timeout = getInputDispatchingTimeoutLocked(proc); 9323 } 9324 9325 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9326 return -1; 9327 } 9328 9329 return timeout; 9330 } 9331 9332 /** 9333 * Handle input dispatching timeouts. 9334 * Returns whether input dispatching should be aborted or not. 9335 */ 9336 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9337 final ActivityRecord activity, final ActivityRecord parent, 9338 final boolean aboveSystem, String reason) { 9339 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9340 != PackageManager.PERMISSION_GRANTED) { 9341 throw new SecurityException("Requires permission " 9342 + android.Manifest.permission.FILTER_EVENTS); 9343 } 9344 9345 final String annotation; 9346 if (reason == null) { 9347 annotation = "Input dispatching timed out"; 9348 } else { 9349 annotation = "Input dispatching timed out (" + reason + ")"; 9350 } 9351 9352 if (proc != null) { 9353 synchronized (this) { 9354 if (proc.debugging) { 9355 return false; 9356 } 9357 9358 if (mDidDexOpt) { 9359 // Give more time since we were dexopting. 9360 mDidDexOpt = false; 9361 return false; 9362 } 9363 9364 if (proc.instrumentationClass != null) { 9365 Bundle info = new Bundle(); 9366 info.putString("shortMsg", "keyDispatchingTimedOut"); 9367 info.putString("longMsg", annotation); 9368 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9369 return true; 9370 } 9371 } 9372 mHandler.post(new Runnable() { 9373 @Override 9374 public void run() { 9375 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9376 } 9377 }); 9378 } 9379 9380 return true; 9381 } 9382 9383 public Bundle getAssistContextExtras(int requestType) { 9384 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9385 "getAssistContextExtras()"); 9386 PendingAssistExtras pae; 9387 Bundle extras = new Bundle(); 9388 synchronized (this) { 9389 ActivityRecord activity = getFocusedStack().mResumedActivity; 9390 if (activity == null) { 9391 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9392 return null; 9393 } 9394 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9395 if (activity.app == null || activity.app.thread == null) { 9396 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9397 return extras; 9398 } 9399 if (activity.app.pid == Binder.getCallingPid()) { 9400 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9401 return extras; 9402 } 9403 pae = new PendingAssistExtras(activity); 9404 try { 9405 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9406 requestType); 9407 mPendingAssistExtras.add(pae); 9408 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9409 } catch (RemoteException e) { 9410 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9411 return extras; 9412 } 9413 } 9414 synchronized (pae) { 9415 while (!pae.haveResult) { 9416 try { 9417 pae.wait(); 9418 } catch (InterruptedException e) { 9419 } 9420 } 9421 if (pae.result != null) { 9422 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9423 } 9424 } 9425 synchronized (this) { 9426 mPendingAssistExtras.remove(pae); 9427 mHandler.removeCallbacks(pae); 9428 } 9429 return extras; 9430 } 9431 9432 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9433 PendingAssistExtras pae = (PendingAssistExtras)token; 9434 synchronized (pae) { 9435 pae.result = extras; 9436 pae.haveResult = true; 9437 pae.notifyAll(); 9438 } 9439 } 9440 9441 public void registerProcessObserver(IProcessObserver observer) { 9442 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9443 "registerProcessObserver()"); 9444 synchronized (this) { 9445 mProcessObservers.register(observer); 9446 } 9447 } 9448 9449 @Override 9450 public void unregisterProcessObserver(IProcessObserver observer) { 9451 synchronized (this) { 9452 mProcessObservers.unregister(observer); 9453 } 9454 } 9455 9456 @Override 9457 public boolean convertFromTranslucent(IBinder token) { 9458 final long origId = Binder.clearCallingIdentity(); 9459 try { 9460 synchronized (this) { 9461 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9462 if (r == null) { 9463 return false; 9464 } 9465 if (r.changeWindowTranslucency(true)) { 9466 mWindowManager.setAppFullscreen(token, true); 9467 r.task.stack.releaseMediaResources(); 9468 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9469 return true; 9470 } 9471 return false; 9472 } 9473 } finally { 9474 Binder.restoreCallingIdentity(origId); 9475 } 9476 } 9477 9478 @Override 9479 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9480 final long origId = Binder.clearCallingIdentity(); 9481 try { 9482 synchronized (this) { 9483 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9484 if (r == null) { 9485 return false; 9486 } 9487 if (r.changeWindowTranslucency(false)) { 9488 r.task.stack.convertToTranslucent(r, options); 9489 mWindowManager.setAppFullscreen(token, false); 9490 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9491 return true; 9492 } else { 9493 r.task.stack.mReturningActivityOptions = options; 9494 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9495 return false; 9496 } 9497 } 9498 } finally { 9499 Binder.restoreCallingIdentity(origId); 9500 } 9501 } 9502 9503 @Override 9504 public boolean setMediaPlaying(IBinder token, boolean playing) { 9505 final long origId = Binder.clearCallingIdentity(); 9506 try { 9507 synchronized (this) { 9508 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9509 if (r != null) { 9510 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9511 } 9512 } 9513 return false; 9514 } finally { 9515 Binder.restoreCallingIdentity(origId); 9516 } 9517 } 9518 9519 @Override 9520 public boolean isBackgroundMediaPlaying(IBinder token) { 9521 final long origId = Binder.clearCallingIdentity(); 9522 try { 9523 synchronized (this) { 9524 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9525 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9526 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9527 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9528 return playing; 9529 } 9530 } finally { 9531 Binder.restoreCallingIdentity(origId); 9532 } 9533 } 9534 9535 @Override 9536 public ActivityOptions getActivityOptions(IBinder token) { 9537 final long origId = Binder.clearCallingIdentity(); 9538 try { 9539 synchronized (this) { 9540 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9541 if (r != null) { 9542 final ActivityOptions activityOptions = r.pendingOptions; 9543 r.pendingOptions = null; 9544 return activityOptions; 9545 } 9546 return null; 9547 } 9548 } finally { 9549 Binder.restoreCallingIdentity(origId); 9550 } 9551 } 9552 9553 @Override 9554 public void setImmersive(IBinder token, boolean immersive) { 9555 synchronized(this) { 9556 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9557 if (r == null) { 9558 throw new IllegalArgumentException(); 9559 } 9560 r.immersive = immersive; 9561 9562 // update associated state if we're frontmost 9563 if (r == mFocusedActivity) { 9564 if (DEBUG_IMMERSIVE) { 9565 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9566 } 9567 applyUpdateLockStateLocked(r); 9568 } 9569 } 9570 } 9571 9572 @Override 9573 public boolean isImmersive(IBinder token) { 9574 synchronized (this) { 9575 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9576 if (r == null) { 9577 throw new IllegalArgumentException(); 9578 } 9579 return r.immersive; 9580 } 9581 } 9582 9583 public boolean isTopActivityImmersive() { 9584 enforceNotIsolatedCaller("startActivity"); 9585 synchronized (this) { 9586 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9587 return (r != null) ? r.immersive : false; 9588 } 9589 } 9590 9591 @Override 9592 public boolean isTopOfTask(IBinder token) { 9593 synchronized (this) { 9594 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9595 if (r == null) { 9596 throw new IllegalArgumentException(); 9597 } 9598 return r.task.getTopActivity() == r; 9599 } 9600 } 9601 9602 public final void enterSafeMode() { 9603 synchronized(this) { 9604 // It only makes sense to do this before the system is ready 9605 // and started launching other packages. 9606 if (!mSystemReady) { 9607 try { 9608 AppGlobals.getPackageManager().enterSafeMode(); 9609 } catch (RemoteException e) { 9610 } 9611 } 9612 9613 mSafeMode = true; 9614 } 9615 } 9616 9617 public final void showSafeModeOverlay() { 9618 View v = LayoutInflater.from(mContext).inflate( 9619 com.android.internal.R.layout.safe_mode, null); 9620 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9621 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9622 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9623 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9624 lp.gravity = Gravity.BOTTOM | Gravity.START; 9625 lp.format = v.getBackground().getOpacity(); 9626 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9627 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9628 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9629 ((WindowManager)mContext.getSystemService( 9630 Context.WINDOW_SERVICE)).addView(v, lp); 9631 } 9632 9633 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9634 if (!(sender instanceof PendingIntentRecord)) { 9635 return; 9636 } 9637 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9638 synchronized (stats) { 9639 if (mBatteryStatsService.isOnBattery()) { 9640 mBatteryStatsService.enforceCallingPermission(); 9641 PendingIntentRecord rec = (PendingIntentRecord)sender; 9642 int MY_UID = Binder.getCallingUid(); 9643 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9644 BatteryStatsImpl.Uid.Pkg pkg = 9645 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9646 sourcePkg != null ? sourcePkg : rec.key.packageName); 9647 pkg.incWakeupsLocked(); 9648 } 9649 } 9650 } 9651 9652 public boolean killPids(int[] pids, String pReason, boolean secure) { 9653 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9654 throw new SecurityException("killPids only available to the system"); 9655 } 9656 String reason = (pReason == null) ? "Unknown" : pReason; 9657 // XXX Note: don't acquire main activity lock here, because the window 9658 // manager calls in with its locks held. 9659 9660 boolean killed = false; 9661 synchronized (mPidsSelfLocked) { 9662 int[] types = new int[pids.length]; 9663 int worstType = 0; 9664 for (int i=0; i<pids.length; i++) { 9665 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9666 if (proc != null) { 9667 int type = proc.setAdj; 9668 types[i] = type; 9669 if (type > worstType) { 9670 worstType = type; 9671 } 9672 } 9673 } 9674 9675 // If the worst oom_adj is somewhere in the cached proc LRU range, 9676 // then constrain it so we will kill all cached procs. 9677 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9678 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9679 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9680 } 9681 9682 // If this is not a secure call, don't let it kill processes that 9683 // are important. 9684 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9685 worstType = ProcessList.SERVICE_ADJ; 9686 } 9687 9688 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9689 for (int i=0; i<pids.length; i++) { 9690 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9691 if (proc == null) { 9692 continue; 9693 } 9694 int adj = proc.setAdj; 9695 if (adj >= worstType && !proc.killedByAm) { 9696 killUnneededProcessLocked(proc, reason); 9697 killed = true; 9698 } 9699 } 9700 } 9701 return killed; 9702 } 9703 9704 @Override 9705 public void killUid(int uid, String reason) { 9706 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9707 throw new SecurityException("killUid only available to the system"); 9708 } 9709 synchronized (this) { 9710 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9711 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9712 reason != null ? reason : "kill uid"); 9713 } 9714 } 9715 9716 @Override 9717 public boolean killProcessesBelowForeground(String reason) { 9718 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9719 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9720 } 9721 9722 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9723 } 9724 9725 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9726 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9727 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9728 } 9729 9730 boolean killed = false; 9731 synchronized (mPidsSelfLocked) { 9732 final int size = mPidsSelfLocked.size(); 9733 for (int i = 0; i < size; i++) { 9734 final int pid = mPidsSelfLocked.keyAt(i); 9735 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9736 if (proc == null) continue; 9737 9738 final int adj = proc.setAdj; 9739 if (adj > belowAdj && !proc.killedByAm) { 9740 killUnneededProcessLocked(proc, reason); 9741 killed = true; 9742 } 9743 } 9744 } 9745 return killed; 9746 } 9747 9748 @Override 9749 public void hang(final IBinder who, boolean allowRestart) { 9750 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9751 != PackageManager.PERMISSION_GRANTED) { 9752 throw new SecurityException("Requires permission " 9753 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9754 } 9755 9756 final IBinder.DeathRecipient death = new DeathRecipient() { 9757 @Override 9758 public void binderDied() { 9759 synchronized (this) { 9760 notifyAll(); 9761 } 9762 } 9763 }; 9764 9765 try { 9766 who.linkToDeath(death, 0); 9767 } catch (RemoteException e) { 9768 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9769 return; 9770 } 9771 9772 synchronized (this) { 9773 Watchdog.getInstance().setAllowRestart(allowRestart); 9774 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9775 synchronized (death) { 9776 while (who.isBinderAlive()) { 9777 try { 9778 death.wait(); 9779 } catch (InterruptedException e) { 9780 } 9781 } 9782 } 9783 Watchdog.getInstance().setAllowRestart(true); 9784 } 9785 } 9786 9787 @Override 9788 public void restart() { 9789 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9790 != PackageManager.PERMISSION_GRANTED) { 9791 throw new SecurityException("Requires permission " 9792 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9793 } 9794 9795 Log.i(TAG, "Sending shutdown broadcast..."); 9796 9797 BroadcastReceiver br = new BroadcastReceiver() { 9798 @Override public void onReceive(Context context, Intent intent) { 9799 // Now the broadcast is done, finish up the low-level shutdown. 9800 Log.i(TAG, "Shutting down activity manager..."); 9801 shutdown(10000); 9802 Log.i(TAG, "Shutdown complete, restarting!"); 9803 Process.killProcess(Process.myPid()); 9804 System.exit(10); 9805 } 9806 }; 9807 9808 // First send the high-level shut down broadcast. 9809 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9810 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9811 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9812 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9813 mContext.sendOrderedBroadcastAsUser(intent, 9814 UserHandle.ALL, null, br, mHandler, 0, null, null); 9815 */ 9816 br.onReceive(mContext, intent); 9817 } 9818 9819 private long getLowRamTimeSinceIdle(long now) { 9820 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9821 } 9822 9823 @Override 9824 public void performIdleMaintenance() { 9825 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9826 != PackageManager.PERMISSION_GRANTED) { 9827 throw new SecurityException("Requires permission " 9828 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9829 } 9830 9831 synchronized (this) { 9832 final long now = SystemClock.uptimeMillis(); 9833 final long timeSinceLastIdle = now - mLastIdleTime; 9834 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9835 mLastIdleTime = now; 9836 mLowRamTimeSinceLastIdle = 0; 9837 if (mLowRamStartTime != 0) { 9838 mLowRamStartTime = now; 9839 } 9840 9841 StringBuilder sb = new StringBuilder(128); 9842 sb.append("Idle maintenance over "); 9843 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9844 sb.append(" low RAM for "); 9845 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9846 Slog.i(TAG, sb.toString()); 9847 9848 // If at least 1/3 of our time since the last idle period has been spent 9849 // with RAM low, then we want to kill processes. 9850 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9851 9852 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9853 ProcessRecord proc = mLruProcesses.get(i); 9854 if (proc.notCachedSinceIdle) { 9855 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9856 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9857 if (doKilling && proc.initialIdlePss != 0 9858 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9859 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9860 + " from " + proc.initialIdlePss + ")"); 9861 } 9862 } 9863 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9864 proc.notCachedSinceIdle = true; 9865 proc.initialIdlePss = 0; 9866 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9867 isSleeping(), now); 9868 } 9869 } 9870 9871 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9872 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9873 } 9874 } 9875 9876 private void retrieveSettings() { 9877 final ContentResolver resolver = mContext.getContentResolver(); 9878 String debugApp = Settings.Global.getString( 9879 resolver, Settings.Global.DEBUG_APP); 9880 boolean waitForDebugger = Settings.Global.getInt( 9881 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9882 boolean alwaysFinishActivities = Settings.Global.getInt( 9883 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9884 boolean forceRtl = Settings.Global.getInt( 9885 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9886 // Transfer any global setting for forcing RTL layout, into a System Property 9887 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9888 9889 Configuration configuration = new Configuration(); 9890 Settings.System.getConfiguration(resolver, configuration); 9891 if (forceRtl) { 9892 // This will take care of setting the correct layout direction flags 9893 configuration.setLayoutDirection(configuration.locale); 9894 } 9895 9896 synchronized (this) { 9897 mDebugApp = mOrigDebugApp = debugApp; 9898 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9899 mAlwaysFinishActivities = alwaysFinishActivities; 9900 // This happens before any activities are started, so we can 9901 // change mConfiguration in-place. 9902 updateConfigurationLocked(configuration, null, false, true); 9903 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9904 } 9905 } 9906 9907 public boolean testIsSystemReady() { 9908 // no need to synchronize(this) just to read & return the value 9909 return mSystemReady; 9910 } 9911 9912 private static File getCalledPreBootReceiversFile() { 9913 File dataDir = Environment.getDataDirectory(); 9914 File systemDir = new File(dataDir, "system"); 9915 File fname = new File(systemDir, "called_pre_boots.dat"); 9916 return fname; 9917 } 9918 9919 static final int LAST_DONE_VERSION = 10000; 9920 9921 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9922 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9923 File file = getCalledPreBootReceiversFile(); 9924 FileInputStream fis = null; 9925 try { 9926 fis = new FileInputStream(file); 9927 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9928 int fvers = dis.readInt(); 9929 if (fvers == LAST_DONE_VERSION) { 9930 String vers = dis.readUTF(); 9931 String codename = dis.readUTF(); 9932 String build = dis.readUTF(); 9933 if (android.os.Build.VERSION.RELEASE.equals(vers) 9934 && android.os.Build.VERSION.CODENAME.equals(codename) 9935 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9936 int num = dis.readInt(); 9937 while (num > 0) { 9938 num--; 9939 String pkg = dis.readUTF(); 9940 String cls = dis.readUTF(); 9941 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9942 } 9943 } 9944 } 9945 } catch (FileNotFoundException e) { 9946 } catch (IOException e) { 9947 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9948 } finally { 9949 if (fis != null) { 9950 try { 9951 fis.close(); 9952 } catch (IOException e) { 9953 } 9954 } 9955 } 9956 return lastDoneReceivers; 9957 } 9958 9959 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9960 File file = getCalledPreBootReceiversFile(); 9961 FileOutputStream fos = null; 9962 DataOutputStream dos = null; 9963 try { 9964 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9965 fos = new FileOutputStream(file); 9966 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9967 dos.writeInt(LAST_DONE_VERSION); 9968 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9969 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9970 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9971 dos.writeInt(list.size()); 9972 for (int i=0; i<list.size(); i++) { 9973 dos.writeUTF(list.get(i).getPackageName()); 9974 dos.writeUTF(list.get(i).getClassName()); 9975 } 9976 } catch (IOException e) { 9977 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9978 file.delete(); 9979 } finally { 9980 FileUtils.sync(fos); 9981 if (dos != null) { 9982 try { 9983 dos.close(); 9984 } catch (IOException e) { 9985 // TODO Auto-generated catch block 9986 e.printStackTrace(); 9987 } 9988 } 9989 } 9990 } 9991 9992 public void systemReady(final Runnable goingCallback) { 9993 synchronized(this) { 9994 if (mSystemReady) { 9995 if (goingCallback != null) goingCallback.run(); 9996 return; 9997 } 9998 9999 // Make sure we have the current profile info, since it is needed for 10000 // security checks. 10001 updateCurrentProfileIdsLocked(); 10002 10003 if (mRecentTasks == null) { 10004 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10005 if (!mRecentTasks.isEmpty()) { 10006 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10007 } 10008 mTaskPersister.startPersisting(); 10009 } 10010 10011 // Check to see if there are any update receivers to run. 10012 if (!mDidUpdate) { 10013 if (mWaitingUpdate) { 10014 return; 10015 } 10016 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10017 List<ResolveInfo> ris = null; 10018 try { 10019 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10020 intent, null, 0, 0); 10021 } catch (RemoteException e) { 10022 } 10023 if (ris != null) { 10024 for (int i=ris.size()-1; i>=0; i--) { 10025 if ((ris.get(i).activityInfo.applicationInfo.flags 10026 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10027 ris.remove(i); 10028 } 10029 } 10030 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10031 10032 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10033 10034 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10035 for (int i=0; i<ris.size(); i++) { 10036 ActivityInfo ai = ris.get(i).activityInfo; 10037 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10038 if (lastDoneReceivers.contains(comp)) { 10039 // We already did the pre boot receiver for this app with the current 10040 // platform version, so don't do it again... 10041 ris.remove(i); 10042 i--; 10043 // ...however, do keep it as one that has been done, so we don't 10044 // forget about it when rewriting the file of last done receivers. 10045 doneReceivers.add(comp); 10046 } 10047 } 10048 10049 final int[] users = getUsersLocked(); 10050 for (int i=0; i<ris.size(); i++) { 10051 ActivityInfo ai = ris.get(i).activityInfo; 10052 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10053 doneReceivers.add(comp); 10054 intent.setComponent(comp); 10055 for (int j=0; j<users.length; j++) { 10056 IIntentReceiver finisher = null; 10057 if (i == ris.size()-1 && j == users.length-1) { 10058 finisher = new IIntentReceiver.Stub() { 10059 public void performReceive(Intent intent, int resultCode, 10060 String data, Bundle extras, boolean ordered, 10061 boolean sticky, int sendingUser) { 10062 // The raw IIntentReceiver interface is called 10063 // with the AM lock held, so redispatch to 10064 // execute our code without the lock. 10065 mHandler.post(new Runnable() { 10066 public void run() { 10067 synchronized (ActivityManagerService.this) { 10068 mDidUpdate = true; 10069 } 10070 writeLastDonePreBootReceivers(doneReceivers); 10071 showBootMessage(mContext.getText( 10072 R.string.android_upgrading_complete), 10073 false); 10074 systemReady(goingCallback); 10075 } 10076 }); 10077 } 10078 }; 10079 } 10080 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10081 + " for user " + users[j]); 10082 broadcastIntentLocked(null, null, intent, null, finisher, 10083 0, null, null, null, AppOpsManager.OP_NONE, 10084 true, false, MY_PID, Process.SYSTEM_UID, 10085 users[j]); 10086 if (finisher != null) { 10087 mWaitingUpdate = true; 10088 } 10089 } 10090 } 10091 } 10092 if (mWaitingUpdate) { 10093 return; 10094 } 10095 mDidUpdate = true; 10096 } 10097 10098 mAppOpsService.systemReady(); 10099 mSystemReady = true; 10100 } 10101 10102 ArrayList<ProcessRecord> procsToKill = null; 10103 synchronized(mPidsSelfLocked) { 10104 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10105 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10106 if (!isAllowedWhileBooting(proc.info)){ 10107 if (procsToKill == null) { 10108 procsToKill = new ArrayList<ProcessRecord>(); 10109 } 10110 procsToKill.add(proc); 10111 } 10112 } 10113 } 10114 10115 synchronized(this) { 10116 if (procsToKill != null) { 10117 for (int i=procsToKill.size()-1; i>=0; i--) { 10118 ProcessRecord proc = procsToKill.get(i); 10119 Slog.i(TAG, "Removing system update proc: " + proc); 10120 removeProcessLocked(proc, true, false, "system update done"); 10121 } 10122 } 10123 10124 // Now that we have cleaned up any update processes, we 10125 // are ready to start launching real processes and know that 10126 // we won't trample on them any more. 10127 mProcessesReady = true; 10128 } 10129 10130 Slog.i(TAG, "System now ready"); 10131 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10132 SystemClock.uptimeMillis()); 10133 10134 synchronized(this) { 10135 // Make sure we have no pre-ready processes sitting around. 10136 10137 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10138 ResolveInfo ri = mContext.getPackageManager() 10139 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10140 STOCK_PM_FLAGS); 10141 CharSequence errorMsg = null; 10142 if (ri != null) { 10143 ActivityInfo ai = ri.activityInfo; 10144 ApplicationInfo app = ai.applicationInfo; 10145 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10146 mTopAction = Intent.ACTION_FACTORY_TEST; 10147 mTopData = null; 10148 mTopComponent = new ComponentName(app.packageName, 10149 ai.name); 10150 } else { 10151 errorMsg = mContext.getResources().getText( 10152 com.android.internal.R.string.factorytest_not_system); 10153 } 10154 } else { 10155 errorMsg = mContext.getResources().getText( 10156 com.android.internal.R.string.factorytest_no_action); 10157 } 10158 if (errorMsg != null) { 10159 mTopAction = null; 10160 mTopData = null; 10161 mTopComponent = null; 10162 Message msg = Message.obtain(); 10163 msg.what = SHOW_FACTORY_ERROR_MSG; 10164 msg.getData().putCharSequence("msg", errorMsg); 10165 mHandler.sendMessage(msg); 10166 } 10167 } 10168 } 10169 10170 retrieveSettings(); 10171 10172 synchronized (this) { 10173 readGrantedUriPermissionsLocked(); 10174 } 10175 10176 if (goingCallback != null) goingCallback.run(); 10177 10178 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10179 Integer.toString(mCurrentUserId), mCurrentUserId); 10180 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10181 Integer.toString(mCurrentUserId), mCurrentUserId); 10182 mSystemServiceManager.startUser(mCurrentUserId); 10183 10184 synchronized (this) { 10185 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10186 try { 10187 List apps = AppGlobals.getPackageManager(). 10188 getPersistentApplications(STOCK_PM_FLAGS); 10189 if (apps != null) { 10190 int N = apps.size(); 10191 int i; 10192 for (i=0; i<N; i++) { 10193 ApplicationInfo info 10194 = (ApplicationInfo)apps.get(i); 10195 if (info != null && 10196 !info.packageName.equals("android")) { 10197 addAppLocked(info, false, null /* ABI override */); 10198 } 10199 } 10200 } 10201 } catch (RemoteException ex) { 10202 // pm is in same process, this will never happen. 10203 } 10204 } 10205 10206 // Start up initial activity. 10207 mBooting = true; 10208 10209 try { 10210 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10211 Message msg = Message.obtain(); 10212 msg.what = SHOW_UID_ERROR_MSG; 10213 mHandler.sendMessage(msg); 10214 } 10215 } catch (RemoteException e) { 10216 } 10217 10218 long ident = Binder.clearCallingIdentity(); 10219 try { 10220 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10221 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10222 | Intent.FLAG_RECEIVER_FOREGROUND); 10223 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10224 broadcastIntentLocked(null, null, intent, 10225 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10226 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10227 intent = new Intent(Intent.ACTION_USER_STARTING); 10228 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10229 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10230 broadcastIntentLocked(null, null, intent, 10231 null, new IIntentReceiver.Stub() { 10232 @Override 10233 public void performReceive(Intent intent, int resultCode, String data, 10234 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10235 throws RemoteException { 10236 } 10237 }, 0, null, null, 10238 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10239 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10240 } catch (Throwable t) { 10241 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10242 } finally { 10243 Binder.restoreCallingIdentity(ident); 10244 } 10245 mStackSupervisor.resumeTopActivitiesLocked(); 10246 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10247 } 10248 } 10249 10250 private boolean makeAppCrashingLocked(ProcessRecord app, 10251 String shortMsg, String longMsg, String stackTrace) { 10252 app.crashing = true; 10253 app.crashingReport = generateProcessError(app, 10254 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10255 startAppProblemLocked(app); 10256 app.stopFreezingAllLocked(); 10257 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10258 } 10259 10260 private void makeAppNotRespondingLocked(ProcessRecord app, 10261 String activity, String shortMsg, String longMsg) { 10262 app.notResponding = true; 10263 app.notRespondingReport = generateProcessError(app, 10264 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10265 activity, shortMsg, longMsg, null); 10266 startAppProblemLocked(app); 10267 app.stopFreezingAllLocked(); 10268 } 10269 10270 /** 10271 * Generate a process error record, suitable for attachment to a ProcessRecord. 10272 * 10273 * @param app The ProcessRecord in which the error occurred. 10274 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10275 * ActivityManager.AppErrorStateInfo 10276 * @param activity The activity associated with the crash, if known. 10277 * @param shortMsg Short message describing the crash. 10278 * @param longMsg Long message describing the crash. 10279 * @param stackTrace Full crash stack trace, may be null. 10280 * 10281 * @return Returns a fully-formed AppErrorStateInfo record. 10282 */ 10283 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10284 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10285 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10286 10287 report.condition = condition; 10288 report.processName = app.processName; 10289 report.pid = app.pid; 10290 report.uid = app.info.uid; 10291 report.tag = activity; 10292 report.shortMsg = shortMsg; 10293 report.longMsg = longMsg; 10294 report.stackTrace = stackTrace; 10295 10296 return report; 10297 } 10298 10299 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10300 synchronized (this) { 10301 app.crashing = false; 10302 app.crashingReport = null; 10303 app.notResponding = false; 10304 app.notRespondingReport = null; 10305 if (app.anrDialog == fromDialog) { 10306 app.anrDialog = null; 10307 } 10308 if (app.waitDialog == fromDialog) { 10309 app.waitDialog = null; 10310 } 10311 if (app.pid > 0 && app.pid != MY_PID) { 10312 handleAppCrashLocked(app, null, null, null); 10313 killUnneededProcessLocked(app, "user request after error"); 10314 } 10315 } 10316 } 10317 10318 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10319 String stackTrace) { 10320 long now = SystemClock.uptimeMillis(); 10321 10322 Long crashTime; 10323 if (!app.isolated) { 10324 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10325 } else { 10326 crashTime = null; 10327 } 10328 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10329 // This process loses! 10330 Slog.w(TAG, "Process " + app.info.processName 10331 + " has crashed too many times: killing!"); 10332 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10333 app.userId, app.info.processName, app.uid); 10334 mStackSupervisor.handleAppCrashLocked(app); 10335 if (!app.persistent) { 10336 // We don't want to start this process again until the user 10337 // explicitly does so... but for persistent process, we really 10338 // need to keep it running. If a persistent process is actually 10339 // repeatedly crashing, then badness for everyone. 10340 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10341 app.info.processName); 10342 if (!app.isolated) { 10343 // XXX We don't have a way to mark isolated processes 10344 // as bad, since they don't have a peristent identity. 10345 mBadProcesses.put(app.info.processName, app.uid, 10346 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10347 mProcessCrashTimes.remove(app.info.processName, app.uid); 10348 } 10349 app.bad = true; 10350 app.removed = true; 10351 // Don't let services in this process be restarted and potentially 10352 // annoy the user repeatedly. Unless it is persistent, since those 10353 // processes run critical code. 10354 removeProcessLocked(app, false, false, "crash"); 10355 mStackSupervisor.resumeTopActivitiesLocked(); 10356 return false; 10357 } 10358 mStackSupervisor.resumeTopActivitiesLocked(); 10359 } else { 10360 mStackSupervisor.finishTopRunningActivityLocked(app); 10361 } 10362 10363 // Bump up the crash count of any services currently running in the proc. 10364 for (int i=app.services.size()-1; i>=0; i--) { 10365 // Any services running in the application need to be placed 10366 // back in the pending list. 10367 ServiceRecord sr = app.services.valueAt(i); 10368 sr.crashCount++; 10369 } 10370 10371 // If the crashing process is what we consider to be the "home process" and it has been 10372 // replaced by a third-party app, clear the package preferred activities from packages 10373 // with a home activity running in the process to prevent a repeatedly crashing app 10374 // from blocking the user to manually clear the list. 10375 final ArrayList<ActivityRecord> activities = app.activities; 10376 if (app == mHomeProcess && activities.size() > 0 10377 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10378 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10379 final ActivityRecord r = activities.get(activityNdx); 10380 if (r.isHomeActivity()) { 10381 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10382 try { 10383 ActivityThread.getPackageManager() 10384 .clearPackagePreferredActivities(r.packageName); 10385 } catch (RemoteException c) { 10386 // pm is in same process, this will never happen. 10387 } 10388 } 10389 } 10390 } 10391 10392 if (!app.isolated) { 10393 // XXX Can't keep track of crash times for isolated processes, 10394 // because they don't have a perisistent identity. 10395 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10396 } 10397 10398 return true; 10399 } 10400 10401 void startAppProblemLocked(ProcessRecord app) { 10402 if (app.userId == mCurrentUserId) { 10403 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10404 mContext, app.info.packageName, app.info.flags); 10405 } else { 10406 // If this app is not running under the current user, then we 10407 // can't give it a report button because that would require 10408 // launching the report UI under a different user. 10409 app.errorReportReceiver = null; 10410 } 10411 skipCurrentReceiverLocked(app); 10412 } 10413 10414 void skipCurrentReceiverLocked(ProcessRecord app) { 10415 for (BroadcastQueue queue : mBroadcastQueues) { 10416 queue.skipCurrentReceiverLocked(app); 10417 } 10418 } 10419 10420 /** 10421 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10422 * The application process will exit immediately after this call returns. 10423 * @param app object of the crashing app, null for the system server 10424 * @param crashInfo describing the exception 10425 */ 10426 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10427 ProcessRecord r = findAppProcess(app, "Crash"); 10428 final String processName = app == null ? "system_server" 10429 : (r == null ? "unknown" : r.processName); 10430 10431 handleApplicationCrashInner("crash", r, processName, crashInfo); 10432 } 10433 10434 /* Native crash reporting uses this inner version because it needs to be somewhat 10435 * decoupled from the AM-managed cleanup lifecycle 10436 */ 10437 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10438 ApplicationErrorReport.CrashInfo crashInfo) { 10439 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10440 UserHandle.getUserId(Binder.getCallingUid()), processName, 10441 r == null ? -1 : r.info.flags, 10442 crashInfo.exceptionClassName, 10443 crashInfo.exceptionMessage, 10444 crashInfo.throwFileName, 10445 crashInfo.throwLineNumber); 10446 10447 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10448 10449 crashApplication(r, crashInfo); 10450 } 10451 10452 public void handleApplicationStrictModeViolation( 10453 IBinder app, 10454 int violationMask, 10455 StrictMode.ViolationInfo info) { 10456 ProcessRecord r = findAppProcess(app, "StrictMode"); 10457 if (r == null) { 10458 return; 10459 } 10460 10461 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10462 Integer stackFingerprint = info.hashCode(); 10463 boolean logIt = true; 10464 synchronized (mAlreadyLoggedViolatedStacks) { 10465 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10466 logIt = false; 10467 // TODO: sub-sample into EventLog for these, with 10468 // the info.durationMillis? Then we'd get 10469 // the relative pain numbers, without logging all 10470 // the stack traces repeatedly. We'd want to do 10471 // likewise in the client code, which also does 10472 // dup suppression, before the Binder call. 10473 } else { 10474 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10475 mAlreadyLoggedViolatedStacks.clear(); 10476 } 10477 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10478 } 10479 } 10480 if (logIt) { 10481 logStrictModeViolationToDropBox(r, info); 10482 } 10483 } 10484 10485 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10486 AppErrorResult result = new AppErrorResult(); 10487 synchronized (this) { 10488 final long origId = Binder.clearCallingIdentity(); 10489 10490 Message msg = Message.obtain(); 10491 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10492 HashMap<String, Object> data = new HashMap<String, Object>(); 10493 data.put("result", result); 10494 data.put("app", r); 10495 data.put("violationMask", violationMask); 10496 data.put("info", info); 10497 msg.obj = data; 10498 mHandler.sendMessage(msg); 10499 10500 Binder.restoreCallingIdentity(origId); 10501 } 10502 int res = result.get(); 10503 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10504 } 10505 } 10506 10507 // Depending on the policy in effect, there could be a bunch of 10508 // these in quick succession so we try to batch these together to 10509 // minimize disk writes, number of dropbox entries, and maximize 10510 // compression, by having more fewer, larger records. 10511 private void logStrictModeViolationToDropBox( 10512 ProcessRecord process, 10513 StrictMode.ViolationInfo info) { 10514 if (info == null) { 10515 return; 10516 } 10517 final boolean isSystemApp = process == null || 10518 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10519 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10520 final String processName = process == null ? "unknown" : process.processName; 10521 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10522 final DropBoxManager dbox = (DropBoxManager) 10523 mContext.getSystemService(Context.DROPBOX_SERVICE); 10524 10525 // Exit early if the dropbox isn't configured to accept this report type. 10526 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10527 10528 boolean bufferWasEmpty; 10529 boolean needsFlush; 10530 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10531 synchronized (sb) { 10532 bufferWasEmpty = sb.length() == 0; 10533 appendDropBoxProcessHeaders(process, processName, sb); 10534 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10535 sb.append("System-App: ").append(isSystemApp).append("\n"); 10536 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10537 if (info.violationNumThisLoop != 0) { 10538 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10539 } 10540 if (info.numAnimationsRunning != 0) { 10541 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10542 } 10543 if (info.broadcastIntentAction != null) { 10544 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10545 } 10546 if (info.durationMillis != -1) { 10547 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10548 } 10549 if (info.numInstances != -1) { 10550 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10551 } 10552 if (info.tags != null) { 10553 for (String tag : info.tags) { 10554 sb.append("Span-Tag: ").append(tag).append("\n"); 10555 } 10556 } 10557 sb.append("\n"); 10558 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10559 sb.append(info.crashInfo.stackTrace); 10560 } 10561 sb.append("\n"); 10562 10563 // Only buffer up to ~64k. Various logging bits truncate 10564 // things at 128k. 10565 needsFlush = (sb.length() > 64 * 1024); 10566 } 10567 10568 // Flush immediately if the buffer's grown too large, or this 10569 // is a non-system app. Non-system apps are isolated with a 10570 // different tag & policy and not batched. 10571 // 10572 // Batching is useful during internal testing with 10573 // StrictMode settings turned up high. Without batching, 10574 // thousands of separate files could be created on boot. 10575 if (!isSystemApp || needsFlush) { 10576 new Thread("Error dump: " + dropboxTag) { 10577 @Override 10578 public void run() { 10579 String report; 10580 synchronized (sb) { 10581 report = sb.toString(); 10582 sb.delete(0, sb.length()); 10583 sb.trimToSize(); 10584 } 10585 if (report.length() != 0) { 10586 dbox.addText(dropboxTag, report); 10587 } 10588 } 10589 }.start(); 10590 return; 10591 } 10592 10593 // System app batching: 10594 if (!bufferWasEmpty) { 10595 // An existing dropbox-writing thread is outstanding, so 10596 // we don't need to start it up. The existing thread will 10597 // catch the buffer appends we just did. 10598 return; 10599 } 10600 10601 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10602 // (After this point, we shouldn't access AMS internal data structures.) 10603 new Thread("Error dump: " + dropboxTag) { 10604 @Override 10605 public void run() { 10606 // 5 second sleep to let stacks arrive and be batched together 10607 try { 10608 Thread.sleep(5000); // 5 seconds 10609 } catch (InterruptedException e) {} 10610 10611 String errorReport; 10612 synchronized (mStrictModeBuffer) { 10613 errorReport = mStrictModeBuffer.toString(); 10614 if (errorReport.length() == 0) { 10615 return; 10616 } 10617 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10618 mStrictModeBuffer.trimToSize(); 10619 } 10620 dbox.addText(dropboxTag, errorReport); 10621 } 10622 }.start(); 10623 } 10624 10625 /** 10626 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10627 * @param app object of the crashing app, null for the system server 10628 * @param tag reported by the caller 10629 * @param crashInfo describing the context of the error 10630 * @return true if the process should exit immediately (WTF is fatal) 10631 */ 10632 public boolean handleApplicationWtf(IBinder app, String tag, 10633 ApplicationErrorReport.CrashInfo crashInfo) { 10634 ProcessRecord r = findAppProcess(app, "WTF"); 10635 final String processName = app == null ? "system_server" 10636 : (r == null ? "unknown" : r.processName); 10637 10638 EventLog.writeEvent(EventLogTags.AM_WTF, 10639 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10640 processName, 10641 r == null ? -1 : r.info.flags, 10642 tag, crashInfo.exceptionMessage); 10643 10644 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10645 10646 if (r != null && r.pid != Process.myPid() && 10647 Settings.Global.getInt(mContext.getContentResolver(), 10648 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10649 crashApplication(r, crashInfo); 10650 return true; 10651 } else { 10652 return false; 10653 } 10654 } 10655 10656 /** 10657 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10658 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10659 */ 10660 private ProcessRecord findAppProcess(IBinder app, String reason) { 10661 if (app == null) { 10662 return null; 10663 } 10664 10665 synchronized (this) { 10666 final int NP = mProcessNames.getMap().size(); 10667 for (int ip=0; ip<NP; ip++) { 10668 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10669 final int NA = apps.size(); 10670 for (int ia=0; ia<NA; ia++) { 10671 ProcessRecord p = apps.valueAt(ia); 10672 if (p.thread != null && p.thread.asBinder() == app) { 10673 return p; 10674 } 10675 } 10676 } 10677 10678 Slog.w(TAG, "Can't find mystery application for " + reason 10679 + " from pid=" + Binder.getCallingPid() 10680 + " uid=" + Binder.getCallingUid() + ": " + app); 10681 return null; 10682 } 10683 } 10684 10685 /** 10686 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10687 * to append various headers to the dropbox log text. 10688 */ 10689 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10690 StringBuilder sb) { 10691 // Watchdog thread ends up invoking this function (with 10692 // a null ProcessRecord) to add the stack file to dropbox. 10693 // Do not acquire a lock on this (am) in such cases, as it 10694 // could cause a potential deadlock, if and when watchdog 10695 // is invoked due to unavailability of lock on am and it 10696 // would prevent watchdog from killing system_server. 10697 if (process == null) { 10698 sb.append("Process: ").append(processName).append("\n"); 10699 return; 10700 } 10701 // Note: ProcessRecord 'process' is guarded by the service 10702 // instance. (notably process.pkgList, which could otherwise change 10703 // concurrently during execution of this method) 10704 synchronized (this) { 10705 sb.append("Process: ").append(processName).append("\n"); 10706 int flags = process.info.flags; 10707 IPackageManager pm = AppGlobals.getPackageManager(); 10708 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10709 for (int ip=0; ip<process.pkgList.size(); ip++) { 10710 String pkg = process.pkgList.keyAt(ip); 10711 sb.append("Package: ").append(pkg); 10712 try { 10713 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10714 if (pi != null) { 10715 sb.append(" v").append(pi.versionCode); 10716 if (pi.versionName != null) { 10717 sb.append(" (").append(pi.versionName).append(")"); 10718 } 10719 } 10720 } catch (RemoteException e) { 10721 Slog.e(TAG, "Error getting package info: " + pkg, e); 10722 } 10723 sb.append("\n"); 10724 } 10725 } 10726 } 10727 10728 private static String processClass(ProcessRecord process) { 10729 if (process == null || process.pid == MY_PID) { 10730 return "system_server"; 10731 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10732 return "system_app"; 10733 } else { 10734 return "data_app"; 10735 } 10736 } 10737 10738 /** 10739 * Write a description of an error (crash, WTF, ANR) to the drop box. 10740 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10741 * @param process which caused the error, null means the system server 10742 * @param activity which triggered the error, null if unknown 10743 * @param parent activity related to the error, null if unknown 10744 * @param subject line related to the error, null if absent 10745 * @param report in long form describing the error, null if absent 10746 * @param logFile to include in the report, null if none 10747 * @param crashInfo giving an application stack trace, null if absent 10748 */ 10749 public void addErrorToDropBox(String eventType, 10750 ProcessRecord process, String processName, ActivityRecord activity, 10751 ActivityRecord parent, String subject, 10752 final String report, final File logFile, 10753 final ApplicationErrorReport.CrashInfo crashInfo) { 10754 // NOTE -- this must never acquire the ActivityManagerService lock, 10755 // otherwise the watchdog may be prevented from resetting the system. 10756 10757 final String dropboxTag = processClass(process) + "_" + eventType; 10758 final DropBoxManager dbox = (DropBoxManager) 10759 mContext.getSystemService(Context.DROPBOX_SERVICE); 10760 10761 // Exit early if the dropbox isn't configured to accept this report type. 10762 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10763 10764 final StringBuilder sb = new StringBuilder(1024); 10765 appendDropBoxProcessHeaders(process, processName, sb); 10766 if (activity != null) { 10767 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10768 } 10769 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10770 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10771 } 10772 if (parent != null && parent != activity) { 10773 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10774 } 10775 if (subject != null) { 10776 sb.append("Subject: ").append(subject).append("\n"); 10777 } 10778 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10779 if (Debug.isDebuggerConnected()) { 10780 sb.append("Debugger: Connected\n"); 10781 } 10782 sb.append("\n"); 10783 10784 // Do the rest in a worker thread to avoid blocking the caller on I/O 10785 // (After this point, we shouldn't access AMS internal data structures.) 10786 Thread worker = new Thread("Error dump: " + dropboxTag) { 10787 @Override 10788 public void run() { 10789 if (report != null) { 10790 sb.append(report); 10791 } 10792 if (logFile != null) { 10793 try { 10794 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10795 "\n\n[[TRUNCATED]]")); 10796 } catch (IOException e) { 10797 Slog.e(TAG, "Error reading " + logFile, e); 10798 } 10799 } 10800 if (crashInfo != null && crashInfo.stackTrace != null) { 10801 sb.append(crashInfo.stackTrace); 10802 } 10803 10804 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10805 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10806 if (lines > 0) { 10807 sb.append("\n"); 10808 10809 // Merge several logcat streams, and take the last N lines 10810 InputStreamReader input = null; 10811 try { 10812 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10813 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10814 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10815 10816 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10817 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10818 input = new InputStreamReader(logcat.getInputStream()); 10819 10820 int num; 10821 char[] buf = new char[8192]; 10822 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10823 } catch (IOException e) { 10824 Slog.e(TAG, "Error running logcat", e); 10825 } finally { 10826 if (input != null) try { input.close(); } catch (IOException e) {} 10827 } 10828 } 10829 10830 dbox.addText(dropboxTag, sb.toString()); 10831 } 10832 }; 10833 10834 if (process == null) { 10835 // If process is null, we are being called from some internal code 10836 // and may be about to die -- run this synchronously. 10837 worker.run(); 10838 } else { 10839 worker.start(); 10840 } 10841 } 10842 10843 /** 10844 * Bring up the "unexpected error" dialog box for a crashing app. 10845 * Deal with edge cases (intercepts from instrumented applications, 10846 * ActivityController, error intent receivers, that sort of thing). 10847 * @param r the application crashing 10848 * @param crashInfo describing the failure 10849 */ 10850 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10851 long timeMillis = System.currentTimeMillis(); 10852 String shortMsg = crashInfo.exceptionClassName; 10853 String longMsg = crashInfo.exceptionMessage; 10854 String stackTrace = crashInfo.stackTrace; 10855 if (shortMsg != null && longMsg != null) { 10856 longMsg = shortMsg + ": " + longMsg; 10857 } else if (shortMsg != null) { 10858 longMsg = shortMsg; 10859 } 10860 10861 AppErrorResult result = new AppErrorResult(); 10862 synchronized (this) { 10863 if (mController != null) { 10864 try { 10865 String name = r != null ? r.processName : null; 10866 int pid = r != null ? r.pid : Binder.getCallingPid(); 10867 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10868 if (!mController.appCrashed(name, pid, 10869 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10870 Slog.w(TAG, "Force-killing crashed app " + name 10871 + " at watcher's request"); 10872 Process.killProcess(pid); 10873 if (r != null) { 10874 Process.killProcessGroup(uid, pid); 10875 } 10876 return; 10877 } 10878 } catch (RemoteException e) { 10879 mController = null; 10880 Watchdog.getInstance().setActivityController(null); 10881 } 10882 } 10883 10884 final long origId = Binder.clearCallingIdentity(); 10885 10886 // If this process is running instrumentation, finish it. 10887 if (r != null && r.instrumentationClass != null) { 10888 Slog.w(TAG, "Error in app " + r.processName 10889 + " running instrumentation " + r.instrumentationClass + ":"); 10890 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10891 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10892 Bundle info = new Bundle(); 10893 info.putString("shortMsg", shortMsg); 10894 info.putString("longMsg", longMsg); 10895 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10896 Binder.restoreCallingIdentity(origId); 10897 return; 10898 } 10899 10900 // If we can't identify the process or it's already exceeded its crash quota, 10901 // quit right away without showing a crash dialog. 10902 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10903 Binder.restoreCallingIdentity(origId); 10904 return; 10905 } 10906 10907 Message msg = Message.obtain(); 10908 msg.what = SHOW_ERROR_MSG; 10909 HashMap data = new HashMap(); 10910 data.put("result", result); 10911 data.put("app", r); 10912 msg.obj = data; 10913 mHandler.sendMessage(msg); 10914 10915 Binder.restoreCallingIdentity(origId); 10916 } 10917 10918 int res = result.get(); 10919 10920 Intent appErrorIntent = null; 10921 synchronized (this) { 10922 if (r != null && !r.isolated) { 10923 // XXX Can't keep track of crash time for isolated processes, 10924 // since they don't have a persistent identity. 10925 mProcessCrashTimes.put(r.info.processName, r.uid, 10926 SystemClock.uptimeMillis()); 10927 } 10928 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10929 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10930 } 10931 } 10932 10933 if (appErrorIntent != null) { 10934 try { 10935 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10936 } catch (ActivityNotFoundException e) { 10937 Slog.w(TAG, "bug report receiver dissappeared", e); 10938 } 10939 } 10940 } 10941 10942 Intent createAppErrorIntentLocked(ProcessRecord r, 10943 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10944 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10945 if (report == null) { 10946 return null; 10947 } 10948 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10949 result.setComponent(r.errorReportReceiver); 10950 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10951 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10952 return result; 10953 } 10954 10955 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10956 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10957 if (r.errorReportReceiver == null) { 10958 return null; 10959 } 10960 10961 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10962 return null; 10963 } 10964 10965 ApplicationErrorReport report = new ApplicationErrorReport(); 10966 report.packageName = r.info.packageName; 10967 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10968 report.processName = r.processName; 10969 report.time = timeMillis; 10970 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10971 10972 if (r.crashing || r.forceCrashReport) { 10973 report.type = ApplicationErrorReport.TYPE_CRASH; 10974 report.crashInfo = crashInfo; 10975 } else if (r.notResponding) { 10976 report.type = ApplicationErrorReport.TYPE_ANR; 10977 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10978 10979 report.anrInfo.activity = r.notRespondingReport.tag; 10980 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10981 report.anrInfo.info = r.notRespondingReport.longMsg; 10982 } 10983 10984 return report; 10985 } 10986 10987 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10988 enforceNotIsolatedCaller("getProcessesInErrorState"); 10989 // assume our apps are happy - lazy create the list 10990 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10991 10992 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10993 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10994 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10995 10996 synchronized (this) { 10997 10998 // iterate across all processes 10999 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11000 ProcessRecord app = mLruProcesses.get(i); 11001 if (!allUsers && app.userId != userId) { 11002 continue; 11003 } 11004 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11005 // This one's in trouble, so we'll generate a report for it 11006 // crashes are higher priority (in case there's a crash *and* an anr) 11007 ActivityManager.ProcessErrorStateInfo report = null; 11008 if (app.crashing) { 11009 report = app.crashingReport; 11010 } else if (app.notResponding) { 11011 report = app.notRespondingReport; 11012 } 11013 11014 if (report != null) { 11015 if (errList == null) { 11016 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11017 } 11018 errList.add(report); 11019 } else { 11020 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11021 " crashing = " + app.crashing + 11022 " notResponding = " + app.notResponding); 11023 } 11024 } 11025 } 11026 } 11027 11028 return errList; 11029 } 11030 11031 static int procStateToImportance(int procState, int memAdj, 11032 ActivityManager.RunningAppProcessInfo currApp) { 11033 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11034 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11035 currApp.lru = memAdj; 11036 } else { 11037 currApp.lru = 0; 11038 } 11039 return imp; 11040 } 11041 11042 private void fillInProcMemInfo(ProcessRecord app, 11043 ActivityManager.RunningAppProcessInfo outInfo) { 11044 outInfo.pid = app.pid; 11045 outInfo.uid = app.info.uid; 11046 if (mHeavyWeightProcess == app) { 11047 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11048 } 11049 if (app.persistent) { 11050 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11051 } 11052 if (app.activities.size() > 0) { 11053 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11054 } 11055 outInfo.lastTrimLevel = app.trimMemoryLevel; 11056 int adj = app.curAdj; 11057 int procState = app.curProcState; 11058 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11059 outInfo.importanceReasonCode = app.adjTypeCode; 11060 outInfo.processState = app.curProcState; 11061 } 11062 11063 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11064 enforceNotIsolatedCaller("getRunningAppProcesses"); 11065 // Lazy instantiation of list 11066 List<ActivityManager.RunningAppProcessInfo> runList = null; 11067 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11068 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11069 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11070 synchronized (this) { 11071 // Iterate across all processes 11072 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11073 ProcessRecord app = mLruProcesses.get(i); 11074 if (!allUsers && app.userId != userId) { 11075 continue; 11076 } 11077 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11078 // Generate process state info for running application 11079 ActivityManager.RunningAppProcessInfo currApp = 11080 new ActivityManager.RunningAppProcessInfo(app.processName, 11081 app.pid, app.getPackageList()); 11082 fillInProcMemInfo(app, currApp); 11083 if (app.adjSource instanceof ProcessRecord) { 11084 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11085 currApp.importanceReasonImportance = 11086 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11087 app.adjSourceProcState); 11088 } else if (app.adjSource instanceof ActivityRecord) { 11089 ActivityRecord r = (ActivityRecord)app.adjSource; 11090 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11091 } 11092 if (app.adjTarget instanceof ComponentName) { 11093 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11094 } 11095 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11096 // + " lru=" + currApp.lru); 11097 if (runList == null) { 11098 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11099 } 11100 runList.add(currApp); 11101 } 11102 } 11103 } 11104 return runList; 11105 } 11106 11107 public List<ApplicationInfo> getRunningExternalApplications() { 11108 enforceNotIsolatedCaller("getRunningExternalApplications"); 11109 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11110 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11111 if (runningApps != null && runningApps.size() > 0) { 11112 Set<String> extList = new HashSet<String>(); 11113 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11114 if (app.pkgList != null) { 11115 for (String pkg : app.pkgList) { 11116 extList.add(pkg); 11117 } 11118 } 11119 } 11120 IPackageManager pm = AppGlobals.getPackageManager(); 11121 for (String pkg : extList) { 11122 try { 11123 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11124 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11125 retList.add(info); 11126 } 11127 } catch (RemoteException e) { 11128 } 11129 } 11130 } 11131 return retList; 11132 } 11133 11134 @Override 11135 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11136 enforceNotIsolatedCaller("getMyMemoryState"); 11137 synchronized (this) { 11138 ProcessRecord proc; 11139 synchronized (mPidsSelfLocked) { 11140 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11141 } 11142 fillInProcMemInfo(proc, outInfo); 11143 } 11144 } 11145 11146 @Override 11147 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11148 if (checkCallingPermission(android.Manifest.permission.DUMP) 11149 != PackageManager.PERMISSION_GRANTED) { 11150 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11151 + Binder.getCallingPid() 11152 + ", uid=" + Binder.getCallingUid() 11153 + " without permission " 11154 + android.Manifest.permission.DUMP); 11155 return; 11156 } 11157 11158 boolean dumpAll = false; 11159 boolean dumpClient = false; 11160 String dumpPackage = null; 11161 11162 int opti = 0; 11163 while (opti < args.length) { 11164 String opt = args[opti]; 11165 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11166 break; 11167 } 11168 opti++; 11169 if ("-a".equals(opt)) { 11170 dumpAll = true; 11171 } else if ("-c".equals(opt)) { 11172 dumpClient = true; 11173 } else if ("-h".equals(opt)) { 11174 pw.println("Activity manager dump options:"); 11175 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11176 pw.println(" cmd may be one of:"); 11177 pw.println(" a[ctivities]: activity stack state"); 11178 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11179 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11180 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11181 pw.println(" o[om]: out of memory management"); 11182 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11183 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11184 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11185 pw.println(" service [COMP_SPEC]: service client-side state"); 11186 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11187 pw.println(" all: dump all activities"); 11188 pw.println(" top: dump the top activity"); 11189 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11190 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11191 pw.println(" a partial substring in a component name, a"); 11192 pw.println(" hex object identifier."); 11193 pw.println(" -a: include all available server state."); 11194 pw.println(" -c: include client state."); 11195 return; 11196 } else { 11197 pw.println("Unknown argument: " + opt + "; use -h for help"); 11198 } 11199 } 11200 11201 long origId = Binder.clearCallingIdentity(); 11202 boolean more = false; 11203 // Is the caller requesting to dump a particular piece of data? 11204 if (opti < args.length) { 11205 String cmd = args[opti]; 11206 opti++; 11207 if ("activities".equals(cmd) || "a".equals(cmd)) { 11208 synchronized (this) { 11209 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11210 } 11211 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11212 String[] newArgs; 11213 String name; 11214 if (opti >= args.length) { 11215 name = null; 11216 newArgs = EMPTY_STRING_ARRAY; 11217 } else { 11218 name = args[opti]; 11219 opti++; 11220 newArgs = new String[args.length - opti]; 11221 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11222 args.length - opti); 11223 } 11224 synchronized (this) { 11225 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11226 } 11227 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11228 String[] newArgs; 11229 String name; 11230 if (opti >= args.length) { 11231 name = null; 11232 newArgs = EMPTY_STRING_ARRAY; 11233 } else { 11234 name = args[opti]; 11235 opti++; 11236 newArgs = new String[args.length - opti]; 11237 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11238 args.length - opti); 11239 } 11240 synchronized (this) { 11241 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11242 } 11243 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11244 String[] newArgs; 11245 String name; 11246 if (opti >= args.length) { 11247 name = null; 11248 newArgs = EMPTY_STRING_ARRAY; 11249 } else { 11250 name = args[opti]; 11251 opti++; 11252 newArgs = new String[args.length - opti]; 11253 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11254 args.length - opti); 11255 } 11256 synchronized (this) { 11257 dumpProcessesLocked(fd, pw, args, opti, true, name); 11258 } 11259 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11260 synchronized (this) { 11261 dumpOomLocked(fd, pw, args, opti, true); 11262 } 11263 } else if ("provider".equals(cmd)) { 11264 String[] newArgs; 11265 String name; 11266 if (opti >= args.length) { 11267 name = null; 11268 newArgs = EMPTY_STRING_ARRAY; 11269 } else { 11270 name = args[opti]; 11271 opti++; 11272 newArgs = new String[args.length - opti]; 11273 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11274 } 11275 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11276 pw.println("No providers match: " + name); 11277 pw.println("Use -h for help."); 11278 } 11279 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11280 synchronized (this) { 11281 dumpProvidersLocked(fd, pw, args, opti, true, null); 11282 } 11283 } else if ("service".equals(cmd)) { 11284 String[] newArgs; 11285 String name; 11286 if (opti >= args.length) { 11287 name = null; 11288 newArgs = EMPTY_STRING_ARRAY; 11289 } else { 11290 name = args[opti]; 11291 opti++; 11292 newArgs = new String[args.length - opti]; 11293 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11294 args.length - opti); 11295 } 11296 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11297 pw.println("No services match: " + name); 11298 pw.println("Use -h for help."); 11299 } 11300 } else if ("package".equals(cmd)) { 11301 String[] newArgs; 11302 if (opti >= args.length) { 11303 pw.println("package: no package name specified"); 11304 pw.println("Use -h for help."); 11305 } else { 11306 dumpPackage = args[opti]; 11307 opti++; 11308 newArgs = new String[args.length - opti]; 11309 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11310 args.length - opti); 11311 args = newArgs; 11312 opti = 0; 11313 more = true; 11314 } 11315 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11316 synchronized (this) { 11317 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11318 } 11319 } else { 11320 // Dumping a single activity? 11321 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11322 pw.println("Bad activity command, or no activities match: " + cmd); 11323 pw.println("Use -h for help."); 11324 } 11325 } 11326 if (!more) { 11327 Binder.restoreCallingIdentity(origId); 11328 return; 11329 } 11330 } 11331 11332 // No piece of data specified, dump everything. 11333 synchronized (this) { 11334 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11335 pw.println(); 11336 if (dumpAll) { 11337 pw.println("-------------------------------------------------------------------------------"); 11338 } 11339 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11340 pw.println(); 11341 if (dumpAll) { 11342 pw.println("-------------------------------------------------------------------------------"); 11343 } 11344 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11345 pw.println(); 11346 if (dumpAll) { 11347 pw.println("-------------------------------------------------------------------------------"); 11348 } 11349 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11350 pw.println(); 11351 if (dumpAll) { 11352 pw.println("-------------------------------------------------------------------------------"); 11353 } 11354 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11355 pw.println(); 11356 if (dumpAll) { 11357 pw.println("-------------------------------------------------------------------------------"); 11358 } 11359 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11360 } 11361 Binder.restoreCallingIdentity(origId); 11362 } 11363 11364 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11365 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11366 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11367 11368 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11369 dumpPackage); 11370 boolean needSep = printedAnything; 11371 11372 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11373 dumpPackage, needSep, " mFocusedActivity: "); 11374 if (printed) { 11375 printedAnything = true; 11376 needSep = false; 11377 } 11378 11379 if (dumpPackage == null) { 11380 if (needSep) { 11381 pw.println(); 11382 } 11383 needSep = true; 11384 printedAnything = true; 11385 mStackSupervisor.dump(pw, " "); 11386 } 11387 11388 if (mRecentTasks.size() > 0) { 11389 boolean printedHeader = false; 11390 11391 final int N = mRecentTasks.size(); 11392 for (int i=0; i<N; i++) { 11393 TaskRecord tr = mRecentTasks.get(i); 11394 if (dumpPackage != null) { 11395 if (tr.realActivity == null || 11396 !dumpPackage.equals(tr.realActivity)) { 11397 continue; 11398 } 11399 } 11400 if (!printedHeader) { 11401 if (needSep) { 11402 pw.println(); 11403 } 11404 pw.println(" Recent tasks:"); 11405 printedHeader = true; 11406 printedAnything = true; 11407 } 11408 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11409 pw.println(tr); 11410 if (dumpAll) { 11411 mRecentTasks.get(i).dump(pw, " "); 11412 } 11413 } 11414 } 11415 11416 if (!printedAnything) { 11417 pw.println(" (nothing)"); 11418 } 11419 } 11420 11421 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11422 int opti, boolean dumpAll, String dumpPackage) { 11423 boolean needSep = false; 11424 boolean printedAnything = false; 11425 int numPers = 0; 11426 11427 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11428 11429 if (dumpAll) { 11430 final int NP = mProcessNames.getMap().size(); 11431 for (int ip=0; ip<NP; ip++) { 11432 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11433 final int NA = procs.size(); 11434 for (int ia=0; ia<NA; ia++) { 11435 ProcessRecord r = procs.valueAt(ia); 11436 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11437 continue; 11438 } 11439 if (!needSep) { 11440 pw.println(" All known processes:"); 11441 needSep = true; 11442 printedAnything = true; 11443 } 11444 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11445 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11446 pw.print(" "); pw.println(r); 11447 r.dump(pw, " "); 11448 if (r.persistent) { 11449 numPers++; 11450 } 11451 } 11452 } 11453 } 11454 11455 if (mIsolatedProcesses.size() > 0) { 11456 boolean printed = false; 11457 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11458 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11459 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11460 continue; 11461 } 11462 if (!printed) { 11463 if (needSep) { 11464 pw.println(); 11465 } 11466 pw.println(" Isolated process list (sorted by uid):"); 11467 printedAnything = true; 11468 printed = true; 11469 needSep = true; 11470 } 11471 pw.println(String.format("%sIsolated #%2d: %s", 11472 " ", i, r.toString())); 11473 } 11474 } 11475 11476 if (mLruProcesses.size() > 0) { 11477 if (needSep) { 11478 pw.println(); 11479 } 11480 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11481 pw.print(" total, non-act at "); 11482 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11483 pw.print(", non-svc at "); 11484 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11485 pw.println("):"); 11486 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11487 needSep = true; 11488 printedAnything = true; 11489 } 11490 11491 if (dumpAll || dumpPackage != null) { 11492 synchronized (mPidsSelfLocked) { 11493 boolean printed = false; 11494 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11495 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11496 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11497 continue; 11498 } 11499 if (!printed) { 11500 if (needSep) pw.println(); 11501 needSep = true; 11502 pw.println(" PID mappings:"); 11503 printed = true; 11504 printedAnything = true; 11505 } 11506 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11507 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11508 } 11509 } 11510 } 11511 11512 if (mForegroundProcesses.size() > 0) { 11513 synchronized (mPidsSelfLocked) { 11514 boolean printed = false; 11515 for (int i=0; i<mForegroundProcesses.size(); i++) { 11516 ProcessRecord r = mPidsSelfLocked.get( 11517 mForegroundProcesses.valueAt(i).pid); 11518 if (dumpPackage != null && (r == null 11519 || !r.pkgList.containsKey(dumpPackage))) { 11520 continue; 11521 } 11522 if (!printed) { 11523 if (needSep) pw.println(); 11524 needSep = true; 11525 pw.println(" Foreground Processes:"); 11526 printed = true; 11527 printedAnything = true; 11528 } 11529 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11530 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11531 } 11532 } 11533 } 11534 11535 if (mPersistentStartingProcesses.size() > 0) { 11536 if (needSep) pw.println(); 11537 needSep = true; 11538 printedAnything = true; 11539 pw.println(" Persisent processes that are starting:"); 11540 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11541 "Starting Norm", "Restarting PERS", dumpPackage); 11542 } 11543 11544 if (mRemovedProcesses.size() > 0) { 11545 if (needSep) pw.println(); 11546 needSep = true; 11547 printedAnything = true; 11548 pw.println(" Processes that are being removed:"); 11549 dumpProcessList(pw, this, mRemovedProcesses, " ", 11550 "Removed Norm", "Removed PERS", dumpPackage); 11551 } 11552 11553 if (mProcessesOnHold.size() > 0) { 11554 if (needSep) pw.println(); 11555 needSep = true; 11556 printedAnything = true; 11557 pw.println(" Processes that are on old until the system is ready:"); 11558 dumpProcessList(pw, this, mProcessesOnHold, " ", 11559 "OnHold Norm", "OnHold PERS", dumpPackage); 11560 } 11561 11562 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11563 11564 if (mProcessCrashTimes.getMap().size() > 0) { 11565 boolean printed = false; 11566 long now = SystemClock.uptimeMillis(); 11567 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11568 final int NP = pmap.size(); 11569 for (int ip=0; ip<NP; ip++) { 11570 String pname = pmap.keyAt(ip); 11571 SparseArray<Long> uids = pmap.valueAt(ip); 11572 final int N = uids.size(); 11573 for (int i=0; i<N; i++) { 11574 int puid = uids.keyAt(i); 11575 ProcessRecord r = mProcessNames.get(pname, puid); 11576 if (dumpPackage != null && (r == null 11577 || !r.pkgList.containsKey(dumpPackage))) { 11578 continue; 11579 } 11580 if (!printed) { 11581 if (needSep) pw.println(); 11582 needSep = true; 11583 pw.println(" Time since processes crashed:"); 11584 printed = true; 11585 printedAnything = true; 11586 } 11587 pw.print(" Process "); pw.print(pname); 11588 pw.print(" uid "); pw.print(puid); 11589 pw.print(": last crashed "); 11590 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11591 pw.println(" ago"); 11592 } 11593 } 11594 } 11595 11596 if (mBadProcesses.getMap().size() > 0) { 11597 boolean printed = false; 11598 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11599 final int NP = pmap.size(); 11600 for (int ip=0; ip<NP; ip++) { 11601 String pname = pmap.keyAt(ip); 11602 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11603 final int N = uids.size(); 11604 for (int i=0; i<N; i++) { 11605 int puid = uids.keyAt(i); 11606 ProcessRecord r = mProcessNames.get(pname, puid); 11607 if (dumpPackage != null && (r == null 11608 || !r.pkgList.containsKey(dumpPackage))) { 11609 continue; 11610 } 11611 if (!printed) { 11612 if (needSep) pw.println(); 11613 needSep = true; 11614 pw.println(" Bad processes:"); 11615 printedAnything = true; 11616 } 11617 BadProcessInfo info = uids.valueAt(i); 11618 pw.print(" Bad process "); pw.print(pname); 11619 pw.print(" uid "); pw.print(puid); 11620 pw.print(": crashed at time "); pw.println(info.time); 11621 if (info.shortMsg != null) { 11622 pw.print(" Short msg: "); pw.println(info.shortMsg); 11623 } 11624 if (info.longMsg != null) { 11625 pw.print(" Long msg: "); pw.println(info.longMsg); 11626 } 11627 if (info.stack != null) { 11628 pw.println(" Stack:"); 11629 int lastPos = 0; 11630 for (int pos=0; pos<info.stack.length(); pos++) { 11631 if (info.stack.charAt(pos) == '\n') { 11632 pw.print(" "); 11633 pw.write(info.stack, lastPos, pos-lastPos); 11634 pw.println(); 11635 lastPos = pos+1; 11636 } 11637 } 11638 if (lastPos < info.stack.length()) { 11639 pw.print(" "); 11640 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11641 pw.println(); 11642 } 11643 } 11644 } 11645 } 11646 } 11647 11648 if (dumpPackage == null) { 11649 pw.println(); 11650 needSep = false; 11651 pw.println(" mStartedUsers:"); 11652 for (int i=0; i<mStartedUsers.size(); i++) { 11653 UserStartedState uss = mStartedUsers.valueAt(i); 11654 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11655 pw.print(": "); uss.dump("", pw); 11656 } 11657 pw.print(" mStartedUserArray: ["); 11658 for (int i=0; i<mStartedUserArray.length; i++) { 11659 if (i > 0) pw.print(", "); 11660 pw.print(mStartedUserArray[i]); 11661 } 11662 pw.println("]"); 11663 pw.print(" mUserLru: ["); 11664 for (int i=0; i<mUserLru.size(); i++) { 11665 if (i > 0) pw.print(", "); 11666 pw.print(mUserLru.get(i)); 11667 } 11668 pw.println("]"); 11669 if (dumpAll) { 11670 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11671 } 11672 synchronized (mUserProfileGroupIdsSelfLocked) { 11673 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 11674 pw.println(" mUserProfileGroupIds:"); 11675 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 11676 pw.print(" User #"); 11677 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 11678 pw.print(" -> profile #"); 11679 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 11680 } 11681 } 11682 } 11683 } 11684 if (mHomeProcess != null && (dumpPackage == null 11685 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11686 if (needSep) { 11687 pw.println(); 11688 needSep = false; 11689 } 11690 pw.println(" mHomeProcess: " + mHomeProcess); 11691 } 11692 if (mPreviousProcess != null && (dumpPackage == null 11693 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11694 if (needSep) { 11695 pw.println(); 11696 needSep = false; 11697 } 11698 pw.println(" mPreviousProcess: " + mPreviousProcess); 11699 } 11700 if (dumpAll) { 11701 StringBuilder sb = new StringBuilder(128); 11702 sb.append(" mPreviousProcessVisibleTime: "); 11703 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11704 pw.println(sb); 11705 } 11706 if (mHeavyWeightProcess != null && (dumpPackage == null 11707 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11708 if (needSep) { 11709 pw.println(); 11710 needSep = false; 11711 } 11712 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11713 } 11714 if (dumpPackage == null) { 11715 pw.println(" mConfiguration: " + mConfiguration); 11716 } 11717 if (dumpAll) { 11718 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11719 if (mCompatModePackages.getPackages().size() > 0) { 11720 boolean printed = false; 11721 for (Map.Entry<String, Integer> entry 11722 : mCompatModePackages.getPackages().entrySet()) { 11723 String pkg = entry.getKey(); 11724 int mode = entry.getValue(); 11725 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11726 continue; 11727 } 11728 if (!printed) { 11729 pw.println(" mScreenCompatPackages:"); 11730 printed = true; 11731 } 11732 pw.print(" "); pw.print(pkg); pw.print(": "); 11733 pw.print(mode); pw.println(); 11734 } 11735 } 11736 } 11737 if (dumpPackage == null) { 11738 if (mSleeping || mWentToSleep || mLockScreenShown) { 11739 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11740 + " mLockScreenShown " + mLockScreenShown); 11741 } 11742 if (mShuttingDown || mRunningVoice) { 11743 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11744 } 11745 } 11746 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11747 || mOrigWaitForDebugger) { 11748 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11749 || dumpPackage.equals(mOrigDebugApp)) { 11750 if (needSep) { 11751 pw.println(); 11752 needSep = false; 11753 } 11754 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11755 + " mDebugTransient=" + mDebugTransient 11756 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11757 } 11758 } 11759 if (mOpenGlTraceApp != null) { 11760 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11761 if (needSep) { 11762 pw.println(); 11763 needSep = false; 11764 } 11765 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11766 } 11767 } 11768 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11769 || mProfileFd != null) { 11770 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11771 if (needSep) { 11772 pw.println(); 11773 needSep = false; 11774 } 11775 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11776 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11777 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11778 + mAutoStopProfiler); 11779 } 11780 } 11781 if (dumpPackage == null) { 11782 if (mAlwaysFinishActivities || mController != null) { 11783 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11784 + " mController=" + mController); 11785 } 11786 if (dumpAll) { 11787 pw.println(" Total persistent processes: " + numPers); 11788 pw.println(" mProcessesReady=" + mProcessesReady 11789 + " mSystemReady=" + mSystemReady); 11790 pw.println(" mBooting=" + mBooting 11791 + " mBooted=" + mBooted 11792 + " mFactoryTest=" + mFactoryTest); 11793 pw.print(" mLastPowerCheckRealtime="); 11794 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11795 pw.println(""); 11796 pw.print(" mLastPowerCheckUptime="); 11797 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11798 pw.println(""); 11799 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11800 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11801 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11802 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11803 + " (" + mLruProcesses.size() + " total)" 11804 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11805 + " mNumServiceProcs=" + mNumServiceProcs 11806 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11807 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11808 + " mLastMemoryLevel" + mLastMemoryLevel 11809 + " mLastNumProcesses" + mLastNumProcesses); 11810 long now = SystemClock.uptimeMillis(); 11811 pw.print(" mLastIdleTime="); 11812 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11813 pw.print(" mLowRamSinceLastIdle="); 11814 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11815 pw.println(); 11816 } 11817 } 11818 11819 if (!printedAnything) { 11820 pw.println(" (nothing)"); 11821 } 11822 } 11823 11824 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11825 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11826 if (mProcessesToGc.size() > 0) { 11827 boolean printed = false; 11828 long now = SystemClock.uptimeMillis(); 11829 for (int i=0; i<mProcessesToGc.size(); i++) { 11830 ProcessRecord proc = mProcessesToGc.get(i); 11831 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11832 continue; 11833 } 11834 if (!printed) { 11835 if (needSep) pw.println(); 11836 needSep = true; 11837 pw.println(" Processes that are waiting to GC:"); 11838 printed = true; 11839 } 11840 pw.print(" Process "); pw.println(proc); 11841 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11842 pw.print(", last gced="); 11843 pw.print(now-proc.lastRequestedGc); 11844 pw.print(" ms ago, last lowMem="); 11845 pw.print(now-proc.lastLowMemory); 11846 pw.println(" ms ago"); 11847 11848 } 11849 } 11850 return needSep; 11851 } 11852 11853 void printOomLevel(PrintWriter pw, String name, int adj) { 11854 pw.print(" "); 11855 if (adj >= 0) { 11856 pw.print(' '); 11857 if (adj < 10) pw.print(' '); 11858 } else { 11859 if (adj > -10) pw.print(' '); 11860 } 11861 pw.print(adj); 11862 pw.print(": "); 11863 pw.print(name); 11864 pw.print(" ("); 11865 pw.print(mProcessList.getMemLevel(adj)/1024); 11866 pw.println(" kB)"); 11867 } 11868 11869 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11870 int opti, boolean dumpAll) { 11871 boolean needSep = false; 11872 11873 if (mLruProcesses.size() > 0) { 11874 if (needSep) pw.println(); 11875 needSep = true; 11876 pw.println(" OOM levels:"); 11877 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11878 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11879 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11880 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11881 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11882 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11883 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11884 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11885 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11886 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11887 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11888 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11889 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11890 11891 if (needSep) pw.println(); 11892 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11893 pw.print(" total, non-act at "); 11894 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11895 pw.print(", non-svc at "); 11896 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11897 pw.println("):"); 11898 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11899 needSep = true; 11900 } 11901 11902 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11903 11904 pw.println(); 11905 pw.println(" mHomeProcess: " + mHomeProcess); 11906 pw.println(" mPreviousProcess: " + mPreviousProcess); 11907 if (mHeavyWeightProcess != null) { 11908 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11909 } 11910 11911 return true; 11912 } 11913 11914 /** 11915 * There are three ways to call this: 11916 * - no provider specified: dump all the providers 11917 * - a flattened component name that matched an existing provider was specified as the 11918 * first arg: dump that one provider 11919 * - the first arg isn't the flattened component name of an existing provider: 11920 * dump all providers whose component contains the first arg as a substring 11921 */ 11922 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11923 int opti, boolean dumpAll) { 11924 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11925 } 11926 11927 static class ItemMatcher { 11928 ArrayList<ComponentName> components; 11929 ArrayList<String> strings; 11930 ArrayList<Integer> objects; 11931 boolean all; 11932 11933 ItemMatcher() { 11934 all = true; 11935 } 11936 11937 void build(String name) { 11938 ComponentName componentName = ComponentName.unflattenFromString(name); 11939 if (componentName != null) { 11940 if (components == null) { 11941 components = new ArrayList<ComponentName>(); 11942 } 11943 components.add(componentName); 11944 all = false; 11945 } else { 11946 int objectId = 0; 11947 // Not a '/' separated full component name; maybe an object ID? 11948 try { 11949 objectId = Integer.parseInt(name, 16); 11950 if (objects == null) { 11951 objects = new ArrayList<Integer>(); 11952 } 11953 objects.add(objectId); 11954 all = false; 11955 } catch (RuntimeException e) { 11956 // Not an integer; just do string match. 11957 if (strings == null) { 11958 strings = new ArrayList<String>(); 11959 } 11960 strings.add(name); 11961 all = false; 11962 } 11963 } 11964 } 11965 11966 int build(String[] args, int opti) { 11967 for (; opti<args.length; opti++) { 11968 String name = args[opti]; 11969 if ("--".equals(name)) { 11970 return opti+1; 11971 } 11972 build(name); 11973 } 11974 return opti; 11975 } 11976 11977 boolean match(Object object, ComponentName comp) { 11978 if (all) { 11979 return true; 11980 } 11981 if (components != null) { 11982 for (int i=0; i<components.size(); i++) { 11983 if (components.get(i).equals(comp)) { 11984 return true; 11985 } 11986 } 11987 } 11988 if (objects != null) { 11989 for (int i=0; i<objects.size(); i++) { 11990 if (System.identityHashCode(object) == objects.get(i)) { 11991 return true; 11992 } 11993 } 11994 } 11995 if (strings != null) { 11996 String flat = comp.flattenToString(); 11997 for (int i=0; i<strings.size(); i++) { 11998 if (flat.contains(strings.get(i))) { 11999 return true; 12000 } 12001 } 12002 } 12003 return false; 12004 } 12005 } 12006 12007 /** 12008 * There are three things that cmd can be: 12009 * - a flattened component name that matches an existing activity 12010 * - the cmd arg isn't the flattened component name of an existing activity: 12011 * dump all activity whose component contains the cmd as a substring 12012 * - A hex number of the ActivityRecord object instance. 12013 */ 12014 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12015 int opti, boolean dumpAll) { 12016 ArrayList<ActivityRecord> activities; 12017 12018 synchronized (this) { 12019 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12020 } 12021 12022 if (activities.size() <= 0) { 12023 return false; 12024 } 12025 12026 String[] newArgs = new String[args.length - opti]; 12027 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12028 12029 TaskRecord lastTask = null; 12030 boolean needSep = false; 12031 for (int i=activities.size()-1; i>=0; i--) { 12032 ActivityRecord r = activities.get(i); 12033 if (needSep) { 12034 pw.println(); 12035 } 12036 needSep = true; 12037 synchronized (this) { 12038 if (lastTask != r.task) { 12039 lastTask = r.task; 12040 pw.print("TASK "); pw.print(lastTask.affinity); 12041 pw.print(" id="); pw.println(lastTask.taskId); 12042 if (dumpAll) { 12043 lastTask.dump(pw, " "); 12044 } 12045 } 12046 } 12047 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12048 } 12049 return true; 12050 } 12051 12052 /** 12053 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12054 * there is a thread associated with the activity. 12055 */ 12056 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12057 final ActivityRecord r, String[] args, boolean dumpAll) { 12058 String innerPrefix = prefix + " "; 12059 synchronized (this) { 12060 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12061 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12062 pw.print(" pid="); 12063 if (r.app != null) pw.println(r.app.pid); 12064 else pw.println("(not running)"); 12065 if (dumpAll) { 12066 r.dump(pw, innerPrefix); 12067 } 12068 } 12069 if (r.app != null && r.app.thread != null) { 12070 // flush anything that is already in the PrintWriter since the thread is going 12071 // to write to the file descriptor directly 12072 pw.flush(); 12073 try { 12074 TransferPipe tp = new TransferPipe(); 12075 try { 12076 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12077 r.appToken, innerPrefix, args); 12078 tp.go(fd); 12079 } finally { 12080 tp.kill(); 12081 } 12082 } catch (IOException e) { 12083 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12084 } catch (RemoteException e) { 12085 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12086 } 12087 } 12088 } 12089 12090 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12091 int opti, boolean dumpAll, String dumpPackage) { 12092 boolean needSep = false; 12093 boolean onlyHistory = false; 12094 boolean printedAnything = false; 12095 12096 if ("history".equals(dumpPackage)) { 12097 if (opti < args.length && "-s".equals(args[opti])) { 12098 dumpAll = false; 12099 } 12100 onlyHistory = true; 12101 dumpPackage = null; 12102 } 12103 12104 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12105 if (!onlyHistory && dumpAll) { 12106 if (mRegisteredReceivers.size() > 0) { 12107 boolean printed = false; 12108 Iterator it = mRegisteredReceivers.values().iterator(); 12109 while (it.hasNext()) { 12110 ReceiverList r = (ReceiverList)it.next(); 12111 if (dumpPackage != null && (r.app == null || 12112 !dumpPackage.equals(r.app.info.packageName))) { 12113 continue; 12114 } 12115 if (!printed) { 12116 pw.println(" Registered Receivers:"); 12117 needSep = true; 12118 printed = true; 12119 printedAnything = true; 12120 } 12121 pw.print(" * "); pw.println(r); 12122 r.dump(pw, " "); 12123 } 12124 } 12125 12126 if (mReceiverResolver.dump(pw, needSep ? 12127 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12128 " ", dumpPackage, false)) { 12129 needSep = true; 12130 printedAnything = true; 12131 } 12132 } 12133 12134 for (BroadcastQueue q : mBroadcastQueues) { 12135 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12136 printedAnything |= needSep; 12137 } 12138 12139 needSep = true; 12140 12141 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12142 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12143 if (needSep) { 12144 pw.println(); 12145 } 12146 needSep = true; 12147 printedAnything = true; 12148 pw.print(" Sticky broadcasts for user "); 12149 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12150 StringBuilder sb = new StringBuilder(128); 12151 for (Map.Entry<String, ArrayList<Intent>> ent 12152 : mStickyBroadcasts.valueAt(user).entrySet()) { 12153 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12154 if (dumpAll) { 12155 pw.println(":"); 12156 ArrayList<Intent> intents = ent.getValue(); 12157 final int N = intents.size(); 12158 for (int i=0; i<N; i++) { 12159 sb.setLength(0); 12160 sb.append(" Intent: "); 12161 intents.get(i).toShortString(sb, false, true, false, false); 12162 pw.println(sb.toString()); 12163 Bundle bundle = intents.get(i).getExtras(); 12164 if (bundle != null) { 12165 pw.print(" "); 12166 pw.println(bundle.toString()); 12167 } 12168 } 12169 } else { 12170 pw.println(""); 12171 } 12172 } 12173 } 12174 } 12175 12176 if (!onlyHistory && dumpAll) { 12177 pw.println(); 12178 for (BroadcastQueue queue : mBroadcastQueues) { 12179 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12180 + queue.mBroadcastsScheduled); 12181 } 12182 pw.println(" mHandler:"); 12183 mHandler.dump(new PrintWriterPrinter(pw), " "); 12184 needSep = true; 12185 printedAnything = true; 12186 } 12187 12188 if (!printedAnything) { 12189 pw.println(" (nothing)"); 12190 } 12191 } 12192 12193 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12194 int opti, boolean dumpAll, String dumpPackage) { 12195 boolean needSep; 12196 boolean printedAnything = false; 12197 12198 ItemMatcher matcher = new ItemMatcher(); 12199 matcher.build(args, opti); 12200 12201 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12202 12203 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12204 printedAnything |= needSep; 12205 12206 if (mLaunchingProviders.size() > 0) { 12207 boolean printed = false; 12208 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12209 ContentProviderRecord r = mLaunchingProviders.get(i); 12210 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12211 continue; 12212 } 12213 if (!printed) { 12214 if (needSep) pw.println(); 12215 needSep = true; 12216 pw.println(" Launching content providers:"); 12217 printed = true; 12218 printedAnything = true; 12219 } 12220 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12221 pw.println(r); 12222 } 12223 } 12224 12225 if (mGrantedUriPermissions.size() > 0) { 12226 boolean printed = false; 12227 int dumpUid = -2; 12228 if (dumpPackage != null) { 12229 try { 12230 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12231 } catch (NameNotFoundException e) { 12232 dumpUid = -1; 12233 } 12234 } 12235 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12236 int uid = mGrantedUriPermissions.keyAt(i); 12237 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12238 continue; 12239 } 12240 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12241 if (!printed) { 12242 if (needSep) pw.println(); 12243 needSep = true; 12244 pw.println(" Granted Uri Permissions:"); 12245 printed = true; 12246 printedAnything = true; 12247 } 12248 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12249 for (UriPermission perm : perms.values()) { 12250 pw.print(" "); pw.println(perm); 12251 if (dumpAll) { 12252 perm.dump(pw, " "); 12253 } 12254 } 12255 } 12256 } 12257 12258 if (!printedAnything) { 12259 pw.println(" (nothing)"); 12260 } 12261 } 12262 12263 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12264 int opti, boolean dumpAll, String dumpPackage) { 12265 boolean printed = false; 12266 12267 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12268 12269 if (mIntentSenderRecords.size() > 0) { 12270 Iterator<WeakReference<PendingIntentRecord>> it 12271 = mIntentSenderRecords.values().iterator(); 12272 while (it.hasNext()) { 12273 WeakReference<PendingIntentRecord> ref = it.next(); 12274 PendingIntentRecord rec = ref != null ? ref.get(): null; 12275 if (dumpPackage != null && (rec == null 12276 || !dumpPackage.equals(rec.key.packageName))) { 12277 continue; 12278 } 12279 printed = true; 12280 if (rec != null) { 12281 pw.print(" * "); pw.println(rec); 12282 if (dumpAll) { 12283 rec.dump(pw, " "); 12284 } 12285 } else { 12286 pw.print(" * "); pw.println(ref); 12287 } 12288 } 12289 } 12290 12291 if (!printed) { 12292 pw.println(" (nothing)"); 12293 } 12294 } 12295 12296 private static final int dumpProcessList(PrintWriter pw, 12297 ActivityManagerService service, List list, 12298 String prefix, String normalLabel, String persistentLabel, 12299 String dumpPackage) { 12300 int numPers = 0; 12301 final int N = list.size()-1; 12302 for (int i=N; i>=0; i--) { 12303 ProcessRecord r = (ProcessRecord)list.get(i); 12304 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12305 continue; 12306 } 12307 pw.println(String.format("%s%s #%2d: %s", 12308 prefix, (r.persistent ? persistentLabel : normalLabel), 12309 i, r.toString())); 12310 if (r.persistent) { 12311 numPers++; 12312 } 12313 } 12314 return numPers; 12315 } 12316 12317 private static final boolean dumpProcessOomList(PrintWriter pw, 12318 ActivityManagerService service, List<ProcessRecord> origList, 12319 String prefix, String normalLabel, String persistentLabel, 12320 boolean inclDetails, String dumpPackage) { 12321 12322 ArrayList<Pair<ProcessRecord, Integer>> list 12323 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12324 for (int i=0; i<origList.size(); i++) { 12325 ProcessRecord r = origList.get(i); 12326 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12327 continue; 12328 } 12329 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12330 } 12331 12332 if (list.size() <= 0) { 12333 return false; 12334 } 12335 12336 Comparator<Pair<ProcessRecord, Integer>> comparator 12337 = new Comparator<Pair<ProcessRecord, Integer>>() { 12338 @Override 12339 public int compare(Pair<ProcessRecord, Integer> object1, 12340 Pair<ProcessRecord, Integer> object2) { 12341 if (object1.first.setAdj != object2.first.setAdj) { 12342 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12343 } 12344 if (object1.second.intValue() != object2.second.intValue()) { 12345 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12346 } 12347 return 0; 12348 } 12349 }; 12350 12351 Collections.sort(list, comparator); 12352 12353 final long curRealtime = SystemClock.elapsedRealtime(); 12354 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12355 final long curUptime = SystemClock.uptimeMillis(); 12356 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12357 12358 for (int i=list.size()-1; i>=0; i--) { 12359 ProcessRecord r = list.get(i).first; 12360 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12361 char schedGroup; 12362 switch (r.setSchedGroup) { 12363 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12364 schedGroup = 'B'; 12365 break; 12366 case Process.THREAD_GROUP_DEFAULT: 12367 schedGroup = 'F'; 12368 break; 12369 default: 12370 schedGroup = '?'; 12371 break; 12372 } 12373 char foreground; 12374 if (r.foregroundActivities) { 12375 foreground = 'A'; 12376 } else if (r.foregroundServices) { 12377 foreground = 'S'; 12378 } else { 12379 foreground = ' '; 12380 } 12381 String procState = ProcessList.makeProcStateString(r.curProcState); 12382 pw.print(prefix); 12383 pw.print(r.persistent ? persistentLabel : normalLabel); 12384 pw.print(" #"); 12385 int num = (origList.size()-1)-list.get(i).second; 12386 if (num < 10) pw.print(' '); 12387 pw.print(num); 12388 pw.print(": "); 12389 pw.print(oomAdj); 12390 pw.print(' '); 12391 pw.print(schedGroup); 12392 pw.print('/'); 12393 pw.print(foreground); 12394 pw.print('/'); 12395 pw.print(procState); 12396 pw.print(" trm:"); 12397 if (r.trimMemoryLevel < 10) pw.print(' '); 12398 pw.print(r.trimMemoryLevel); 12399 pw.print(' '); 12400 pw.print(r.toShortString()); 12401 pw.print(" ("); 12402 pw.print(r.adjType); 12403 pw.println(')'); 12404 if (r.adjSource != null || r.adjTarget != null) { 12405 pw.print(prefix); 12406 pw.print(" "); 12407 if (r.adjTarget instanceof ComponentName) { 12408 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12409 } else if (r.adjTarget != null) { 12410 pw.print(r.adjTarget.toString()); 12411 } else { 12412 pw.print("{null}"); 12413 } 12414 pw.print("<="); 12415 if (r.adjSource instanceof ProcessRecord) { 12416 pw.print("Proc{"); 12417 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12418 pw.println("}"); 12419 } else if (r.adjSource != null) { 12420 pw.println(r.adjSource.toString()); 12421 } else { 12422 pw.println("{null}"); 12423 } 12424 } 12425 if (inclDetails) { 12426 pw.print(prefix); 12427 pw.print(" "); 12428 pw.print("oom: max="); pw.print(r.maxAdj); 12429 pw.print(" curRaw="); pw.print(r.curRawAdj); 12430 pw.print(" setRaw="); pw.print(r.setRawAdj); 12431 pw.print(" cur="); pw.print(r.curAdj); 12432 pw.print(" set="); pw.println(r.setAdj); 12433 pw.print(prefix); 12434 pw.print(" "); 12435 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12436 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12437 pw.print(" lastPss="); pw.print(r.lastPss); 12438 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12439 pw.print(prefix); 12440 pw.print(" "); 12441 pw.print("cached="); pw.print(r.cached); 12442 pw.print(" empty="); pw.print(r.empty); 12443 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12444 12445 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12446 if (r.lastWakeTime != 0) { 12447 long wtime; 12448 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12449 synchronized (stats) { 12450 wtime = stats.getProcessWakeTime(r.info.uid, 12451 r.pid, curRealtime); 12452 } 12453 long timeUsed = wtime - r.lastWakeTime; 12454 pw.print(prefix); 12455 pw.print(" "); 12456 pw.print("keep awake over "); 12457 TimeUtils.formatDuration(realtimeSince, pw); 12458 pw.print(" used "); 12459 TimeUtils.formatDuration(timeUsed, pw); 12460 pw.print(" ("); 12461 pw.print((timeUsed*100)/realtimeSince); 12462 pw.println("%)"); 12463 } 12464 if (r.lastCpuTime != 0) { 12465 long timeUsed = r.curCpuTime - r.lastCpuTime; 12466 pw.print(prefix); 12467 pw.print(" "); 12468 pw.print("run cpu over "); 12469 TimeUtils.formatDuration(uptimeSince, pw); 12470 pw.print(" used "); 12471 TimeUtils.formatDuration(timeUsed, pw); 12472 pw.print(" ("); 12473 pw.print((timeUsed*100)/uptimeSince); 12474 pw.println("%)"); 12475 } 12476 } 12477 } 12478 } 12479 return true; 12480 } 12481 12482 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12483 ArrayList<ProcessRecord> procs; 12484 synchronized (this) { 12485 if (args != null && args.length > start 12486 && args[start].charAt(0) != '-') { 12487 procs = new ArrayList<ProcessRecord>(); 12488 int pid = -1; 12489 try { 12490 pid = Integer.parseInt(args[start]); 12491 } catch (NumberFormatException e) { 12492 } 12493 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12494 ProcessRecord proc = mLruProcesses.get(i); 12495 if (proc.pid == pid) { 12496 procs.add(proc); 12497 } else if (proc.processName.equals(args[start])) { 12498 procs.add(proc); 12499 } 12500 } 12501 if (procs.size() <= 0) { 12502 return null; 12503 } 12504 } else { 12505 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12506 } 12507 } 12508 return procs; 12509 } 12510 12511 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12512 PrintWriter pw, String[] args) { 12513 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12514 if (procs == null) { 12515 pw.println("No process found for: " + args[0]); 12516 return; 12517 } 12518 12519 long uptime = SystemClock.uptimeMillis(); 12520 long realtime = SystemClock.elapsedRealtime(); 12521 pw.println("Applications Graphics Acceleration Info:"); 12522 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12523 12524 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12525 ProcessRecord r = procs.get(i); 12526 if (r.thread != null) { 12527 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12528 pw.flush(); 12529 try { 12530 TransferPipe tp = new TransferPipe(); 12531 try { 12532 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12533 tp.go(fd); 12534 } finally { 12535 tp.kill(); 12536 } 12537 } catch (IOException e) { 12538 pw.println("Failure while dumping the app: " + r); 12539 pw.flush(); 12540 } catch (RemoteException e) { 12541 pw.println("Got a RemoteException while dumping the app " + r); 12542 pw.flush(); 12543 } 12544 } 12545 } 12546 } 12547 12548 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12549 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12550 if (procs == null) { 12551 pw.println("No process found for: " + args[0]); 12552 return; 12553 } 12554 12555 pw.println("Applications Database Info:"); 12556 12557 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12558 ProcessRecord r = procs.get(i); 12559 if (r.thread != null) { 12560 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12561 pw.flush(); 12562 try { 12563 TransferPipe tp = new TransferPipe(); 12564 try { 12565 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12566 tp.go(fd); 12567 } finally { 12568 tp.kill(); 12569 } 12570 } catch (IOException e) { 12571 pw.println("Failure while dumping the app: " + r); 12572 pw.flush(); 12573 } catch (RemoteException e) { 12574 pw.println("Got a RemoteException while dumping the app " + r); 12575 pw.flush(); 12576 } 12577 } 12578 } 12579 } 12580 12581 final static class MemItem { 12582 final boolean isProc; 12583 final String label; 12584 final String shortLabel; 12585 final long pss; 12586 final int id; 12587 final boolean hasActivities; 12588 ArrayList<MemItem> subitems; 12589 12590 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12591 boolean _hasActivities) { 12592 isProc = true; 12593 label = _label; 12594 shortLabel = _shortLabel; 12595 pss = _pss; 12596 id = _id; 12597 hasActivities = _hasActivities; 12598 } 12599 12600 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12601 isProc = false; 12602 label = _label; 12603 shortLabel = _shortLabel; 12604 pss = _pss; 12605 id = _id; 12606 hasActivities = false; 12607 } 12608 } 12609 12610 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12611 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12612 if (sort && !isCompact) { 12613 Collections.sort(items, new Comparator<MemItem>() { 12614 @Override 12615 public int compare(MemItem lhs, MemItem rhs) { 12616 if (lhs.pss < rhs.pss) { 12617 return 1; 12618 } else if (lhs.pss > rhs.pss) { 12619 return -1; 12620 } 12621 return 0; 12622 } 12623 }); 12624 } 12625 12626 for (int i=0; i<items.size(); i++) { 12627 MemItem mi = items.get(i); 12628 if (!isCompact) { 12629 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12630 } else if (mi.isProc) { 12631 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12632 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12633 pw.println(mi.hasActivities ? ",a" : ",e"); 12634 } else { 12635 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12636 pw.println(mi.pss); 12637 } 12638 if (mi.subitems != null) { 12639 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12640 true, isCompact); 12641 } 12642 } 12643 } 12644 12645 // These are in KB. 12646 static final long[] DUMP_MEM_BUCKETS = new long[] { 12647 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12648 120*1024, 160*1024, 200*1024, 12649 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12650 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12651 }; 12652 12653 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12654 boolean stackLike) { 12655 int start = label.lastIndexOf('.'); 12656 if (start >= 0) start++; 12657 else start = 0; 12658 int end = label.length(); 12659 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12660 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12661 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12662 out.append(bucket); 12663 out.append(stackLike ? "MB." : "MB "); 12664 out.append(label, start, end); 12665 return; 12666 } 12667 } 12668 out.append(memKB/1024); 12669 out.append(stackLike ? "MB." : "MB "); 12670 out.append(label, start, end); 12671 } 12672 12673 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12674 ProcessList.NATIVE_ADJ, 12675 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12676 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12677 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12678 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12679 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12680 }; 12681 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12682 "Native", 12683 "System", "Persistent", "Foreground", 12684 "Visible", "Perceptible", 12685 "Heavy Weight", "Backup", 12686 "A Services", "Home", 12687 "Previous", "B Services", "Cached" 12688 }; 12689 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12690 "native", 12691 "sys", "pers", "fore", 12692 "vis", "percept", 12693 "heavy", "backup", 12694 "servicea", "home", 12695 "prev", "serviceb", "cached" 12696 }; 12697 12698 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12699 long realtime, boolean isCheckinRequest, boolean isCompact) { 12700 if (isCheckinRequest || isCompact) { 12701 // short checkin version 12702 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12703 } else { 12704 pw.println("Applications Memory Usage (kB):"); 12705 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12706 } 12707 } 12708 12709 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12710 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12711 boolean dumpDetails = false; 12712 boolean dumpFullDetails = false; 12713 boolean dumpDalvik = false; 12714 boolean oomOnly = false; 12715 boolean isCompact = false; 12716 boolean localOnly = false; 12717 12718 int opti = 0; 12719 while (opti < args.length) { 12720 String opt = args[opti]; 12721 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12722 break; 12723 } 12724 opti++; 12725 if ("-a".equals(opt)) { 12726 dumpDetails = true; 12727 dumpFullDetails = true; 12728 dumpDalvik = true; 12729 } else if ("-d".equals(opt)) { 12730 dumpDalvik = true; 12731 } else if ("-c".equals(opt)) { 12732 isCompact = true; 12733 } else if ("--oom".equals(opt)) { 12734 oomOnly = true; 12735 } else if ("--local".equals(opt)) { 12736 localOnly = true; 12737 } else if ("-h".equals(opt)) { 12738 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12739 pw.println(" -a: include all available information for each process."); 12740 pw.println(" -d: include dalvik details when dumping process details."); 12741 pw.println(" -c: dump in a compact machine-parseable representation."); 12742 pw.println(" --oom: only show processes organized by oom adj."); 12743 pw.println(" --local: only collect details locally, don't call process."); 12744 pw.println("If [process] is specified it can be the name or "); 12745 pw.println("pid of a specific process to dump."); 12746 return; 12747 } else { 12748 pw.println("Unknown argument: " + opt + "; use -h for help"); 12749 } 12750 } 12751 12752 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12753 long uptime = SystemClock.uptimeMillis(); 12754 long realtime = SystemClock.elapsedRealtime(); 12755 final long[] tmpLong = new long[1]; 12756 12757 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12758 if (procs == null) { 12759 // No Java processes. Maybe they want to print a native process. 12760 if (args != null && args.length > opti 12761 && args[opti].charAt(0) != '-') { 12762 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12763 = new ArrayList<ProcessCpuTracker.Stats>(); 12764 updateCpuStatsNow(); 12765 int findPid = -1; 12766 try { 12767 findPid = Integer.parseInt(args[opti]); 12768 } catch (NumberFormatException e) { 12769 } 12770 synchronized (mProcessCpuThread) { 12771 final int N = mProcessCpuTracker.countStats(); 12772 for (int i=0; i<N; i++) { 12773 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12774 if (st.pid == findPid || (st.baseName != null 12775 && st.baseName.equals(args[opti]))) { 12776 nativeProcs.add(st); 12777 } 12778 } 12779 } 12780 if (nativeProcs.size() > 0) { 12781 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12782 isCompact); 12783 Debug.MemoryInfo mi = null; 12784 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12785 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12786 final int pid = r.pid; 12787 if (!isCheckinRequest && dumpDetails) { 12788 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12789 } 12790 if (mi == null) { 12791 mi = new Debug.MemoryInfo(); 12792 } 12793 if (dumpDetails || (!brief && !oomOnly)) { 12794 Debug.getMemoryInfo(pid, mi); 12795 } else { 12796 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12797 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12798 } 12799 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12800 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12801 if (isCheckinRequest) { 12802 pw.println(); 12803 } 12804 } 12805 return; 12806 } 12807 } 12808 pw.println("No process found for: " + args[opti]); 12809 return; 12810 } 12811 12812 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12813 dumpDetails = true; 12814 } 12815 12816 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12817 12818 String[] innerArgs = new String[args.length-opti]; 12819 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12820 12821 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12822 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12823 long nativePss=0, dalvikPss=0, otherPss=0; 12824 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12825 12826 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12827 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12828 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12829 12830 long totalPss = 0; 12831 long cachedPss = 0; 12832 12833 Debug.MemoryInfo mi = null; 12834 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12835 final ProcessRecord r = procs.get(i); 12836 final IApplicationThread thread; 12837 final int pid; 12838 final int oomAdj; 12839 final boolean hasActivities; 12840 synchronized (this) { 12841 thread = r.thread; 12842 pid = r.pid; 12843 oomAdj = r.getSetAdjWithServices(); 12844 hasActivities = r.activities.size() > 0; 12845 } 12846 if (thread != null) { 12847 if (!isCheckinRequest && dumpDetails) { 12848 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12849 } 12850 if (mi == null) { 12851 mi = new Debug.MemoryInfo(); 12852 } 12853 if (dumpDetails || (!brief && !oomOnly)) { 12854 Debug.getMemoryInfo(pid, mi); 12855 } else { 12856 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12857 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12858 } 12859 if (dumpDetails) { 12860 if (localOnly) { 12861 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12862 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12863 if (isCheckinRequest) { 12864 pw.println(); 12865 } 12866 } else { 12867 try { 12868 pw.flush(); 12869 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12870 dumpDalvik, innerArgs); 12871 } catch (RemoteException e) { 12872 if (!isCheckinRequest) { 12873 pw.println("Got RemoteException!"); 12874 pw.flush(); 12875 } 12876 } 12877 } 12878 } 12879 12880 final long myTotalPss = mi.getTotalPss(); 12881 final long myTotalUss = mi.getTotalUss(); 12882 12883 synchronized (this) { 12884 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12885 // Record this for posterity if the process has been stable. 12886 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12887 } 12888 } 12889 12890 if (!isCheckinRequest && mi != null) { 12891 totalPss += myTotalPss; 12892 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12893 (hasActivities ? " / activities)" : ")"), 12894 r.processName, myTotalPss, pid, hasActivities); 12895 procMems.add(pssItem); 12896 procMemsMap.put(pid, pssItem); 12897 12898 nativePss += mi.nativePss; 12899 dalvikPss += mi.dalvikPss; 12900 otherPss += mi.otherPss; 12901 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12902 long mem = mi.getOtherPss(j); 12903 miscPss[j] += mem; 12904 otherPss -= mem; 12905 } 12906 12907 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12908 cachedPss += myTotalPss; 12909 } 12910 12911 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12912 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12913 || oomIndex == (oomPss.length-1)) { 12914 oomPss[oomIndex] += myTotalPss; 12915 if (oomProcs[oomIndex] == null) { 12916 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12917 } 12918 oomProcs[oomIndex].add(pssItem); 12919 break; 12920 } 12921 } 12922 } 12923 } 12924 } 12925 12926 long nativeProcTotalPss = 0; 12927 12928 if (!isCheckinRequest && procs.size() > 1) { 12929 // If we are showing aggregations, also look for native processes to 12930 // include so that our aggregations are more accurate. 12931 updateCpuStatsNow(); 12932 synchronized (mProcessCpuThread) { 12933 final int N = mProcessCpuTracker.countStats(); 12934 for (int i=0; i<N; i++) { 12935 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12936 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12937 if (mi == null) { 12938 mi = new Debug.MemoryInfo(); 12939 } 12940 if (!brief && !oomOnly) { 12941 Debug.getMemoryInfo(st.pid, mi); 12942 } else { 12943 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12944 mi.nativePrivateDirty = (int)tmpLong[0]; 12945 } 12946 12947 final long myTotalPss = mi.getTotalPss(); 12948 totalPss += myTotalPss; 12949 nativeProcTotalPss += myTotalPss; 12950 12951 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12952 st.name, myTotalPss, st.pid, false); 12953 procMems.add(pssItem); 12954 12955 nativePss += mi.nativePss; 12956 dalvikPss += mi.dalvikPss; 12957 otherPss += mi.otherPss; 12958 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12959 long mem = mi.getOtherPss(j); 12960 miscPss[j] += mem; 12961 otherPss -= mem; 12962 } 12963 oomPss[0] += myTotalPss; 12964 if (oomProcs[0] == null) { 12965 oomProcs[0] = new ArrayList<MemItem>(); 12966 } 12967 oomProcs[0].add(pssItem); 12968 } 12969 } 12970 } 12971 12972 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12973 12974 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12975 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12976 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12977 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12978 String label = Debug.MemoryInfo.getOtherLabel(j); 12979 catMems.add(new MemItem(label, label, miscPss[j], j)); 12980 } 12981 12982 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12983 for (int j=0; j<oomPss.length; j++) { 12984 if (oomPss[j] != 0) { 12985 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12986 : DUMP_MEM_OOM_LABEL[j]; 12987 MemItem item = new MemItem(label, label, oomPss[j], 12988 DUMP_MEM_OOM_ADJ[j]); 12989 item.subitems = oomProcs[j]; 12990 oomMems.add(item); 12991 } 12992 } 12993 12994 if (!brief && !oomOnly && !isCompact) { 12995 pw.println(); 12996 pw.println("Total PSS by process:"); 12997 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12998 pw.println(); 12999 } 13000 if (!isCompact) { 13001 pw.println("Total PSS by OOM adjustment:"); 13002 } 13003 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13004 if (!brief && !oomOnly) { 13005 PrintWriter out = categoryPw != null ? categoryPw : pw; 13006 if (!isCompact) { 13007 out.println(); 13008 out.println("Total PSS by category:"); 13009 } 13010 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13011 } 13012 if (!isCompact) { 13013 pw.println(); 13014 } 13015 MemInfoReader memInfo = new MemInfoReader(); 13016 memInfo.readMemInfo(); 13017 if (nativeProcTotalPss > 0) { 13018 synchronized (this) { 13019 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13020 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13021 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13022 nativeProcTotalPss); 13023 } 13024 } 13025 if (!brief) { 13026 if (!isCompact) { 13027 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13028 pw.print(" kB (status "); 13029 switch (mLastMemoryLevel) { 13030 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13031 pw.println("normal)"); 13032 break; 13033 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13034 pw.println("moderate)"); 13035 break; 13036 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13037 pw.println("low)"); 13038 break; 13039 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13040 pw.println("critical)"); 13041 break; 13042 default: 13043 pw.print(mLastMemoryLevel); 13044 pw.println(")"); 13045 break; 13046 } 13047 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13048 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13049 pw.print(cachedPss); pw.print(" cached pss + "); 13050 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13051 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13052 } else { 13053 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13054 pw.print(cachedPss + memInfo.getCachedSizeKb() 13055 + memInfo.getFreeSizeKb()); pw.print(","); 13056 pw.println(totalPss - cachedPss); 13057 } 13058 } 13059 if (!isCompact) { 13060 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13061 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13062 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13063 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13064 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13065 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13066 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13067 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13068 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13069 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13070 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13071 } 13072 if (!brief) { 13073 if (memInfo.getZramTotalSizeKb() != 0) { 13074 if (!isCompact) { 13075 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13076 pw.print(" kB physical used for "); 13077 pw.print(memInfo.getSwapTotalSizeKb() 13078 - memInfo.getSwapFreeSizeKb()); 13079 pw.print(" kB in swap ("); 13080 pw.print(memInfo.getSwapTotalSizeKb()); 13081 pw.println(" kB total swap)"); 13082 } else { 13083 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13084 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13085 pw.println(memInfo.getSwapFreeSizeKb()); 13086 } 13087 } 13088 final int[] SINGLE_LONG_FORMAT = new int[] { 13089 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13090 }; 13091 long[] longOut = new long[1]; 13092 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13093 SINGLE_LONG_FORMAT, null, longOut, null); 13094 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13095 longOut[0] = 0; 13096 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13097 SINGLE_LONG_FORMAT, null, longOut, null); 13098 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13099 longOut[0] = 0; 13100 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13101 SINGLE_LONG_FORMAT, null, longOut, null); 13102 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13103 longOut[0] = 0; 13104 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13105 SINGLE_LONG_FORMAT, null, longOut, null); 13106 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13107 if (!isCompact) { 13108 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13109 pw.print(" KSM: "); pw.print(sharing); 13110 pw.print(" kB saved from shared "); 13111 pw.print(shared); pw.println(" kB"); 13112 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13113 pw.print(voltile); pw.println(" kB volatile"); 13114 } 13115 pw.print(" Tuning: "); 13116 pw.print(ActivityManager.staticGetMemoryClass()); 13117 pw.print(" (large "); 13118 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13119 pw.print("), oom "); 13120 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13121 pw.print(" kB"); 13122 pw.print(", restore limit "); 13123 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13124 pw.print(" kB"); 13125 if (ActivityManager.isLowRamDeviceStatic()) { 13126 pw.print(" (low-ram)"); 13127 } 13128 if (ActivityManager.isHighEndGfx()) { 13129 pw.print(" (high-end-gfx)"); 13130 } 13131 pw.println(); 13132 } else { 13133 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13134 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13135 pw.println(voltile); 13136 pw.print("tuning,"); 13137 pw.print(ActivityManager.staticGetMemoryClass()); 13138 pw.print(','); 13139 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13140 pw.print(','); 13141 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13142 if (ActivityManager.isLowRamDeviceStatic()) { 13143 pw.print(",low-ram"); 13144 } 13145 if (ActivityManager.isHighEndGfx()) { 13146 pw.print(",high-end-gfx"); 13147 } 13148 pw.println(); 13149 } 13150 } 13151 } 13152 } 13153 13154 /** 13155 * Searches array of arguments for the specified string 13156 * @param args array of argument strings 13157 * @param value value to search for 13158 * @return true if the value is contained in the array 13159 */ 13160 private static boolean scanArgs(String[] args, String value) { 13161 if (args != null) { 13162 for (String arg : args) { 13163 if (value.equals(arg)) { 13164 return true; 13165 } 13166 } 13167 } 13168 return false; 13169 } 13170 13171 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13172 ContentProviderRecord cpr, boolean always) { 13173 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13174 13175 if (!inLaunching || always) { 13176 synchronized (cpr) { 13177 cpr.launchingApp = null; 13178 cpr.notifyAll(); 13179 } 13180 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13181 String names[] = cpr.info.authority.split(";"); 13182 for (int j = 0; j < names.length; j++) { 13183 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13184 } 13185 } 13186 13187 for (int i=0; i<cpr.connections.size(); i++) { 13188 ContentProviderConnection conn = cpr.connections.get(i); 13189 if (conn.waiting) { 13190 // If this connection is waiting for the provider, then we don't 13191 // need to mess with its process unless we are always removing 13192 // or for some reason the provider is not currently launching. 13193 if (inLaunching && !always) { 13194 continue; 13195 } 13196 } 13197 ProcessRecord capp = conn.client; 13198 conn.dead = true; 13199 if (conn.stableCount > 0) { 13200 if (!capp.persistent && capp.thread != null 13201 && capp.pid != 0 13202 && capp.pid != MY_PID) { 13203 killUnneededProcessLocked(capp, "depends on provider " 13204 + cpr.name.flattenToShortString() 13205 + " in dying proc " + (proc != null ? proc.processName : "??")); 13206 } 13207 } else if (capp.thread != null && conn.provider.provider != null) { 13208 try { 13209 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13210 } catch (RemoteException e) { 13211 } 13212 // In the protocol here, we don't expect the client to correctly 13213 // clean up this connection, we'll just remove it. 13214 cpr.connections.remove(i); 13215 conn.client.conProviders.remove(conn); 13216 } 13217 } 13218 13219 if (inLaunching && always) { 13220 mLaunchingProviders.remove(cpr); 13221 } 13222 return inLaunching; 13223 } 13224 13225 /** 13226 * Main code for cleaning up a process when it has gone away. This is 13227 * called both as a result of the process dying, or directly when stopping 13228 * a process when running in single process mode. 13229 */ 13230 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13231 boolean restarting, boolean allowRestart, int index) { 13232 if (index >= 0) { 13233 removeLruProcessLocked(app); 13234 ProcessList.remove(app.pid); 13235 } 13236 13237 mProcessesToGc.remove(app); 13238 mPendingPssProcesses.remove(app); 13239 13240 // Dismiss any open dialogs. 13241 if (app.crashDialog != null && !app.forceCrashReport) { 13242 app.crashDialog.dismiss(); 13243 app.crashDialog = null; 13244 } 13245 if (app.anrDialog != null) { 13246 app.anrDialog.dismiss(); 13247 app.anrDialog = null; 13248 } 13249 if (app.waitDialog != null) { 13250 app.waitDialog.dismiss(); 13251 app.waitDialog = null; 13252 } 13253 13254 app.crashing = false; 13255 app.notResponding = false; 13256 13257 app.resetPackageList(mProcessStats); 13258 app.unlinkDeathRecipient(); 13259 app.makeInactive(mProcessStats); 13260 app.waitingToKill = null; 13261 app.forcingToForeground = null; 13262 updateProcessForegroundLocked(app, false, false); 13263 app.foregroundActivities = false; 13264 app.hasShownUi = false; 13265 app.treatLikeActivity = false; 13266 app.hasAboveClient = false; 13267 app.hasClientActivities = false; 13268 13269 mServices.killServicesLocked(app, allowRestart); 13270 13271 boolean restart = false; 13272 13273 // Remove published content providers. 13274 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13275 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13276 final boolean always = app.bad || !allowRestart; 13277 if (removeDyingProviderLocked(app, cpr, always) || always) { 13278 // We left the provider in the launching list, need to 13279 // restart it. 13280 restart = true; 13281 } 13282 13283 cpr.provider = null; 13284 cpr.proc = null; 13285 } 13286 app.pubProviders.clear(); 13287 13288 // Take care of any launching providers waiting for this process. 13289 if (checkAppInLaunchingProvidersLocked(app, false)) { 13290 restart = true; 13291 } 13292 13293 // Unregister from connected content providers. 13294 if (!app.conProviders.isEmpty()) { 13295 for (int i=0; i<app.conProviders.size(); i++) { 13296 ContentProviderConnection conn = app.conProviders.get(i); 13297 conn.provider.connections.remove(conn); 13298 } 13299 app.conProviders.clear(); 13300 } 13301 13302 // At this point there may be remaining entries in mLaunchingProviders 13303 // where we were the only one waiting, so they are no longer of use. 13304 // Look for these and clean up if found. 13305 // XXX Commented out for now. Trying to figure out a way to reproduce 13306 // the actual situation to identify what is actually going on. 13307 if (false) { 13308 for (int i=0; i<mLaunchingProviders.size(); i++) { 13309 ContentProviderRecord cpr = (ContentProviderRecord) 13310 mLaunchingProviders.get(i); 13311 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13312 synchronized (cpr) { 13313 cpr.launchingApp = null; 13314 cpr.notifyAll(); 13315 } 13316 } 13317 } 13318 } 13319 13320 skipCurrentReceiverLocked(app); 13321 13322 // Unregister any receivers. 13323 for (int i=app.receivers.size()-1; i>=0; i--) { 13324 removeReceiverLocked(app.receivers.valueAt(i)); 13325 } 13326 app.receivers.clear(); 13327 13328 // If the app is undergoing backup, tell the backup manager about it 13329 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13330 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13331 + mBackupTarget.appInfo + " died during backup"); 13332 try { 13333 IBackupManager bm = IBackupManager.Stub.asInterface( 13334 ServiceManager.getService(Context.BACKUP_SERVICE)); 13335 bm.agentDisconnected(app.info.packageName); 13336 } catch (RemoteException e) { 13337 // can't happen; backup manager is local 13338 } 13339 } 13340 13341 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13342 ProcessChangeItem item = mPendingProcessChanges.get(i); 13343 if (item.pid == app.pid) { 13344 mPendingProcessChanges.remove(i); 13345 mAvailProcessChanges.add(item); 13346 } 13347 } 13348 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13349 13350 // If the caller is restarting this app, then leave it in its 13351 // current lists and let the caller take care of it. 13352 if (restarting) { 13353 return; 13354 } 13355 13356 if (!app.persistent || app.isolated) { 13357 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13358 "Removing non-persistent process during cleanup: " + app); 13359 mProcessNames.remove(app.processName, app.uid); 13360 mIsolatedProcesses.remove(app.uid); 13361 if (mHeavyWeightProcess == app) { 13362 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13363 mHeavyWeightProcess.userId, 0)); 13364 mHeavyWeightProcess = null; 13365 } 13366 } else if (!app.removed) { 13367 // This app is persistent, so we need to keep its record around. 13368 // If it is not already on the pending app list, add it there 13369 // and start a new process for it. 13370 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13371 mPersistentStartingProcesses.add(app); 13372 restart = true; 13373 } 13374 } 13375 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13376 "Clean-up removing on hold: " + app); 13377 mProcessesOnHold.remove(app); 13378 13379 if (app == mHomeProcess) { 13380 mHomeProcess = null; 13381 } 13382 if (app == mPreviousProcess) { 13383 mPreviousProcess = null; 13384 } 13385 13386 if (restart && !app.isolated) { 13387 // We have components that still need to be running in the 13388 // process, so re-launch it. 13389 mProcessNames.put(app.processName, app.uid, app); 13390 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13391 } else if (app.pid > 0 && app.pid != MY_PID) { 13392 // Goodbye! 13393 boolean removed; 13394 synchronized (mPidsSelfLocked) { 13395 mPidsSelfLocked.remove(app.pid); 13396 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13397 } 13398 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13399 if (app.isolated) { 13400 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13401 } 13402 app.setPid(0); 13403 } 13404 } 13405 13406 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13407 // Look through the content providers we are waiting to have launched, 13408 // and if any run in this process then either schedule a restart of 13409 // the process or kill the client waiting for it if this process has 13410 // gone bad. 13411 int NL = mLaunchingProviders.size(); 13412 boolean restart = false; 13413 for (int i=0; i<NL; i++) { 13414 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13415 if (cpr.launchingApp == app) { 13416 if (!alwaysBad && !app.bad) { 13417 restart = true; 13418 } else { 13419 removeDyingProviderLocked(app, cpr, true); 13420 // cpr should have been removed from mLaunchingProviders 13421 NL = mLaunchingProviders.size(); 13422 i--; 13423 } 13424 } 13425 } 13426 return restart; 13427 } 13428 13429 // ========================================================= 13430 // SERVICES 13431 // ========================================================= 13432 13433 @Override 13434 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13435 int flags) { 13436 enforceNotIsolatedCaller("getServices"); 13437 synchronized (this) { 13438 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13439 } 13440 } 13441 13442 @Override 13443 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13444 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13445 synchronized (this) { 13446 return mServices.getRunningServiceControlPanelLocked(name); 13447 } 13448 } 13449 13450 @Override 13451 public ComponentName startService(IApplicationThread caller, Intent service, 13452 String resolvedType, int userId) { 13453 enforceNotIsolatedCaller("startService"); 13454 // Refuse possible leaked file descriptors 13455 if (service != null && service.hasFileDescriptors() == true) { 13456 throw new IllegalArgumentException("File descriptors passed in Intent"); 13457 } 13458 13459 if (DEBUG_SERVICE) 13460 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13461 synchronized(this) { 13462 final int callingPid = Binder.getCallingPid(); 13463 final int callingUid = Binder.getCallingUid(); 13464 final long origId = Binder.clearCallingIdentity(); 13465 ComponentName res = mServices.startServiceLocked(caller, service, 13466 resolvedType, callingPid, callingUid, userId); 13467 Binder.restoreCallingIdentity(origId); 13468 return res; 13469 } 13470 } 13471 13472 ComponentName startServiceInPackage(int uid, 13473 Intent service, String resolvedType, int userId) { 13474 synchronized(this) { 13475 if (DEBUG_SERVICE) 13476 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13477 final long origId = Binder.clearCallingIdentity(); 13478 ComponentName res = mServices.startServiceLocked(null, service, 13479 resolvedType, -1, uid, userId); 13480 Binder.restoreCallingIdentity(origId); 13481 return res; 13482 } 13483 } 13484 13485 @Override 13486 public int stopService(IApplicationThread caller, Intent service, 13487 String resolvedType, int userId) { 13488 enforceNotIsolatedCaller("stopService"); 13489 // Refuse possible leaked file descriptors 13490 if (service != null && service.hasFileDescriptors() == true) { 13491 throw new IllegalArgumentException("File descriptors passed in Intent"); 13492 } 13493 13494 synchronized(this) { 13495 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13496 } 13497 } 13498 13499 @Override 13500 public IBinder peekService(Intent service, String resolvedType) { 13501 enforceNotIsolatedCaller("peekService"); 13502 // Refuse possible leaked file descriptors 13503 if (service != null && service.hasFileDescriptors() == true) { 13504 throw new IllegalArgumentException("File descriptors passed in Intent"); 13505 } 13506 synchronized(this) { 13507 return mServices.peekServiceLocked(service, resolvedType); 13508 } 13509 } 13510 13511 @Override 13512 public boolean stopServiceToken(ComponentName className, IBinder token, 13513 int startId) { 13514 synchronized(this) { 13515 return mServices.stopServiceTokenLocked(className, token, startId); 13516 } 13517 } 13518 13519 @Override 13520 public void setServiceForeground(ComponentName className, IBinder token, 13521 int id, Notification notification, boolean removeNotification) { 13522 synchronized(this) { 13523 mServices.setServiceForegroundLocked(className, token, id, notification, 13524 removeNotification); 13525 } 13526 } 13527 13528 @Override 13529 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13530 boolean requireFull, String name, String callerPackage) { 13531 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13532 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13533 } 13534 13535 int unsafeConvertIncomingUser(int userId) { 13536 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13537 ? mCurrentUserId : userId; 13538 } 13539 13540 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13541 int allowMode, String name, String callerPackage) { 13542 final int callingUserId = UserHandle.getUserId(callingUid); 13543 if (callingUserId == userId) { 13544 return userId; 13545 } 13546 13547 // Note that we may be accessing mCurrentUserId outside of a lock... 13548 // shouldn't be a big deal, if this is being called outside 13549 // of a locked context there is intrinsically a race with 13550 // the value the caller will receive and someone else changing it. 13551 // We assume that USER_CURRENT_OR_SELF will use the current user; later 13552 // we will switch to the calling user if access to the current user fails. 13553 int targetUserId = unsafeConvertIncomingUser(userId); 13554 13555 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13556 final boolean allow; 13557 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 13558 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 13559 // If the caller has this permission, they always pass go. And collect $200. 13560 allow = true; 13561 } else if (allowMode == ALLOW_FULL_ONLY) { 13562 // We require full access, sucks to be you. 13563 allow = false; 13564 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 13565 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 13566 // If the caller does not have either permission, they are always doomed. 13567 allow = false; 13568 } else if (allowMode == ALLOW_NON_FULL) { 13569 // We are blanket allowing non-full access, you lucky caller! 13570 allow = true; 13571 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 13572 // We may or may not allow this depending on whether the two users are 13573 // in the same profile. 13574 synchronized (mUserProfileGroupIdsSelfLocked) { 13575 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 13576 UserInfo.NO_PROFILE_GROUP_ID); 13577 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 13578 UserInfo.NO_PROFILE_GROUP_ID); 13579 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 13580 && callingProfile == targetProfile; 13581 } 13582 } else { 13583 throw new IllegalArgumentException("Unknown mode: " + allowMode); 13584 } 13585 if (!allow) { 13586 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13587 // In this case, they would like to just execute as their 13588 // owner user instead of failing. 13589 targetUserId = callingUserId; 13590 } else { 13591 StringBuilder builder = new StringBuilder(128); 13592 builder.append("Permission Denial: "); 13593 builder.append(name); 13594 if (callerPackage != null) { 13595 builder.append(" from "); 13596 builder.append(callerPackage); 13597 } 13598 builder.append(" asks to run as user "); 13599 builder.append(userId); 13600 builder.append(" but is calling from user "); 13601 builder.append(UserHandle.getUserId(callingUid)); 13602 builder.append("; this requires "); 13603 builder.append(INTERACT_ACROSS_USERS_FULL); 13604 if (allowMode != ALLOW_FULL_ONLY) { 13605 builder.append(" or "); 13606 builder.append(INTERACT_ACROSS_USERS); 13607 } 13608 String msg = builder.toString(); 13609 Slog.w(TAG, msg); 13610 throw new SecurityException(msg); 13611 } 13612 } 13613 } 13614 if (!allowAll && targetUserId < 0) { 13615 throw new IllegalArgumentException( 13616 "Call does not support special user #" + targetUserId); 13617 } 13618 return targetUserId; 13619 } 13620 13621 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13622 String className, int flags) { 13623 boolean result = false; 13624 // For apps that don't have pre-defined UIDs, check for permission 13625 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13626 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13627 if (ActivityManager.checkUidPermission( 13628 INTERACT_ACROSS_USERS, 13629 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13630 ComponentName comp = new ComponentName(aInfo.packageName, className); 13631 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13632 + " requests FLAG_SINGLE_USER, but app does not hold " 13633 + INTERACT_ACROSS_USERS; 13634 Slog.w(TAG, msg); 13635 throw new SecurityException(msg); 13636 } 13637 // Permission passed 13638 result = true; 13639 } 13640 } else if ("system".equals(componentProcessName)) { 13641 result = true; 13642 } else { 13643 // App with pre-defined UID, check if it's a persistent app 13644 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13645 } 13646 if (DEBUG_MU) { 13647 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13648 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13649 } 13650 return result; 13651 } 13652 13653 /** 13654 * Checks to see if the caller is in the same app as the singleton 13655 * component, or the component is in a special app. It allows special apps 13656 * to export singleton components but prevents exporting singleton 13657 * components for regular apps. 13658 */ 13659 boolean isValidSingletonCall(int callingUid, int componentUid) { 13660 int componentAppId = UserHandle.getAppId(componentUid); 13661 return UserHandle.isSameApp(callingUid, componentUid) 13662 || componentAppId == Process.SYSTEM_UID 13663 || componentAppId == Process.PHONE_UID 13664 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13665 == PackageManager.PERMISSION_GRANTED; 13666 } 13667 13668 public int bindService(IApplicationThread caller, IBinder token, 13669 Intent service, String resolvedType, 13670 IServiceConnection connection, int flags, int userId) { 13671 enforceNotIsolatedCaller("bindService"); 13672 // Refuse possible leaked file descriptors 13673 if (service != null && service.hasFileDescriptors() == true) { 13674 throw new IllegalArgumentException("File descriptors passed in Intent"); 13675 } 13676 13677 synchronized(this) { 13678 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13679 connection, flags, userId); 13680 } 13681 } 13682 13683 public boolean unbindService(IServiceConnection connection) { 13684 synchronized (this) { 13685 return mServices.unbindServiceLocked(connection); 13686 } 13687 } 13688 13689 public void publishService(IBinder token, Intent intent, IBinder service) { 13690 // Refuse possible leaked file descriptors 13691 if (intent != null && intent.hasFileDescriptors() == true) { 13692 throw new IllegalArgumentException("File descriptors passed in Intent"); 13693 } 13694 13695 synchronized(this) { 13696 if (!(token instanceof ServiceRecord)) { 13697 throw new IllegalArgumentException("Invalid service token"); 13698 } 13699 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13700 } 13701 } 13702 13703 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13704 // Refuse possible leaked file descriptors 13705 if (intent != null && intent.hasFileDescriptors() == true) { 13706 throw new IllegalArgumentException("File descriptors passed in Intent"); 13707 } 13708 13709 synchronized(this) { 13710 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13711 } 13712 } 13713 13714 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13715 synchronized(this) { 13716 if (!(token instanceof ServiceRecord)) { 13717 throw new IllegalArgumentException("Invalid service token"); 13718 } 13719 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13720 } 13721 } 13722 13723 // ========================================================= 13724 // BACKUP AND RESTORE 13725 // ========================================================= 13726 13727 // Cause the target app to be launched if necessary and its backup agent 13728 // instantiated. The backup agent will invoke backupAgentCreated() on the 13729 // activity manager to announce its creation. 13730 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13731 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13732 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13733 13734 synchronized(this) { 13735 // !!! TODO: currently no check here that we're already bound 13736 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13737 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13738 synchronized (stats) { 13739 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13740 } 13741 13742 // Backup agent is now in use, its package can't be stopped. 13743 try { 13744 AppGlobals.getPackageManager().setPackageStoppedState( 13745 app.packageName, false, UserHandle.getUserId(app.uid)); 13746 } catch (RemoteException e) { 13747 } catch (IllegalArgumentException e) { 13748 Slog.w(TAG, "Failed trying to unstop package " 13749 + app.packageName + ": " + e); 13750 } 13751 13752 BackupRecord r = new BackupRecord(ss, app, backupMode); 13753 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13754 ? new ComponentName(app.packageName, app.backupAgentName) 13755 : new ComponentName("android", "FullBackupAgent"); 13756 // startProcessLocked() returns existing proc's record if it's already running 13757 ProcessRecord proc = startProcessLocked(app.processName, app, 13758 false, 0, "backup", hostingName, false, false, false); 13759 if (proc == null) { 13760 Slog.e(TAG, "Unable to start backup agent process " + r); 13761 return false; 13762 } 13763 13764 r.app = proc; 13765 mBackupTarget = r; 13766 mBackupAppName = app.packageName; 13767 13768 // Try not to kill the process during backup 13769 updateOomAdjLocked(proc); 13770 13771 // If the process is already attached, schedule the creation of the backup agent now. 13772 // If it is not yet live, this will be done when it attaches to the framework. 13773 if (proc.thread != null) { 13774 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13775 try { 13776 proc.thread.scheduleCreateBackupAgent(app, 13777 compatibilityInfoForPackageLocked(app), backupMode); 13778 } catch (RemoteException e) { 13779 // Will time out on the backup manager side 13780 } 13781 } else { 13782 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13783 } 13784 // Invariants: at this point, the target app process exists and the application 13785 // is either already running or in the process of coming up. mBackupTarget and 13786 // mBackupAppName describe the app, so that when it binds back to the AM we 13787 // know that it's scheduled for a backup-agent operation. 13788 } 13789 13790 return true; 13791 } 13792 13793 @Override 13794 public void clearPendingBackup() { 13795 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13796 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13797 13798 synchronized (this) { 13799 mBackupTarget = null; 13800 mBackupAppName = null; 13801 } 13802 } 13803 13804 // A backup agent has just come up 13805 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13806 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13807 + " = " + agent); 13808 13809 synchronized(this) { 13810 if (!agentPackageName.equals(mBackupAppName)) { 13811 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13812 return; 13813 } 13814 } 13815 13816 long oldIdent = Binder.clearCallingIdentity(); 13817 try { 13818 IBackupManager bm = IBackupManager.Stub.asInterface( 13819 ServiceManager.getService(Context.BACKUP_SERVICE)); 13820 bm.agentConnected(agentPackageName, agent); 13821 } catch (RemoteException e) { 13822 // can't happen; the backup manager service is local 13823 } catch (Exception e) { 13824 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13825 e.printStackTrace(); 13826 } finally { 13827 Binder.restoreCallingIdentity(oldIdent); 13828 } 13829 } 13830 13831 // done with this agent 13832 public void unbindBackupAgent(ApplicationInfo appInfo) { 13833 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13834 if (appInfo == null) { 13835 Slog.w(TAG, "unbind backup agent for null app"); 13836 return; 13837 } 13838 13839 synchronized(this) { 13840 try { 13841 if (mBackupAppName == null) { 13842 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13843 return; 13844 } 13845 13846 if (!mBackupAppName.equals(appInfo.packageName)) { 13847 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13848 return; 13849 } 13850 13851 // Not backing this app up any more; reset its OOM adjustment 13852 final ProcessRecord proc = mBackupTarget.app; 13853 updateOomAdjLocked(proc); 13854 13855 // If the app crashed during backup, 'thread' will be null here 13856 if (proc.thread != null) { 13857 try { 13858 proc.thread.scheduleDestroyBackupAgent(appInfo, 13859 compatibilityInfoForPackageLocked(appInfo)); 13860 } catch (Exception e) { 13861 Slog.e(TAG, "Exception when unbinding backup agent:"); 13862 e.printStackTrace(); 13863 } 13864 } 13865 } finally { 13866 mBackupTarget = null; 13867 mBackupAppName = null; 13868 } 13869 } 13870 } 13871 // ========================================================= 13872 // BROADCASTS 13873 // ========================================================= 13874 13875 private final List getStickiesLocked(String action, IntentFilter filter, 13876 List cur, int userId) { 13877 final ContentResolver resolver = mContext.getContentResolver(); 13878 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13879 if (stickies == null) { 13880 return cur; 13881 } 13882 final ArrayList<Intent> list = stickies.get(action); 13883 if (list == null) { 13884 return cur; 13885 } 13886 int N = list.size(); 13887 for (int i=0; i<N; i++) { 13888 Intent intent = list.get(i); 13889 if (filter.match(resolver, intent, true, TAG) >= 0) { 13890 if (cur == null) { 13891 cur = new ArrayList<Intent>(); 13892 } 13893 cur.add(intent); 13894 } 13895 } 13896 return cur; 13897 } 13898 13899 boolean isPendingBroadcastProcessLocked(int pid) { 13900 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13901 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13902 } 13903 13904 void skipPendingBroadcastLocked(int pid) { 13905 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13906 for (BroadcastQueue queue : mBroadcastQueues) { 13907 queue.skipPendingBroadcastLocked(pid); 13908 } 13909 } 13910 13911 // The app just attached; send any pending broadcasts that it should receive 13912 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13913 boolean didSomething = false; 13914 for (BroadcastQueue queue : mBroadcastQueues) { 13915 didSomething |= queue.sendPendingBroadcastsLocked(app); 13916 } 13917 return didSomething; 13918 } 13919 13920 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13921 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13922 enforceNotIsolatedCaller("registerReceiver"); 13923 int callingUid; 13924 int callingPid; 13925 synchronized(this) { 13926 ProcessRecord callerApp = null; 13927 if (caller != null) { 13928 callerApp = getRecordForAppLocked(caller); 13929 if (callerApp == null) { 13930 throw new SecurityException( 13931 "Unable to find app for caller " + caller 13932 + " (pid=" + Binder.getCallingPid() 13933 + ") when registering receiver " + receiver); 13934 } 13935 if (callerApp.info.uid != Process.SYSTEM_UID && 13936 !callerApp.pkgList.containsKey(callerPackage) && 13937 !"android".equals(callerPackage)) { 13938 throw new SecurityException("Given caller package " + callerPackage 13939 + " is not running in process " + callerApp); 13940 } 13941 callingUid = callerApp.info.uid; 13942 callingPid = callerApp.pid; 13943 } else { 13944 callerPackage = null; 13945 callingUid = Binder.getCallingUid(); 13946 callingPid = Binder.getCallingPid(); 13947 } 13948 13949 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13950 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 13951 13952 List allSticky = null; 13953 13954 // Look for any matching sticky broadcasts... 13955 Iterator actions = filter.actionsIterator(); 13956 if (actions != null) { 13957 while (actions.hasNext()) { 13958 String action = (String)actions.next(); 13959 allSticky = getStickiesLocked(action, filter, allSticky, 13960 UserHandle.USER_ALL); 13961 allSticky = getStickiesLocked(action, filter, allSticky, 13962 UserHandle.getUserId(callingUid)); 13963 } 13964 } else { 13965 allSticky = getStickiesLocked(null, filter, allSticky, 13966 UserHandle.USER_ALL); 13967 allSticky = getStickiesLocked(null, filter, allSticky, 13968 UserHandle.getUserId(callingUid)); 13969 } 13970 13971 // The first sticky in the list is returned directly back to 13972 // the client. 13973 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13974 13975 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13976 + ": " + sticky); 13977 13978 if (receiver == null) { 13979 return sticky; 13980 } 13981 13982 ReceiverList rl 13983 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13984 if (rl == null) { 13985 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13986 userId, receiver); 13987 if (rl.app != null) { 13988 rl.app.receivers.add(rl); 13989 } else { 13990 try { 13991 receiver.asBinder().linkToDeath(rl, 0); 13992 } catch (RemoteException e) { 13993 return sticky; 13994 } 13995 rl.linkedToDeath = true; 13996 } 13997 mRegisteredReceivers.put(receiver.asBinder(), rl); 13998 } else if (rl.uid != callingUid) { 13999 throw new IllegalArgumentException( 14000 "Receiver requested to register for uid " + callingUid 14001 + " was previously registered for uid " + rl.uid); 14002 } else if (rl.pid != callingPid) { 14003 throw new IllegalArgumentException( 14004 "Receiver requested to register for pid " + callingPid 14005 + " was previously registered for pid " + rl.pid); 14006 } else if (rl.userId != userId) { 14007 throw new IllegalArgumentException( 14008 "Receiver requested to register for user " + userId 14009 + " was previously registered for user " + rl.userId); 14010 } 14011 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14012 permission, callingUid, userId); 14013 rl.add(bf); 14014 if (!bf.debugCheck()) { 14015 Slog.w(TAG, "==> For Dynamic broadast"); 14016 } 14017 mReceiverResolver.addFilter(bf); 14018 14019 // Enqueue broadcasts for all existing stickies that match 14020 // this filter. 14021 if (allSticky != null) { 14022 ArrayList receivers = new ArrayList(); 14023 receivers.add(bf); 14024 14025 int N = allSticky.size(); 14026 for (int i=0; i<N; i++) { 14027 Intent intent = (Intent)allSticky.get(i); 14028 BroadcastQueue queue = broadcastQueueForIntent(intent); 14029 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14030 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14031 null, null, false, true, true, -1); 14032 queue.enqueueParallelBroadcastLocked(r); 14033 queue.scheduleBroadcastsLocked(); 14034 } 14035 } 14036 14037 return sticky; 14038 } 14039 } 14040 14041 public void unregisterReceiver(IIntentReceiver receiver) { 14042 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14043 14044 final long origId = Binder.clearCallingIdentity(); 14045 try { 14046 boolean doTrim = false; 14047 14048 synchronized(this) { 14049 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14050 if (rl != null) { 14051 if (rl.curBroadcast != null) { 14052 BroadcastRecord r = rl.curBroadcast; 14053 final boolean doNext = finishReceiverLocked( 14054 receiver.asBinder(), r.resultCode, r.resultData, 14055 r.resultExtras, r.resultAbort); 14056 if (doNext) { 14057 doTrim = true; 14058 r.queue.processNextBroadcast(false); 14059 } 14060 } 14061 14062 if (rl.app != null) { 14063 rl.app.receivers.remove(rl); 14064 } 14065 removeReceiverLocked(rl); 14066 if (rl.linkedToDeath) { 14067 rl.linkedToDeath = false; 14068 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14069 } 14070 } 14071 } 14072 14073 // If we actually concluded any broadcasts, we might now be able 14074 // to trim the recipients' apps from our working set 14075 if (doTrim) { 14076 trimApplications(); 14077 return; 14078 } 14079 14080 } finally { 14081 Binder.restoreCallingIdentity(origId); 14082 } 14083 } 14084 14085 void removeReceiverLocked(ReceiverList rl) { 14086 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14087 int N = rl.size(); 14088 for (int i=0; i<N; i++) { 14089 mReceiverResolver.removeFilter(rl.get(i)); 14090 } 14091 } 14092 14093 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14094 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14095 ProcessRecord r = mLruProcesses.get(i); 14096 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14097 try { 14098 r.thread.dispatchPackageBroadcast(cmd, packages); 14099 } catch (RemoteException ex) { 14100 } 14101 } 14102 } 14103 } 14104 14105 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14106 int[] users) { 14107 List<ResolveInfo> receivers = null; 14108 try { 14109 HashSet<ComponentName> singleUserReceivers = null; 14110 boolean scannedFirstReceivers = false; 14111 for (int user : users) { 14112 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14113 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14114 if (user != 0 && newReceivers != null) { 14115 // If this is not the primary user, we need to check for 14116 // any receivers that should be filtered out. 14117 for (int i=0; i<newReceivers.size(); i++) { 14118 ResolveInfo ri = newReceivers.get(i); 14119 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14120 newReceivers.remove(i); 14121 i--; 14122 } 14123 } 14124 } 14125 if (newReceivers != null && newReceivers.size() == 0) { 14126 newReceivers = null; 14127 } 14128 if (receivers == null) { 14129 receivers = newReceivers; 14130 } else if (newReceivers != null) { 14131 // We need to concatenate the additional receivers 14132 // found with what we have do far. This would be easy, 14133 // but we also need to de-dup any receivers that are 14134 // singleUser. 14135 if (!scannedFirstReceivers) { 14136 // Collect any single user receivers we had already retrieved. 14137 scannedFirstReceivers = true; 14138 for (int i=0; i<receivers.size(); i++) { 14139 ResolveInfo ri = receivers.get(i); 14140 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14141 ComponentName cn = new ComponentName( 14142 ri.activityInfo.packageName, ri.activityInfo.name); 14143 if (singleUserReceivers == null) { 14144 singleUserReceivers = new HashSet<ComponentName>(); 14145 } 14146 singleUserReceivers.add(cn); 14147 } 14148 } 14149 } 14150 // Add the new results to the existing results, tracking 14151 // and de-dupping single user receivers. 14152 for (int i=0; i<newReceivers.size(); i++) { 14153 ResolveInfo ri = newReceivers.get(i); 14154 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14155 ComponentName cn = new ComponentName( 14156 ri.activityInfo.packageName, ri.activityInfo.name); 14157 if (singleUserReceivers == null) { 14158 singleUserReceivers = new HashSet<ComponentName>(); 14159 } 14160 if (!singleUserReceivers.contains(cn)) { 14161 singleUserReceivers.add(cn); 14162 receivers.add(ri); 14163 } 14164 } else { 14165 receivers.add(ri); 14166 } 14167 } 14168 } 14169 } 14170 } catch (RemoteException ex) { 14171 // pm is in same process, this will never happen. 14172 } 14173 return receivers; 14174 } 14175 14176 private final int broadcastIntentLocked(ProcessRecord callerApp, 14177 String callerPackage, Intent intent, String resolvedType, 14178 IIntentReceiver resultTo, int resultCode, String resultData, 14179 Bundle map, String requiredPermission, int appOp, 14180 boolean ordered, boolean sticky, int callingPid, int callingUid, 14181 int userId) { 14182 intent = new Intent(intent); 14183 14184 // By default broadcasts do not go to stopped apps. 14185 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14186 14187 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14188 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14189 + " ordered=" + ordered + " userid=" + userId); 14190 if ((resultTo != null) && !ordered) { 14191 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14192 } 14193 14194 userId = handleIncomingUser(callingPid, callingUid, userId, 14195 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14196 14197 // Make sure that the user who is receiving this broadcast is started. 14198 // If not, we will just skip it. 14199 14200 14201 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14202 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14203 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14204 Slog.w(TAG, "Skipping broadcast of " + intent 14205 + ": user " + userId + " is stopped"); 14206 return ActivityManager.BROADCAST_SUCCESS; 14207 } 14208 } 14209 14210 /* 14211 * Prevent non-system code (defined here to be non-persistent 14212 * processes) from sending protected broadcasts. 14213 */ 14214 int callingAppId = UserHandle.getAppId(callingUid); 14215 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14216 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14217 || callingAppId == Process.NFC_UID || callingUid == 0) { 14218 // Always okay. 14219 } else if (callerApp == null || !callerApp.persistent) { 14220 try { 14221 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14222 intent.getAction())) { 14223 String msg = "Permission Denial: not allowed to send broadcast " 14224 + intent.getAction() + " from pid=" 14225 + callingPid + ", uid=" + callingUid; 14226 Slog.w(TAG, msg); 14227 throw new SecurityException(msg); 14228 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14229 // Special case for compatibility: we don't want apps to send this, 14230 // but historically it has not been protected and apps may be using it 14231 // to poke their own app widget. So, instead of making it protected, 14232 // just limit it to the caller. 14233 if (callerApp == null) { 14234 String msg = "Permission Denial: not allowed to send broadcast " 14235 + intent.getAction() + " from unknown caller."; 14236 Slog.w(TAG, msg); 14237 throw new SecurityException(msg); 14238 } else if (intent.getComponent() != null) { 14239 // They are good enough to send to an explicit component... verify 14240 // it is being sent to the calling app. 14241 if (!intent.getComponent().getPackageName().equals( 14242 callerApp.info.packageName)) { 14243 String msg = "Permission Denial: not allowed to send broadcast " 14244 + intent.getAction() + " to " 14245 + intent.getComponent().getPackageName() + " from " 14246 + callerApp.info.packageName; 14247 Slog.w(TAG, msg); 14248 throw new SecurityException(msg); 14249 } 14250 } else { 14251 // Limit broadcast to their own package. 14252 intent.setPackage(callerApp.info.packageName); 14253 } 14254 } 14255 } catch (RemoteException e) { 14256 Slog.w(TAG, "Remote exception", e); 14257 return ActivityManager.BROADCAST_SUCCESS; 14258 } 14259 } 14260 14261 // Handle special intents: if this broadcast is from the package 14262 // manager about a package being removed, we need to remove all of 14263 // its activities from the history stack. 14264 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14265 intent.getAction()); 14266 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14267 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14268 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14269 || uidRemoved) { 14270 if (checkComponentPermission( 14271 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14272 callingPid, callingUid, -1, true) 14273 == PackageManager.PERMISSION_GRANTED) { 14274 if (uidRemoved) { 14275 final Bundle intentExtras = intent.getExtras(); 14276 final int uid = intentExtras != null 14277 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14278 if (uid >= 0) { 14279 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14280 synchronized (bs) { 14281 bs.removeUidStatsLocked(uid); 14282 } 14283 mAppOpsService.uidRemoved(uid); 14284 } 14285 } else { 14286 // If resources are unavailable just force stop all 14287 // those packages and flush the attribute cache as well. 14288 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14289 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14290 if (list != null && (list.length > 0)) { 14291 for (String pkg : list) { 14292 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14293 "storage unmount"); 14294 } 14295 sendPackageBroadcastLocked( 14296 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14297 } 14298 } else { 14299 Uri data = intent.getData(); 14300 String ssp; 14301 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14302 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14303 intent.getAction()); 14304 boolean fullUninstall = removed && 14305 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14306 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14307 forceStopPackageLocked(ssp, UserHandle.getAppId( 14308 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14309 false, fullUninstall, userId, 14310 removed ? "pkg removed" : "pkg changed"); 14311 } 14312 if (removed) { 14313 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14314 new String[] {ssp}, userId); 14315 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14316 mAppOpsService.packageRemoved( 14317 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14318 14319 // Remove all permissions granted from/to this package 14320 removeUriPermissionsForPackageLocked(ssp, userId, true); 14321 } 14322 } 14323 } 14324 } 14325 } 14326 } else { 14327 String msg = "Permission Denial: " + intent.getAction() 14328 + " broadcast from " + callerPackage + " (pid=" + callingPid 14329 + ", uid=" + callingUid + ")" 14330 + " requires " 14331 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14332 Slog.w(TAG, msg); 14333 throw new SecurityException(msg); 14334 } 14335 14336 // Special case for adding a package: by default turn on compatibility 14337 // mode. 14338 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14339 Uri data = intent.getData(); 14340 String ssp; 14341 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14342 mCompatModePackages.handlePackageAddedLocked(ssp, 14343 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14344 } 14345 } 14346 14347 /* 14348 * If this is the time zone changed action, queue up a message that will reset the timezone 14349 * of all currently running processes. This message will get queued up before the broadcast 14350 * happens. 14351 */ 14352 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14353 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14354 } 14355 14356 /* 14357 * If the user set the time, let all running processes know. 14358 */ 14359 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14360 final int is24Hour = intent.getBooleanExtra( 14361 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14362 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14363 } 14364 14365 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14366 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14367 } 14368 14369 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14370 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14371 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14372 } 14373 14374 // Add to the sticky list if requested. 14375 if (sticky) { 14376 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14377 callingPid, callingUid) 14378 != PackageManager.PERMISSION_GRANTED) { 14379 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14380 + callingPid + ", uid=" + callingUid 14381 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14382 Slog.w(TAG, msg); 14383 throw new SecurityException(msg); 14384 } 14385 if (requiredPermission != null) { 14386 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14387 + " and enforce permission " + requiredPermission); 14388 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14389 } 14390 if (intent.getComponent() != null) { 14391 throw new SecurityException( 14392 "Sticky broadcasts can't target a specific component"); 14393 } 14394 // We use userId directly here, since the "all" target is maintained 14395 // as a separate set of sticky broadcasts. 14396 if (userId != UserHandle.USER_ALL) { 14397 // But first, if this is not a broadcast to all users, then 14398 // make sure it doesn't conflict with an existing broadcast to 14399 // all users. 14400 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14401 UserHandle.USER_ALL); 14402 if (stickies != null) { 14403 ArrayList<Intent> list = stickies.get(intent.getAction()); 14404 if (list != null) { 14405 int N = list.size(); 14406 int i; 14407 for (i=0; i<N; i++) { 14408 if (intent.filterEquals(list.get(i))) { 14409 throw new IllegalArgumentException( 14410 "Sticky broadcast " + intent + " for user " 14411 + userId + " conflicts with existing global broadcast"); 14412 } 14413 } 14414 } 14415 } 14416 } 14417 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14418 if (stickies == null) { 14419 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14420 mStickyBroadcasts.put(userId, stickies); 14421 } 14422 ArrayList<Intent> list = stickies.get(intent.getAction()); 14423 if (list == null) { 14424 list = new ArrayList<Intent>(); 14425 stickies.put(intent.getAction(), list); 14426 } 14427 int N = list.size(); 14428 int i; 14429 for (i=0; i<N; i++) { 14430 if (intent.filterEquals(list.get(i))) { 14431 // This sticky already exists, replace it. 14432 list.set(i, new Intent(intent)); 14433 break; 14434 } 14435 } 14436 if (i >= N) { 14437 list.add(new Intent(intent)); 14438 } 14439 } 14440 14441 int[] users; 14442 if (userId == UserHandle.USER_ALL) { 14443 // Caller wants broadcast to go to all started users. 14444 users = mStartedUserArray; 14445 } else { 14446 // Caller wants broadcast to go to one specific user. 14447 users = new int[] {userId}; 14448 } 14449 14450 // Figure out who all will receive this broadcast. 14451 List receivers = null; 14452 List<BroadcastFilter> registeredReceivers = null; 14453 // Need to resolve the intent to interested receivers... 14454 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14455 == 0) { 14456 receivers = collectReceiverComponents(intent, resolvedType, users); 14457 } 14458 if (intent.getComponent() == null) { 14459 registeredReceivers = mReceiverResolver.queryIntent(intent, 14460 resolvedType, false, userId); 14461 } 14462 14463 final boolean replacePending = 14464 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14465 14466 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14467 + " replacePending=" + replacePending); 14468 14469 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14470 if (!ordered && NR > 0) { 14471 // If we are not serializing this broadcast, then send the 14472 // registered receivers separately so they don't wait for the 14473 // components to be launched. 14474 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14475 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14476 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14477 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14478 ordered, sticky, false, userId); 14479 if (DEBUG_BROADCAST) Slog.v( 14480 TAG, "Enqueueing parallel broadcast " + r); 14481 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14482 if (!replaced) { 14483 queue.enqueueParallelBroadcastLocked(r); 14484 queue.scheduleBroadcastsLocked(); 14485 } 14486 registeredReceivers = null; 14487 NR = 0; 14488 } 14489 14490 // Merge into one list. 14491 int ir = 0; 14492 if (receivers != null) { 14493 // A special case for PACKAGE_ADDED: do not allow the package 14494 // being added to see this broadcast. This prevents them from 14495 // using this as a back door to get run as soon as they are 14496 // installed. Maybe in the future we want to have a special install 14497 // broadcast or such for apps, but we'd like to deliberately make 14498 // this decision. 14499 String skipPackages[] = null; 14500 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14501 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14502 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14503 Uri data = intent.getData(); 14504 if (data != null) { 14505 String pkgName = data.getSchemeSpecificPart(); 14506 if (pkgName != null) { 14507 skipPackages = new String[] { pkgName }; 14508 } 14509 } 14510 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14511 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14512 } 14513 if (skipPackages != null && (skipPackages.length > 0)) { 14514 for (String skipPackage : skipPackages) { 14515 if (skipPackage != null) { 14516 int NT = receivers.size(); 14517 for (int it=0; it<NT; it++) { 14518 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14519 if (curt.activityInfo.packageName.equals(skipPackage)) { 14520 receivers.remove(it); 14521 it--; 14522 NT--; 14523 } 14524 } 14525 } 14526 } 14527 } 14528 14529 int NT = receivers != null ? receivers.size() : 0; 14530 int it = 0; 14531 ResolveInfo curt = null; 14532 BroadcastFilter curr = null; 14533 while (it < NT && ir < NR) { 14534 if (curt == null) { 14535 curt = (ResolveInfo)receivers.get(it); 14536 } 14537 if (curr == null) { 14538 curr = registeredReceivers.get(ir); 14539 } 14540 if (curr.getPriority() >= curt.priority) { 14541 // Insert this broadcast record into the final list. 14542 receivers.add(it, curr); 14543 ir++; 14544 curr = null; 14545 it++; 14546 NT++; 14547 } else { 14548 // Skip to the next ResolveInfo in the final list. 14549 it++; 14550 curt = null; 14551 } 14552 } 14553 } 14554 while (ir < NR) { 14555 if (receivers == null) { 14556 receivers = new ArrayList(); 14557 } 14558 receivers.add(registeredReceivers.get(ir)); 14559 ir++; 14560 } 14561 14562 if ((receivers != null && receivers.size() > 0) 14563 || resultTo != null) { 14564 BroadcastQueue queue = broadcastQueueForIntent(intent); 14565 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14566 callerPackage, callingPid, callingUid, resolvedType, 14567 requiredPermission, appOp, receivers, resultTo, resultCode, 14568 resultData, map, ordered, sticky, false, userId); 14569 if (DEBUG_BROADCAST) Slog.v( 14570 TAG, "Enqueueing ordered broadcast " + r 14571 + ": prev had " + queue.mOrderedBroadcasts.size()); 14572 if (DEBUG_BROADCAST) { 14573 int seq = r.intent.getIntExtra("seq", -1); 14574 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14575 } 14576 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14577 if (!replaced) { 14578 queue.enqueueOrderedBroadcastLocked(r); 14579 queue.scheduleBroadcastsLocked(); 14580 } 14581 } 14582 14583 return ActivityManager.BROADCAST_SUCCESS; 14584 } 14585 14586 final Intent verifyBroadcastLocked(Intent intent) { 14587 // Refuse possible leaked file descriptors 14588 if (intent != null && intent.hasFileDescriptors() == true) { 14589 throw new IllegalArgumentException("File descriptors passed in Intent"); 14590 } 14591 14592 int flags = intent.getFlags(); 14593 14594 if (!mProcessesReady) { 14595 // if the caller really truly claims to know what they're doing, go 14596 // ahead and allow the broadcast without launching any receivers 14597 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14598 intent = new Intent(intent); 14599 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14600 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14601 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14602 + " before boot completion"); 14603 throw new IllegalStateException("Cannot broadcast before boot completed"); 14604 } 14605 } 14606 14607 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14608 throw new IllegalArgumentException( 14609 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14610 } 14611 14612 return intent; 14613 } 14614 14615 public final int broadcastIntent(IApplicationThread caller, 14616 Intent intent, String resolvedType, IIntentReceiver resultTo, 14617 int resultCode, String resultData, Bundle map, 14618 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14619 enforceNotIsolatedCaller("broadcastIntent"); 14620 synchronized(this) { 14621 intent = verifyBroadcastLocked(intent); 14622 14623 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14624 final int callingPid = Binder.getCallingPid(); 14625 final int callingUid = Binder.getCallingUid(); 14626 final long origId = Binder.clearCallingIdentity(); 14627 int res = broadcastIntentLocked(callerApp, 14628 callerApp != null ? callerApp.info.packageName : null, 14629 intent, resolvedType, resultTo, 14630 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14631 callingPid, callingUid, userId); 14632 Binder.restoreCallingIdentity(origId); 14633 return res; 14634 } 14635 } 14636 14637 int broadcastIntentInPackage(String packageName, int uid, 14638 Intent intent, String resolvedType, IIntentReceiver resultTo, 14639 int resultCode, String resultData, Bundle map, 14640 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14641 synchronized(this) { 14642 intent = verifyBroadcastLocked(intent); 14643 14644 final long origId = Binder.clearCallingIdentity(); 14645 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14646 resultTo, resultCode, resultData, map, requiredPermission, 14647 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14648 Binder.restoreCallingIdentity(origId); 14649 return res; 14650 } 14651 } 14652 14653 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14654 // Refuse possible leaked file descriptors 14655 if (intent != null && intent.hasFileDescriptors() == true) { 14656 throw new IllegalArgumentException("File descriptors passed in Intent"); 14657 } 14658 14659 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14660 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 14661 14662 synchronized(this) { 14663 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14664 != PackageManager.PERMISSION_GRANTED) { 14665 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14666 + Binder.getCallingPid() 14667 + ", uid=" + Binder.getCallingUid() 14668 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14669 Slog.w(TAG, msg); 14670 throw new SecurityException(msg); 14671 } 14672 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14673 if (stickies != null) { 14674 ArrayList<Intent> list = stickies.get(intent.getAction()); 14675 if (list != null) { 14676 int N = list.size(); 14677 int i; 14678 for (i=0; i<N; i++) { 14679 if (intent.filterEquals(list.get(i))) { 14680 list.remove(i); 14681 break; 14682 } 14683 } 14684 if (list.size() <= 0) { 14685 stickies.remove(intent.getAction()); 14686 } 14687 } 14688 if (stickies.size() <= 0) { 14689 mStickyBroadcasts.remove(userId); 14690 } 14691 } 14692 } 14693 } 14694 14695 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14696 String resultData, Bundle resultExtras, boolean resultAbort) { 14697 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14698 if (r == null) { 14699 Slog.w(TAG, "finishReceiver called but not found on queue"); 14700 return false; 14701 } 14702 14703 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14704 } 14705 14706 void backgroundServicesFinishedLocked(int userId) { 14707 for (BroadcastQueue queue : mBroadcastQueues) { 14708 queue.backgroundServicesFinishedLocked(userId); 14709 } 14710 } 14711 14712 public void finishReceiver(IBinder who, int resultCode, String resultData, 14713 Bundle resultExtras, boolean resultAbort) { 14714 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14715 14716 // Refuse possible leaked file descriptors 14717 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14718 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14719 } 14720 14721 final long origId = Binder.clearCallingIdentity(); 14722 try { 14723 boolean doNext = false; 14724 BroadcastRecord r; 14725 14726 synchronized(this) { 14727 r = broadcastRecordForReceiverLocked(who); 14728 if (r != null) { 14729 doNext = r.queue.finishReceiverLocked(r, resultCode, 14730 resultData, resultExtras, resultAbort, true); 14731 } 14732 } 14733 14734 if (doNext) { 14735 r.queue.processNextBroadcast(false); 14736 } 14737 trimApplications(); 14738 } finally { 14739 Binder.restoreCallingIdentity(origId); 14740 } 14741 } 14742 14743 // ========================================================= 14744 // INSTRUMENTATION 14745 // ========================================================= 14746 14747 public boolean startInstrumentation(ComponentName className, 14748 String profileFile, int flags, Bundle arguments, 14749 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14750 int userId, String abiOverride) { 14751 enforceNotIsolatedCaller("startInstrumentation"); 14752 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14753 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 14754 // Refuse possible leaked file descriptors 14755 if (arguments != null && arguments.hasFileDescriptors()) { 14756 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14757 } 14758 14759 synchronized(this) { 14760 InstrumentationInfo ii = null; 14761 ApplicationInfo ai = null; 14762 try { 14763 ii = mContext.getPackageManager().getInstrumentationInfo( 14764 className, STOCK_PM_FLAGS); 14765 ai = AppGlobals.getPackageManager().getApplicationInfo( 14766 ii.targetPackage, STOCK_PM_FLAGS, userId); 14767 } catch (PackageManager.NameNotFoundException e) { 14768 } catch (RemoteException e) { 14769 } 14770 if (ii == null) { 14771 reportStartInstrumentationFailure(watcher, className, 14772 "Unable to find instrumentation info for: " + className); 14773 return false; 14774 } 14775 if (ai == null) { 14776 reportStartInstrumentationFailure(watcher, className, 14777 "Unable to find instrumentation target package: " + ii.targetPackage); 14778 return false; 14779 } 14780 14781 int match = mContext.getPackageManager().checkSignatures( 14782 ii.targetPackage, ii.packageName); 14783 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14784 String msg = "Permission Denial: starting instrumentation " 14785 + className + " from pid=" 14786 + Binder.getCallingPid() 14787 + ", uid=" + Binder.getCallingPid() 14788 + " not allowed because package " + ii.packageName 14789 + " does not have a signature matching the target " 14790 + ii.targetPackage; 14791 reportStartInstrumentationFailure(watcher, className, msg); 14792 throw new SecurityException(msg); 14793 } 14794 14795 final long origId = Binder.clearCallingIdentity(); 14796 // Instrumentation can kill and relaunch even persistent processes 14797 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14798 "start instr"); 14799 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14800 app.instrumentationClass = className; 14801 app.instrumentationInfo = ai; 14802 app.instrumentationProfileFile = profileFile; 14803 app.instrumentationArguments = arguments; 14804 app.instrumentationWatcher = watcher; 14805 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14806 app.instrumentationResultClass = className; 14807 Binder.restoreCallingIdentity(origId); 14808 } 14809 14810 return true; 14811 } 14812 14813 /** 14814 * Report errors that occur while attempting to start Instrumentation. Always writes the 14815 * error to the logs, but if somebody is watching, send the report there too. This enables 14816 * the "am" command to report errors with more information. 14817 * 14818 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14819 * @param cn The component name of the instrumentation. 14820 * @param report The error report. 14821 */ 14822 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14823 ComponentName cn, String report) { 14824 Slog.w(TAG, report); 14825 try { 14826 if (watcher != null) { 14827 Bundle results = new Bundle(); 14828 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14829 results.putString("Error", report); 14830 watcher.instrumentationStatus(cn, -1, results); 14831 } 14832 } catch (RemoteException e) { 14833 Slog.w(TAG, e); 14834 } 14835 } 14836 14837 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14838 if (app.instrumentationWatcher != null) { 14839 try { 14840 // NOTE: IInstrumentationWatcher *must* be oneway here 14841 app.instrumentationWatcher.instrumentationFinished( 14842 app.instrumentationClass, 14843 resultCode, 14844 results); 14845 } catch (RemoteException e) { 14846 } 14847 } 14848 if (app.instrumentationUiAutomationConnection != null) { 14849 try { 14850 app.instrumentationUiAutomationConnection.shutdown(); 14851 } catch (RemoteException re) { 14852 /* ignore */ 14853 } 14854 // Only a UiAutomation can set this flag and now that 14855 // it is finished we make sure it is reset to its default. 14856 mUserIsMonkey = false; 14857 } 14858 app.instrumentationWatcher = null; 14859 app.instrumentationUiAutomationConnection = null; 14860 app.instrumentationClass = null; 14861 app.instrumentationInfo = null; 14862 app.instrumentationProfileFile = null; 14863 app.instrumentationArguments = null; 14864 14865 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14866 "finished inst"); 14867 } 14868 14869 public void finishInstrumentation(IApplicationThread target, 14870 int resultCode, Bundle results) { 14871 int userId = UserHandle.getCallingUserId(); 14872 // Refuse possible leaked file descriptors 14873 if (results != null && results.hasFileDescriptors()) { 14874 throw new IllegalArgumentException("File descriptors passed in Intent"); 14875 } 14876 14877 synchronized(this) { 14878 ProcessRecord app = getRecordForAppLocked(target); 14879 if (app == null) { 14880 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14881 return; 14882 } 14883 final long origId = Binder.clearCallingIdentity(); 14884 finishInstrumentationLocked(app, resultCode, results); 14885 Binder.restoreCallingIdentity(origId); 14886 } 14887 } 14888 14889 // ========================================================= 14890 // CONFIGURATION 14891 // ========================================================= 14892 14893 public ConfigurationInfo getDeviceConfigurationInfo() { 14894 ConfigurationInfo config = new ConfigurationInfo(); 14895 synchronized (this) { 14896 config.reqTouchScreen = mConfiguration.touchscreen; 14897 config.reqKeyboardType = mConfiguration.keyboard; 14898 config.reqNavigation = mConfiguration.navigation; 14899 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14900 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14901 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14902 } 14903 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14904 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14905 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14906 } 14907 config.reqGlEsVersion = GL_ES_VERSION; 14908 } 14909 return config; 14910 } 14911 14912 ActivityStack getFocusedStack() { 14913 return mStackSupervisor.getFocusedStack(); 14914 } 14915 14916 public Configuration getConfiguration() { 14917 Configuration ci; 14918 synchronized(this) { 14919 ci = new Configuration(mConfiguration); 14920 } 14921 return ci; 14922 } 14923 14924 public void updatePersistentConfiguration(Configuration values) { 14925 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14926 "updateConfiguration()"); 14927 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14928 "updateConfiguration()"); 14929 if (values == null) { 14930 throw new NullPointerException("Configuration must not be null"); 14931 } 14932 14933 synchronized(this) { 14934 final long origId = Binder.clearCallingIdentity(); 14935 updateConfigurationLocked(values, null, true, false); 14936 Binder.restoreCallingIdentity(origId); 14937 } 14938 } 14939 14940 public void updateConfiguration(Configuration values) { 14941 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14942 "updateConfiguration()"); 14943 14944 synchronized(this) { 14945 if (values == null && mWindowManager != null) { 14946 // sentinel: fetch the current configuration from the window manager 14947 values = mWindowManager.computeNewConfiguration(); 14948 } 14949 14950 if (mWindowManager != null) { 14951 mProcessList.applyDisplaySize(mWindowManager); 14952 } 14953 14954 final long origId = Binder.clearCallingIdentity(); 14955 if (values != null) { 14956 Settings.System.clearConfiguration(values); 14957 } 14958 updateConfigurationLocked(values, null, false, false); 14959 Binder.restoreCallingIdentity(origId); 14960 } 14961 } 14962 14963 /** 14964 * Do either or both things: (1) change the current configuration, and (2) 14965 * make sure the given activity is running with the (now) current 14966 * configuration. Returns true if the activity has been left running, or 14967 * false if <var>starting</var> is being destroyed to match the new 14968 * configuration. 14969 * @param persistent TODO 14970 */ 14971 boolean updateConfigurationLocked(Configuration values, 14972 ActivityRecord starting, boolean persistent, boolean initLocale) { 14973 int changes = 0; 14974 14975 if (values != null) { 14976 Configuration newConfig = new Configuration(mConfiguration); 14977 changes = newConfig.updateFrom(values); 14978 if (changes != 0) { 14979 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14980 Slog.i(TAG, "Updating configuration to: " + values); 14981 } 14982 14983 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14984 14985 if (values.locale != null && !initLocale) { 14986 saveLocaleLocked(values.locale, 14987 !values.locale.equals(mConfiguration.locale), 14988 values.userSetLocale); 14989 } 14990 14991 mConfigurationSeq++; 14992 if (mConfigurationSeq <= 0) { 14993 mConfigurationSeq = 1; 14994 } 14995 newConfig.seq = mConfigurationSeq; 14996 mConfiguration = newConfig; 14997 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14998 //mUsageStatsService.noteStartConfig(newConfig); 14999 15000 final Configuration configCopy = new Configuration(mConfiguration); 15001 15002 // TODO: If our config changes, should we auto dismiss any currently 15003 // showing dialogs? 15004 mShowDialogs = shouldShowDialogs(newConfig); 15005 15006 AttributeCache ac = AttributeCache.instance(); 15007 if (ac != null) { 15008 ac.updateConfiguration(configCopy); 15009 } 15010 15011 // Make sure all resources in our process are updated 15012 // right now, so that anyone who is going to retrieve 15013 // resource values after we return will be sure to get 15014 // the new ones. This is especially important during 15015 // boot, where the first config change needs to guarantee 15016 // all resources have that config before following boot 15017 // code is executed. 15018 mSystemThread.applyConfigurationToResources(configCopy); 15019 15020 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15021 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15022 msg.obj = new Configuration(configCopy); 15023 mHandler.sendMessage(msg); 15024 } 15025 15026 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15027 ProcessRecord app = mLruProcesses.get(i); 15028 try { 15029 if (app.thread != null) { 15030 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15031 + app.processName + " new config " + mConfiguration); 15032 app.thread.scheduleConfigurationChanged(configCopy); 15033 } 15034 } catch (Exception e) { 15035 } 15036 } 15037 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15038 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15039 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15040 | Intent.FLAG_RECEIVER_FOREGROUND); 15041 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15042 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15043 Process.SYSTEM_UID, UserHandle.USER_ALL); 15044 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15045 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15046 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15047 broadcastIntentLocked(null, null, intent, 15048 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15049 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15050 } 15051 } 15052 } 15053 15054 boolean kept = true; 15055 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15056 // mainStack is null during startup. 15057 if (mainStack != null) { 15058 if (changes != 0 && starting == null) { 15059 // If the configuration changed, and the caller is not already 15060 // in the process of starting an activity, then find the top 15061 // activity to check if its configuration needs to change. 15062 starting = mainStack.topRunningActivityLocked(null); 15063 } 15064 15065 if (starting != null) { 15066 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15067 // And we need to make sure at this point that all other activities 15068 // are made visible with the correct configuration. 15069 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15070 } 15071 } 15072 15073 if (values != null && mWindowManager != null) { 15074 mWindowManager.setNewConfiguration(mConfiguration); 15075 } 15076 15077 return kept; 15078 } 15079 15080 /** 15081 * Decide based on the configuration whether we should shouw the ANR, 15082 * crash, etc dialogs. The idea is that if there is no affordnace to 15083 * press the on-screen buttons, we shouldn't show the dialog. 15084 * 15085 * A thought: SystemUI might also want to get told about this, the Power 15086 * dialog / global actions also might want different behaviors. 15087 */ 15088 private static final boolean shouldShowDialogs(Configuration config) { 15089 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15090 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15091 } 15092 15093 /** 15094 * Save the locale. You must be inside a synchronized (this) block. 15095 */ 15096 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15097 if(isDiff) { 15098 SystemProperties.set("user.language", l.getLanguage()); 15099 SystemProperties.set("user.region", l.getCountry()); 15100 } 15101 15102 if(isPersist) { 15103 SystemProperties.set("persist.sys.language", l.getLanguage()); 15104 SystemProperties.set("persist.sys.country", l.getCountry()); 15105 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15106 } 15107 } 15108 15109 @Override 15110 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15111 ActivityRecord srec = ActivityRecord.forToken(token); 15112 return srec != null && srec.task.affinity != null && 15113 srec.task.affinity.equals(destAffinity); 15114 } 15115 15116 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15117 Intent resultData) { 15118 15119 synchronized (this) { 15120 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15121 if (stack != null) { 15122 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15123 } 15124 return false; 15125 } 15126 } 15127 15128 public int getLaunchedFromUid(IBinder activityToken) { 15129 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15130 if (srec == null) { 15131 return -1; 15132 } 15133 return srec.launchedFromUid; 15134 } 15135 15136 public String getLaunchedFromPackage(IBinder activityToken) { 15137 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15138 if (srec == null) { 15139 return null; 15140 } 15141 return srec.launchedFromPackage; 15142 } 15143 15144 // ========================================================= 15145 // LIFETIME MANAGEMENT 15146 // ========================================================= 15147 15148 // Returns which broadcast queue the app is the current [or imminent] receiver 15149 // on, or 'null' if the app is not an active broadcast recipient. 15150 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15151 BroadcastRecord r = app.curReceiver; 15152 if (r != null) { 15153 return r.queue; 15154 } 15155 15156 // It's not the current receiver, but it might be starting up to become one 15157 synchronized (this) { 15158 for (BroadcastQueue queue : mBroadcastQueues) { 15159 r = queue.mPendingBroadcast; 15160 if (r != null && r.curApp == app) { 15161 // found it; report which queue it's in 15162 return queue; 15163 } 15164 } 15165 } 15166 15167 return null; 15168 } 15169 15170 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15171 boolean doingAll, long now) { 15172 if (mAdjSeq == app.adjSeq) { 15173 // This adjustment has already been computed. 15174 return app.curRawAdj; 15175 } 15176 15177 if (app.thread == null) { 15178 app.adjSeq = mAdjSeq; 15179 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15180 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15181 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15182 } 15183 15184 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15185 app.adjSource = null; 15186 app.adjTarget = null; 15187 app.empty = false; 15188 app.cached = false; 15189 15190 final int activitiesSize = app.activities.size(); 15191 15192 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15193 // The max adjustment doesn't allow this app to be anything 15194 // below foreground, so it is not worth doing work for it. 15195 app.adjType = "fixed"; 15196 app.adjSeq = mAdjSeq; 15197 app.curRawAdj = app.maxAdj; 15198 app.foregroundActivities = false; 15199 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15200 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15201 // System processes can do UI, and when they do we want to have 15202 // them trim their memory after the user leaves the UI. To 15203 // facilitate this, here we need to determine whether or not it 15204 // is currently showing UI. 15205 app.systemNoUi = true; 15206 if (app == TOP_APP) { 15207 app.systemNoUi = false; 15208 } else if (activitiesSize > 0) { 15209 for (int j = 0; j < activitiesSize; j++) { 15210 final ActivityRecord r = app.activities.get(j); 15211 if (r.visible) { 15212 app.systemNoUi = false; 15213 } 15214 } 15215 } 15216 if (!app.systemNoUi) { 15217 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15218 } 15219 return (app.curAdj=app.maxAdj); 15220 } 15221 15222 app.systemNoUi = false; 15223 15224 // Determine the importance of the process, starting with most 15225 // important to least, and assign an appropriate OOM adjustment. 15226 int adj; 15227 int schedGroup; 15228 int procState; 15229 boolean foregroundActivities = false; 15230 BroadcastQueue queue; 15231 if (app == TOP_APP) { 15232 // The last app on the list is the foreground app. 15233 adj = ProcessList.FOREGROUND_APP_ADJ; 15234 schedGroup = Process.THREAD_GROUP_DEFAULT; 15235 app.adjType = "top-activity"; 15236 foregroundActivities = true; 15237 procState = ActivityManager.PROCESS_STATE_TOP; 15238 } else if (app.instrumentationClass != null) { 15239 // Don't want to kill running instrumentation. 15240 adj = ProcessList.FOREGROUND_APP_ADJ; 15241 schedGroup = Process.THREAD_GROUP_DEFAULT; 15242 app.adjType = "instrumentation"; 15243 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15244 } else if ((queue = isReceivingBroadcast(app)) != null) { 15245 // An app that is currently receiving a broadcast also 15246 // counts as being in the foreground for OOM killer purposes. 15247 // It's placed in a sched group based on the nature of the 15248 // broadcast as reflected by which queue it's active in. 15249 adj = ProcessList.FOREGROUND_APP_ADJ; 15250 schedGroup = (queue == mFgBroadcastQueue) 15251 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15252 app.adjType = "broadcast"; 15253 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15254 } else if (app.executingServices.size() > 0) { 15255 // An app that is currently executing a service callback also 15256 // counts as being in the foreground. 15257 adj = ProcessList.FOREGROUND_APP_ADJ; 15258 schedGroup = app.execServicesFg ? 15259 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15260 app.adjType = "exec-service"; 15261 procState = ActivityManager.PROCESS_STATE_SERVICE; 15262 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15263 } else { 15264 // As far as we know the process is empty. We may change our mind later. 15265 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15266 // At this point we don't actually know the adjustment. Use the cached adj 15267 // value that the caller wants us to. 15268 adj = cachedAdj; 15269 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15270 app.cached = true; 15271 app.empty = true; 15272 app.adjType = "cch-empty"; 15273 } 15274 15275 // Examine all activities if not already foreground. 15276 if (!foregroundActivities && activitiesSize > 0) { 15277 for (int j = 0; j < activitiesSize; j++) { 15278 final ActivityRecord r = app.activities.get(j); 15279 if (r.app != app) { 15280 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15281 + app + "?!?"); 15282 continue; 15283 } 15284 if (r.visible) { 15285 // App has a visible activity; only upgrade adjustment. 15286 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15287 adj = ProcessList.VISIBLE_APP_ADJ; 15288 app.adjType = "visible"; 15289 } 15290 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15291 procState = ActivityManager.PROCESS_STATE_TOP; 15292 } 15293 schedGroup = Process.THREAD_GROUP_DEFAULT; 15294 app.cached = false; 15295 app.empty = false; 15296 foregroundActivities = true; 15297 break; 15298 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15299 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15300 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15301 app.adjType = "pausing"; 15302 } 15303 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15304 procState = ActivityManager.PROCESS_STATE_TOP; 15305 } 15306 schedGroup = Process.THREAD_GROUP_DEFAULT; 15307 app.cached = false; 15308 app.empty = false; 15309 foregroundActivities = true; 15310 } else if (r.state == ActivityState.STOPPING) { 15311 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15312 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15313 app.adjType = "stopping"; 15314 } 15315 // For the process state, we will at this point consider the 15316 // process to be cached. It will be cached either as an activity 15317 // or empty depending on whether the activity is finishing. We do 15318 // this so that we can treat the process as cached for purposes of 15319 // memory trimming (determing current memory level, trim command to 15320 // send to process) since there can be an arbitrary number of stopping 15321 // processes and they should soon all go into the cached state. 15322 if (!r.finishing) { 15323 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15324 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15325 } 15326 } 15327 app.cached = false; 15328 app.empty = false; 15329 foregroundActivities = true; 15330 } else { 15331 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15332 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15333 app.adjType = "cch-act"; 15334 } 15335 } 15336 } 15337 } 15338 15339 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15340 if (app.foregroundServices) { 15341 // The user is aware of this app, so make it visible. 15342 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15343 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15344 app.cached = false; 15345 app.adjType = "fg-service"; 15346 schedGroup = Process.THREAD_GROUP_DEFAULT; 15347 } else if (app.forcingToForeground != null) { 15348 // The user is aware of this app, so make it visible. 15349 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15350 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15351 app.cached = false; 15352 app.adjType = "force-fg"; 15353 app.adjSource = app.forcingToForeground; 15354 schedGroup = Process.THREAD_GROUP_DEFAULT; 15355 } 15356 } 15357 15358 if (app == mHeavyWeightProcess) { 15359 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15360 // We don't want to kill the current heavy-weight process. 15361 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15362 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15363 app.cached = false; 15364 app.adjType = "heavy"; 15365 } 15366 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15367 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15368 } 15369 } 15370 15371 if (app == mHomeProcess) { 15372 if (adj > ProcessList.HOME_APP_ADJ) { 15373 // This process is hosting what we currently consider to be the 15374 // home app, so we don't want to let it go into the background. 15375 adj = ProcessList.HOME_APP_ADJ; 15376 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15377 app.cached = false; 15378 app.adjType = "home"; 15379 } 15380 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15381 procState = ActivityManager.PROCESS_STATE_HOME; 15382 } 15383 } 15384 15385 if (app == mPreviousProcess && app.activities.size() > 0) { 15386 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15387 // This was the previous process that showed UI to the user. 15388 // We want to try to keep it around more aggressively, to give 15389 // a good experience around switching between two apps. 15390 adj = ProcessList.PREVIOUS_APP_ADJ; 15391 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15392 app.cached = false; 15393 app.adjType = "previous"; 15394 } 15395 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15396 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15397 } 15398 } 15399 15400 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15401 + " reason=" + app.adjType); 15402 15403 // By default, we use the computed adjustment. It may be changed if 15404 // there are applications dependent on our services or providers, but 15405 // this gives us a baseline and makes sure we don't get into an 15406 // infinite recursion. 15407 app.adjSeq = mAdjSeq; 15408 app.curRawAdj = adj; 15409 app.hasStartedServices = false; 15410 15411 if (mBackupTarget != null && app == mBackupTarget.app) { 15412 // If possible we want to avoid killing apps while they're being backed up 15413 if (adj > ProcessList.BACKUP_APP_ADJ) { 15414 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15415 adj = ProcessList.BACKUP_APP_ADJ; 15416 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15417 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15418 } 15419 app.adjType = "backup"; 15420 app.cached = false; 15421 } 15422 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15423 procState = ActivityManager.PROCESS_STATE_BACKUP; 15424 } 15425 } 15426 15427 boolean mayBeTop = false; 15428 15429 for (int is = app.services.size()-1; 15430 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15431 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15432 || procState > ActivityManager.PROCESS_STATE_TOP); 15433 is--) { 15434 ServiceRecord s = app.services.valueAt(is); 15435 if (s.startRequested) { 15436 app.hasStartedServices = true; 15437 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15438 procState = ActivityManager.PROCESS_STATE_SERVICE; 15439 } 15440 if (app.hasShownUi && app != mHomeProcess) { 15441 // If this process has shown some UI, let it immediately 15442 // go to the LRU list because it may be pretty heavy with 15443 // UI stuff. We'll tag it with a label just to help 15444 // debug and understand what is going on. 15445 if (adj > ProcessList.SERVICE_ADJ) { 15446 app.adjType = "cch-started-ui-services"; 15447 } 15448 } else { 15449 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15450 // This service has seen some activity within 15451 // recent memory, so we will keep its process ahead 15452 // of the background processes. 15453 if (adj > ProcessList.SERVICE_ADJ) { 15454 adj = ProcessList.SERVICE_ADJ; 15455 app.adjType = "started-services"; 15456 app.cached = false; 15457 } 15458 } 15459 // If we have let the service slide into the background 15460 // state, still have some text describing what it is doing 15461 // even though the service no longer has an impact. 15462 if (adj > ProcessList.SERVICE_ADJ) { 15463 app.adjType = "cch-started-services"; 15464 } 15465 } 15466 } 15467 for (int conni = s.connections.size()-1; 15468 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15469 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15470 || procState > ActivityManager.PROCESS_STATE_TOP); 15471 conni--) { 15472 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15473 for (int i = 0; 15474 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15475 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15476 || procState > ActivityManager.PROCESS_STATE_TOP); 15477 i++) { 15478 // XXX should compute this based on the max of 15479 // all connected clients. 15480 ConnectionRecord cr = clist.get(i); 15481 if (cr.binding.client == app) { 15482 // Binding to ourself is not interesting. 15483 continue; 15484 } 15485 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15486 ProcessRecord client = cr.binding.client; 15487 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15488 TOP_APP, doingAll, now); 15489 int clientProcState = client.curProcState; 15490 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15491 // If the other app is cached for any reason, for purposes here 15492 // we are going to consider it empty. The specific cached state 15493 // doesn't propagate except under certain conditions. 15494 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15495 } 15496 String adjType = null; 15497 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15498 // Not doing bind OOM management, so treat 15499 // this guy more like a started service. 15500 if (app.hasShownUi && app != mHomeProcess) { 15501 // If this process has shown some UI, let it immediately 15502 // go to the LRU list because it may be pretty heavy with 15503 // UI stuff. We'll tag it with a label just to help 15504 // debug and understand what is going on. 15505 if (adj > clientAdj) { 15506 adjType = "cch-bound-ui-services"; 15507 } 15508 app.cached = false; 15509 clientAdj = adj; 15510 clientProcState = procState; 15511 } else { 15512 if (now >= (s.lastActivity 15513 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15514 // This service has not seen activity within 15515 // recent memory, so allow it to drop to the 15516 // LRU list if there is no other reason to keep 15517 // it around. We'll also tag it with a label just 15518 // to help debug and undertand what is going on. 15519 if (adj > clientAdj) { 15520 adjType = "cch-bound-services"; 15521 } 15522 clientAdj = adj; 15523 } 15524 } 15525 } 15526 if (adj > clientAdj) { 15527 // If this process has recently shown UI, and 15528 // the process that is binding to it is less 15529 // important than being visible, then we don't 15530 // care about the binding as much as we care 15531 // about letting this process get into the LRU 15532 // list to be killed and restarted if needed for 15533 // memory. 15534 if (app.hasShownUi && app != mHomeProcess 15535 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15536 adjType = "cch-bound-ui-services"; 15537 } else { 15538 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15539 |Context.BIND_IMPORTANT)) != 0) { 15540 adj = clientAdj; 15541 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15542 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15543 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15544 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15545 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15546 adj = clientAdj; 15547 } else { 15548 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15549 adj = ProcessList.VISIBLE_APP_ADJ; 15550 } 15551 } 15552 if (!client.cached) { 15553 app.cached = false; 15554 } 15555 adjType = "service"; 15556 } 15557 } 15558 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15559 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15560 schedGroup = Process.THREAD_GROUP_DEFAULT; 15561 } 15562 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15563 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15564 // Special handling of clients who are in the top state. 15565 // We *may* want to consider this process to be in the 15566 // top state as well, but only if there is not another 15567 // reason for it to be running. Being on the top is a 15568 // special state, meaning you are specifically running 15569 // for the current top app. If the process is already 15570 // running in the background for some other reason, it 15571 // is more important to continue considering it to be 15572 // in the background state. 15573 mayBeTop = true; 15574 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15575 } else { 15576 // Special handling for above-top states (persistent 15577 // processes). These should not bring the current process 15578 // into the top state, since they are not on top. Instead 15579 // give them the best state after that. 15580 clientProcState = 15581 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15582 } 15583 } 15584 } else { 15585 if (clientProcState < 15586 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15587 clientProcState = 15588 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15589 } 15590 } 15591 if (procState > clientProcState) { 15592 procState = clientProcState; 15593 } 15594 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15595 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15596 app.pendingUiClean = true; 15597 } 15598 if (adjType != null) { 15599 app.adjType = adjType; 15600 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15601 .REASON_SERVICE_IN_USE; 15602 app.adjSource = cr.binding.client; 15603 app.adjSourceProcState = clientProcState; 15604 app.adjTarget = s.name; 15605 } 15606 } 15607 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15608 app.treatLikeActivity = true; 15609 } 15610 final ActivityRecord a = cr.activity; 15611 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15612 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15613 (a.visible || a.state == ActivityState.RESUMED 15614 || a.state == ActivityState.PAUSING)) { 15615 adj = ProcessList.FOREGROUND_APP_ADJ; 15616 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15617 schedGroup = Process.THREAD_GROUP_DEFAULT; 15618 } 15619 app.cached = false; 15620 app.adjType = "service"; 15621 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15622 .REASON_SERVICE_IN_USE; 15623 app.adjSource = a; 15624 app.adjSourceProcState = procState; 15625 app.adjTarget = s.name; 15626 } 15627 } 15628 } 15629 } 15630 } 15631 15632 for (int provi = app.pubProviders.size()-1; 15633 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15634 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15635 || procState > ActivityManager.PROCESS_STATE_TOP); 15636 provi--) { 15637 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15638 for (int i = cpr.connections.size()-1; 15639 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15640 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15641 || procState > ActivityManager.PROCESS_STATE_TOP); 15642 i--) { 15643 ContentProviderConnection conn = cpr.connections.get(i); 15644 ProcessRecord client = conn.client; 15645 if (client == app) { 15646 // Being our own client is not interesting. 15647 continue; 15648 } 15649 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15650 int clientProcState = client.curProcState; 15651 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15652 // If the other app is cached for any reason, for purposes here 15653 // we are going to consider it empty. 15654 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15655 } 15656 if (adj > clientAdj) { 15657 if (app.hasShownUi && app != mHomeProcess 15658 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15659 app.adjType = "cch-ui-provider"; 15660 } else { 15661 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15662 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15663 app.adjType = "provider"; 15664 } 15665 app.cached &= client.cached; 15666 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15667 .REASON_PROVIDER_IN_USE; 15668 app.adjSource = client; 15669 app.adjSourceProcState = clientProcState; 15670 app.adjTarget = cpr.name; 15671 } 15672 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15673 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15674 // Special handling of clients who are in the top state. 15675 // We *may* want to consider this process to be in the 15676 // top state as well, but only if there is not another 15677 // reason for it to be running. Being on the top is a 15678 // special state, meaning you are specifically running 15679 // for the current top app. If the process is already 15680 // running in the background for some other reason, it 15681 // is more important to continue considering it to be 15682 // in the background state. 15683 mayBeTop = true; 15684 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15685 } else { 15686 // Special handling for above-top states (persistent 15687 // processes). These should not bring the current process 15688 // into the top state, since they are not on top. Instead 15689 // give them the best state after that. 15690 clientProcState = 15691 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15692 } 15693 } 15694 if (procState > clientProcState) { 15695 procState = clientProcState; 15696 } 15697 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15698 schedGroup = Process.THREAD_GROUP_DEFAULT; 15699 } 15700 } 15701 // If the provider has external (non-framework) process 15702 // dependencies, ensure that its adjustment is at least 15703 // FOREGROUND_APP_ADJ. 15704 if (cpr.hasExternalProcessHandles()) { 15705 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15706 adj = ProcessList.FOREGROUND_APP_ADJ; 15707 schedGroup = Process.THREAD_GROUP_DEFAULT; 15708 app.cached = false; 15709 app.adjType = "provider"; 15710 app.adjTarget = cpr.name; 15711 } 15712 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15713 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15714 } 15715 } 15716 } 15717 15718 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15719 // A client of one of our services or providers is in the top state. We 15720 // *may* want to be in the top state, but not if we are already running in 15721 // the background for some other reason. For the decision here, we are going 15722 // to pick out a few specific states that we want to remain in when a client 15723 // is top (states that tend to be longer-term) and otherwise allow it to go 15724 // to the top state. 15725 switch (procState) { 15726 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15727 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15728 case ActivityManager.PROCESS_STATE_SERVICE: 15729 // These all are longer-term states, so pull them up to the top 15730 // of the background states, but not all the way to the top state. 15731 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15732 break; 15733 default: 15734 // Otherwise, top is a better choice, so take it. 15735 procState = ActivityManager.PROCESS_STATE_TOP; 15736 break; 15737 } 15738 } 15739 15740 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15741 if (app.hasClientActivities) { 15742 // This is a cached process, but with client activities. Mark it so. 15743 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15744 app.adjType = "cch-client-act"; 15745 } else if (app.treatLikeActivity) { 15746 // This is a cached process, but somebody wants us to treat it like it has 15747 // an activity, okay! 15748 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15749 app.adjType = "cch-as-act"; 15750 } 15751 } 15752 15753 if (adj == ProcessList.SERVICE_ADJ) { 15754 if (doingAll) { 15755 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15756 mNewNumServiceProcs++; 15757 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15758 if (!app.serviceb) { 15759 // This service isn't far enough down on the LRU list to 15760 // normally be a B service, but if we are low on RAM and it 15761 // is large we want to force it down since we would prefer to 15762 // keep launcher over it. 15763 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15764 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15765 app.serviceHighRam = true; 15766 app.serviceb = true; 15767 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15768 } else { 15769 mNewNumAServiceProcs++; 15770 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15771 } 15772 } else { 15773 app.serviceHighRam = false; 15774 } 15775 } 15776 if (app.serviceb) { 15777 adj = ProcessList.SERVICE_B_ADJ; 15778 } 15779 } 15780 15781 app.curRawAdj = adj; 15782 15783 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15784 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15785 if (adj > app.maxAdj) { 15786 adj = app.maxAdj; 15787 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15788 schedGroup = Process.THREAD_GROUP_DEFAULT; 15789 } 15790 } 15791 15792 // Do final modification to adj. Everything we do between here and applying 15793 // the final setAdj must be done in this function, because we will also use 15794 // it when computing the final cached adj later. Note that we don't need to 15795 // worry about this for max adj above, since max adj will always be used to 15796 // keep it out of the cached vaues. 15797 app.curAdj = app.modifyRawOomAdj(adj); 15798 app.curSchedGroup = schedGroup; 15799 app.curProcState = procState; 15800 app.foregroundActivities = foregroundActivities; 15801 15802 return app.curRawAdj; 15803 } 15804 15805 /** 15806 * Schedule PSS collection of a process. 15807 */ 15808 void requestPssLocked(ProcessRecord proc, int procState) { 15809 if (mPendingPssProcesses.contains(proc)) { 15810 return; 15811 } 15812 if (mPendingPssProcesses.size() == 0) { 15813 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15814 } 15815 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15816 proc.pssProcState = procState; 15817 mPendingPssProcesses.add(proc); 15818 } 15819 15820 /** 15821 * Schedule PSS collection of all processes. 15822 */ 15823 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15824 if (!always) { 15825 if (now < (mLastFullPssTime + 15826 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15827 return; 15828 } 15829 } 15830 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15831 mLastFullPssTime = now; 15832 mFullPssPending = true; 15833 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15834 mPendingPssProcesses.clear(); 15835 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15836 ProcessRecord app = mLruProcesses.get(i); 15837 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15838 app.pssProcState = app.setProcState; 15839 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15840 isSleeping(), now); 15841 mPendingPssProcesses.add(app); 15842 } 15843 } 15844 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15845 } 15846 15847 /** 15848 * Ask a given process to GC right now. 15849 */ 15850 final void performAppGcLocked(ProcessRecord app) { 15851 try { 15852 app.lastRequestedGc = SystemClock.uptimeMillis(); 15853 if (app.thread != null) { 15854 if (app.reportLowMemory) { 15855 app.reportLowMemory = false; 15856 app.thread.scheduleLowMemory(); 15857 } else { 15858 app.thread.processInBackground(); 15859 } 15860 } 15861 } catch (Exception e) { 15862 // whatever. 15863 } 15864 } 15865 15866 /** 15867 * Returns true if things are idle enough to perform GCs. 15868 */ 15869 private final boolean canGcNowLocked() { 15870 boolean processingBroadcasts = false; 15871 for (BroadcastQueue q : mBroadcastQueues) { 15872 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15873 processingBroadcasts = true; 15874 } 15875 } 15876 return !processingBroadcasts 15877 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15878 } 15879 15880 /** 15881 * Perform GCs on all processes that are waiting for it, but only 15882 * if things are idle. 15883 */ 15884 final void performAppGcsLocked() { 15885 final int N = mProcessesToGc.size(); 15886 if (N <= 0) { 15887 return; 15888 } 15889 if (canGcNowLocked()) { 15890 while (mProcessesToGc.size() > 0) { 15891 ProcessRecord proc = mProcessesToGc.remove(0); 15892 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15893 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15894 <= SystemClock.uptimeMillis()) { 15895 // To avoid spamming the system, we will GC processes one 15896 // at a time, waiting a few seconds between each. 15897 performAppGcLocked(proc); 15898 scheduleAppGcsLocked(); 15899 return; 15900 } else { 15901 // It hasn't been long enough since we last GCed this 15902 // process... put it in the list to wait for its time. 15903 addProcessToGcListLocked(proc); 15904 break; 15905 } 15906 } 15907 } 15908 15909 scheduleAppGcsLocked(); 15910 } 15911 } 15912 15913 /** 15914 * If all looks good, perform GCs on all processes waiting for them. 15915 */ 15916 final void performAppGcsIfAppropriateLocked() { 15917 if (canGcNowLocked()) { 15918 performAppGcsLocked(); 15919 return; 15920 } 15921 // Still not idle, wait some more. 15922 scheduleAppGcsLocked(); 15923 } 15924 15925 /** 15926 * Schedule the execution of all pending app GCs. 15927 */ 15928 final void scheduleAppGcsLocked() { 15929 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15930 15931 if (mProcessesToGc.size() > 0) { 15932 // Schedule a GC for the time to the next process. 15933 ProcessRecord proc = mProcessesToGc.get(0); 15934 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15935 15936 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15937 long now = SystemClock.uptimeMillis(); 15938 if (when < (now+GC_TIMEOUT)) { 15939 when = now + GC_TIMEOUT; 15940 } 15941 mHandler.sendMessageAtTime(msg, when); 15942 } 15943 } 15944 15945 /** 15946 * Add a process to the array of processes waiting to be GCed. Keeps the 15947 * list in sorted order by the last GC time. The process can't already be 15948 * on the list. 15949 */ 15950 final void addProcessToGcListLocked(ProcessRecord proc) { 15951 boolean added = false; 15952 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15953 if (mProcessesToGc.get(i).lastRequestedGc < 15954 proc.lastRequestedGc) { 15955 added = true; 15956 mProcessesToGc.add(i+1, proc); 15957 break; 15958 } 15959 } 15960 if (!added) { 15961 mProcessesToGc.add(0, proc); 15962 } 15963 } 15964 15965 /** 15966 * Set up to ask a process to GC itself. This will either do it 15967 * immediately, or put it on the list of processes to gc the next 15968 * time things are idle. 15969 */ 15970 final void scheduleAppGcLocked(ProcessRecord app) { 15971 long now = SystemClock.uptimeMillis(); 15972 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15973 return; 15974 } 15975 if (!mProcessesToGc.contains(app)) { 15976 addProcessToGcListLocked(app); 15977 scheduleAppGcsLocked(); 15978 } 15979 } 15980 15981 final void checkExcessivePowerUsageLocked(boolean doKills) { 15982 updateCpuStatsNow(); 15983 15984 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15985 boolean doWakeKills = doKills; 15986 boolean doCpuKills = doKills; 15987 if (mLastPowerCheckRealtime == 0) { 15988 doWakeKills = false; 15989 } 15990 if (mLastPowerCheckUptime == 0) { 15991 doCpuKills = false; 15992 } 15993 if (stats.isScreenOn()) { 15994 doWakeKills = false; 15995 } 15996 final long curRealtime = SystemClock.elapsedRealtime(); 15997 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15998 final long curUptime = SystemClock.uptimeMillis(); 15999 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16000 mLastPowerCheckRealtime = curRealtime; 16001 mLastPowerCheckUptime = curUptime; 16002 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16003 doWakeKills = false; 16004 } 16005 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16006 doCpuKills = false; 16007 } 16008 int i = mLruProcesses.size(); 16009 while (i > 0) { 16010 i--; 16011 ProcessRecord app = mLruProcesses.get(i); 16012 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16013 long wtime; 16014 synchronized (stats) { 16015 wtime = stats.getProcessWakeTime(app.info.uid, 16016 app.pid, curRealtime); 16017 } 16018 long wtimeUsed = wtime - app.lastWakeTime; 16019 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16020 if (DEBUG_POWER) { 16021 StringBuilder sb = new StringBuilder(128); 16022 sb.append("Wake for "); 16023 app.toShortString(sb); 16024 sb.append(": over "); 16025 TimeUtils.formatDuration(realtimeSince, sb); 16026 sb.append(" used "); 16027 TimeUtils.formatDuration(wtimeUsed, sb); 16028 sb.append(" ("); 16029 sb.append((wtimeUsed*100)/realtimeSince); 16030 sb.append("%)"); 16031 Slog.i(TAG, sb.toString()); 16032 sb.setLength(0); 16033 sb.append("CPU for "); 16034 app.toShortString(sb); 16035 sb.append(": over "); 16036 TimeUtils.formatDuration(uptimeSince, sb); 16037 sb.append(" used "); 16038 TimeUtils.formatDuration(cputimeUsed, sb); 16039 sb.append(" ("); 16040 sb.append((cputimeUsed*100)/uptimeSince); 16041 sb.append("%)"); 16042 Slog.i(TAG, sb.toString()); 16043 } 16044 // If a process has held a wake lock for more 16045 // than 50% of the time during this period, 16046 // that sounds bad. Kill! 16047 if (doWakeKills && realtimeSince > 0 16048 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16049 synchronized (stats) { 16050 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16051 realtimeSince, wtimeUsed); 16052 } 16053 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16054 + " during " + realtimeSince); 16055 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16056 } else if (doCpuKills && uptimeSince > 0 16057 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16058 synchronized (stats) { 16059 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16060 uptimeSince, cputimeUsed); 16061 } 16062 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16063 + " during " + uptimeSince); 16064 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16065 } else { 16066 app.lastWakeTime = wtime; 16067 app.lastCpuTime = app.curCpuTime; 16068 } 16069 } 16070 } 16071 } 16072 16073 private final boolean applyOomAdjLocked(ProcessRecord app, 16074 ProcessRecord TOP_APP, boolean doingAll, long now) { 16075 boolean success = true; 16076 16077 if (app.curRawAdj != app.setRawAdj) { 16078 app.setRawAdj = app.curRawAdj; 16079 } 16080 16081 int changes = 0; 16082 16083 if (app.curAdj != app.setAdj) { 16084 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16085 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16086 TAG, "Set " + app.pid + " " + app.processName + 16087 " adj " + app.curAdj + ": " + app.adjType); 16088 app.setAdj = app.curAdj; 16089 } 16090 16091 if (app.setSchedGroup != app.curSchedGroup) { 16092 app.setSchedGroup = app.curSchedGroup; 16093 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16094 "Setting process group of " + app.processName 16095 + " to " + app.curSchedGroup); 16096 if (app.waitingToKill != null && 16097 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16098 killUnneededProcessLocked(app, app.waitingToKill); 16099 success = false; 16100 } else { 16101 if (true) { 16102 long oldId = Binder.clearCallingIdentity(); 16103 try { 16104 Process.setProcessGroup(app.pid, app.curSchedGroup); 16105 } catch (Exception e) { 16106 Slog.w(TAG, "Failed setting process group of " + app.pid 16107 + " to " + app.curSchedGroup); 16108 e.printStackTrace(); 16109 } finally { 16110 Binder.restoreCallingIdentity(oldId); 16111 } 16112 } else { 16113 if (app.thread != null) { 16114 try { 16115 app.thread.setSchedulingGroup(app.curSchedGroup); 16116 } catch (RemoteException e) { 16117 } 16118 } 16119 } 16120 Process.setSwappiness(app.pid, 16121 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16122 } 16123 } 16124 if (app.repForegroundActivities != app.foregroundActivities) { 16125 app.repForegroundActivities = app.foregroundActivities; 16126 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16127 } 16128 if (app.repProcState != app.curProcState) { 16129 app.repProcState = app.curProcState; 16130 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16131 if (app.thread != null) { 16132 try { 16133 if (false) { 16134 //RuntimeException h = new RuntimeException("here"); 16135 Slog.i(TAG, "Sending new process state " + app.repProcState 16136 + " to " + app /*, h*/); 16137 } 16138 app.thread.setProcessState(app.repProcState); 16139 } catch (RemoteException e) { 16140 } 16141 } 16142 } 16143 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16144 app.setProcState)) { 16145 app.lastStateTime = now; 16146 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16147 isSleeping(), now); 16148 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16149 + ProcessList.makeProcStateString(app.setProcState) + " to " 16150 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16151 + (app.nextPssTime-now) + ": " + app); 16152 } else { 16153 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16154 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16155 requestPssLocked(app, app.setProcState); 16156 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16157 isSleeping(), now); 16158 } else if (false && DEBUG_PSS) { 16159 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16160 } 16161 } 16162 if (app.setProcState != app.curProcState) { 16163 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16164 "Proc state change of " + app.processName 16165 + " to " + app.curProcState); 16166 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16167 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16168 if (setImportant && !curImportant) { 16169 // This app is no longer something we consider important enough to allow to 16170 // use arbitrary amounts of battery power. Note 16171 // its current wake lock time to later know to kill it if 16172 // it is not behaving well. 16173 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16174 synchronized (stats) { 16175 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16176 app.pid, SystemClock.elapsedRealtime()); 16177 } 16178 app.lastCpuTime = app.curCpuTime; 16179 16180 } 16181 app.setProcState = app.curProcState; 16182 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16183 app.notCachedSinceIdle = false; 16184 } 16185 if (!doingAll) { 16186 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16187 } else { 16188 app.procStateChanged = true; 16189 } 16190 } 16191 16192 if (changes != 0) { 16193 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16194 int i = mPendingProcessChanges.size()-1; 16195 ProcessChangeItem item = null; 16196 while (i >= 0) { 16197 item = mPendingProcessChanges.get(i); 16198 if (item.pid == app.pid) { 16199 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16200 break; 16201 } 16202 i--; 16203 } 16204 if (i < 0) { 16205 // No existing item in pending changes; need a new one. 16206 final int NA = mAvailProcessChanges.size(); 16207 if (NA > 0) { 16208 item = mAvailProcessChanges.remove(NA-1); 16209 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16210 } else { 16211 item = new ProcessChangeItem(); 16212 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16213 } 16214 item.changes = 0; 16215 item.pid = app.pid; 16216 item.uid = app.info.uid; 16217 if (mPendingProcessChanges.size() == 0) { 16218 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16219 "*** Enqueueing dispatch processes changed!"); 16220 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16221 } 16222 mPendingProcessChanges.add(item); 16223 } 16224 item.changes |= changes; 16225 item.processState = app.repProcState; 16226 item.foregroundActivities = app.repForegroundActivities; 16227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16228 + Integer.toHexString(System.identityHashCode(item)) 16229 + " " + app.toShortString() + ": changes=" + item.changes 16230 + " procState=" + item.processState 16231 + " foreground=" + item.foregroundActivities 16232 + " type=" + app.adjType + " source=" + app.adjSource 16233 + " target=" + app.adjTarget); 16234 } 16235 16236 return success; 16237 } 16238 16239 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16240 if (proc.thread != null) { 16241 if (proc.baseProcessTracker != null) { 16242 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16243 } 16244 if (proc.repProcState >= 0) { 16245 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16246 proc.repProcState); 16247 } 16248 } 16249 } 16250 16251 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16252 ProcessRecord TOP_APP, boolean doingAll, long now) { 16253 if (app.thread == null) { 16254 return false; 16255 } 16256 16257 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16258 16259 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16260 } 16261 16262 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16263 boolean oomAdj) { 16264 if (isForeground != proc.foregroundServices) { 16265 proc.foregroundServices = isForeground; 16266 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16267 proc.info.uid); 16268 if (isForeground) { 16269 if (curProcs == null) { 16270 curProcs = new ArrayList<ProcessRecord>(); 16271 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16272 } 16273 if (!curProcs.contains(proc)) { 16274 curProcs.add(proc); 16275 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16276 proc.info.packageName, proc.info.uid); 16277 } 16278 } else { 16279 if (curProcs != null) { 16280 if (curProcs.remove(proc)) { 16281 mBatteryStatsService.noteEvent( 16282 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16283 proc.info.packageName, proc.info.uid); 16284 if (curProcs.size() <= 0) { 16285 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16286 } 16287 } 16288 } 16289 } 16290 if (oomAdj) { 16291 updateOomAdjLocked(); 16292 } 16293 } 16294 } 16295 16296 private final ActivityRecord resumedAppLocked() { 16297 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16298 String pkg; 16299 int uid; 16300 if (act != null) { 16301 pkg = act.packageName; 16302 uid = act.info.applicationInfo.uid; 16303 } else { 16304 pkg = null; 16305 uid = -1; 16306 } 16307 // Has the UID or resumed package name changed? 16308 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16309 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16310 if (mCurResumedPackage != null) { 16311 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16312 mCurResumedPackage, mCurResumedUid); 16313 } 16314 mCurResumedPackage = pkg; 16315 mCurResumedUid = uid; 16316 if (mCurResumedPackage != null) { 16317 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16318 mCurResumedPackage, mCurResumedUid); 16319 } 16320 } 16321 return act; 16322 } 16323 16324 final boolean updateOomAdjLocked(ProcessRecord app) { 16325 final ActivityRecord TOP_ACT = resumedAppLocked(); 16326 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16327 final boolean wasCached = app.cached; 16328 16329 mAdjSeq++; 16330 16331 // This is the desired cached adjusment we want to tell it to use. 16332 // If our app is currently cached, we know it, and that is it. Otherwise, 16333 // we don't know it yet, and it needs to now be cached we will then 16334 // need to do a complete oom adj. 16335 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16336 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16337 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16338 SystemClock.uptimeMillis()); 16339 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16340 // Changed to/from cached state, so apps after it in the LRU 16341 // list may also be changed. 16342 updateOomAdjLocked(); 16343 } 16344 return success; 16345 } 16346 16347 final void updateOomAdjLocked() { 16348 final ActivityRecord TOP_ACT = resumedAppLocked(); 16349 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16350 final long now = SystemClock.uptimeMillis(); 16351 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16352 final int N = mLruProcesses.size(); 16353 16354 if (false) { 16355 RuntimeException e = new RuntimeException(); 16356 e.fillInStackTrace(); 16357 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16358 } 16359 16360 mAdjSeq++; 16361 mNewNumServiceProcs = 0; 16362 mNewNumAServiceProcs = 0; 16363 16364 final int emptyProcessLimit; 16365 final int cachedProcessLimit; 16366 if (mProcessLimit <= 0) { 16367 emptyProcessLimit = cachedProcessLimit = 0; 16368 } else if (mProcessLimit == 1) { 16369 emptyProcessLimit = 1; 16370 cachedProcessLimit = 0; 16371 } else { 16372 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16373 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16374 } 16375 16376 // Let's determine how many processes we have running vs. 16377 // how many slots we have for background processes; we may want 16378 // to put multiple processes in a slot of there are enough of 16379 // them. 16380 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16381 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16382 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16383 if (numEmptyProcs > cachedProcessLimit) { 16384 // If there are more empty processes than our limit on cached 16385 // processes, then use the cached process limit for the factor. 16386 // This ensures that the really old empty processes get pushed 16387 // down to the bottom, so if we are running low on memory we will 16388 // have a better chance at keeping around more cached processes 16389 // instead of a gazillion empty processes. 16390 numEmptyProcs = cachedProcessLimit; 16391 } 16392 int emptyFactor = numEmptyProcs/numSlots; 16393 if (emptyFactor < 1) emptyFactor = 1; 16394 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16395 if (cachedFactor < 1) cachedFactor = 1; 16396 int stepCached = 0; 16397 int stepEmpty = 0; 16398 int numCached = 0; 16399 int numEmpty = 0; 16400 int numTrimming = 0; 16401 16402 mNumNonCachedProcs = 0; 16403 mNumCachedHiddenProcs = 0; 16404 16405 // First update the OOM adjustment for each of the 16406 // application processes based on their current state. 16407 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16408 int nextCachedAdj = curCachedAdj+1; 16409 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16410 int nextEmptyAdj = curEmptyAdj+2; 16411 for (int i=N-1; i>=0; i--) { 16412 ProcessRecord app = mLruProcesses.get(i); 16413 if (!app.killedByAm && app.thread != null) { 16414 app.procStateChanged = false; 16415 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16416 16417 // If we haven't yet assigned the final cached adj 16418 // to the process, do that now. 16419 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16420 switch (app.curProcState) { 16421 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16422 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16423 // This process is a cached process holding activities... 16424 // assign it the next cached value for that type, and then 16425 // step that cached level. 16426 app.curRawAdj = curCachedAdj; 16427 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16428 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16429 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16430 + ")"); 16431 if (curCachedAdj != nextCachedAdj) { 16432 stepCached++; 16433 if (stepCached >= cachedFactor) { 16434 stepCached = 0; 16435 curCachedAdj = nextCachedAdj; 16436 nextCachedAdj += 2; 16437 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16438 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16439 } 16440 } 16441 } 16442 break; 16443 default: 16444 // For everything else, assign next empty cached process 16445 // level and bump that up. Note that this means that 16446 // long-running services that have dropped down to the 16447 // cached level will be treated as empty (since their process 16448 // state is still as a service), which is what we want. 16449 app.curRawAdj = curEmptyAdj; 16450 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16451 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16452 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16453 + ")"); 16454 if (curEmptyAdj != nextEmptyAdj) { 16455 stepEmpty++; 16456 if (stepEmpty >= emptyFactor) { 16457 stepEmpty = 0; 16458 curEmptyAdj = nextEmptyAdj; 16459 nextEmptyAdj += 2; 16460 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16461 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16462 } 16463 } 16464 } 16465 break; 16466 } 16467 } 16468 16469 applyOomAdjLocked(app, TOP_APP, true, now); 16470 16471 // Count the number of process types. 16472 switch (app.curProcState) { 16473 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16474 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16475 mNumCachedHiddenProcs++; 16476 numCached++; 16477 if (numCached > cachedProcessLimit) { 16478 killUnneededProcessLocked(app, "cached #" + numCached); 16479 } 16480 break; 16481 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16482 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16483 && app.lastActivityTime < oldTime) { 16484 killUnneededProcessLocked(app, "empty for " 16485 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16486 / 1000) + "s"); 16487 } else { 16488 numEmpty++; 16489 if (numEmpty > emptyProcessLimit) { 16490 killUnneededProcessLocked(app, "empty #" + numEmpty); 16491 } 16492 } 16493 break; 16494 default: 16495 mNumNonCachedProcs++; 16496 break; 16497 } 16498 16499 if (app.isolated && app.services.size() <= 0) { 16500 // If this is an isolated process, and there are no 16501 // services running in it, then the process is no longer 16502 // needed. We agressively kill these because we can by 16503 // definition not re-use the same process again, and it is 16504 // good to avoid having whatever code was running in them 16505 // left sitting around after no longer needed. 16506 killUnneededProcessLocked(app, "isolated not needed"); 16507 } 16508 16509 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16510 && !app.killedByAm) { 16511 numTrimming++; 16512 } 16513 } 16514 } 16515 16516 mNumServiceProcs = mNewNumServiceProcs; 16517 16518 // Now determine the memory trimming level of background processes. 16519 // Unfortunately we need to start at the back of the list to do this 16520 // properly. We only do this if the number of background apps we 16521 // are managing to keep around is less than half the maximum we desire; 16522 // if we are keeping a good number around, we'll let them use whatever 16523 // memory they want. 16524 final int numCachedAndEmpty = numCached + numEmpty; 16525 int memFactor; 16526 if (numCached <= ProcessList.TRIM_CACHED_APPS 16527 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16528 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16529 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16530 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16531 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16532 } else { 16533 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16534 } 16535 } else { 16536 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16537 } 16538 // We always allow the memory level to go up (better). We only allow it to go 16539 // down if we are in a state where that is allowed, *and* the total number of processes 16540 // has gone down since last time. 16541 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16542 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16543 + " last=" + mLastNumProcesses); 16544 if (memFactor > mLastMemoryLevel) { 16545 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16546 memFactor = mLastMemoryLevel; 16547 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16548 } 16549 } 16550 mLastMemoryLevel = memFactor; 16551 mLastNumProcesses = mLruProcesses.size(); 16552 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16553 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16554 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16555 if (mLowRamStartTime == 0) { 16556 mLowRamStartTime = now; 16557 } 16558 int step = 0; 16559 int fgTrimLevel; 16560 switch (memFactor) { 16561 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16562 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16563 break; 16564 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16565 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16566 break; 16567 default: 16568 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16569 break; 16570 } 16571 int factor = numTrimming/3; 16572 int minFactor = 2; 16573 if (mHomeProcess != null) minFactor++; 16574 if (mPreviousProcess != null) minFactor++; 16575 if (factor < minFactor) factor = minFactor; 16576 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16577 for (int i=N-1; i>=0; i--) { 16578 ProcessRecord app = mLruProcesses.get(i); 16579 if (allChanged || app.procStateChanged) { 16580 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16581 app.procStateChanged = false; 16582 } 16583 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16584 && !app.killedByAm) { 16585 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16586 try { 16587 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16588 "Trimming memory of " + app.processName 16589 + " to " + curLevel); 16590 app.thread.scheduleTrimMemory(curLevel); 16591 } catch (RemoteException e) { 16592 } 16593 if (false) { 16594 // For now we won't do this; our memory trimming seems 16595 // to be good enough at this point that destroying 16596 // activities causes more harm than good. 16597 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16598 && app != mHomeProcess && app != mPreviousProcess) { 16599 // Need to do this on its own message because the stack may not 16600 // be in a consistent state at this point. 16601 // For these apps we will also finish their activities 16602 // to help them free memory. 16603 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16604 } 16605 } 16606 } 16607 app.trimMemoryLevel = curLevel; 16608 step++; 16609 if (step >= factor) { 16610 step = 0; 16611 switch (curLevel) { 16612 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16613 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16614 break; 16615 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16616 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16617 break; 16618 } 16619 } 16620 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16621 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16622 && app.thread != null) { 16623 try { 16624 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16625 "Trimming memory of heavy-weight " + app.processName 16626 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16627 app.thread.scheduleTrimMemory( 16628 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16629 } catch (RemoteException e) { 16630 } 16631 } 16632 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16633 } else { 16634 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16635 || app.systemNoUi) && app.pendingUiClean) { 16636 // If this application is now in the background and it 16637 // had done UI, then give it the special trim level to 16638 // have it free UI resources. 16639 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16640 if (app.trimMemoryLevel < level && app.thread != null) { 16641 try { 16642 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16643 "Trimming memory of bg-ui " + app.processName 16644 + " to " + level); 16645 app.thread.scheduleTrimMemory(level); 16646 } catch (RemoteException e) { 16647 } 16648 } 16649 app.pendingUiClean = false; 16650 } 16651 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16652 try { 16653 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16654 "Trimming memory of fg " + app.processName 16655 + " to " + fgTrimLevel); 16656 app.thread.scheduleTrimMemory(fgTrimLevel); 16657 } catch (RemoteException e) { 16658 } 16659 } 16660 app.trimMemoryLevel = fgTrimLevel; 16661 } 16662 } 16663 } else { 16664 if (mLowRamStartTime != 0) { 16665 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16666 mLowRamStartTime = 0; 16667 } 16668 for (int i=N-1; i>=0; i--) { 16669 ProcessRecord app = mLruProcesses.get(i); 16670 if (allChanged || app.procStateChanged) { 16671 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16672 app.procStateChanged = false; 16673 } 16674 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16675 || app.systemNoUi) && app.pendingUiClean) { 16676 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16677 && app.thread != null) { 16678 try { 16679 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16680 "Trimming memory of ui hidden " + app.processName 16681 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16682 app.thread.scheduleTrimMemory( 16683 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16684 } catch (RemoteException e) { 16685 } 16686 } 16687 app.pendingUiClean = false; 16688 } 16689 app.trimMemoryLevel = 0; 16690 } 16691 } 16692 16693 if (mAlwaysFinishActivities) { 16694 // Need to do this on its own message because the stack may not 16695 // be in a consistent state at this point. 16696 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16697 } 16698 16699 if (allChanged) { 16700 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16701 } 16702 16703 if (mProcessStats.shouldWriteNowLocked(now)) { 16704 mHandler.post(new Runnable() { 16705 @Override public void run() { 16706 synchronized (ActivityManagerService.this) { 16707 mProcessStats.writeStateAsyncLocked(); 16708 } 16709 } 16710 }); 16711 } 16712 16713 if (DEBUG_OOM_ADJ) { 16714 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16715 } 16716 } 16717 16718 final void trimApplications() { 16719 synchronized (this) { 16720 int i; 16721 16722 // First remove any unused application processes whose package 16723 // has been removed. 16724 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16725 final ProcessRecord app = mRemovedProcesses.get(i); 16726 if (app.activities.size() == 0 16727 && app.curReceiver == null && app.services.size() == 0) { 16728 Slog.i( 16729 TAG, "Exiting empty application process " 16730 + app.processName + " (" 16731 + (app.thread != null ? app.thread.asBinder() : null) 16732 + ")\n"); 16733 if (app.pid > 0 && app.pid != MY_PID) { 16734 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16735 app.processName, app.setAdj, "empty"); 16736 app.killedByAm = true; 16737 Process.killProcessQuiet(app.pid); 16738 Process.killProcessGroup(app.info.uid, app.pid); 16739 } else { 16740 try { 16741 app.thread.scheduleExit(); 16742 } catch (Exception e) { 16743 // Ignore exceptions. 16744 } 16745 } 16746 cleanUpApplicationRecordLocked(app, false, true, -1); 16747 mRemovedProcesses.remove(i); 16748 16749 if (app.persistent) { 16750 addAppLocked(app.info, false, null /* ABI override */); 16751 } 16752 } 16753 } 16754 16755 // Now update the oom adj for all processes. 16756 updateOomAdjLocked(); 16757 } 16758 } 16759 16760 /** This method sends the specified signal to each of the persistent apps */ 16761 public void signalPersistentProcesses(int sig) throws RemoteException { 16762 if (sig != Process.SIGNAL_USR1) { 16763 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16764 } 16765 16766 synchronized (this) { 16767 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16768 != PackageManager.PERMISSION_GRANTED) { 16769 throw new SecurityException("Requires permission " 16770 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16771 } 16772 16773 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16774 ProcessRecord r = mLruProcesses.get(i); 16775 if (r.thread != null && r.persistent) { 16776 Process.sendSignal(r.pid, sig); 16777 } 16778 } 16779 } 16780 } 16781 16782 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16783 if (proc == null || proc == mProfileProc) { 16784 proc = mProfileProc; 16785 path = mProfileFile; 16786 profileType = mProfileType; 16787 clearProfilerLocked(); 16788 } 16789 if (proc == null) { 16790 return; 16791 } 16792 try { 16793 proc.thread.profilerControl(false, path, null, profileType); 16794 } catch (RemoteException e) { 16795 throw new IllegalStateException("Process disappeared"); 16796 } 16797 } 16798 16799 private void clearProfilerLocked() { 16800 if (mProfileFd != null) { 16801 try { 16802 mProfileFd.close(); 16803 } catch (IOException e) { 16804 } 16805 } 16806 mProfileApp = null; 16807 mProfileProc = null; 16808 mProfileFile = null; 16809 mProfileType = 0; 16810 mAutoStopProfiler = false; 16811 } 16812 16813 public boolean profileControl(String process, int userId, boolean start, 16814 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16815 16816 try { 16817 synchronized (this) { 16818 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16819 // its own permission. 16820 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16821 != PackageManager.PERMISSION_GRANTED) { 16822 throw new SecurityException("Requires permission " 16823 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16824 } 16825 16826 if (start && fd == null) { 16827 throw new IllegalArgumentException("null fd"); 16828 } 16829 16830 ProcessRecord proc = null; 16831 if (process != null) { 16832 proc = findProcessLocked(process, userId, "profileControl"); 16833 } 16834 16835 if (start && (proc == null || proc.thread == null)) { 16836 throw new IllegalArgumentException("Unknown process: " + process); 16837 } 16838 16839 if (start) { 16840 stopProfilerLocked(null, null, 0); 16841 setProfileApp(proc.info, proc.processName, path, fd, false); 16842 mProfileProc = proc; 16843 mProfileType = profileType; 16844 try { 16845 fd = fd.dup(); 16846 } catch (IOException e) { 16847 fd = null; 16848 } 16849 proc.thread.profilerControl(start, path, fd, profileType); 16850 fd = null; 16851 mProfileFd = null; 16852 } else { 16853 stopProfilerLocked(proc, path, profileType); 16854 if (fd != null) { 16855 try { 16856 fd.close(); 16857 } catch (IOException e) { 16858 } 16859 } 16860 } 16861 16862 return true; 16863 } 16864 } catch (RemoteException e) { 16865 throw new IllegalStateException("Process disappeared"); 16866 } finally { 16867 if (fd != null) { 16868 try { 16869 fd.close(); 16870 } catch (IOException e) { 16871 } 16872 } 16873 } 16874 } 16875 16876 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16877 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16878 userId, true, ALLOW_FULL_ONLY, callName, null); 16879 ProcessRecord proc = null; 16880 try { 16881 int pid = Integer.parseInt(process); 16882 synchronized (mPidsSelfLocked) { 16883 proc = mPidsSelfLocked.get(pid); 16884 } 16885 } catch (NumberFormatException e) { 16886 } 16887 16888 if (proc == null) { 16889 ArrayMap<String, SparseArray<ProcessRecord>> all 16890 = mProcessNames.getMap(); 16891 SparseArray<ProcessRecord> procs = all.get(process); 16892 if (procs != null && procs.size() > 0) { 16893 proc = procs.valueAt(0); 16894 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16895 for (int i=1; i<procs.size(); i++) { 16896 ProcessRecord thisProc = procs.valueAt(i); 16897 if (thisProc.userId == userId) { 16898 proc = thisProc; 16899 break; 16900 } 16901 } 16902 } 16903 } 16904 } 16905 16906 return proc; 16907 } 16908 16909 public boolean dumpHeap(String process, int userId, boolean managed, 16910 String path, ParcelFileDescriptor fd) throws RemoteException { 16911 16912 try { 16913 synchronized (this) { 16914 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16915 // its own permission (same as profileControl). 16916 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16917 != PackageManager.PERMISSION_GRANTED) { 16918 throw new SecurityException("Requires permission " 16919 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16920 } 16921 16922 if (fd == null) { 16923 throw new IllegalArgumentException("null fd"); 16924 } 16925 16926 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16927 if (proc == null || proc.thread == null) { 16928 throw new IllegalArgumentException("Unknown process: " + process); 16929 } 16930 16931 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16932 if (!isDebuggable) { 16933 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16934 throw new SecurityException("Process not debuggable: " + proc); 16935 } 16936 } 16937 16938 proc.thread.dumpHeap(managed, path, fd); 16939 fd = null; 16940 return true; 16941 } 16942 } catch (RemoteException e) { 16943 throw new IllegalStateException("Process disappeared"); 16944 } finally { 16945 if (fd != null) { 16946 try { 16947 fd.close(); 16948 } catch (IOException e) { 16949 } 16950 } 16951 } 16952 } 16953 16954 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16955 public void monitor() { 16956 synchronized (this) { } 16957 } 16958 16959 void onCoreSettingsChange(Bundle settings) { 16960 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16961 ProcessRecord processRecord = mLruProcesses.get(i); 16962 try { 16963 if (processRecord.thread != null) { 16964 processRecord.thread.setCoreSettings(settings); 16965 } 16966 } catch (RemoteException re) { 16967 /* ignore */ 16968 } 16969 } 16970 } 16971 16972 // Multi-user methods 16973 16974 /** 16975 * Start user, if its not already running, but don't bring it to foreground. 16976 */ 16977 @Override 16978 public boolean startUserInBackground(final int userId) { 16979 return startUser(userId, /* foreground */ false); 16980 } 16981 16982 /** 16983 * Refreshes the list of users related to the current user when either a 16984 * user switch happens or when a new related user is started in the 16985 * background. 16986 */ 16987 private void updateCurrentProfileIdsLocked() { 16988 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16989 mCurrentUserId, false /* enabledOnly */); 16990 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16991 for (int i = 0; i < currentProfileIds.length; i++) { 16992 currentProfileIds[i] = profiles.get(i).id; 16993 } 16994 mCurrentProfileIds = currentProfileIds; 16995 16996 synchronized (mUserProfileGroupIdsSelfLocked) { 16997 mUserProfileGroupIdsSelfLocked.clear(); 16998 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 16999 for (int i = 0; i < users.size(); i++) { 17000 UserInfo user = users.get(i); 17001 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17002 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17003 } 17004 } 17005 } 17006 } 17007 17008 private Set getProfileIdsLocked(int userId) { 17009 Set userIds = new HashSet<Integer>(); 17010 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17011 userId, false /* enabledOnly */); 17012 for (UserInfo user : profiles) { 17013 userIds.add(Integer.valueOf(user.id)); 17014 } 17015 return userIds; 17016 } 17017 17018 @Override 17019 public boolean switchUser(final int userId) { 17020 return startUser(userId, /* foregound */ true); 17021 } 17022 17023 private boolean startUser(final int userId, boolean foreground) { 17024 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17025 != PackageManager.PERMISSION_GRANTED) { 17026 String msg = "Permission Denial: switchUser() from pid=" 17027 + Binder.getCallingPid() 17028 + ", uid=" + Binder.getCallingUid() 17029 + " requires " + INTERACT_ACROSS_USERS_FULL; 17030 Slog.w(TAG, msg); 17031 throw new SecurityException(msg); 17032 } 17033 17034 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17035 17036 final long ident = Binder.clearCallingIdentity(); 17037 try { 17038 synchronized (this) { 17039 final int oldUserId = mCurrentUserId; 17040 if (oldUserId == userId) { 17041 return true; 17042 } 17043 17044 mStackSupervisor.setLockTaskModeLocked(null, false); 17045 17046 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17047 if (userInfo == null) { 17048 Slog.w(TAG, "No user info for user #" + userId); 17049 return false; 17050 } 17051 17052 if (foreground) { 17053 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17054 R.anim.screen_user_enter); 17055 } 17056 17057 boolean needStart = false; 17058 17059 // If the user we are switching to is not currently started, then 17060 // we need to start it now. 17061 if (mStartedUsers.get(userId) == null) { 17062 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17063 updateStartedUserArrayLocked(); 17064 needStart = true; 17065 } 17066 17067 final Integer userIdInt = Integer.valueOf(userId); 17068 mUserLru.remove(userIdInt); 17069 mUserLru.add(userIdInt); 17070 17071 if (foreground) { 17072 mCurrentUserId = userId; 17073 updateCurrentProfileIdsLocked(); 17074 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17075 // Once the internal notion of the active user has switched, we lock the device 17076 // with the option to show the user switcher on the keyguard. 17077 mWindowManager.lockNow(null); 17078 } else { 17079 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17080 updateCurrentProfileIdsLocked(); 17081 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17082 mUserLru.remove(currentUserIdInt); 17083 mUserLru.add(currentUserIdInt); 17084 } 17085 17086 final UserStartedState uss = mStartedUsers.get(userId); 17087 17088 // Make sure user is in the started state. If it is currently 17089 // stopping, we need to knock that off. 17090 if (uss.mState == UserStartedState.STATE_STOPPING) { 17091 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17092 // so we can just fairly silently bring the user back from 17093 // the almost-dead. 17094 uss.mState = UserStartedState.STATE_RUNNING; 17095 updateStartedUserArrayLocked(); 17096 needStart = true; 17097 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17098 // This means ACTION_SHUTDOWN has been sent, so we will 17099 // need to treat this as a new boot of the user. 17100 uss.mState = UserStartedState.STATE_BOOTING; 17101 updateStartedUserArrayLocked(); 17102 needStart = true; 17103 } 17104 17105 if (uss.mState == UserStartedState.STATE_BOOTING) { 17106 // Booting up a new user, need to tell system services about it. 17107 // Note that this is on the same handler as scheduling of broadcasts, 17108 // which is important because it needs to go first. 17109 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 17110 } 17111 17112 if (foreground) { 17113 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17114 oldUserId)); 17115 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17116 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17117 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17118 oldUserId, userId, uss)); 17119 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17120 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17121 } 17122 17123 if (needStart) { 17124 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17125 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17126 | Intent.FLAG_RECEIVER_FOREGROUND); 17127 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17128 broadcastIntentLocked(null, null, intent, 17129 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17130 false, false, MY_PID, Process.SYSTEM_UID, userId); 17131 } 17132 17133 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17134 if (userId != UserHandle.USER_OWNER) { 17135 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17136 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17137 broadcastIntentLocked(null, null, intent, null, 17138 new IIntentReceiver.Stub() { 17139 public void performReceive(Intent intent, int resultCode, 17140 String data, Bundle extras, boolean ordered, 17141 boolean sticky, int sendingUser) { 17142 userInitialized(uss, userId); 17143 } 17144 }, 0, null, null, null, AppOpsManager.OP_NONE, 17145 true, false, MY_PID, Process.SYSTEM_UID, 17146 userId); 17147 uss.initializing = true; 17148 } else { 17149 getUserManagerLocked().makeInitialized(userInfo.id); 17150 } 17151 } 17152 17153 if (foreground) { 17154 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17155 if (homeInFront) { 17156 startHomeActivityLocked(userId); 17157 } else { 17158 mStackSupervisor.resumeTopActivitiesLocked(); 17159 } 17160 EventLogTags.writeAmSwitchUser(userId); 17161 getUserManagerLocked().userForeground(userId); 17162 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17163 } else { 17164 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17165 } 17166 17167 if (needStart) { 17168 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17169 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17170 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17171 broadcastIntentLocked(null, null, intent, 17172 null, new IIntentReceiver.Stub() { 17173 @Override 17174 public void performReceive(Intent intent, int resultCode, String data, 17175 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17176 throws RemoteException { 17177 } 17178 }, 0, null, null, 17179 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17180 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17181 } 17182 } 17183 } finally { 17184 Binder.restoreCallingIdentity(ident); 17185 } 17186 17187 return true; 17188 } 17189 17190 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17191 long ident = Binder.clearCallingIdentity(); 17192 try { 17193 Intent intent; 17194 if (oldUserId >= 0) { 17195 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17196 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17197 int count = profiles.size(); 17198 for (int i = 0; i < count; i++) { 17199 int profileUserId = profiles.get(i).id; 17200 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17201 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17202 | Intent.FLAG_RECEIVER_FOREGROUND); 17203 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17204 broadcastIntentLocked(null, null, intent, 17205 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17206 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17207 } 17208 } 17209 if (newUserId >= 0) { 17210 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17211 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17212 int count = profiles.size(); 17213 for (int i = 0; i < count; i++) { 17214 int profileUserId = profiles.get(i).id; 17215 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17216 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17217 | Intent.FLAG_RECEIVER_FOREGROUND); 17218 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17219 broadcastIntentLocked(null, null, intent, 17220 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17221 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17222 } 17223 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17224 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17225 | Intent.FLAG_RECEIVER_FOREGROUND); 17226 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17227 broadcastIntentLocked(null, null, intent, 17228 null, null, 0, null, null, 17229 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17230 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17231 } 17232 } finally { 17233 Binder.restoreCallingIdentity(ident); 17234 } 17235 } 17236 17237 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17238 final int newUserId) { 17239 final int N = mUserSwitchObservers.beginBroadcast(); 17240 if (N > 0) { 17241 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17242 int mCount = 0; 17243 @Override 17244 public void sendResult(Bundle data) throws RemoteException { 17245 synchronized (ActivityManagerService.this) { 17246 if (mCurUserSwitchCallback == this) { 17247 mCount++; 17248 if (mCount == N) { 17249 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17250 } 17251 } 17252 } 17253 } 17254 }; 17255 synchronized (this) { 17256 uss.switching = true; 17257 mCurUserSwitchCallback = callback; 17258 } 17259 for (int i=0; i<N; i++) { 17260 try { 17261 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17262 newUserId, callback); 17263 } catch (RemoteException e) { 17264 } 17265 } 17266 } else { 17267 synchronized (this) { 17268 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17269 } 17270 } 17271 mUserSwitchObservers.finishBroadcast(); 17272 } 17273 17274 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17275 synchronized (this) { 17276 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17277 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17278 } 17279 } 17280 17281 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17282 mCurUserSwitchCallback = null; 17283 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17284 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17285 oldUserId, newUserId, uss)); 17286 } 17287 17288 void userInitialized(UserStartedState uss, int newUserId) { 17289 completeSwitchAndInitalize(uss, newUserId, true, false); 17290 } 17291 17292 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17293 completeSwitchAndInitalize(uss, newUserId, false, true); 17294 } 17295 17296 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17297 boolean clearInitializing, boolean clearSwitching) { 17298 boolean unfrozen = false; 17299 synchronized (this) { 17300 if (clearInitializing) { 17301 uss.initializing = false; 17302 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17303 } 17304 if (clearSwitching) { 17305 uss.switching = false; 17306 } 17307 if (!uss.switching && !uss.initializing) { 17308 mWindowManager.stopFreezingScreen(); 17309 unfrozen = true; 17310 } 17311 } 17312 if (unfrozen) { 17313 final int N = mUserSwitchObservers.beginBroadcast(); 17314 for (int i=0; i<N; i++) { 17315 try { 17316 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17317 } catch (RemoteException e) { 17318 } 17319 } 17320 mUserSwitchObservers.finishBroadcast(); 17321 } 17322 } 17323 17324 void scheduleStartProfilesLocked() { 17325 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17326 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17327 DateUtils.SECOND_IN_MILLIS); 17328 } 17329 } 17330 17331 void startProfilesLocked() { 17332 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17333 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17334 mCurrentUserId, false /* enabledOnly */); 17335 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17336 for (UserInfo user : profiles) { 17337 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17338 && user.id != mCurrentUserId) { 17339 toStart.add(user); 17340 } 17341 } 17342 final int n = toStart.size(); 17343 int i = 0; 17344 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17345 startUserInBackground(toStart.get(i).id); 17346 } 17347 if (i < n) { 17348 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17349 } 17350 } 17351 17352 void finishUserBoot(UserStartedState uss) { 17353 synchronized (this) { 17354 if (uss.mState == UserStartedState.STATE_BOOTING 17355 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17356 uss.mState = UserStartedState.STATE_RUNNING; 17357 final int userId = uss.mHandle.getIdentifier(); 17358 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17359 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17360 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17361 broadcastIntentLocked(null, null, intent, 17362 null, null, 0, null, null, 17363 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17364 true, false, MY_PID, Process.SYSTEM_UID, userId); 17365 } 17366 } 17367 } 17368 17369 void finishUserSwitch(UserStartedState uss) { 17370 synchronized (this) { 17371 finishUserBoot(uss); 17372 17373 startProfilesLocked(); 17374 17375 int num = mUserLru.size(); 17376 int i = 0; 17377 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17378 Integer oldUserId = mUserLru.get(i); 17379 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17380 if (oldUss == null) { 17381 // Shouldn't happen, but be sane if it does. 17382 mUserLru.remove(i); 17383 num--; 17384 continue; 17385 } 17386 if (oldUss.mState == UserStartedState.STATE_STOPPING 17387 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17388 // This user is already stopping, doesn't count. 17389 num--; 17390 i++; 17391 continue; 17392 } 17393 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17394 // Owner and current can't be stopped, but count as running. 17395 i++; 17396 continue; 17397 } 17398 // This is a user to be stopped. 17399 stopUserLocked(oldUserId, null); 17400 num--; 17401 i++; 17402 } 17403 } 17404 } 17405 17406 @Override 17407 public int stopUser(final int userId, final IStopUserCallback callback) { 17408 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17409 != PackageManager.PERMISSION_GRANTED) { 17410 String msg = "Permission Denial: switchUser() from pid=" 17411 + Binder.getCallingPid() 17412 + ", uid=" + Binder.getCallingUid() 17413 + " requires " + INTERACT_ACROSS_USERS_FULL; 17414 Slog.w(TAG, msg); 17415 throw new SecurityException(msg); 17416 } 17417 if (userId <= 0) { 17418 throw new IllegalArgumentException("Can't stop primary user " + userId); 17419 } 17420 synchronized (this) { 17421 return stopUserLocked(userId, callback); 17422 } 17423 } 17424 17425 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17426 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17427 if (mCurrentUserId == userId) { 17428 return ActivityManager.USER_OP_IS_CURRENT; 17429 } 17430 17431 final UserStartedState uss = mStartedUsers.get(userId); 17432 if (uss == null) { 17433 // User is not started, nothing to do... but we do need to 17434 // callback if requested. 17435 if (callback != null) { 17436 mHandler.post(new Runnable() { 17437 @Override 17438 public void run() { 17439 try { 17440 callback.userStopped(userId); 17441 } catch (RemoteException e) { 17442 } 17443 } 17444 }); 17445 } 17446 return ActivityManager.USER_OP_SUCCESS; 17447 } 17448 17449 if (callback != null) { 17450 uss.mStopCallbacks.add(callback); 17451 } 17452 17453 if (uss.mState != UserStartedState.STATE_STOPPING 17454 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17455 uss.mState = UserStartedState.STATE_STOPPING; 17456 updateStartedUserArrayLocked(); 17457 17458 long ident = Binder.clearCallingIdentity(); 17459 try { 17460 // We are going to broadcast ACTION_USER_STOPPING and then 17461 // once that is done send a final ACTION_SHUTDOWN and then 17462 // stop the user. 17463 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17464 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17465 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17466 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17467 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17468 // This is the result receiver for the final shutdown broadcast. 17469 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17470 @Override 17471 public void performReceive(Intent intent, int resultCode, String data, 17472 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17473 finishUserStop(uss); 17474 } 17475 }; 17476 // This is the result receiver for the initial stopping broadcast. 17477 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17478 @Override 17479 public void performReceive(Intent intent, int resultCode, String data, 17480 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17481 // On to the next. 17482 synchronized (ActivityManagerService.this) { 17483 if (uss.mState != UserStartedState.STATE_STOPPING) { 17484 // Whoops, we are being started back up. Abort, abort! 17485 return; 17486 } 17487 uss.mState = UserStartedState.STATE_SHUTDOWN; 17488 } 17489 mBatteryStatsService.noteEvent( 17490 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17491 Integer.toString(userId), userId); 17492 mSystemServiceManager.stopUser(userId); 17493 broadcastIntentLocked(null, null, shutdownIntent, 17494 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17495 true, false, MY_PID, Process.SYSTEM_UID, userId); 17496 } 17497 }; 17498 // Kick things off. 17499 broadcastIntentLocked(null, null, stoppingIntent, 17500 null, stoppingReceiver, 0, null, null, 17501 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17502 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17503 } finally { 17504 Binder.restoreCallingIdentity(ident); 17505 } 17506 } 17507 17508 return ActivityManager.USER_OP_SUCCESS; 17509 } 17510 17511 void finishUserStop(UserStartedState uss) { 17512 final int userId = uss.mHandle.getIdentifier(); 17513 boolean stopped; 17514 ArrayList<IStopUserCallback> callbacks; 17515 synchronized (this) { 17516 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17517 if (mStartedUsers.get(userId) != uss) { 17518 stopped = false; 17519 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17520 stopped = false; 17521 } else { 17522 stopped = true; 17523 // User can no longer run. 17524 mStartedUsers.remove(userId); 17525 mUserLru.remove(Integer.valueOf(userId)); 17526 updateStartedUserArrayLocked(); 17527 17528 // Clean up all state and processes associated with the user. 17529 // Kill all the processes for the user. 17530 forceStopUserLocked(userId, "finish user"); 17531 } 17532 } 17533 17534 for (int i=0; i<callbacks.size(); i++) { 17535 try { 17536 if (stopped) callbacks.get(i).userStopped(userId); 17537 else callbacks.get(i).userStopAborted(userId); 17538 } catch (RemoteException e) { 17539 } 17540 } 17541 17542 if (stopped) { 17543 mSystemServiceManager.cleanupUser(userId); 17544 synchronized (this) { 17545 mStackSupervisor.removeUserLocked(userId); 17546 } 17547 } 17548 } 17549 17550 @Override 17551 public UserInfo getCurrentUser() { 17552 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 17553 != PackageManager.PERMISSION_GRANTED) && ( 17554 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17555 != PackageManager.PERMISSION_GRANTED)) { 17556 String msg = "Permission Denial: getCurrentUser() from pid=" 17557 + Binder.getCallingPid() 17558 + ", uid=" + Binder.getCallingUid() 17559 + " requires " + INTERACT_ACROSS_USERS; 17560 Slog.w(TAG, msg); 17561 throw new SecurityException(msg); 17562 } 17563 synchronized (this) { 17564 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17565 } 17566 } 17567 17568 int getCurrentUserIdLocked() { 17569 return mCurrentUserId; 17570 } 17571 17572 @Override 17573 public boolean isUserRunning(int userId, boolean orStopped) { 17574 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17575 != PackageManager.PERMISSION_GRANTED) { 17576 String msg = "Permission Denial: isUserRunning() from pid=" 17577 + Binder.getCallingPid() 17578 + ", uid=" + Binder.getCallingUid() 17579 + " requires " + INTERACT_ACROSS_USERS; 17580 Slog.w(TAG, msg); 17581 throw new SecurityException(msg); 17582 } 17583 synchronized (this) { 17584 return isUserRunningLocked(userId, orStopped); 17585 } 17586 } 17587 17588 boolean isUserRunningLocked(int userId, boolean orStopped) { 17589 UserStartedState state = mStartedUsers.get(userId); 17590 if (state == null) { 17591 return false; 17592 } 17593 if (orStopped) { 17594 return true; 17595 } 17596 return state.mState != UserStartedState.STATE_STOPPING 17597 && state.mState != UserStartedState.STATE_SHUTDOWN; 17598 } 17599 17600 @Override 17601 public int[] getRunningUserIds() { 17602 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17603 != PackageManager.PERMISSION_GRANTED) { 17604 String msg = "Permission Denial: isUserRunning() from pid=" 17605 + Binder.getCallingPid() 17606 + ", uid=" + Binder.getCallingUid() 17607 + " requires " + INTERACT_ACROSS_USERS; 17608 Slog.w(TAG, msg); 17609 throw new SecurityException(msg); 17610 } 17611 synchronized (this) { 17612 return mStartedUserArray; 17613 } 17614 } 17615 17616 private void updateStartedUserArrayLocked() { 17617 int num = 0; 17618 for (int i=0; i<mStartedUsers.size(); i++) { 17619 UserStartedState uss = mStartedUsers.valueAt(i); 17620 // This list does not include stopping users. 17621 if (uss.mState != UserStartedState.STATE_STOPPING 17622 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17623 num++; 17624 } 17625 } 17626 mStartedUserArray = new int[num]; 17627 num = 0; 17628 for (int i=0; i<mStartedUsers.size(); i++) { 17629 UserStartedState uss = mStartedUsers.valueAt(i); 17630 if (uss.mState != UserStartedState.STATE_STOPPING 17631 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17632 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17633 num++; 17634 } 17635 } 17636 } 17637 17638 @Override 17639 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17640 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17641 != PackageManager.PERMISSION_GRANTED) { 17642 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17643 + Binder.getCallingPid() 17644 + ", uid=" + Binder.getCallingUid() 17645 + " requires " + INTERACT_ACROSS_USERS_FULL; 17646 Slog.w(TAG, msg); 17647 throw new SecurityException(msg); 17648 } 17649 17650 mUserSwitchObservers.register(observer); 17651 } 17652 17653 @Override 17654 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17655 mUserSwitchObservers.unregister(observer); 17656 } 17657 17658 private boolean userExists(int userId) { 17659 if (userId == 0) { 17660 return true; 17661 } 17662 UserManagerService ums = getUserManagerLocked(); 17663 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17664 } 17665 17666 int[] getUsersLocked() { 17667 UserManagerService ums = getUserManagerLocked(); 17668 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17669 } 17670 17671 UserManagerService getUserManagerLocked() { 17672 if (mUserManager == null) { 17673 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17674 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17675 } 17676 return mUserManager; 17677 } 17678 17679 private int applyUserId(int uid, int userId) { 17680 return UserHandle.getUid(userId, uid); 17681 } 17682 17683 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17684 if (info == null) return null; 17685 ApplicationInfo newInfo = new ApplicationInfo(info); 17686 newInfo.uid = applyUserId(info.uid, userId); 17687 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17688 + info.packageName; 17689 return newInfo; 17690 } 17691 17692 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17693 if (aInfo == null 17694 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17695 return aInfo; 17696 } 17697 17698 ActivityInfo info = new ActivityInfo(aInfo); 17699 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17700 return info; 17701 } 17702 17703 private final class LocalService extends ActivityManagerInternal { 17704 @Override 17705 public void goingToSleep() { 17706 ActivityManagerService.this.goingToSleep(); 17707 } 17708 17709 @Override 17710 public void wakingUp() { 17711 ActivityManagerService.this.wakingUp(); 17712 } 17713 } 17714 17715 /** 17716 * An implementation of IAppTask, that allows an app to manage its own tasks via 17717 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17718 * only the process that calls getAppTasks() can call the AppTask methods. 17719 */ 17720 class AppTaskImpl extends IAppTask.Stub { 17721 private int mTaskId; 17722 private int mCallingUid; 17723 17724 public AppTaskImpl(int taskId, int callingUid) { 17725 mTaskId = taskId; 17726 mCallingUid = callingUid; 17727 } 17728 17729 @Override 17730 public void finishAndRemoveTask() { 17731 // Ensure that we are called from the same process that created this AppTask 17732 if (mCallingUid != Binder.getCallingUid()) { 17733 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17734 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17735 return; 17736 } 17737 17738 synchronized (ActivityManagerService.this) { 17739 long origId = Binder.clearCallingIdentity(); 17740 try { 17741 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17742 if (tr != null) { 17743 // Only kill the process if we are not a new document 17744 int flags = tr.getBaseIntent().getFlags(); 17745 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17746 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17747 removeTaskByIdLocked(mTaskId, 17748 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17749 } 17750 } finally { 17751 Binder.restoreCallingIdentity(origId); 17752 } 17753 } 17754 } 17755 17756 @Override 17757 public ActivityManager.RecentTaskInfo getTaskInfo() { 17758 // Ensure that we are called from the same process that created this AppTask 17759 if (mCallingUid != Binder.getCallingUid()) { 17760 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17761 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17762 return null; 17763 } 17764 17765 synchronized (ActivityManagerService.this) { 17766 long origId = Binder.clearCallingIdentity(); 17767 try { 17768 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17769 if (tr != null) { 17770 return createRecentTaskInfoFromTaskRecord(tr); 17771 } 17772 } finally { 17773 Binder.restoreCallingIdentity(origId); 17774 } 17775 return null; 17776 } 17777 } 17778 } 17779} 17780