ActivityManagerService.java revision 0debc9aff4c0cbc28e083a948081d91b0f171319
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.intent != null && 7427 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7428 != 0 && tr.getTopActivity() == null) { 7429 // Don't include auto remove tasks that are finished or finishing. 7430 continue; 7431 } 7432 7433 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7434 if (!detailed) { 7435 rti.baseIntent.replaceExtras((Bundle)null); 7436 } 7437 7438 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7439 // Check whether this activity is currently available. 7440 try { 7441 if (rti.origActivity != null) { 7442 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7443 == null) { 7444 continue; 7445 } 7446 } else if (rti.baseIntent != null) { 7447 if (pm.queryIntentActivities(rti.baseIntent, 7448 null, 0, userId) == null) { 7449 continue; 7450 } 7451 } 7452 } catch (RemoteException e) { 7453 // Will never happen. 7454 } 7455 } 7456 7457 res.add(rti); 7458 maxNum--; 7459 } 7460 } 7461 return res; 7462 } 7463 } 7464 7465 private TaskRecord recentTaskForIdLocked(int id) { 7466 final int N = mRecentTasks.size(); 7467 for (int i=0; i<N; i++) { 7468 TaskRecord tr = mRecentTasks.get(i); 7469 if (tr.taskId == id) { 7470 return tr; 7471 } 7472 } 7473 return null; 7474 } 7475 7476 @Override 7477 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7478 synchronized (this) { 7479 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7480 "getTaskThumbnail()"); 7481 TaskRecord tr = recentTaskForIdLocked(id); 7482 if (tr != null) { 7483 return tr.getTaskThumbnailLocked(); 7484 } 7485 } 7486 return null; 7487 } 7488 7489 @Override 7490 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7491 synchronized (this) { 7492 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7493 if (r != null) { 7494 r.taskDescription = td; 7495 r.task.updateTaskDescription(); 7496 } 7497 } 7498 } 7499 7500 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7501 if (!pr.killedByAm) { 7502 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7503 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7504 pr.processName, pr.setAdj, reason); 7505 pr.killedByAm = true; 7506 Process.killProcessQuiet(pr.pid); 7507 Process.killProcessGroup(pr.info.uid, pr.pid); 7508 } 7509 } 7510 7511 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7512 tr.disposeThumbnail(); 7513 mRecentTasks.remove(tr); 7514 tr.closeRecentsChain(); 7515 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7516 Intent baseIntent = new Intent( 7517 tr.intent != null ? tr.intent : tr.affinityIntent); 7518 ComponentName component = baseIntent.getComponent(); 7519 if (component == null) { 7520 Slog.w(TAG, "Now component for base intent of task: " + tr); 7521 return; 7522 } 7523 7524 // Find any running services associated with this app. 7525 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7526 7527 if (killProcesses) { 7528 // Find any running processes associated with this app. 7529 final String pkg = component.getPackageName(); 7530 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7531 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7532 for (int i=0; i<pmap.size(); i++) { 7533 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7534 for (int j=0; j<uids.size(); j++) { 7535 ProcessRecord proc = uids.valueAt(j); 7536 if (proc.userId != tr.userId) { 7537 continue; 7538 } 7539 if (!proc.pkgList.containsKey(pkg)) { 7540 continue; 7541 } 7542 procs.add(proc); 7543 } 7544 } 7545 7546 // Kill the running processes. 7547 for (int i=0; i<procs.size(); i++) { 7548 ProcessRecord pr = procs.get(i); 7549 if (pr == mHomeProcess) { 7550 // Don't kill the home process along with tasks from the same package. 7551 continue; 7552 } 7553 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7554 killUnneededProcessLocked(pr, "remove task"); 7555 } else { 7556 pr.waitingToKill = "remove task"; 7557 } 7558 } 7559 } 7560 } 7561 7562 /** 7563 * Removes the task with the specified task id. 7564 * 7565 * @param taskId Identifier of the task to be removed. 7566 * @param flags Additional operational flags. May be 0 or 7567 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7568 * @return Returns true if the given task was found and removed. 7569 */ 7570 private boolean removeTaskByIdLocked(int taskId, int flags) { 7571 TaskRecord tr = recentTaskForIdLocked(taskId); 7572 if (tr != null) { 7573 tr.removeTaskActivitiesLocked(); 7574 cleanUpRemovedTaskLocked(tr, flags); 7575 if (tr.isPersistable) { 7576 notifyTaskPersisterLocked(tr, true); 7577 } 7578 return true; 7579 } 7580 return false; 7581 } 7582 7583 @Override 7584 public boolean removeTask(int taskId, int flags) { 7585 synchronized (this) { 7586 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7587 "removeTask()"); 7588 long ident = Binder.clearCallingIdentity(); 7589 try { 7590 return removeTaskByIdLocked(taskId, flags); 7591 } finally { 7592 Binder.restoreCallingIdentity(ident); 7593 } 7594 } 7595 } 7596 7597 /** 7598 * TODO: Add mController hook 7599 */ 7600 @Override 7601 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7602 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7603 "moveTaskToFront()"); 7604 7605 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7606 synchronized(this) { 7607 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7608 Binder.getCallingUid(), "Task to front")) { 7609 ActivityOptions.abort(options); 7610 return; 7611 } 7612 final long origId = Binder.clearCallingIdentity(); 7613 try { 7614 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7615 if (task == null) { 7616 return; 7617 } 7618 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7619 mStackSupervisor.showLockTaskToast(); 7620 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7621 return; 7622 } 7623 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7624 if (prev != null && prev.isRecentsActivity()) { 7625 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7626 } 7627 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7628 } finally { 7629 Binder.restoreCallingIdentity(origId); 7630 } 7631 ActivityOptions.abort(options); 7632 } 7633 } 7634 7635 @Override 7636 public void moveTaskToBack(int taskId) { 7637 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7638 "moveTaskToBack()"); 7639 7640 synchronized(this) { 7641 TaskRecord tr = recentTaskForIdLocked(taskId); 7642 if (tr != null) { 7643 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7644 ActivityStack stack = tr.stack; 7645 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7646 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7647 Binder.getCallingUid(), "Task to back")) { 7648 return; 7649 } 7650 } 7651 final long origId = Binder.clearCallingIdentity(); 7652 try { 7653 stack.moveTaskToBackLocked(taskId, null); 7654 } finally { 7655 Binder.restoreCallingIdentity(origId); 7656 } 7657 } 7658 } 7659 } 7660 7661 /** 7662 * Moves an activity, and all of the other activities within the same task, to the bottom 7663 * of the history stack. The activity's order within the task is unchanged. 7664 * 7665 * @param token A reference to the activity we wish to move 7666 * @param nonRoot If false then this only works if the activity is the root 7667 * of a task; if true it will work for any activity in a task. 7668 * @return Returns true if the move completed, false if not. 7669 */ 7670 @Override 7671 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7672 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7673 synchronized(this) { 7674 final long origId = Binder.clearCallingIdentity(); 7675 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7676 if (taskId >= 0) { 7677 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7678 } 7679 Binder.restoreCallingIdentity(origId); 7680 } 7681 return false; 7682 } 7683 7684 @Override 7685 public void moveTaskBackwards(int task) { 7686 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7687 "moveTaskBackwards()"); 7688 7689 synchronized(this) { 7690 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7691 Binder.getCallingUid(), "Task backwards")) { 7692 return; 7693 } 7694 final long origId = Binder.clearCallingIdentity(); 7695 moveTaskBackwardsLocked(task); 7696 Binder.restoreCallingIdentity(origId); 7697 } 7698 } 7699 7700 private final void moveTaskBackwardsLocked(int task) { 7701 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7702 } 7703 7704 @Override 7705 public IBinder getHomeActivityToken() throws RemoteException { 7706 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7707 "getHomeActivityToken()"); 7708 synchronized (this) { 7709 return mStackSupervisor.getHomeActivityToken(); 7710 } 7711 } 7712 7713 @Override 7714 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7715 IActivityContainerCallback callback) throws RemoteException { 7716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7717 "createActivityContainer()"); 7718 synchronized (this) { 7719 if (parentActivityToken == null) { 7720 throw new IllegalArgumentException("parent token must not be null"); 7721 } 7722 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7723 if (r == null) { 7724 return null; 7725 } 7726 if (callback == null) { 7727 throw new IllegalArgumentException("callback must not be null"); 7728 } 7729 return mStackSupervisor.createActivityContainer(r, callback); 7730 } 7731 } 7732 7733 @Override 7734 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7735 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7736 "deleteActivityContainer()"); 7737 synchronized (this) { 7738 mStackSupervisor.deleteActivityContainer(container); 7739 } 7740 } 7741 7742 @Override 7743 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7744 throws RemoteException { 7745 synchronized (this) { 7746 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7747 if (stack != null) { 7748 return stack.mActivityContainer; 7749 } 7750 return null; 7751 } 7752 } 7753 7754 @Override 7755 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7756 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7757 "moveTaskToStack()"); 7758 if (stackId == HOME_STACK_ID) { 7759 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7760 new RuntimeException("here").fillInStackTrace()); 7761 } 7762 synchronized (this) { 7763 long ident = Binder.clearCallingIdentity(); 7764 try { 7765 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7766 + stackId + " toTop=" + toTop); 7767 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7768 } finally { 7769 Binder.restoreCallingIdentity(ident); 7770 } 7771 } 7772 } 7773 7774 @Override 7775 public void resizeStack(int stackBoxId, Rect bounds) { 7776 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7777 "resizeStackBox()"); 7778 long ident = Binder.clearCallingIdentity(); 7779 try { 7780 mWindowManager.resizeStack(stackBoxId, bounds); 7781 } finally { 7782 Binder.restoreCallingIdentity(ident); 7783 } 7784 } 7785 7786 @Override 7787 public List<StackInfo> getAllStackInfos() { 7788 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7789 "getAllStackInfos()"); 7790 long ident = Binder.clearCallingIdentity(); 7791 try { 7792 synchronized (this) { 7793 return mStackSupervisor.getAllStackInfosLocked(); 7794 } 7795 } finally { 7796 Binder.restoreCallingIdentity(ident); 7797 } 7798 } 7799 7800 @Override 7801 public StackInfo getStackInfo(int stackId) { 7802 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7803 "getStackInfo()"); 7804 long ident = Binder.clearCallingIdentity(); 7805 try { 7806 synchronized (this) { 7807 return mStackSupervisor.getStackInfoLocked(stackId); 7808 } 7809 } finally { 7810 Binder.restoreCallingIdentity(ident); 7811 } 7812 } 7813 7814 @Override 7815 public boolean isInHomeStack(int taskId) { 7816 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7817 "getStackInfo()"); 7818 long ident = Binder.clearCallingIdentity(); 7819 try { 7820 synchronized (this) { 7821 TaskRecord tr = recentTaskForIdLocked(taskId); 7822 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7823 } 7824 } finally { 7825 Binder.restoreCallingIdentity(ident); 7826 } 7827 } 7828 7829 @Override 7830 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7831 synchronized(this) { 7832 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7833 } 7834 } 7835 7836 private boolean isLockTaskAuthorized(String pkg) { 7837 final DevicePolicyManager dpm = (DevicePolicyManager) 7838 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7839 try { 7840 int uid = mContext.getPackageManager().getPackageUid(pkg, 7841 Binder.getCallingUserHandle().getIdentifier()); 7842 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7843 } catch (NameNotFoundException e) { 7844 return false; 7845 } 7846 } 7847 7848 void startLockTaskMode(TaskRecord task) { 7849 final String pkg; 7850 synchronized (this) { 7851 pkg = task.intent.getComponent().getPackageName(); 7852 } 7853 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7854 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7855 final TaskRecord taskRecord = task; 7856 mHandler.post(new Runnable() { 7857 @Override 7858 public void run() { 7859 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7860 } 7861 }); 7862 return; 7863 } 7864 long ident = Binder.clearCallingIdentity(); 7865 try { 7866 synchronized (this) { 7867 // Since we lost lock on task, make sure it is still there. 7868 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7869 if (task != null) { 7870 if (!isSystemInitiated 7871 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7872 throw new IllegalArgumentException("Invalid task, not in foreground"); 7873 } 7874 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7875 } 7876 } 7877 } finally { 7878 Binder.restoreCallingIdentity(ident); 7879 } 7880 } 7881 7882 @Override 7883 public void startLockTaskMode(int taskId) { 7884 final TaskRecord task; 7885 long ident = Binder.clearCallingIdentity(); 7886 try { 7887 synchronized (this) { 7888 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7889 } 7890 } finally { 7891 Binder.restoreCallingIdentity(ident); 7892 } 7893 if (task != null) { 7894 startLockTaskMode(task); 7895 } 7896 } 7897 7898 @Override 7899 public void startLockTaskMode(IBinder token) { 7900 final TaskRecord task; 7901 long ident = Binder.clearCallingIdentity(); 7902 try { 7903 synchronized (this) { 7904 final ActivityRecord r = ActivityRecord.forToken(token); 7905 if (r == null) { 7906 return; 7907 } 7908 task = r.task; 7909 } 7910 } finally { 7911 Binder.restoreCallingIdentity(ident); 7912 } 7913 if (task != null) { 7914 startLockTaskMode(task); 7915 } 7916 } 7917 7918 @Override 7919 public void startLockTaskModeOnCurrent() throws RemoteException { 7920 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7921 ActivityRecord r = null; 7922 synchronized (this) { 7923 r = mStackSupervisor.topRunningActivityLocked(); 7924 } 7925 startLockTaskMode(r.task); 7926 } 7927 7928 @Override 7929 public void stopLockTaskMode() { 7930 // Verify that the user matches the package of the intent for the TaskRecord 7931 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7932 // and stopLockTaskMode. 7933 final int callingUid = Binder.getCallingUid(); 7934 if (callingUid != Process.SYSTEM_UID) { 7935 try { 7936 String pkg = 7937 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7938 int uid = mContext.getPackageManager().getPackageUid(pkg, 7939 Binder.getCallingUserHandle().getIdentifier()); 7940 if (uid != callingUid) { 7941 throw new SecurityException("Invalid uid, expected " + uid); 7942 } 7943 } catch (NameNotFoundException e) { 7944 Log.d(TAG, "stopLockTaskMode " + e); 7945 return; 7946 } 7947 } 7948 long ident = Binder.clearCallingIdentity(); 7949 try { 7950 Log.d(TAG, "stopLockTaskMode"); 7951 // Stop lock task 7952 synchronized (this) { 7953 mStackSupervisor.setLockTaskModeLocked(null, false); 7954 } 7955 } finally { 7956 Binder.restoreCallingIdentity(ident); 7957 } 7958 } 7959 7960 @Override 7961 public void stopLockTaskModeOnCurrent() throws RemoteException { 7962 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7963 long ident = Binder.clearCallingIdentity(); 7964 try { 7965 stopLockTaskMode(); 7966 } finally { 7967 Binder.restoreCallingIdentity(ident); 7968 } 7969 } 7970 7971 @Override 7972 public boolean isInLockTaskMode() { 7973 synchronized (this) { 7974 return mStackSupervisor.isInLockTaskMode(); 7975 } 7976 } 7977 7978 // ========================================================= 7979 // CONTENT PROVIDERS 7980 // ========================================================= 7981 7982 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7983 List<ProviderInfo> providers = null; 7984 try { 7985 providers = AppGlobals.getPackageManager(). 7986 queryContentProviders(app.processName, app.uid, 7987 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7988 } catch (RemoteException ex) { 7989 } 7990 if (DEBUG_MU) 7991 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7992 int userId = app.userId; 7993 if (providers != null) { 7994 int N = providers.size(); 7995 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7996 for (int i=0; i<N; i++) { 7997 ProviderInfo cpi = 7998 (ProviderInfo)providers.get(i); 7999 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8000 cpi.name, cpi.flags); 8001 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8002 // This is a singleton provider, but a user besides the 8003 // default user is asking to initialize a process it runs 8004 // in... well, no, it doesn't actually run in this process, 8005 // it runs in the process of the default user. Get rid of it. 8006 providers.remove(i); 8007 N--; 8008 i--; 8009 continue; 8010 } 8011 8012 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8013 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8014 if (cpr == null) { 8015 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8016 mProviderMap.putProviderByClass(comp, cpr); 8017 } 8018 if (DEBUG_MU) 8019 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8020 app.pubProviders.put(cpi.name, cpr); 8021 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8022 // Don't add this if it is a platform component that is marked 8023 // to run in multiple processes, because this is actually 8024 // part of the framework so doesn't make sense to track as a 8025 // separate apk in the process. 8026 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8027 mProcessStats); 8028 } 8029 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8030 } 8031 } 8032 return providers; 8033 } 8034 8035 /** 8036 * Check if {@link ProcessRecord} has a possible chance at accessing the 8037 * given {@link ProviderInfo}. Final permission checking is always done 8038 * in {@link ContentProvider}. 8039 */ 8040 private final String checkContentProviderPermissionLocked( 8041 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8042 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8043 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8044 boolean checkedGrants = false; 8045 if (checkUser) { 8046 // Looking for cross-user grants before enforcing the typical cross-users permissions 8047 int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid)); 8048 if (tmpTargetUserId != userId) { 8049 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8050 return null; 8051 } 8052 checkedGrants = true; 8053 } 8054 userId = handleIncomingUser(callingPid, callingUid, userId, 8055 false, ALLOW_NON_FULL, 8056 "checkContentProviderPermissionLocked " + cpi.authority, null); 8057 if (userId != tmpTargetUserId) { 8058 // When we actually went to determine the final targer user ID, this ended 8059 // up different than our initial check for the authority. This is because 8060 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8061 // SELF. So we need to re-check the grants again. 8062 checkedGrants = false; 8063 } 8064 } 8065 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8066 cpi.applicationInfo.uid, cpi.exported) 8067 == PackageManager.PERMISSION_GRANTED) { 8068 return null; 8069 } 8070 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8071 cpi.applicationInfo.uid, cpi.exported) 8072 == PackageManager.PERMISSION_GRANTED) { 8073 return null; 8074 } 8075 8076 PathPermission[] pps = cpi.pathPermissions; 8077 if (pps != null) { 8078 int i = pps.length; 8079 while (i > 0) { 8080 i--; 8081 PathPermission pp = pps[i]; 8082 String pprperm = pp.getReadPermission(); 8083 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8084 cpi.applicationInfo.uid, cpi.exported) 8085 == PackageManager.PERMISSION_GRANTED) { 8086 return null; 8087 } 8088 String ppwperm = pp.getWritePermission(); 8089 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8090 cpi.applicationInfo.uid, cpi.exported) 8091 == PackageManager.PERMISSION_GRANTED) { 8092 return null; 8093 } 8094 } 8095 } 8096 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8097 return null; 8098 } 8099 8100 String msg; 8101 if (!cpi.exported) { 8102 msg = "Permission Denial: opening provider " + cpi.name 8103 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8104 + ", uid=" + callingUid + ") that is not exported from uid " 8105 + cpi.applicationInfo.uid; 8106 } else { 8107 msg = "Permission Denial: opening provider " + cpi.name 8108 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8109 + ", uid=" + callingUid + ") requires " 8110 + cpi.readPermission + " or " + cpi.writePermission; 8111 } 8112 Slog.w(TAG, msg); 8113 return msg; 8114 } 8115 8116 /** 8117 * Returns if the ContentProvider has granted a uri to callingUid 8118 */ 8119 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8120 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8121 if (perms != null) { 8122 for (int i=perms.size()-1; i>=0; i--) { 8123 GrantUri grantUri = perms.keyAt(i); 8124 if (grantUri.sourceUserId == userId || !checkUser) { 8125 if (matchesProvider(grantUri.uri, cpi)) { 8126 return true; 8127 } 8128 } 8129 } 8130 } 8131 return false; 8132 } 8133 8134 /** 8135 * Returns true if the uri authority is one of the authorities specified in the provider. 8136 */ 8137 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8138 String uriAuth = uri.getAuthority(); 8139 String cpiAuth = cpi.authority; 8140 if (cpiAuth.indexOf(';') == -1) { 8141 return cpiAuth.equals(uriAuth); 8142 } 8143 String[] cpiAuths = cpiAuth.split(";"); 8144 int length = cpiAuths.length; 8145 for (int i = 0; i < length; i++) { 8146 if (cpiAuths[i].equals(uriAuth)) return true; 8147 } 8148 return false; 8149 } 8150 8151 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8152 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8153 if (r != null) { 8154 for (int i=0; i<r.conProviders.size(); i++) { 8155 ContentProviderConnection conn = r.conProviders.get(i); 8156 if (conn.provider == cpr) { 8157 if (DEBUG_PROVIDER) Slog.v(TAG, 8158 "Adding provider requested by " 8159 + r.processName + " from process " 8160 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8161 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8162 if (stable) { 8163 conn.stableCount++; 8164 conn.numStableIncs++; 8165 } else { 8166 conn.unstableCount++; 8167 conn.numUnstableIncs++; 8168 } 8169 return conn; 8170 } 8171 } 8172 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8173 if (stable) { 8174 conn.stableCount = 1; 8175 conn.numStableIncs = 1; 8176 } else { 8177 conn.unstableCount = 1; 8178 conn.numUnstableIncs = 1; 8179 } 8180 cpr.connections.add(conn); 8181 r.conProviders.add(conn); 8182 return conn; 8183 } 8184 cpr.addExternalProcessHandleLocked(externalProcessToken); 8185 return null; 8186 } 8187 8188 boolean decProviderCountLocked(ContentProviderConnection conn, 8189 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8190 if (conn != null) { 8191 cpr = conn.provider; 8192 if (DEBUG_PROVIDER) Slog.v(TAG, 8193 "Removing provider requested by " 8194 + conn.client.processName + " from process " 8195 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8196 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8197 if (stable) { 8198 conn.stableCount--; 8199 } else { 8200 conn.unstableCount--; 8201 } 8202 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8203 cpr.connections.remove(conn); 8204 conn.client.conProviders.remove(conn); 8205 return true; 8206 } 8207 return false; 8208 } 8209 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8210 return false; 8211 } 8212 8213 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8214 String name, IBinder token, boolean stable, int userId) { 8215 ContentProviderRecord cpr; 8216 ContentProviderConnection conn = null; 8217 ProviderInfo cpi = null; 8218 8219 synchronized(this) { 8220 ProcessRecord r = null; 8221 if (caller != null) { 8222 r = getRecordForAppLocked(caller); 8223 if (r == null) { 8224 throw new SecurityException( 8225 "Unable to find app for caller " + caller 8226 + " (pid=" + Binder.getCallingPid() 8227 + ") when getting content provider " + name); 8228 } 8229 } 8230 8231 boolean checkCrossUser = true; 8232 8233 // First check if this content provider has been published... 8234 cpr = mProviderMap.getProviderByName(name, userId); 8235 // If that didn't work, check if it exists for user 0 and then 8236 // verify that it's a singleton provider before using it. 8237 if (cpr == null && userId != UserHandle.USER_OWNER) { 8238 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8239 if (cpr != null) { 8240 cpi = cpr.info; 8241 if (isSingleton(cpi.processName, cpi.applicationInfo, 8242 cpi.name, cpi.flags) 8243 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8244 userId = UserHandle.USER_OWNER; 8245 checkCrossUser = false; 8246 } else { 8247 cpr = null; 8248 cpi = null; 8249 } 8250 } 8251 } 8252 8253 boolean providerRunning = cpr != null; 8254 if (providerRunning) { 8255 cpi = cpr.info; 8256 String msg; 8257 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8258 != null) { 8259 throw new SecurityException(msg); 8260 } 8261 8262 if (r != null && cpr.canRunHere(r)) { 8263 // This provider has been published or is in the process 8264 // of being published... but it is also allowed to run 8265 // in the caller's process, so don't make a connection 8266 // and just let the caller instantiate its own instance. 8267 ContentProviderHolder holder = cpr.newHolder(null); 8268 // don't give caller the provider object, it needs 8269 // to make its own. 8270 holder.provider = null; 8271 return holder; 8272 } 8273 8274 final long origId = Binder.clearCallingIdentity(); 8275 8276 // In this case the provider instance already exists, so we can 8277 // return it right away. 8278 conn = incProviderCountLocked(r, cpr, token, stable); 8279 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8280 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8281 // If this is a perceptible app accessing the provider, 8282 // make sure to count it as being accessed and thus 8283 // back up on the LRU list. This is good because 8284 // content providers are often expensive to start. 8285 updateLruProcessLocked(cpr.proc, false, null); 8286 } 8287 } 8288 8289 if (cpr.proc != null) { 8290 if (false) { 8291 if (cpr.name.flattenToShortString().equals( 8292 "com.android.providers.calendar/.CalendarProvider2")) { 8293 Slog.v(TAG, "****************** KILLING " 8294 + cpr.name.flattenToShortString()); 8295 Process.killProcess(cpr.proc.pid); 8296 } 8297 } 8298 boolean success = updateOomAdjLocked(cpr.proc); 8299 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8300 // NOTE: there is still a race here where a signal could be 8301 // pending on the process even though we managed to update its 8302 // adj level. Not sure what to do about this, but at least 8303 // the race is now smaller. 8304 if (!success) { 8305 // Uh oh... it looks like the provider's process 8306 // has been killed on us. We need to wait for a new 8307 // process to be started, and make sure its death 8308 // doesn't kill our process. 8309 Slog.i(TAG, 8310 "Existing provider " + cpr.name.flattenToShortString() 8311 + " is crashing; detaching " + r); 8312 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8313 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8314 if (!lastRef) { 8315 // This wasn't the last ref our process had on 8316 // the provider... we have now been killed, bail. 8317 return null; 8318 } 8319 providerRunning = false; 8320 conn = null; 8321 } 8322 } 8323 8324 Binder.restoreCallingIdentity(origId); 8325 } 8326 8327 boolean singleton; 8328 if (!providerRunning) { 8329 try { 8330 cpi = AppGlobals.getPackageManager(). 8331 resolveContentProvider(name, 8332 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8333 } catch (RemoteException ex) { 8334 } 8335 if (cpi == null) { 8336 return null; 8337 } 8338 // If the provider is a singleton AND 8339 // (it's a call within the same user || the provider is a 8340 // privileged app) 8341 // Then allow connecting to the singleton provider 8342 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8343 cpi.name, cpi.flags) 8344 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8345 if (singleton) { 8346 userId = UserHandle.USER_OWNER; 8347 } 8348 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8349 8350 String msg; 8351 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8352 != null) { 8353 throw new SecurityException(msg); 8354 } 8355 8356 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8357 && !cpi.processName.equals("system")) { 8358 // If this content provider does not run in the system 8359 // process, and the system is not yet ready to run other 8360 // processes, then fail fast instead of hanging. 8361 throw new IllegalArgumentException( 8362 "Attempt to launch content provider before system ready"); 8363 } 8364 8365 // Make sure that the user who owns this provider is started. If not, 8366 // we don't want to allow it to run. 8367 if (mStartedUsers.get(userId) == null) { 8368 Slog.w(TAG, "Unable to launch app " 8369 + cpi.applicationInfo.packageName + "/" 8370 + cpi.applicationInfo.uid + " for provider " 8371 + name + ": user " + userId + " is stopped"); 8372 return null; 8373 } 8374 8375 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8376 cpr = mProviderMap.getProviderByClass(comp, userId); 8377 final boolean firstClass = cpr == null; 8378 if (firstClass) { 8379 try { 8380 ApplicationInfo ai = 8381 AppGlobals.getPackageManager(). 8382 getApplicationInfo( 8383 cpi.applicationInfo.packageName, 8384 STOCK_PM_FLAGS, userId); 8385 if (ai == null) { 8386 Slog.w(TAG, "No package info for content provider " 8387 + cpi.name); 8388 return null; 8389 } 8390 ai = getAppInfoForUser(ai, userId); 8391 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8392 } catch (RemoteException ex) { 8393 // pm is in same process, this will never happen. 8394 } 8395 } 8396 8397 if (r != null && cpr.canRunHere(r)) { 8398 // If this is a multiprocess provider, then just return its 8399 // info and allow the caller to instantiate it. Only do 8400 // this if the provider is the same user as the caller's 8401 // process, or can run as root (so can be in any process). 8402 return cpr.newHolder(null); 8403 } 8404 8405 if (DEBUG_PROVIDER) { 8406 RuntimeException e = new RuntimeException("here"); 8407 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8408 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8409 } 8410 8411 // This is single process, and our app is now connecting to it. 8412 // See if we are already in the process of launching this 8413 // provider. 8414 final int N = mLaunchingProviders.size(); 8415 int i; 8416 for (i=0; i<N; i++) { 8417 if (mLaunchingProviders.get(i) == cpr) { 8418 break; 8419 } 8420 } 8421 8422 // If the provider is not already being launched, then get it 8423 // started. 8424 if (i >= N) { 8425 final long origId = Binder.clearCallingIdentity(); 8426 8427 try { 8428 // Content provider is now in use, its package can't be stopped. 8429 try { 8430 AppGlobals.getPackageManager().setPackageStoppedState( 8431 cpr.appInfo.packageName, false, userId); 8432 } catch (RemoteException e) { 8433 } catch (IllegalArgumentException e) { 8434 Slog.w(TAG, "Failed trying to unstop package " 8435 + cpr.appInfo.packageName + ": " + e); 8436 } 8437 8438 // Use existing process if already started 8439 ProcessRecord proc = getProcessRecordLocked( 8440 cpi.processName, cpr.appInfo.uid, false); 8441 if (proc != null && proc.thread != null) { 8442 if (DEBUG_PROVIDER) { 8443 Slog.d(TAG, "Installing in existing process " + proc); 8444 } 8445 proc.pubProviders.put(cpi.name, cpr); 8446 try { 8447 proc.thread.scheduleInstallProvider(cpi); 8448 } catch (RemoteException e) { 8449 } 8450 } else { 8451 proc = startProcessLocked(cpi.processName, 8452 cpr.appInfo, false, 0, "content provider", 8453 new ComponentName(cpi.applicationInfo.packageName, 8454 cpi.name), false, false, false); 8455 if (proc == null) { 8456 Slog.w(TAG, "Unable to launch app " 8457 + cpi.applicationInfo.packageName + "/" 8458 + cpi.applicationInfo.uid + " for provider " 8459 + name + ": process is bad"); 8460 return null; 8461 } 8462 } 8463 cpr.launchingApp = proc; 8464 mLaunchingProviders.add(cpr); 8465 } finally { 8466 Binder.restoreCallingIdentity(origId); 8467 } 8468 } 8469 8470 // Make sure the provider is published (the same provider class 8471 // may be published under multiple names). 8472 if (firstClass) { 8473 mProviderMap.putProviderByClass(comp, cpr); 8474 } 8475 8476 mProviderMap.putProviderByName(name, cpr); 8477 conn = incProviderCountLocked(r, cpr, token, stable); 8478 if (conn != null) { 8479 conn.waiting = true; 8480 } 8481 } 8482 } 8483 8484 // Wait for the provider to be published... 8485 synchronized (cpr) { 8486 while (cpr.provider == null) { 8487 if (cpr.launchingApp == null) { 8488 Slog.w(TAG, "Unable to launch app " 8489 + cpi.applicationInfo.packageName + "/" 8490 + cpi.applicationInfo.uid + " for provider " 8491 + name + ": launching app became null"); 8492 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8493 UserHandle.getUserId(cpi.applicationInfo.uid), 8494 cpi.applicationInfo.packageName, 8495 cpi.applicationInfo.uid, name); 8496 return null; 8497 } 8498 try { 8499 if (DEBUG_MU) { 8500 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8501 + cpr.launchingApp); 8502 } 8503 if (conn != null) { 8504 conn.waiting = true; 8505 } 8506 cpr.wait(); 8507 } catch (InterruptedException ex) { 8508 } finally { 8509 if (conn != null) { 8510 conn.waiting = false; 8511 } 8512 } 8513 } 8514 } 8515 return cpr != null ? cpr.newHolder(conn) : null; 8516 } 8517 8518 @Override 8519 public final ContentProviderHolder getContentProvider( 8520 IApplicationThread caller, String name, int userId, boolean stable) { 8521 enforceNotIsolatedCaller("getContentProvider"); 8522 if (caller == null) { 8523 String msg = "null IApplicationThread when getting content provider " 8524 + name; 8525 Slog.w(TAG, msg); 8526 throw new SecurityException(msg); 8527 } 8528 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8529 // with cross-user grant. 8530 return getContentProviderImpl(caller, name, null, stable, userId); 8531 } 8532 8533 public ContentProviderHolder getContentProviderExternal( 8534 String name, int userId, IBinder token) { 8535 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8536 "Do not have permission in call getContentProviderExternal()"); 8537 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8538 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8539 return getContentProviderExternalUnchecked(name, token, userId); 8540 } 8541 8542 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8543 IBinder token, int userId) { 8544 return getContentProviderImpl(null, name, token, true, userId); 8545 } 8546 8547 /** 8548 * Drop a content provider from a ProcessRecord's bookkeeping 8549 */ 8550 public void removeContentProvider(IBinder connection, boolean stable) { 8551 enforceNotIsolatedCaller("removeContentProvider"); 8552 long ident = Binder.clearCallingIdentity(); 8553 try { 8554 synchronized (this) { 8555 ContentProviderConnection conn; 8556 try { 8557 conn = (ContentProviderConnection)connection; 8558 } catch (ClassCastException e) { 8559 String msg ="removeContentProvider: " + connection 8560 + " not a ContentProviderConnection"; 8561 Slog.w(TAG, msg); 8562 throw new IllegalArgumentException(msg); 8563 } 8564 if (conn == null) { 8565 throw new NullPointerException("connection is null"); 8566 } 8567 if (decProviderCountLocked(conn, null, null, stable)) { 8568 updateOomAdjLocked(); 8569 } 8570 } 8571 } finally { 8572 Binder.restoreCallingIdentity(ident); 8573 } 8574 } 8575 8576 public void removeContentProviderExternal(String name, IBinder token) { 8577 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8578 "Do not have permission in call removeContentProviderExternal()"); 8579 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8580 } 8581 8582 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8583 synchronized (this) { 8584 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8585 if(cpr == null) { 8586 //remove from mProvidersByClass 8587 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8588 return; 8589 } 8590 8591 //update content provider record entry info 8592 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8593 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8594 if (localCpr.hasExternalProcessHandles()) { 8595 if (localCpr.removeExternalProcessHandleLocked(token)) { 8596 updateOomAdjLocked(); 8597 } else { 8598 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8599 + " with no external reference for token: " 8600 + token + "."); 8601 } 8602 } else { 8603 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8604 + " with no external references."); 8605 } 8606 } 8607 } 8608 8609 public final void publishContentProviders(IApplicationThread caller, 8610 List<ContentProviderHolder> providers) { 8611 if (providers == null) { 8612 return; 8613 } 8614 8615 enforceNotIsolatedCaller("publishContentProviders"); 8616 synchronized (this) { 8617 final ProcessRecord r = getRecordForAppLocked(caller); 8618 if (DEBUG_MU) 8619 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8620 if (r == null) { 8621 throw new SecurityException( 8622 "Unable to find app for caller " + caller 8623 + " (pid=" + Binder.getCallingPid() 8624 + ") when publishing content providers"); 8625 } 8626 8627 final long origId = Binder.clearCallingIdentity(); 8628 8629 final int N = providers.size(); 8630 for (int i=0; i<N; i++) { 8631 ContentProviderHolder src = providers.get(i); 8632 if (src == null || src.info == null || src.provider == null) { 8633 continue; 8634 } 8635 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8636 if (DEBUG_MU) 8637 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8638 if (dst != null) { 8639 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8640 mProviderMap.putProviderByClass(comp, dst); 8641 String names[] = dst.info.authority.split(";"); 8642 for (int j = 0; j < names.length; j++) { 8643 mProviderMap.putProviderByName(names[j], dst); 8644 } 8645 8646 int NL = mLaunchingProviders.size(); 8647 int j; 8648 for (j=0; j<NL; j++) { 8649 if (mLaunchingProviders.get(j) == dst) { 8650 mLaunchingProviders.remove(j); 8651 j--; 8652 NL--; 8653 } 8654 } 8655 synchronized (dst) { 8656 dst.provider = src.provider; 8657 dst.proc = r; 8658 dst.notifyAll(); 8659 } 8660 updateOomAdjLocked(r); 8661 } 8662 } 8663 8664 Binder.restoreCallingIdentity(origId); 8665 } 8666 } 8667 8668 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8669 ContentProviderConnection conn; 8670 try { 8671 conn = (ContentProviderConnection)connection; 8672 } catch (ClassCastException e) { 8673 String msg ="refContentProvider: " + connection 8674 + " not a ContentProviderConnection"; 8675 Slog.w(TAG, msg); 8676 throw new IllegalArgumentException(msg); 8677 } 8678 if (conn == null) { 8679 throw new NullPointerException("connection is null"); 8680 } 8681 8682 synchronized (this) { 8683 if (stable > 0) { 8684 conn.numStableIncs += stable; 8685 } 8686 stable = conn.stableCount + stable; 8687 if (stable < 0) { 8688 throw new IllegalStateException("stableCount < 0: " + stable); 8689 } 8690 8691 if (unstable > 0) { 8692 conn.numUnstableIncs += unstable; 8693 } 8694 unstable = conn.unstableCount + unstable; 8695 if (unstable < 0) { 8696 throw new IllegalStateException("unstableCount < 0: " + unstable); 8697 } 8698 8699 if ((stable+unstable) <= 0) { 8700 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8701 + stable + " unstable=" + unstable); 8702 } 8703 conn.stableCount = stable; 8704 conn.unstableCount = unstable; 8705 return !conn.dead; 8706 } 8707 } 8708 8709 public void unstableProviderDied(IBinder connection) { 8710 ContentProviderConnection conn; 8711 try { 8712 conn = (ContentProviderConnection)connection; 8713 } catch (ClassCastException e) { 8714 String msg ="refContentProvider: " + connection 8715 + " not a ContentProviderConnection"; 8716 Slog.w(TAG, msg); 8717 throw new IllegalArgumentException(msg); 8718 } 8719 if (conn == null) { 8720 throw new NullPointerException("connection is null"); 8721 } 8722 8723 // Safely retrieve the content provider associated with the connection. 8724 IContentProvider provider; 8725 synchronized (this) { 8726 provider = conn.provider.provider; 8727 } 8728 8729 if (provider == null) { 8730 // Um, yeah, we're way ahead of you. 8731 return; 8732 } 8733 8734 // Make sure the caller is being honest with us. 8735 if (provider.asBinder().pingBinder()) { 8736 // Er, no, still looks good to us. 8737 synchronized (this) { 8738 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8739 + " says " + conn + " died, but we don't agree"); 8740 return; 8741 } 8742 } 8743 8744 // Well look at that! It's dead! 8745 synchronized (this) { 8746 if (conn.provider.provider != provider) { 8747 // But something changed... good enough. 8748 return; 8749 } 8750 8751 ProcessRecord proc = conn.provider.proc; 8752 if (proc == null || proc.thread == null) { 8753 // Seems like the process is already cleaned up. 8754 return; 8755 } 8756 8757 // As far as we're concerned, this is just like receiving a 8758 // death notification... just a bit prematurely. 8759 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8760 + ") early provider death"); 8761 final long ident = Binder.clearCallingIdentity(); 8762 try { 8763 appDiedLocked(proc, proc.pid, proc.thread); 8764 } finally { 8765 Binder.restoreCallingIdentity(ident); 8766 } 8767 } 8768 } 8769 8770 @Override 8771 public void appNotRespondingViaProvider(IBinder connection) { 8772 enforceCallingPermission( 8773 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8774 8775 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8776 if (conn == null) { 8777 Slog.w(TAG, "ContentProviderConnection is null"); 8778 return; 8779 } 8780 8781 final ProcessRecord host = conn.provider.proc; 8782 if (host == null) { 8783 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8784 return; 8785 } 8786 8787 final long token = Binder.clearCallingIdentity(); 8788 try { 8789 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8790 } finally { 8791 Binder.restoreCallingIdentity(token); 8792 } 8793 } 8794 8795 public final void installSystemProviders() { 8796 List<ProviderInfo> providers; 8797 synchronized (this) { 8798 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8799 providers = generateApplicationProvidersLocked(app); 8800 if (providers != null) { 8801 for (int i=providers.size()-1; i>=0; i--) { 8802 ProviderInfo pi = (ProviderInfo)providers.get(i); 8803 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8804 Slog.w(TAG, "Not installing system proc provider " + pi.name 8805 + ": not system .apk"); 8806 providers.remove(i); 8807 } 8808 } 8809 } 8810 } 8811 if (providers != null) { 8812 mSystemThread.installSystemProviders(providers); 8813 } 8814 8815 mCoreSettingsObserver = new CoreSettingsObserver(this); 8816 8817 //mUsageStatsService.monitorPackages(); 8818 } 8819 8820 /** 8821 * Allows app to retrieve the MIME type of a URI without having permission 8822 * to access its content provider. 8823 * 8824 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8825 * 8826 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8827 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8828 */ 8829 public String getProviderMimeType(Uri uri, int userId) { 8830 enforceNotIsolatedCaller("getProviderMimeType"); 8831 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8832 userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null); 8833 final String name = uri.getAuthority(); 8834 final long ident = Binder.clearCallingIdentity(); 8835 ContentProviderHolder holder = null; 8836 8837 try { 8838 holder = getContentProviderExternalUnchecked(name, null, userId); 8839 if (holder != null) { 8840 return holder.provider.getType(uri); 8841 } 8842 } catch (RemoteException e) { 8843 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8844 return null; 8845 } finally { 8846 if (holder != null) { 8847 removeContentProviderExternalUnchecked(name, null, userId); 8848 } 8849 Binder.restoreCallingIdentity(ident); 8850 } 8851 8852 return null; 8853 } 8854 8855 // ========================================================= 8856 // GLOBAL MANAGEMENT 8857 // ========================================================= 8858 8859 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8860 boolean isolated) { 8861 String proc = customProcess != null ? customProcess : info.processName; 8862 BatteryStatsImpl.Uid.Proc ps = null; 8863 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8864 int uid = info.uid; 8865 if (isolated) { 8866 int userId = UserHandle.getUserId(uid); 8867 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8868 while (true) { 8869 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8870 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8871 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8872 } 8873 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8874 mNextIsolatedProcessUid++; 8875 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8876 // No process for this uid, use it. 8877 break; 8878 } 8879 stepsLeft--; 8880 if (stepsLeft <= 0) { 8881 return null; 8882 } 8883 } 8884 } 8885 return new ProcessRecord(stats, info, proc, uid); 8886 } 8887 8888 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8889 String abiOverride) { 8890 ProcessRecord app; 8891 if (!isolated) { 8892 app = getProcessRecordLocked(info.processName, info.uid, true); 8893 } else { 8894 app = null; 8895 } 8896 8897 if (app == null) { 8898 app = newProcessRecordLocked(info, null, isolated); 8899 mProcessNames.put(info.processName, app.uid, app); 8900 if (isolated) { 8901 mIsolatedProcesses.put(app.uid, app); 8902 } 8903 updateLruProcessLocked(app, false, null); 8904 updateOomAdjLocked(); 8905 } 8906 8907 // This package really, really can not be stopped. 8908 try { 8909 AppGlobals.getPackageManager().setPackageStoppedState( 8910 info.packageName, false, UserHandle.getUserId(app.uid)); 8911 } catch (RemoteException e) { 8912 } catch (IllegalArgumentException e) { 8913 Slog.w(TAG, "Failed trying to unstop package " 8914 + info.packageName + ": " + e); 8915 } 8916 8917 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8918 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8919 app.persistent = true; 8920 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8921 } 8922 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8923 mPersistentStartingProcesses.add(app); 8924 startProcessLocked(app, "added application", app.processName, 8925 abiOverride); 8926 } 8927 8928 return app; 8929 } 8930 8931 public void unhandledBack() { 8932 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8933 "unhandledBack()"); 8934 8935 synchronized(this) { 8936 final long origId = Binder.clearCallingIdentity(); 8937 try { 8938 getFocusedStack().unhandledBackLocked(); 8939 } finally { 8940 Binder.restoreCallingIdentity(origId); 8941 } 8942 } 8943 } 8944 8945 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8946 enforceNotIsolatedCaller("openContentUri"); 8947 final int userId = UserHandle.getCallingUserId(); 8948 String name = uri.getAuthority(); 8949 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8950 ParcelFileDescriptor pfd = null; 8951 if (cph != null) { 8952 // We record the binder invoker's uid in thread-local storage before 8953 // going to the content provider to open the file. Later, in the code 8954 // that handles all permissions checks, we look for this uid and use 8955 // that rather than the Activity Manager's own uid. The effect is that 8956 // we do the check against the caller's permissions even though it looks 8957 // to the content provider like the Activity Manager itself is making 8958 // the request. 8959 sCallerIdentity.set(new Identity( 8960 Binder.getCallingPid(), Binder.getCallingUid())); 8961 try { 8962 pfd = cph.provider.openFile(null, uri, "r", null); 8963 } catch (FileNotFoundException e) { 8964 // do nothing; pfd will be returned null 8965 } finally { 8966 // Ensure that whatever happens, we clean up the identity state 8967 sCallerIdentity.remove(); 8968 } 8969 8970 // We've got the fd now, so we're done with the provider. 8971 removeContentProviderExternalUnchecked(name, null, userId); 8972 } else { 8973 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8974 } 8975 return pfd; 8976 } 8977 8978 // Actually is sleeping or shutting down or whatever else in the future 8979 // is an inactive state. 8980 public boolean isSleepingOrShuttingDown() { 8981 return mSleeping || mShuttingDown; 8982 } 8983 8984 public boolean isSleeping() { 8985 return mSleeping; 8986 } 8987 8988 void goingToSleep() { 8989 synchronized(this) { 8990 mWentToSleep = true; 8991 updateEventDispatchingLocked(); 8992 goToSleepIfNeededLocked(); 8993 } 8994 } 8995 8996 void finishRunningVoiceLocked() { 8997 if (mRunningVoice) { 8998 mRunningVoice = false; 8999 goToSleepIfNeededLocked(); 9000 } 9001 } 9002 9003 void goToSleepIfNeededLocked() { 9004 if (mWentToSleep && !mRunningVoice) { 9005 if (!mSleeping) { 9006 mSleeping = true; 9007 mStackSupervisor.goingToSleepLocked(); 9008 9009 // Initialize the wake times of all processes. 9010 checkExcessivePowerUsageLocked(false); 9011 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9012 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9013 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9014 } 9015 } 9016 } 9017 9018 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9019 mTaskPersister.notify(task, flush); 9020 } 9021 9022 @Override 9023 public boolean shutdown(int timeout) { 9024 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9025 != PackageManager.PERMISSION_GRANTED) { 9026 throw new SecurityException("Requires permission " 9027 + android.Manifest.permission.SHUTDOWN); 9028 } 9029 9030 boolean timedout = false; 9031 9032 synchronized(this) { 9033 mShuttingDown = true; 9034 updateEventDispatchingLocked(); 9035 timedout = mStackSupervisor.shutdownLocked(timeout); 9036 } 9037 9038 mAppOpsService.shutdown(); 9039 if (mUsageStatsService != null) { 9040 mUsageStatsService.prepareShutdown(); 9041 } 9042 mBatteryStatsService.shutdown(); 9043 synchronized (this) { 9044 mProcessStats.shutdownLocked(); 9045 } 9046 notifyTaskPersisterLocked(null, true); 9047 9048 return timedout; 9049 } 9050 9051 public final void activitySlept(IBinder token) { 9052 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9053 9054 final long origId = Binder.clearCallingIdentity(); 9055 9056 synchronized (this) { 9057 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9058 if (r != null) { 9059 mStackSupervisor.activitySleptLocked(r); 9060 } 9061 } 9062 9063 Binder.restoreCallingIdentity(origId); 9064 } 9065 9066 void logLockScreen(String msg) { 9067 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9068 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9069 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 9070 mStackSupervisor.mDismissKeyguardOnNextActivity); 9071 } 9072 9073 private void comeOutOfSleepIfNeededLocked() { 9074 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9075 if (mSleeping) { 9076 mSleeping = false; 9077 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9078 } 9079 } 9080 } 9081 9082 void wakingUp() { 9083 synchronized(this) { 9084 mWentToSleep = false; 9085 updateEventDispatchingLocked(); 9086 comeOutOfSleepIfNeededLocked(); 9087 } 9088 } 9089 9090 void startRunningVoiceLocked() { 9091 if (!mRunningVoice) { 9092 mRunningVoice = true; 9093 comeOutOfSleepIfNeededLocked(); 9094 } 9095 } 9096 9097 private void updateEventDispatchingLocked() { 9098 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9099 } 9100 9101 public void setLockScreenShown(boolean shown) { 9102 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9103 != PackageManager.PERMISSION_GRANTED) { 9104 throw new SecurityException("Requires permission " 9105 + android.Manifest.permission.DEVICE_POWER); 9106 } 9107 9108 synchronized(this) { 9109 long ident = Binder.clearCallingIdentity(); 9110 try { 9111 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9112 mLockScreenShown = shown; 9113 comeOutOfSleepIfNeededLocked(); 9114 } finally { 9115 Binder.restoreCallingIdentity(ident); 9116 } 9117 } 9118 } 9119 9120 @Override 9121 public void stopAppSwitches() { 9122 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9123 != PackageManager.PERMISSION_GRANTED) { 9124 throw new SecurityException("Requires permission " 9125 + android.Manifest.permission.STOP_APP_SWITCHES); 9126 } 9127 9128 synchronized(this) { 9129 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9130 + APP_SWITCH_DELAY_TIME; 9131 mDidAppSwitch = false; 9132 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9133 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9134 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9135 } 9136 } 9137 9138 public void resumeAppSwitches() { 9139 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9140 != PackageManager.PERMISSION_GRANTED) { 9141 throw new SecurityException("Requires permission " 9142 + android.Manifest.permission.STOP_APP_SWITCHES); 9143 } 9144 9145 synchronized(this) { 9146 // Note that we don't execute any pending app switches... we will 9147 // let those wait until either the timeout, or the next start 9148 // activity request. 9149 mAppSwitchesAllowedTime = 0; 9150 } 9151 } 9152 9153 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9154 String name) { 9155 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9156 return true; 9157 } 9158 9159 final int perm = checkComponentPermission( 9160 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9161 callingUid, -1, true); 9162 if (perm == PackageManager.PERMISSION_GRANTED) { 9163 return true; 9164 } 9165 9166 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9167 return false; 9168 } 9169 9170 public void setDebugApp(String packageName, boolean waitForDebugger, 9171 boolean persistent) { 9172 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9173 "setDebugApp()"); 9174 9175 long ident = Binder.clearCallingIdentity(); 9176 try { 9177 // Note that this is not really thread safe if there are multiple 9178 // callers into it at the same time, but that's not a situation we 9179 // care about. 9180 if (persistent) { 9181 final ContentResolver resolver = mContext.getContentResolver(); 9182 Settings.Global.putString( 9183 resolver, Settings.Global.DEBUG_APP, 9184 packageName); 9185 Settings.Global.putInt( 9186 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9187 waitForDebugger ? 1 : 0); 9188 } 9189 9190 synchronized (this) { 9191 if (!persistent) { 9192 mOrigDebugApp = mDebugApp; 9193 mOrigWaitForDebugger = mWaitForDebugger; 9194 } 9195 mDebugApp = packageName; 9196 mWaitForDebugger = waitForDebugger; 9197 mDebugTransient = !persistent; 9198 if (packageName != null) { 9199 forceStopPackageLocked(packageName, -1, false, false, true, true, 9200 false, UserHandle.USER_ALL, "set debug app"); 9201 } 9202 } 9203 } finally { 9204 Binder.restoreCallingIdentity(ident); 9205 } 9206 } 9207 9208 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9209 synchronized (this) { 9210 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9211 if (!isDebuggable) { 9212 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9213 throw new SecurityException("Process not debuggable: " + app.packageName); 9214 } 9215 } 9216 9217 mOpenGlTraceApp = processName; 9218 } 9219 } 9220 9221 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9222 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9223 synchronized (this) { 9224 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9225 if (!isDebuggable) { 9226 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9227 throw new SecurityException("Process not debuggable: " + app.packageName); 9228 } 9229 } 9230 mProfileApp = processName; 9231 mProfileFile = profileFile; 9232 if (mProfileFd != null) { 9233 try { 9234 mProfileFd.close(); 9235 } catch (IOException e) { 9236 } 9237 mProfileFd = null; 9238 } 9239 mProfileFd = profileFd; 9240 mProfileType = 0; 9241 mAutoStopProfiler = autoStopProfiler; 9242 } 9243 } 9244 9245 @Override 9246 public void setAlwaysFinish(boolean enabled) { 9247 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9248 "setAlwaysFinish()"); 9249 9250 Settings.Global.putInt( 9251 mContext.getContentResolver(), 9252 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9253 9254 synchronized (this) { 9255 mAlwaysFinishActivities = enabled; 9256 } 9257 } 9258 9259 @Override 9260 public void setActivityController(IActivityController controller) { 9261 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9262 "setActivityController()"); 9263 synchronized (this) { 9264 mController = controller; 9265 Watchdog.getInstance().setActivityController(controller); 9266 } 9267 } 9268 9269 @Override 9270 public void setUserIsMonkey(boolean userIsMonkey) { 9271 synchronized (this) { 9272 synchronized (mPidsSelfLocked) { 9273 final int callingPid = Binder.getCallingPid(); 9274 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9275 if (precessRecord == null) { 9276 throw new SecurityException("Unknown process: " + callingPid); 9277 } 9278 if (precessRecord.instrumentationUiAutomationConnection == null) { 9279 throw new SecurityException("Only an instrumentation process " 9280 + "with a UiAutomation can call setUserIsMonkey"); 9281 } 9282 } 9283 mUserIsMonkey = userIsMonkey; 9284 } 9285 } 9286 9287 @Override 9288 public boolean isUserAMonkey() { 9289 synchronized (this) { 9290 // If there is a controller also implies the user is a monkey. 9291 return (mUserIsMonkey || mController != null); 9292 } 9293 } 9294 9295 public void requestBugReport() { 9296 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9297 SystemProperties.set("ctl.start", "bugreport"); 9298 } 9299 9300 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9301 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9302 } 9303 9304 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9305 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9306 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9307 } 9308 return KEY_DISPATCHING_TIMEOUT; 9309 } 9310 9311 @Override 9312 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9313 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9314 != PackageManager.PERMISSION_GRANTED) { 9315 throw new SecurityException("Requires permission " 9316 + android.Manifest.permission.FILTER_EVENTS); 9317 } 9318 ProcessRecord proc; 9319 long timeout; 9320 synchronized (this) { 9321 synchronized (mPidsSelfLocked) { 9322 proc = mPidsSelfLocked.get(pid); 9323 } 9324 timeout = getInputDispatchingTimeoutLocked(proc); 9325 } 9326 9327 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9328 return -1; 9329 } 9330 9331 return timeout; 9332 } 9333 9334 /** 9335 * Handle input dispatching timeouts. 9336 * Returns whether input dispatching should be aborted or not. 9337 */ 9338 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9339 final ActivityRecord activity, final ActivityRecord parent, 9340 final boolean aboveSystem, String reason) { 9341 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9342 != PackageManager.PERMISSION_GRANTED) { 9343 throw new SecurityException("Requires permission " 9344 + android.Manifest.permission.FILTER_EVENTS); 9345 } 9346 9347 final String annotation; 9348 if (reason == null) { 9349 annotation = "Input dispatching timed out"; 9350 } else { 9351 annotation = "Input dispatching timed out (" + reason + ")"; 9352 } 9353 9354 if (proc != null) { 9355 synchronized (this) { 9356 if (proc.debugging) { 9357 return false; 9358 } 9359 9360 if (mDidDexOpt) { 9361 // Give more time since we were dexopting. 9362 mDidDexOpt = false; 9363 return false; 9364 } 9365 9366 if (proc.instrumentationClass != null) { 9367 Bundle info = new Bundle(); 9368 info.putString("shortMsg", "keyDispatchingTimedOut"); 9369 info.putString("longMsg", annotation); 9370 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9371 return true; 9372 } 9373 } 9374 mHandler.post(new Runnable() { 9375 @Override 9376 public void run() { 9377 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9378 } 9379 }); 9380 } 9381 9382 return true; 9383 } 9384 9385 public Bundle getAssistContextExtras(int requestType) { 9386 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9387 "getAssistContextExtras()"); 9388 PendingAssistExtras pae; 9389 Bundle extras = new Bundle(); 9390 synchronized (this) { 9391 ActivityRecord activity = getFocusedStack().mResumedActivity; 9392 if (activity == null) { 9393 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9394 return null; 9395 } 9396 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9397 if (activity.app == null || activity.app.thread == null) { 9398 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9399 return extras; 9400 } 9401 if (activity.app.pid == Binder.getCallingPid()) { 9402 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9403 return extras; 9404 } 9405 pae = new PendingAssistExtras(activity); 9406 try { 9407 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9408 requestType); 9409 mPendingAssistExtras.add(pae); 9410 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9411 } catch (RemoteException e) { 9412 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9413 return extras; 9414 } 9415 } 9416 synchronized (pae) { 9417 while (!pae.haveResult) { 9418 try { 9419 pae.wait(); 9420 } catch (InterruptedException e) { 9421 } 9422 } 9423 if (pae.result != null) { 9424 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9425 } 9426 } 9427 synchronized (this) { 9428 mPendingAssistExtras.remove(pae); 9429 mHandler.removeCallbacks(pae); 9430 } 9431 return extras; 9432 } 9433 9434 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9435 PendingAssistExtras pae = (PendingAssistExtras)token; 9436 synchronized (pae) { 9437 pae.result = extras; 9438 pae.haveResult = true; 9439 pae.notifyAll(); 9440 } 9441 } 9442 9443 public void registerProcessObserver(IProcessObserver observer) { 9444 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9445 "registerProcessObserver()"); 9446 synchronized (this) { 9447 mProcessObservers.register(observer); 9448 } 9449 } 9450 9451 @Override 9452 public void unregisterProcessObserver(IProcessObserver observer) { 9453 synchronized (this) { 9454 mProcessObservers.unregister(observer); 9455 } 9456 } 9457 9458 @Override 9459 public boolean convertFromTranslucent(IBinder token) { 9460 final long origId = Binder.clearCallingIdentity(); 9461 try { 9462 synchronized (this) { 9463 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9464 if (r == null) { 9465 return false; 9466 } 9467 if (r.changeWindowTranslucency(true)) { 9468 mWindowManager.setAppFullscreen(token, true); 9469 r.task.stack.releaseMediaResources(); 9470 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9471 return true; 9472 } 9473 return false; 9474 } 9475 } finally { 9476 Binder.restoreCallingIdentity(origId); 9477 } 9478 } 9479 9480 @Override 9481 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9482 final long origId = Binder.clearCallingIdentity(); 9483 try { 9484 synchronized (this) { 9485 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9486 if (r == null) { 9487 return false; 9488 } 9489 if (r.changeWindowTranslucency(false)) { 9490 r.task.stack.convertToTranslucent(r, options); 9491 mWindowManager.setAppFullscreen(token, false); 9492 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9493 return true; 9494 } else { 9495 r.task.stack.mReturningActivityOptions = options; 9496 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9497 return false; 9498 } 9499 } 9500 } finally { 9501 Binder.restoreCallingIdentity(origId); 9502 } 9503 } 9504 9505 @Override 9506 public boolean setMediaPlaying(IBinder token, boolean playing) { 9507 final long origId = Binder.clearCallingIdentity(); 9508 try { 9509 synchronized (this) { 9510 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9511 if (r != null) { 9512 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9513 } 9514 } 9515 return false; 9516 } finally { 9517 Binder.restoreCallingIdentity(origId); 9518 } 9519 } 9520 9521 @Override 9522 public boolean isBackgroundMediaPlaying(IBinder token) { 9523 final long origId = Binder.clearCallingIdentity(); 9524 try { 9525 synchronized (this) { 9526 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9527 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9528 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9529 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9530 return playing; 9531 } 9532 } finally { 9533 Binder.restoreCallingIdentity(origId); 9534 } 9535 } 9536 9537 @Override 9538 public ActivityOptions getActivityOptions(IBinder token) { 9539 final long origId = Binder.clearCallingIdentity(); 9540 try { 9541 synchronized (this) { 9542 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9543 if (r != null) { 9544 final ActivityOptions activityOptions = r.pendingOptions; 9545 r.pendingOptions = null; 9546 return activityOptions; 9547 } 9548 return null; 9549 } 9550 } finally { 9551 Binder.restoreCallingIdentity(origId); 9552 } 9553 } 9554 9555 @Override 9556 public void setImmersive(IBinder token, boolean immersive) { 9557 synchronized(this) { 9558 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9559 if (r == null) { 9560 throw new IllegalArgumentException(); 9561 } 9562 r.immersive = immersive; 9563 9564 // update associated state if we're frontmost 9565 if (r == mFocusedActivity) { 9566 if (DEBUG_IMMERSIVE) { 9567 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9568 } 9569 applyUpdateLockStateLocked(r); 9570 } 9571 } 9572 } 9573 9574 @Override 9575 public boolean isImmersive(IBinder token) { 9576 synchronized (this) { 9577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9578 if (r == null) { 9579 throw new IllegalArgumentException(); 9580 } 9581 return r.immersive; 9582 } 9583 } 9584 9585 public boolean isTopActivityImmersive() { 9586 enforceNotIsolatedCaller("startActivity"); 9587 synchronized (this) { 9588 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9589 return (r != null) ? r.immersive : false; 9590 } 9591 } 9592 9593 @Override 9594 public boolean isTopOfTask(IBinder token) { 9595 synchronized (this) { 9596 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9597 if (r == null) { 9598 throw new IllegalArgumentException(); 9599 } 9600 return r.task.getTopActivity() == r; 9601 } 9602 } 9603 9604 public final void enterSafeMode() { 9605 synchronized(this) { 9606 // It only makes sense to do this before the system is ready 9607 // and started launching other packages. 9608 if (!mSystemReady) { 9609 try { 9610 AppGlobals.getPackageManager().enterSafeMode(); 9611 } catch (RemoteException e) { 9612 } 9613 } 9614 9615 mSafeMode = true; 9616 } 9617 } 9618 9619 public final void showSafeModeOverlay() { 9620 View v = LayoutInflater.from(mContext).inflate( 9621 com.android.internal.R.layout.safe_mode, null); 9622 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9623 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9624 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9625 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9626 lp.gravity = Gravity.BOTTOM | Gravity.START; 9627 lp.format = v.getBackground().getOpacity(); 9628 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9629 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9630 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9631 ((WindowManager)mContext.getSystemService( 9632 Context.WINDOW_SERVICE)).addView(v, lp); 9633 } 9634 9635 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9636 if (!(sender instanceof PendingIntentRecord)) { 9637 return; 9638 } 9639 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9640 synchronized (stats) { 9641 if (mBatteryStatsService.isOnBattery()) { 9642 mBatteryStatsService.enforceCallingPermission(); 9643 PendingIntentRecord rec = (PendingIntentRecord)sender; 9644 int MY_UID = Binder.getCallingUid(); 9645 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9646 BatteryStatsImpl.Uid.Pkg pkg = 9647 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9648 sourcePkg != null ? sourcePkg : rec.key.packageName); 9649 pkg.incWakeupsLocked(); 9650 } 9651 } 9652 } 9653 9654 public boolean killPids(int[] pids, String pReason, boolean secure) { 9655 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9656 throw new SecurityException("killPids only available to the system"); 9657 } 9658 String reason = (pReason == null) ? "Unknown" : pReason; 9659 // XXX Note: don't acquire main activity lock here, because the window 9660 // manager calls in with its locks held. 9661 9662 boolean killed = false; 9663 synchronized (mPidsSelfLocked) { 9664 int[] types = new int[pids.length]; 9665 int worstType = 0; 9666 for (int i=0; i<pids.length; i++) { 9667 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9668 if (proc != null) { 9669 int type = proc.setAdj; 9670 types[i] = type; 9671 if (type > worstType) { 9672 worstType = type; 9673 } 9674 } 9675 } 9676 9677 // If the worst oom_adj is somewhere in the cached proc LRU range, 9678 // then constrain it so we will kill all cached procs. 9679 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9680 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9681 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9682 } 9683 9684 // If this is not a secure call, don't let it kill processes that 9685 // are important. 9686 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9687 worstType = ProcessList.SERVICE_ADJ; 9688 } 9689 9690 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9691 for (int i=0; i<pids.length; i++) { 9692 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9693 if (proc == null) { 9694 continue; 9695 } 9696 int adj = proc.setAdj; 9697 if (adj >= worstType && !proc.killedByAm) { 9698 killUnneededProcessLocked(proc, reason); 9699 killed = true; 9700 } 9701 } 9702 } 9703 return killed; 9704 } 9705 9706 @Override 9707 public void killUid(int uid, String reason) { 9708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9709 throw new SecurityException("killUid only available to the system"); 9710 } 9711 synchronized (this) { 9712 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9713 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9714 reason != null ? reason : "kill uid"); 9715 } 9716 } 9717 9718 @Override 9719 public boolean killProcessesBelowForeground(String reason) { 9720 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9721 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9722 } 9723 9724 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9725 } 9726 9727 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9728 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9729 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9730 } 9731 9732 boolean killed = false; 9733 synchronized (mPidsSelfLocked) { 9734 final int size = mPidsSelfLocked.size(); 9735 for (int i = 0; i < size; i++) { 9736 final int pid = mPidsSelfLocked.keyAt(i); 9737 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9738 if (proc == null) continue; 9739 9740 final int adj = proc.setAdj; 9741 if (adj > belowAdj && !proc.killedByAm) { 9742 killUnneededProcessLocked(proc, reason); 9743 killed = true; 9744 } 9745 } 9746 } 9747 return killed; 9748 } 9749 9750 @Override 9751 public void hang(final IBinder who, boolean allowRestart) { 9752 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9753 != PackageManager.PERMISSION_GRANTED) { 9754 throw new SecurityException("Requires permission " 9755 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9756 } 9757 9758 final IBinder.DeathRecipient death = new DeathRecipient() { 9759 @Override 9760 public void binderDied() { 9761 synchronized (this) { 9762 notifyAll(); 9763 } 9764 } 9765 }; 9766 9767 try { 9768 who.linkToDeath(death, 0); 9769 } catch (RemoteException e) { 9770 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9771 return; 9772 } 9773 9774 synchronized (this) { 9775 Watchdog.getInstance().setAllowRestart(allowRestart); 9776 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9777 synchronized (death) { 9778 while (who.isBinderAlive()) { 9779 try { 9780 death.wait(); 9781 } catch (InterruptedException e) { 9782 } 9783 } 9784 } 9785 Watchdog.getInstance().setAllowRestart(true); 9786 } 9787 } 9788 9789 @Override 9790 public void restart() { 9791 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9792 != PackageManager.PERMISSION_GRANTED) { 9793 throw new SecurityException("Requires permission " 9794 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9795 } 9796 9797 Log.i(TAG, "Sending shutdown broadcast..."); 9798 9799 BroadcastReceiver br = new BroadcastReceiver() { 9800 @Override public void onReceive(Context context, Intent intent) { 9801 // Now the broadcast is done, finish up the low-level shutdown. 9802 Log.i(TAG, "Shutting down activity manager..."); 9803 shutdown(10000); 9804 Log.i(TAG, "Shutdown complete, restarting!"); 9805 Process.killProcess(Process.myPid()); 9806 System.exit(10); 9807 } 9808 }; 9809 9810 // First send the high-level shut down broadcast. 9811 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9812 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9813 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9814 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9815 mContext.sendOrderedBroadcastAsUser(intent, 9816 UserHandle.ALL, null, br, mHandler, 0, null, null); 9817 */ 9818 br.onReceive(mContext, intent); 9819 } 9820 9821 private long getLowRamTimeSinceIdle(long now) { 9822 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9823 } 9824 9825 @Override 9826 public void performIdleMaintenance() { 9827 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9828 != PackageManager.PERMISSION_GRANTED) { 9829 throw new SecurityException("Requires permission " 9830 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9831 } 9832 9833 synchronized (this) { 9834 final long now = SystemClock.uptimeMillis(); 9835 final long timeSinceLastIdle = now - mLastIdleTime; 9836 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9837 mLastIdleTime = now; 9838 mLowRamTimeSinceLastIdle = 0; 9839 if (mLowRamStartTime != 0) { 9840 mLowRamStartTime = now; 9841 } 9842 9843 StringBuilder sb = new StringBuilder(128); 9844 sb.append("Idle maintenance over "); 9845 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9846 sb.append(" low RAM for "); 9847 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9848 Slog.i(TAG, sb.toString()); 9849 9850 // If at least 1/3 of our time since the last idle period has been spent 9851 // with RAM low, then we want to kill processes. 9852 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9853 9854 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9855 ProcessRecord proc = mLruProcesses.get(i); 9856 if (proc.notCachedSinceIdle) { 9857 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9858 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9859 if (doKilling && proc.initialIdlePss != 0 9860 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9861 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9862 + " from " + proc.initialIdlePss + ")"); 9863 } 9864 } 9865 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9866 proc.notCachedSinceIdle = true; 9867 proc.initialIdlePss = 0; 9868 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9869 isSleeping(), now); 9870 } 9871 } 9872 9873 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9874 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9875 } 9876 } 9877 9878 private void retrieveSettings() { 9879 final ContentResolver resolver = mContext.getContentResolver(); 9880 String debugApp = Settings.Global.getString( 9881 resolver, Settings.Global.DEBUG_APP); 9882 boolean waitForDebugger = Settings.Global.getInt( 9883 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9884 boolean alwaysFinishActivities = Settings.Global.getInt( 9885 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9886 boolean forceRtl = Settings.Global.getInt( 9887 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9888 // Transfer any global setting for forcing RTL layout, into a System Property 9889 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9890 9891 Configuration configuration = new Configuration(); 9892 Settings.System.getConfiguration(resolver, configuration); 9893 if (forceRtl) { 9894 // This will take care of setting the correct layout direction flags 9895 configuration.setLayoutDirection(configuration.locale); 9896 } 9897 9898 synchronized (this) { 9899 mDebugApp = mOrigDebugApp = debugApp; 9900 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9901 mAlwaysFinishActivities = alwaysFinishActivities; 9902 // This happens before any activities are started, so we can 9903 // change mConfiguration in-place. 9904 updateConfigurationLocked(configuration, null, false, true); 9905 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9906 } 9907 } 9908 9909 public boolean testIsSystemReady() { 9910 // no need to synchronize(this) just to read & return the value 9911 return mSystemReady; 9912 } 9913 9914 private static File getCalledPreBootReceiversFile() { 9915 File dataDir = Environment.getDataDirectory(); 9916 File systemDir = new File(dataDir, "system"); 9917 File fname = new File(systemDir, "called_pre_boots.dat"); 9918 return fname; 9919 } 9920 9921 static final int LAST_DONE_VERSION = 10000; 9922 9923 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9924 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9925 File file = getCalledPreBootReceiversFile(); 9926 FileInputStream fis = null; 9927 try { 9928 fis = new FileInputStream(file); 9929 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9930 int fvers = dis.readInt(); 9931 if (fvers == LAST_DONE_VERSION) { 9932 String vers = dis.readUTF(); 9933 String codename = dis.readUTF(); 9934 String build = dis.readUTF(); 9935 if (android.os.Build.VERSION.RELEASE.equals(vers) 9936 && android.os.Build.VERSION.CODENAME.equals(codename) 9937 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9938 int num = dis.readInt(); 9939 while (num > 0) { 9940 num--; 9941 String pkg = dis.readUTF(); 9942 String cls = dis.readUTF(); 9943 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9944 } 9945 } 9946 } 9947 } catch (FileNotFoundException e) { 9948 } catch (IOException e) { 9949 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9950 } finally { 9951 if (fis != null) { 9952 try { 9953 fis.close(); 9954 } catch (IOException e) { 9955 } 9956 } 9957 } 9958 return lastDoneReceivers; 9959 } 9960 9961 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9962 File file = getCalledPreBootReceiversFile(); 9963 FileOutputStream fos = null; 9964 DataOutputStream dos = null; 9965 try { 9966 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9967 fos = new FileOutputStream(file); 9968 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9969 dos.writeInt(LAST_DONE_VERSION); 9970 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9971 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9972 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9973 dos.writeInt(list.size()); 9974 for (int i=0; i<list.size(); i++) { 9975 dos.writeUTF(list.get(i).getPackageName()); 9976 dos.writeUTF(list.get(i).getClassName()); 9977 } 9978 } catch (IOException e) { 9979 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9980 file.delete(); 9981 } finally { 9982 FileUtils.sync(fos); 9983 if (dos != null) { 9984 try { 9985 dos.close(); 9986 } catch (IOException e) { 9987 // TODO Auto-generated catch block 9988 e.printStackTrace(); 9989 } 9990 } 9991 } 9992 } 9993 9994 public void systemReady(final Runnable goingCallback) { 9995 synchronized(this) { 9996 if (mSystemReady) { 9997 if (goingCallback != null) goingCallback.run(); 9998 return; 9999 } 10000 10001 // Make sure we have the current profile info, since it is needed for 10002 // security checks. 10003 updateCurrentProfileIdsLocked(); 10004 10005 if (mRecentTasks == null) { 10006 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10007 if (!mRecentTasks.isEmpty()) { 10008 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10009 } 10010 mTaskPersister.startPersisting(); 10011 } 10012 10013 // Check to see if there are any update receivers to run. 10014 if (!mDidUpdate) { 10015 if (mWaitingUpdate) { 10016 return; 10017 } 10018 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10019 List<ResolveInfo> ris = null; 10020 try { 10021 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10022 intent, null, 0, 0); 10023 } catch (RemoteException e) { 10024 } 10025 if (ris != null) { 10026 for (int i=ris.size()-1; i>=0; i--) { 10027 if ((ris.get(i).activityInfo.applicationInfo.flags 10028 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10029 ris.remove(i); 10030 } 10031 } 10032 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10033 10034 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10035 10036 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10037 for (int i=0; i<ris.size(); i++) { 10038 ActivityInfo ai = ris.get(i).activityInfo; 10039 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10040 if (lastDoneReceivers.contains(comp)) { 10041 // We already did the pre boot receiver for this app with the current 10042 // platform version, so don't do it again... 10043 ris.remove(i); 10044 i--; 10045 // ...however, do keep it as one that has been done, so we don't 10046 // forget about it when rewriting the file of last done receivers. 10047 doneReceivers.add(comp); 10048 } 10049 } 10050 10051 final int[] users = getUsersLocked(); 10052 for (int i=0; i<ris.size(); i++) { 10053 ActivityInfo ai = ris.get(i).activityInfo; 10054 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10055 doneReceivers.add(comp); 10056 intent.setComponent(comp); 10057 for (int j=0; j<users.length; j++) { 10058 IIntentReceiver finisher = null; 10059 if (i == ris.size()-1 && j == users.length-1) { 10060 finisher = new IIntentReceiver.Stub() { 10061 public void performReceive(Intent intent, int resultCode, 10062 String data, Bundle extras, boolean ordered, 10063 boolean sticky, int sendingUser) { 10064 // The raw IIntentReceiver interface is called 10065 // with the AM lock held, so redispatch to 10066 // execute our code without the lock. 10067 mHandler.post(new Runnable() { 10068 public void run() { 10069 synchronized (ActivityManagerService.this) { 10070 mDidUpdate = true; 10071 } 10072 writeLastDonePreBootReceivers(doneReceivers); 10073 showBootMessage(mContext.getText( 10074 R.string.android_upgrading_complete), 10075 false); 10076 systemReady(goingCallback); 10077 } 10078 }); 10079 } 10080 }; 10081 } 10082 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10083 + " for user " + users[j]); 10084 broadcastIntentLocked(null, null, intent, null, finisher, 10085 0, null, null, null, AppOpsManager.OP_NONE, 10086 true, false, MY_PID, Process.SYSTEM_UID, 10087 users[j]); 10088 if (finisher != null) { 10089 mWaitingUpdate = true; 10090 } 10091 } 10092 } 10093 } 10094 if (mWaitingUpdate) { 10095 return; 10096 } 10097 mDidUpdate = true; 10098 } 10099 10100 mAppOpsService.systemReady(); 10101 mSystemReady = true; 10102 } 10103 10104 ArrayList<ProcessRecord> procsToKill = null; 10105 synchronized(mPidsSelfLocked) { 10106 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10107 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10108 if (!isAllowedWhileBooting(proc.info)){ 10109 if (procsToKill == null) { 10110 procsToKill = new ArrayList<ProcessRecord>(); 10111 } 10112 procsToKill.add(proc); 10113 } 10114 } 10115 } 10116 10117 synchronized(this) { 10118 if (procsToKill != null) { 10119 for (int i=procsToKill.size()-1; i>=0; i--) { 10120 ProcessRecord proc = procsToKill.get(i); 10121 Slog.i(TAG, "Removing system update proc: " + proc); 10122 removeProcessLocked(proc, true, false, "system update done"); 10123 } 10124 } 10125 10126 // Now that we have cleaned up any update processes, we 10127 // are ready to start launching real processes and know that 10128 // we won't trample on them any more. 10129 mProcessesReady = true; 10130 } 10131 10132 Slog.i(TAG, "System now ready"); 10133 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10134 SystemClock.uptimeMillis()); 10135 10136 synchronized(this) { 10137 // Make sure we have no pre-ready processes sitting around. 10138 10139 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10140 ResolveInfo ri = mContext.getPackageManager() 10141 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10142 STOCK_PM_FLAGS); 10143 CharSequence errorMsg = null; 10144 if (ri != null) { 10145 ActivityInfo ai = ri.activityInfo; 10146 ApplicationInfo app = ai.applicationInfo; 10147 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10148 mTopAction = Intent.ACTION_FACTORY_TEST; 10149 mTopData = null; 10150 mTopComponent = new ComponentName(app.packageName, 10151 ai.name); 10152 } else { 10153 errorMsg = mContext.getResources().getText( 10154 com.android.internal.R.string.factorytest_not_system); 10155 } 10156 } else { 10157 errorMsg = mContext.getResources().getText( 10158 com.android.internal.R.string.factorytest_no_action); 10159 } 10160 if (errorMsg != null) { 10161 mTopAction = null; 10162 mTopData = null; 10163 mTopComponent = null; 10164 Message msg = Message.obtain(); 10165 msg.what = SHOW_FACTORY_ERROR_MSG; 10166 msg.getData().putCharSequence("msg", errorMsg); 10167 mHandler.sendMessage(msg); 10168 } 10169 } 10170 } 10171 10172 retrieveSettings(); 10173 10174 synchronized (this) { 10175 readGrantedUriPermissionsLocked(); 10176 } 10177 10178 if (goingCallback != null) goingCallback.run(); 10179 10180 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10181 Integer.toString(mCurrentUserId), mCurrentUserId); 10182 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10183 Integer.toString(mCurrentUserId), mCurrentUserId); 10184 mSystemServiceManager.startUser(mCurrentUserId); 10185 10186 synchronized (this) { 10187 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10188 try { 10189 List apps = AppGlobals.getPackageManager(). 10190 getPersistentApplications(STOCK_PM_FLAGS); 10191 if (apps != null) { 10192 int N = apps.size(); 10193 int i; 10194 for (i=0; i<N; i++) { 10195 ApplicationInfo info 10196 = (ApplicationInfo)apps.get(i); 10197 if (info != null && 10198 !info.packageName.equals("android")) { 10199 addAppLocked(info, false, null /* ABI override */); 10200 } 10201 } 10202 } 10203 } catch (RemoteException ex) { 10204 // pm is in same process, this will never happen. 10205 } 10206 } 10207 10208 // Start up initial activity. 10209 mBooting = true; 10210 10211 try { 10212 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10213 Message msg = Message.obtain(); 10214 msg.what = SHOW_UID_ERROR_MSG; 10215 mHandler.sendMessage(msg); 10216 } 10217 } catch (RemoteException e) { 10218 } 10219 10220 long ident = Binder.clearCallingIdentity(); 10221 try { 10222 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10223 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10224 | Intent.FLAG_RECEIVER_FOREGROUND); 10225 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10226 broadcastIntentLocked(null, null, intent, 10227 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10228 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10229 intent = new Intent(Intent.ACTION_USER_STARTING); 10230 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10231 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10232 broadcastIntentLocked(null, null, intent, 10233 null, new IIntentReceiver.Stub() { 10234 @Override 10235 public void performReceive(Intent intent, int resultCode, String data, 10236 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10237 throws RemoteException { 10238 } 10239 }, 0, null, null, 10240 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10241 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10242 } catch (Throwable t) { 10243 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10244 } finally { 10245 Binder.restoreCallingIdentity(ident); 10246 } 10247 mStackSupervisor.resumeTopActivitiesLocked(); 10248 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10249 } 10250 } 10251 10252 private boolean makeAppCrashingLocked(ProcessRecord app, 10253 String shortMsg, String longMsg, String stackTrace) { 10254 app.crashing = true; 10255 app.crashingReport = generateProcessError(app, 10256 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10257 startAppProblemLocked(app); 10258 app.stopFreezingAllLocked(); 10259 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10260 } 10261 10262 private void makeAppNotRespondingLocked(ProcessRecord app, 10263 String activity, String shortMsg, String longMsg) { 10264 app.notResponding = true; 10265 app.notRespondingReport = generateProcessError(app, 10266 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10267 activity, shortMsg, longMsg, null); 10268 startAppProblemLocked(app); 10269 app.stopFreezingAllLocked(); 10270 } 10271 10272 /** 10273 * Generate a process error record, suitable for attachment to a ProcessRecord. 10274 * 10275 * @param app The ProcessRecord in which the error occurred. 10276 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10277 * ActivityManager.AppErrorStateInfo 10278 * @param activity The activity associated with the crash, if known. 10279 * @param shortMsg Short message describing the crash. 10280 * @param longMsg Long message describing the crash. 10281 * @param stackTrace Full crash stack trace, may be null. 10282 * 10283 * @return Returns a fully-formed AppErrorStateInfo record. 10284 */ 10285 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10286 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10287 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10288 10289 report.condition = condition; 10290 report.processName = app.processName; 10291 report.pid = app.pid; 10292 report.uid = app.info.uid; 10293 report.tag = activity; 10294 report.shortMsg = shortMsg; 10295 report.longMsg = longMsg; 10296 report.stackTrace = stackTrace; 10297 10298 return report; 10299 } 10300 10301 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10302 synchronized (this) { 10303 app.crashing = false; 10304 app.crashingReport = null; 10305 app.notResponding = false; 10306 app.notRespondingReport = null; 10307 if (app.anrDialog == fromDialog) { 10308 app.anrDialog = null; 10309 } 10310 if (app.waitDialog == fromDialog) { 10311 app.waitDialog = null; 10312 } 10313 if (app.pid > 0 && app.pid != MY_PID) { 10314 handleAppCrashLocked(app, null, null, null); 10315 killUnneededProcessLocked(app, "user request after error"); 10316 } 10317 } 10318 } 10319 10320 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10321 String stackTrace) { 10322 long now = SystemClock.uptimeMillis(); 10323 10324 Long crashTime; 10325 if (!app.isolated) { 10326 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10327 } else { 10328 crashTime = null; 10329 } 10330 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10331 // This process loses! 10332 Slog.w(TAG, "Process " + app.info.processName 10333 + " has crashed too many times: killing!"); 10334 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10335 app.userId, app.info.processName, app.uid); 10336 mStackSupervisor.handleAppCrashLocked(app); 10337 if (!app.persistent) { 10338 // We don't want to start this process again until the user 10339 // explicitly does so... but for persistent process, we really 10340 // need to keep it running. If a persistent process is actually 10341 // repeatedly crashing, then badness for everyone. 10342 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10343 app.info.processName); 10344 if (!app.isolated) { 10345 // XXX We don't have a way to mark isolated processes 10346 // as bad, since they don't have a peristent identity. 10347 mBadProcesses.put(app.info.processName, app.uid, 10348 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10349 mProcessCrashTimes.remove(app.info.processName, app.uid); 10350 } 10351 app.bad = true; 10352 app.removed = true; 10353 // Don't let services in this process be restarted and potentially 10354 // annoy the user repeatedly. Unless it is persistent, since those 10355 // processes run critical code. 10356 removeProcessLocked(app, false, false, "crash"); 10357 mStackSupervisor.resumeTopActivitiesLocked(); 10358 return false; 10359 } 10360 mStackSupervisor.resumeTopActivitiesLocked(); 10361 } else { 10362 mStackSupervisor.finishTopRunningActivityLocked(app); 10363 } 10364 10365 // Bump up the crash count of any services currently running in the proc. 10366 for (int i=app.services.size()-1; i>=0; i--) { 10367 // Any services running in the application need to be placed 10368 // back in the pending list. 10369 ServiceRecord sr = app.services.valueAt(i); 10370 sr.crashCount++; 10371 } 10372 10373 // If the crashing process is what we consider to be the "home process" and it has been 10374 // replaced by a third-party app, clear the package preferred activities from packages 10375 // with a home activity running in the process to prevent a repeatedly crashing app 10376 // from blocking the user to manually clear the list. 10377 final ArrayList<ActivityRecord> activities = app.activities; 10378 if (app == mHomeProcess && activities.size() > 0 10379 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10380 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10381 final ActivityRecord r = activities.get(activityNdx); 10382 if (r.isHomeActivity()) { 10383 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10384 try { 10385 ActivityThread.getPackageManager() 10386 .clearPackagePreferredActivities(r.packageName); 10387 } catch (RemoteException c) { 10388 // pm is in same process, this will never happen. 10389 } 10390 } 10391 } 10392 } 10393 10394 if (!app.isolated) { 10395 // XXX Can't keep track of crash times for isolated processes, 10396 // because they don't have a perisistent identity. 10397 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10398 } 10399 10400 return true; 10401 } 10402 10403 void startAppProblemLocked(ProcessRecord app) { 10404 if (app.userId == mCurrentUserId) { 10405 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10406 mContext, app.info.packageName, app.info.flags); 10407 } else { 10408 // If this app is not running under the current user, then we 10409 // can't give it a report button because that would require 10410 // launching the report UI under a different user. 10411 app.errorReportReceiver = null; 10412 } 10413 skipCurrentReceiverLocked(app); 10414 } 10415 10416 void skipCurrentReceiverLocked(ProcessRecord app) { 10417 for (BroadcastQueue queue : mBroadcastQueues) { 10418 queue.skipCurrentReceiverLocked(app); 10419 } 10420 } 10421 10422 /** 10423 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10424 * The application process will exit immediately after this call returns. 10425 * @param app object of the crashing app, null for the system server 10426 * @param crashInfo describing the exception 10427 */ 10428 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10429 ProcessRecord r = findAppProcess(app, "Crash"); 10430 final String processName = app == null ? "system_server" 10431 : (r == null ? "unknown" : r.processName); 10432 10433 handleApplicationCrashInner("crash", r, processName, crashInfo); 10434 } 10435 10436 /* Native crash reporting uses this inner version because it needs to be somewhat 10437 * decoupled from the AM-managed cleanup lifecycle 10438 */ 10439 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10440 ApplicationErrorReport.CrashInfo crashInfo) { 10441 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10442 UserHandle.getUserId(Binder.getCallingUid()), processName, 10443 r == null ? -1 : r.info.flags, 10444 crashInfo.exceptionClassName, 10445 crashInfo.exceptionMessage, 10446 crashInfo.throwFileName, 10447 crashInfo.throwLineNumber); 10448 10449 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10450 10451 crashApplication(r, crashInfo); 10452 } 10453 10454 public void handleApplicationStrictModeViolation( 10455 IBinder app, 10456 int violationMask, 10457 StrictMode.ViolationInfo info) { 10458 ProcessRecord r = findAppProcess(app, "StrictMode"); 10459 if (r == null) { 10460 return; 10461 } 10462 10463 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10464 Integer stackFingerprint = info.hashCode(); 10465 boolean logIt = true; 10466 synchronized (mAlreadyLoggedViolatedStacks) { 10467 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10468 logIt = false; 10469 // TODO: sub-sample into EventLog for these, with 10470 // the info.durationMillis? Then we'd get 10471 // the relative pain numbers, without logging all 10472 // the stack traces repeatedly. We'd want to do 10473 // likewise in the client code, which also does 10474 // dup suppression, before the Binder call. 10475 } else { 10476 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10477 mAlreadyLoggedViolatedStacks.clear(); 10478 } 10479 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10480 } 10481 } 10482 if (logIt) { 10483 logStrictModeViolationToDropBox(r, info); 10484 } 10485 } 10486 10487 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10488 AppErrorResult result = new AppErrorResult(); 10489 synchronized (this) { 10490 final long origId = Binder.clearCallingIdentity(); 10491 10492 Message msg = Message.obtain(); 10493 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10494 HashMap<String, Object> data = new HashMap<String, Object>(); 10495 data.put("result", result); 10496 data.put("app", r); 10497 data.put("violationMask", violationMask); 10498 data.put("info", info); 10499 msg.obj = data; 10500 mHandler.sendMessage(msg); 10501 10502 Binder.restoreCallingIdentity(origId); 10503 } 10504 int res = result.get(); 10505 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10506 } 10507 } 10508 10509 // Depending on the policy in effect, there could be a bunch of 10510 // these in quick succession so we try to batch these together to 10511 // minimize disk writes, number of dropbox entries, and maximize 10512 // compression, by having more fewer, larger records. 10513 private void logStrictModeViolationToDropBox( 10514 ProcessRecord process, 10515 StrictMode.ViolationInfo info) { 10516 if (info == null) { 10517 return; 10518 } 10519 final boolean isSystemApp = process == null || 10520 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10521 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10522 final String processName = process == null ? "unknown" : process.processName; 10523 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10524 final DropBoxManager dbox = (DropBoxManager) 10525 mContext.getSystemService(Context.DROPBOX_SERVICE); 10526 10527 // Exit early if the dropbox isn't configured to accept this report type. 10528 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10529 10530 boolean bufferWasEmpty; 10531 boolean needsFlush; 10532 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10533 synchronized (sb) { 10534 bufferWasEmpty = sb.length() == 0; 10535 appendDropBoxProcessHeaders(process, processName, sb); 10536 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10537 sb.append("System-App: ").append(isSystemApp).append("\n"); 10538 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10539 if (info.violationNumThisLoop != 0) { 10540 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10541 } 10542 if (info.numAnimationsRunning != 0) { 10543 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10544 } 10545 if (info.broadcastIntentAction != null) { 10546 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10547 } 10548 if (info.durationMillis != -1) { 10549 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10550 } 10551 if (info.numInstances != -1) { 10552 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10553 } 10554 if (info.tags != null) { 10555 for (String tag : info.tags) { 10556 sb.append("Span-Tag: ").append(tag).append("\n"); 10557 } 10558 } 10559 sb.append("\n"); 10560 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10561 sb.append(info.crashInfo.stackTrace); 10562 } 10563 sb.append("\n"); 10564 10565 // Only buffer up to ~64k. Various logging bits truncate 10566 // things at 128k. 10567 needsFlush = (sb.length() > 64 * 1024); 10568 } 10569 10570 // Flush immediately if the buffer's grown too large, or this 10571 // is a non-system app. Non-system apps are isolated with a 10572 // different tag & policy and not batched. 10573 // 10574 // Batching is useful during internal testing with 10575 // StrictMode settings turned up high. Without batching, 10576 // thousands of separate files could be created on boot. 10577 if (!isSystemApp || needsFlush) { 10578 new Thread("Error dump: " + dropboxTag) { 10579 @Override 10580 public void run() { 10581 String report; 10582 synchronized (sb) { 10583 report = sb.toString(); 10584 sb.delete(0, sb.length()); 10585 sb.trimToSize(); 10586 } 10587 if (report.length() != 0) { 10588 dbox.addText(dropboxTag, report); 10589 } 10590 } 10591 }.start(); 10592 return; 10593 } 10594 10595 // System app batching: 10596 if (!bufferWasEmpty) { 10597 // An existing dropbox-writing thread is outstanding, so 10598 // we don't need to start it up. The existing thread will 10599 // catch the buffer appends we just did. 10600 return; 10601 } 10602 10603 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10604 // (After this point, we shouldn't access AMS internal data structures.) 10605 new Thread("Error dump: " + dropboxTag) { 10606 @Override 10607 public void run() { 10608 // 5 second sleep to let stacks arrive and be batched together 10609 try { 10610 Thread.sleep(5000); // 5 seconds 10611 } catch (InterruptedException e) {} 10612 10613 String errorReport; 10614 synchronized (mStrictModeBuffer) { 10615 errorReport = mStrictModeBuffer.toString(); 10616 if (errorReport.length() == 0) { 10617 return; 10618 } 10619 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10620 mStrictModeBuffer.trimToSize(); 10621 } 10622 dbox.addText(dropboxTag, errorReport); 10623 } 10624 }.start(); 10625 } 10626 10627 /** 10628 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10629 * @param app object of the crashing app, null for the system server 10630 * @param tag reported by the caller 10631 * @param crashInfo describing the context of the error 10632 * @return true if the process should exit immediately (WTF is fatal) 10633 */ 10634 public boolean handleApplicationWtf(IBinder app, String tag, 10635 ApplicationErrorReport.CrashInfo crashInfo) { 10636 ProcessRecord r = findAppProcess(app, "WTF"); 10637 final String processName = app == null ? "system_server" 10638 : (r == null ? "unknown" : r.processName); 10639 10640 EventLog.writeEvent(EventLogTags.AM_WTF, 10641 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10642 processName, 10643 r == null ? -1 : r.info.flags, 10644 tag, crashInfo.exceptionMessage); 10645 10646 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10647 10648 if (r != null && r.pid != Process.myPid() && 10649 Settings.Global.getInt(mContext.getContentResolver(), 10650 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10651 crashApplication(r, crashInfo); 10652 return true; 10653 } else { 10654 return false; 10655 } 10656 } 10657 10658 /** 10659 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10660 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10661 */ 10662 private ProcessRecord findAppProcess(IBinder app, String reason) { 10663 if (app == null) { 10664 return null; 10665 } 10666 10667 synchronized (this) { 10668 final int NP = mProcessNames.getMap().size(); 10669 for (int ip=0; ip<NP; ip++) { 10670 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10671 final int NA = apps.size(); 10672 for (int ia=0; ia<NA; ia++) { 10673 ProcessRecord p = apps.valueAt(ia); 10674 if (p.thread != null && p.thread.asBinder() == app) { 10675 return p; 10676 } 10677 } 10678 } 10679 10680 Slog.w(TAG, "Can't find mystery application for " + reason 10681 + " from pid=" + Binder.getCallingPid() 10682 + " uid=" + Binder.getCallingUid() + ": " + app); 10683 return null; 10684 } 10685 } 10686 10687 /** 10688 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10689 * to append various headers to the dropbox log text. 10690 */ 10691 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10692 StringBuilder sb) { 10693 // Watchdog thread ends up invoking this function (with 10694 // a null ProcessRecord) to add the stack file to dropbox. 10695 // Do not acquire a lock on this (am) in such cases, as it 10696 // could cause a potential deadlock, if and when watchdog 10697 // is invoked due to unavailability of lock on am and it 10698 // would prevent watchdog from killing system_server. 10699 if (process == null) { 10700 sb.append("Process: ").append(processName).append("\n"); 10701 return; 10702 } 10703 // Note: ProcessRecord 'process' is guarded by the service 10704 // instance. (notably process.pkgList, which could otherwise change 10705 // concurrently during execution of this method) 10706 synchronized (this) { 10707 sb.append("Process: ").append(processName).append("\n"); 10708 int flags = process.info.flags; 10709 IPackageManager pm = AppGlobals.getPackageManager(); 10710 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10711 for (int ip=0; ip<process.pkgList.size(); ip++) { 10712 String pkg = process.pkgList.keyAt(ip); 10713 sb.append("Package: ").append(pkg); 10714 try { 10715 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10716 if (pi != null) { 10717 sb.append(" v").append(pi.versionCode); 10718 if (pi.versionName != null) { 10719 sb.append(" (").append(pi.versionName).append(")"); 10720 } 10721 } 10722 } catch (RemoteException e) { 10723 Slog.e(TAG, "Error getting package info: " + pkg, e); 10724 } 10725 sb.append("\n"); 10726 } 10727 } 10728 } 10729 10730 private static String processClass(ProcessRecord process) { 10731 if (process == null || process.pid == MY_PID) { 10732 return "system_server"; 10733 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10734 return "system_app"; 10735 } else { 10736 return "data_app"; 10737 } 10738 } 10739 10740 /** 10741 * Write a description of an error (crash, WTF, ANR) to the drop box. 10742 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10743 * @param process which caused the error, null means the system server 10744 * @param activity which triggered the error, null if unknown 10745 * @param parent activity related to the error, null if unknown 10746 * @param subject line related to the error, null if absent 10747 * @param report in long form describing the error, null if absent 10748 * @param logFile to include in the report, null if none 10749 * @param crashInfo giving an application stack trace, null if absent 10750 */ 10751 public void addErrorToDropBox(String eventType, 10752 ProcessRecord process, String processName, ActivityRecord activity, 10753 ActivityRecord parent, String subject, 10754 final String report, final File logFile, 10755 final ApplicationErrorReport.CrashInfo crashInfo) { 10756 // NOTE -- this must never acquire the ActivityManagerService lock, 10757 // otherwise the watchdog may be prevented from resetting the system. 10758 10759 final String dropboxTag = processClass(process) + "_" + eventType; 10760 final DropBoxManager dbox = (DropBoxManager) 10761 mContext.getSystemService(Context.DROPBOX_SERVICE); 10762 10763 // Exit early if the dropbox isn't configured to accept this report type. 10764 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10765 10766 final StringBuilder sb = new StringBuilder(1024); 10767 appendDropBoxProcessHeaders(process, processName, sb); 10768 if (activity != null) { 10769 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10770 } 10771 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10772 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10773 } 10774 if (parent != null && parent != activity) { 10775 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10776 } 10777 if (subject != null) { 10778 sb.append("Subject: ").append(subject).append("\n"); 10779 } 10780 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10781 if (Debug.isDebuggerConnected()) { 10782 sb.append("Debugger: Connected\n"); 10783 } 10784 sb.append("\n"); 10785 10786 // Do the rest in a worker thread to avoid blocking the caller on I/O 10787 // (After this point, we shouldn't access AMS internal data structures.) 10788 Thread worker = new Thread("Error dump: " + dropboxTag) { 10789 @Override 10790 public void run() { 10791 if (report != null) { 10792 sb.append(report); 10793 } 10794 if (logFile != null) { 10795 try { 10796 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10797 "\n\n[[TRUNCATED]]")); 10798 } catch (IOException e) { 10799 Slog.e(TAG, "Error reading " + logFile, e); 10800 } 10801 } 10802 if (crashInfo != null && crashInfo.stackTrace != null) { 10803 sb.append(crashInfo.stackTrace); 10804 } 10805 10806 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10807 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10808 if (lines > 0) { 10809 sb.append("\n"); 10810 10811 // Merge several logcat streams, and take the last N lines 10812 InputStreamReader input = null; 10813 try { 10814 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10815 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10816 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10817 10818 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10819 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10820 input = new InputStreamReader(logcat.getInputStream()); 10821 10822 int num; 10823 char[] buf = new char[8192]; 10824 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10825 } catch (IOException e) { 10826 Slog.e(TAG, "Error running logcat", e); 10827 } finally { 10828 if (input != null) try { input.close(); } catch (IOException e) {} 10829 } 10830 } 10831 10832 dbox.addText(dropboxTag, sb.toString()); 10833 } 10834 }; 10835 10836 if (process == null) { 10837 // If process is null, we are being called from some internal code 10838 // and may be about to die -- run this synchronously. 10839 worker.run(); 10840 } else { 10841 worker.start(); 10842 } 10843 } 10844 10845 /** 10846 * Bring up the "unexpected error" dialog box for a crashing app. 10847 * Deal with edge cases (intercepts from instrumented applications, 10848 * ActivityController, error intent receivers, that sort of thing). 10849 * @param r the application crashing 10850 * @param crashInfo describing the failure 10851 */ 10852 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10853 long timeMillis = System.currentTimeMillis(); 10854 String shortMsg = crashInfo.exceptionClassName; 10855 String longMsg = crashInfo.exceptionMessage; 10856 String stackTrace = crashInfo.stackTrace; 10857 if (shortMsg != null && longMsg != null) { 10858 longMsg = shortMsg + ": " + longMsg; 10859 } else if (shortMsg != null) { 10860 longMsg = shortMsg; 10861 } 10862 10863 AppErrorResult result = new AppErrorResult(); 10864 synchronized (this) { 10865 if (mController != null) { 10866 try { 10867 String name = r != null ? r.processName : null; 10868 int pid = r != null ? r.pid : Binder.getCallingPid(); 10869 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10870 if (!mController.appCrashed(name, pid, 10871 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10872 Slog.w(TAG, "Force-killing crashed app " + name 10873 + " at watcher's request"); 10874 Process.killProcess(pid); 10875 if (r != null) { 10876 Process.killProcessGroup(uid, pid); 10877 } 10878 return; 10879 } 10880 } catch (RemoteException e) { 10881 mController = null; 10882 Watchdog.getInstance().setActivityController(null); 10883 } 10884 } 10885 10886 final long origId = Binder.clearCallingIdentity(); 10887 10888 // If this process is running instrumentation, finish it. 10889 if (r != null && r.instrumentationClass != null) { 10890 Slog.w(TAG, "Error in app " + r.processName 10891 + " running instrumentation " + r.instrumentationClass + ":"); 10892 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10893 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10894 Bundle info = new Bundle(); 10895 info.putString("shortMsg", shortMsg); 10896 info.putString("longMsg", longMsg); 10897 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10898 Binder.restoreCallingIdentity(origId); 10899 return; 10900 } 10901 10902 // If we can't identify the process or it's already exceeded its crash quota, 10903 // quit right away without showing a crash dialog. 10904 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10905 Binder.restoreCallingIdentity(origId); 10906 return; 10907 } 10908 10909 Message msg = Message.obtain(); 10910 msg.what = SHOW_ERROR_MSG; 10911 HashMap data = new HashMap(); 10912 data.put("result", result); 10913 data.put("app", r); 10914 msg.obj = data; 10915 mHandler.sendMessage(msg); 10916 10917 Binder.restoreCallingIdentity(origId); 10918 } 10919 10920 int res = result.get(); 10921 10922 Intent appErrorIntent = null; 10923 synchronized (this) { 10924 if (r != null && !r.isolated) { 10925 // XXX Can't keep track of crash time for isolated processes, 10926 // since they don't have a persistent identity. 10927 mProcessCrashTimes.put(r.info.processName, r.uid, 10928 SystemClock.uptimeMillis()); 10929 } 10930 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10931 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10932 } 10933 } 10934 10935 if (appErrorIntent != null) { 10936 try { 10937 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10938 } catch (ActivityNotFoundException e) { 10939 Slog.w(TAG, "bug report receiver dissappeared", e); 10940 } 10941 } 10942 } 10943 10944 Intent createAppErrorIntentLocked(ProcessRecord r, 10945 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10946 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10947 if (report == null) { 10948 return null; 10949 } 10950 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10951 result.setComponent(r.errorReportReceiver); 10952 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10953 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10954 return result; 10955 } 10956 10957 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10958 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10959 if (r.errorReportReceiver == null) { 10960 return null; 10961 } 10962 10963 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10964 return null; 10965 } 10966 10967 ApplicationErrorReport report = new ApplicationErrorReport(); 10968 report.packageName = r.info.packageName; 10969 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10970 report.processName = r.processName; 10971 report.time = timeMillis; 10972 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10973 10974 if (r.crashing || r.forceCrashReport) { 10975 report.type = ApplicationErrorReport.TYPE_CRASH; 10976 report.crashInfo = crashInfo; 10977 } else if (r.notResponding) { 10978 report.type = ApplicationErrorReport.TYPE_ANR; 10979 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10980 10981 report.anrInfo.activity = r.notRespondingReport.tag; 10982 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10983 report.anrInfo.info = r.notRespondingReport.longMsg; 10984 } 10985 10986 return report; 10987 } 10988 10989 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10990 enforceNotIsolatedCaller("getProcessesInErrorState"); 10991 // assume our apps are happy - lazy create the list 10992 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10993 10994 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10995 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10996 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10997 10998 synchronized (this) { 10999 11000 // iterate across all processes 11001 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11002 ProcessRecord app = mLruProcesses.get(i); 11003 if (!allUsers && app.userId != userId) { 11004 continue; 11005 } 11006 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11007 // This one's in trouble, so we'll generate a report for it 11008 // crashes are higher priority (in case there's a crash *and* an anr) 11009 ActivityManager.ProcessErrorStateInfo report = null; 11010 if (app.crashing) { 11011 report = app.crashingReport; 11012 } else if (app.notResponding) { 11013 report = app.notRespondingReport; 11014 } 11015 11016 if (report != null) { 11017 if (errList == null) { 11018 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11019 } 11020 errList.add(report); 11021 } else { 11022 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11023 " crashing = " + app.crashing + 11024 " notResponding = " + app.notResponding); 11025 } 11026 } 11027 } 11028 } 11029 11030 return errList; 11031 } 11032 11033 static int procStateToImportance(int procState, int memAdj, 11034 ActivityManager.RunningAppProcessInfo currApp) { 11035 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11036 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11037 currApp.lru = memAdj; 11038 } else { 11039 currApp.lru = 0; 11040 } 11041 return imp; 11042 } 11043 11044 private void fillInProcMemInfo(ProcessRecord app, 11045 ActivityManager.RunningAppProcessInfo outInfo) { 11046 outInfo.pid = app.pid; 11047 outInfo.uid = app.info.uid; 11048 if (mHeavyWeightProcess == app) { 11049 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11050 } 11051 if (app.persistent) { 11052 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11053 } 11054 if (app.activities.size() > 0) { 11055 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11056 } 11057 outInfo.lastTrimLevel = app.trimMemoryLevel; 11058 int adj = app.curAdj; 11059 int procState = app.curProcState; 11060 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11061 outInfo.importanceReasonCode = app.adjTypeCode; 11062 outInfo.processState = app.curProcState; 11063 } 11064 11065 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11066 enforceNotIsolatedCaller("getRunningAppProcesses"); 11067 // Lazy instantiation of list 11068 List<ActivityManager.RunningAppProcessInfo> runList = null; 11069 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11070 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11071 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11072 synchronized (this) { 11073 // Iterate across all processes 11074 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11075 ProcessRecord app = mLruProcesses.get(i); 11076 if (!allUsers && app.userId != userId) { 11077 continue; 11078 } 11079 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11080 // Generate process state info for running application 11081 ActivityManager.RunningAppProcessInfo currApp = 11082 new ActivityManager.RunningAppProcessInfo(app.processName, 11083 app.pid, app.getPackageList()); 11084 fillInProcMemInfo(app, currApp); 11085 if (app.adjSource instanceof ProcessRecord) { 11086 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11087 currApp.importanceReasonImportance = 11088 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11089 app.adjSourceProcState); 11090 } else if (app.adjSource instanceof ActivityRecord) { 11091 ActivityRecord r = (ActivityRecord)app.adjSource; 11092 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11093 } 11094 if (app.adjTarget instanceof ComponentName) { 11095 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11096 } 11097 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11098 // + " lru=" + currApp.lru); 11099 if (runList == null) { 11100 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11101 } 11102 runList.add(currApp); 11103 } 11104 } 11105 } 11106 return runList; 11107 } 11108 11109 public List<ApplicationInfo> getRunningExternalApplications() { 11110 enforceNotIsolatedCaller("getRunningExternalApplications"); 11111 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11112 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11113 if (runningApps != null && runningApps.size() > 0) { 11114 Set<String> extList = new HashSet<String>(); 11115 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11116 if (app.pkgList != null) { 11117 for (String pkg : app.pkgList) { 11118 extList.add(pkg); 11119 } 11120 } 11121 } 11122 IPackageManager pm = AppGlobals.getPackageManager(); 11123 for (String pkg : extList) { 11124 try { 11125 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11126 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11127 retList.add(info); 11128 } 11129 } catch (RemoteException e) { 11130 } 11131 } 11132 } 11133 return retList; 11134 } 11135 11136 @Override 11137 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11138 enforceNotIsolatedCaller("getMyMemoryState"); 11139 synchronized (this) { 11140 ProcessRecord proc; 11141 synchronized (mPidsSelfLocked) { 11142 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11143 } 11144 fillInProcMemInfo(proc, outInfo); 11145 } 11146 } 11147 11148 @Override 11149 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11150 if (checkCallingPermission(android.Manifest.permission.DUMP) 11151 != PackageManager.PERMISSION_GRANTED) { 11152 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11153 + Binder.getCallingPid() 11154 + ", uid=" + Binder.getCallingUid() 11155 + " without permission " 11156 + android.Manifest.permission.DUMP); 11157 return; 11158 } 11159 11160 boolean dumpAll = false; 11161 boolean dumpClient = false; 11162 String dumpPackage = null; 11163 11164 int opti = 0; 11165 while (opti < args.length) { 11166 String opt = args[opti]; 11167 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11168 break; 11169 } 11170 opti++; 11171 if ("-a".equals(opt)) { 11172 dumpAll = true; 11173 } else if ("-c".equals(opt)) { 11174 dumpClient = true; 11175 } else if ("-h".equals(opt)) { 11176 pw.println("Activity manager dump options:"); 11177 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11178 pw.println(" cmd may be one of:"); 11179 pw.println(" a[ctivities]: activity stack state"); 11180 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11181 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11182 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11183 pw.println(" o[om]: out of memory management"); 11184 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11185 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11186 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11187 pw.println(" service [COMP_SPEC]: service client-side state"); 11188 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11189 pw.println(" all: dump all activities"); 11190 pw.println(" top: dump the top activity"); 11191 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11192 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11193 pw.println(" a partial substring in a component name, a"); 11194 pw.println(" hex object identifier."); 11195 pw.println(" -a: include all available server state."); 11196 pw.println(" -c: include client state."); 11197 return; 11198 } else { 11199 pw.println("Unknown argument: " + opt + "; use -h for help"); 11200 } 11201 } 11202 11203 long origId = Binder.clearCallingIdentity(); 11204 boolean more = false; 11205 // Is the caller requesting to dump a particular piece of data? 11206 if (opti < args.length) { 11207 String cmd = args[opti]; 11208 opti++; 11209 if ("activities".equals(cmd) || "a".equals(cmd)) { 11210 synchronized (this) { 11211 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11212 } 11213 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11214 String[] newArgs; 11215 String name; 11216 if (opti >= args.length) { 11217 name = null; 11218 newArgs = EMPTY_STRING_ARRAY; 11219 } else { 11220 name = args[opti]; 11221 opti++; 11222 newArgs = new String[args.length - opti]; 11223 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11224 args.length - opti); 11225 } 11226 synchronized (this) { 11227 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11228 } 11229 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11230 String[] newArgs; 11231 String name; 11232 if (opti >= args.length) { 11233 name = null; 11234 newArgs = EMPTY_STRING_ARRAY; 11235 } else { 11236 name = args[opti]; 11237 opti++; 11238 newArgs = new String[args.length - opti]; 11239 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11240 args.length - opti); 11241 } 11242 synchronized (this) { 11243 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11244 } 11245 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11246 String[] newArgs; 11247 String name; 11248 if (opti >= args.length) { 11249 name = null; 11250 newArgs = EMPTY_STRING_ARRAY; 11251 } else { 11252 name = args[opti]; 11253 opti++; 11254 newArgs = new String[args.length - opti]; 11255 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11256 args.length - opti); 11257 } 11258 synchronized (this) { 11259 dumpProcessesLocked(fd, pw, args, opti, true, name); 11260 } 11261 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11262 synchronized (this) { 11263 dumpOomLocked(fd, pw, args, opti, true); 11264 } 11265 } else if ("provider".equals(cmd)) { 11266 String[] newArgs; 11267 String name; 11268 if (opti >= args.length) { 11269 name = null; 11270 newArgs = EMPTY_STRING_ARRAY; 11271 } else { 11272 name = args[opti]; 11273 opti++; 11274 newArgs = new String[args.length - opti]; 11275 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11276 } 11277 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11278 pw.println("No providers match: " + name); 11279 pw.println("Use -h for help."); 11280 } 11281 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11282 synchronized (this) { 11283 dumpProvidersLocked(fd, pw, args, opti, true, null); 11284 } 11285 } else if ("service".equals(cmd)) { 11286 String[] newArgs; 11287 String name; 11288 if (opti >= args.length) { 11289 name = null; 11290 newArgs = EMPTY_STRING_ARRAY; 11291 } else { 11292 name = args[opti]; 11293 opti++; 11294 newArgs = new String[args.length - opti]; 11295 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11296 args.length - opti); 11297 } 11298 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11299 pw.println("No services match: " + name); 11300 pw.println("Use -h for help."); 11301 } 11302 } else if ("package".equals(cmd)) { 11303 String[] newArgs; 11304 if (opti >= args.length) { 11305 pw.println("package: no package name specified"); 11306 pw.println("Use -h for help."); 11307 } else { 11308 dumpPackage = args[opti]; 11309 opti++; 11310 newArgs = new String[args.length - opti]; 11311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11312 args.length - opti); 11313 args = newArgs; 11314 opti = 0; 11315 more = true; 11316 } 11317 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11318 synchronized (this) { 11319 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11320 } 11321 } else { 11322 // Dumping a single activity? 11323 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11324 pw.println("Bad activity command, or no activities match: " + cmd); 11325 pw.println("Use -h for help."); 11326 } 11327 } 11328 if (!more) { 11329 Binder.restoreCallingIdentity(origId); 11330 return; 11331 } 11332 } 11333 11334 // No piece of data specified, dump everything. 11335 synchronized (this) { 11336 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11337 pw.println(); 11338 if (dumpAll) { 11339 pw.println("-------------------------------------------------------------------------------"); 11340 } 11341 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11342 pw.println(); 11343 if (dumpAll) { 11344 pw.println("-------------------------------------------------------------------------------"); 11345 } 11346 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11347 pw.println(); 11348 if (dumpAll) { 11349 pw.println("-------------------------------------------------------------------------------"); 11350 } 11351 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11352 pw.println(); 11353 if (dumpAll) { 11354 pw.println("-------------------------------------------------------------------------------"); 11355 } 11356 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11357 pw.println(); 11358 if (dumpAll) { 11359 pw.println("-------------------------------------------------------------------------------"); 11360 } 11361 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11362 } 11363 Binder.restoreCallingIdentity(origId); 11364 } 11365 11366 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11367 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11368 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11369 11370 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11371 dumpPackage); 11372 boolean needSep = printedAnything; 11373 11374 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11375 dumpPackage, needSep, " mFocusedActivity: "); 11376 if (printed) { 11377 printedAnything = true; 11378 needSep = false; 11379 } 11380 11381 if (dumpPackage == null) { 11382 if (needSep) { 11383 pw.println(); 11384 } 11385 needSep = true; 11386 printedAnything = true; 11387 mStackSupervisor.dump(pw, " "); 11388 } 11389 11390 if (mRecentTasks.size() > 0) { 11391 boolean printedHeader = false; 11392 11393 final int N = mRecentTasks.size(); 11394 for (int i=0; i<N; i++) { 11395 TaskRecord tr = mRecentTasks.get(i); 11396 if (dumpPackage != null) { 11397 if (tr.realActivity == null || 11398 !dumpPackage.equals(tr.realActivity)) { 11399 continue; 11400 } 11401 } 11402 if (!printedHeader) { 11403 if (needSep) { 11404 pw.println(); 11405 } 11406 pw.println(" Recent tasks:"); 11407 printedHeader = true; 11408 printedAnything = true; 11409 } 11410 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11411 pw.println(tr); 11412 if (dumpAll) { 11413 mRecentTasks.get(i).dump(pw, " "); 11414 } 11415 } 11416 } 11417 11418 if (!printedAnything) { 11419 pw.println(" (nothing)"); 11420 } 11421 } 11422 11423 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11424 int opti, boolean dumpAll, String dumpPackage) { 11425 boolean needSep = false; 11426 boolean printedAnything = false; 11427 int numPers = 0; 11428 11429 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11430 11431 if (dumpAll) { 11432 final int NP = mProcessNames.getMap().size(); 11433 for (int ip=0; ip<NP; ip++) { 11434 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11435 final int NA = procs.size(); 11436 for (int ia=0; ia<NA; ia++) { 11437 ProcessRecord r = procs.valueAt(ia); 11438 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11439 continue; 11440 } 11441 if (!needSep) { 11442 pw.println(" All known processes:"); 11443 needSep = true; 11444 printedAnything = true; 11445 } 11446 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11447 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11448 pw.print(" "); pw.println(r); 11449 r.dump(pw, " "); 11450 if (r.persistent) { 11451 numPers++; 11452 } 11453 } 11454 } 11455 } 11456 11457 if (mIsolatedProcesses.size() > 0) { 11458 boolean printed = false; 11459 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11460 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11461 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11462 continue; 11463 } 11464 if (!printed) { 11465 if (needSep) { 11466 pw.println(); 11467 } 11468 pw.println(" Isolated process list (sorted by uid):"); 11469 printedAnything = true; 11470 printed = true; 11471 needSep = true; 11472 } 11473 pw.println(String.format("%sIsolated #%2d: %s", 11474 " ", i, r.toString())); 11475 } 11476 } 11477 11478 if (mLruProcesses.size() > 0) { 11479 if (needSep) { 11480 pw.println(); 11481 } 11482 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11483 pw.print(" total, non-act at "); 11484 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11485 pw.print(", non-svc at "); 11486 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11487 pw.println("):"); 11488 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11489 needSep = true; 11490 printedAnything = true; 11491 } 11492 11493 if (dumpAll || dumpPackage != null) { 11494 synchronized (mPidsSelfLocked) { 11495 boolean printed = false; 11496 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11497 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11498 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11499 continue; 11500 } 11501 if (!printed) { 11502 if (needSep) pw.println(); 11503 needSep = true; 11504 pw.println(" PID mappings:"); 11505 printed = true; 11506 printedAnything = true; 11507 } 11508 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11509 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11510 } 11511 } 11512 } 11513 11514 if (mForegroundProcesses.size() > 0) { 11515 synchronized (mPidsSelfLocked) { 11516 boolean printed = false; 11517 for (int i=0; i<mForegroundProcesses.size(); i++) { 11518 ProcessRecord r = mPidsSelfLocked.get( 11519 mForegroundProcesses.valueAt(i).pid); 11520 if (dumpPackage != null && (r == null 11521 || !r.pkgList.containsKey(dumpPackage))) { 11522 continue; 11523 } 11524 if (!printed) { 11525 if (needSep) pw.println(); 11526 needSep = true; 11527 pw.println(" Foreground Processes:"); 11528 printed = true; 11529 printedAnything = true; 11530 } 11531 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11532 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11533 } 11534 } 11535 } 11536 11537 if (mPersistentStartingProcesses.size() > 0) { 11538 if (needSep) pw.println(); 11539 needSep = true; 11540 printedAnything = true; 11541 pw.println(" Persisent processes that are starting:"); 11542 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11543 "Starting Norm", "Restarting PERS", dumpPackage); 11544 } 11545 11546 if (mRemovedProcesses.size() > 0) { 11547 if (needSep) pw.println(); 11548 needSep = true; 11549 printedAnything = true; 11550 pw.println(" Processes that are being removed:"); 11551 dumpProcessList(pw, this, mRemovedProcesses, " ", 11552 "Removed Norm", "Removed PERS", dumpPackage); 11553 } 11554 11555 if (mProcessesOnHold.size() > 0) { 11556 if (needSep) pw.println(); 11557 needSep = true; 11558 printedAnything = true; 11559 pw.println(" Processes that are on old until the system is ready:"); 11560 dumpProcessList(pw, this, mProcessesOnHold, " ", 11561 "OnHold Norm", "OnHold PERS", dumpPackage); 11562 } 11563 11564 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11565 11566 if (mProcessCrashTimes.getMap().size() > 0) { 11567 boolean printed = false; 11568 long now = SystemClock.uptimeMillis(); 11569 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11570 final int NP = pmap.size(); 11571 for (int ip=0; ip<NP; ip++) { 11572 String pname = pmap.keyAt(ip); 11573 SparseArray<Long> uids = pmap.valueAt(ip); 11574 final int N = uids.size(); 11575 for (int i=0; i<N; i++) { 11576 int puid = uids.keyAt(i); 11577 ProcessRecord r = mProcessNames.get(pname, puid); 11578 if (dumpPackage != null && (r == null 11579 || !r.pkgList.containsKey(dumpPackage))) { 11580 continue; 11581 } 11582 if (!printed) { 11583 if (needSep) pw.println(); 11584 needSep = true; 11585 pw.println(" Time since processes crashed:"); 11586 printed = true; 11587 printedAnything = true; 11588 } 11589 pw.print(" Process "); pw.print(pname); 11590 pw.print(" uid "); pw.print(puid); 11591 pw.print(": last crashed "); 11592 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11593 pw.println(" ago"); 11594 } 11595 } 11596 } 11597 11598 if (mBadProcesses.getMap().size() > 0) { 11599 boolean printed = false; 11600 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11601 final int NP = pmap.size(); 11602 for (int ip=0; ip<NP; ip++) { 11603 String pname = pmap.keyAt(ip); 11604 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11605 final int N = uids.size(); 11606 for (int i=0; i<N; i++) { 11607 int puid = uids.keyAt(i); 11608 ProcessRecord r = mProcessNames.get(pname, puid); 11609 if (dumpPackage != null && (r == null 11610 || !r.pkgList.containsKey(dumpPackage))) { 11611 continue; 11612 } 11613 if (!printed) { 11614 if (needSep) pw.println(); 11615 needSep = true; 11616 pw.println(" Bad processes:"); 11617 printedAnything = true; 11618 } 11619 BadProcessInfo info = uids.valueAt(i); 11620 pw.print(" Bad process "); pw.print(pname); 11621 pw.print(" uid "); pw.print(puid); 11622 pw.print(": crashed at time "); pw.println(info.time); 11623 if (info.shortMsg != null) { 11624 pw.print(" Short msg: "); pw.println(info.shortMsg); 11625 } 11626 if (info.longMsg != null) { 11627 pw.print(" Long msg: "); pw.println(info.longMsg); 11628 } 11629 if (info.stack != null) { 11630 pw.println(" Stack:"); 11631 int lastPos = 0; 11632 for (int pos=0; pos<info.stack.length(); pos++) { 11633 if (info.stack.charAt(pos) == '\n') { 11634 pw.print(" "); 11635 pw.write(info.stack, lastPos, pos-lastPos); 11636 pw.println(); 11637 lastPos = pos+1; 11638 } 11639 } 11640 if (lastPos < info.stack.length()) { 11641 pw.print(" "); 11642 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11643 pw.println(); 11644 } 11645 } 11646 } 11647 } 11648 } 11649 11650 if (dumpPackage == null) { 11651 pw.println(); 11652 needSep = false; 11653 pw.println(" mStartedUsers:"); 11654 for (int i=0; i<mStartedUsers.size(); i++) { 11655 UserStartedState uss = mStartedUsers.valueAt(i); 11656 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11657 pw.print(": "); uss.dump("", pw); 11658 } 11659 pw.print(" mStartedUserArray: ["); 11660 for (int i=0; i<mStartedUserArray.length; i++) { 11661 if (i > 0) pw.print(", "); 11662 pw.print(mStartedUserArray[i]); 11663 } 11664 pw.println("]"); 11665 pw.print(" mUserLru: ["); 11666 for (int i=0; i<mUserLru.size(); i++) { 11667 if (i > 0) pw.print(", "); 11668 pw.print(mUserLru.get(i)); 11669 } 11670 pw.println("]"); 11671 if (dumpAll) { 11672 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11673 } 11674 synchronized (mUserProfileGroupIdsSelfLocked) { 11675 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 11676 pw.println(" mUserProfileGroupIds:"); 11677 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 11678 pw.print(" User #"); 11679 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 11680 pw.print(" -> profile #"); 11681 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 11682 } 11683 } 11684 } 11685 } 11686 if (mHomeProcess != null && (dumpPackage == null 11687 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11688 if (needSep) { 11689 pw.println(); 11690 needSep = false; 11691 } 11692 pw.println(" mHomeProcess: " + mHomeProcess); 11693 } 11694 if (mPreviousProcess != null && (dumpPackage == null 11695 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11696 if (needSep) { 11697 pw.println(); 11698 needSep = false; 11699 } 11700 pw.println(" mPreviousProcess: " + mPreviousProcess); 11701 } 11702 if (dumpAll) { 11703 StringBuilder sb = new StringBuilder(128); 11704 sb.append(" mPreviousProcessVisibleTime: "); 11705 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11706 pw.println(sb); 11707 } 11708 if (mHeavyWeightProcess != null && (dumpPackage == null 11709 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11710 if (needSep) { 11711 pw.println(); 11712 needSep = false; 11713 } 11714 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11715 } 11716 if (dumpPackage == null) { 11717 pw.println(" mConfiguration: " + mConfiguration); 11718 } 11719 if (dumpAll) { 11720 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11721 if (mCompatModePackages.getPackages().size() > 0) { 11722 boolean printed = false; 11723 for (Map.Entry<String, Integer> entry 11724 : mCompatModePackages.getPackages().entrySet()) { 11725 String pkg = entry.getKey(); 11726 int mode = entry.getValue(); 11727 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11728 continue; 11729 } 11730 if (!printed) { 11731 pw.println(" mScreenCompatPackages:"); 11732 printed = true; 11733 } 11734 pw.print(" "); pw.print(pkg); pw.print(": "); 11735 pw.print(mode); pw.println(); 11736 } 11737 } 11738 } 11739 if (dumpPackage == null) { 11740 if (mSleeping || mWentToSleep || mLockScreenShown) { 11741 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11742 + " mLockScreenShown " + mLockScreenShown); 11743 } 11744 if (mShuttingDown || mRunningVoice) { 11745 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11746 } 11747 } 11748 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11749 || mOrigWaitForDebugger) { 11750 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11751 || dumpPackage.equals(mOrigDebugApp)) { 11752 if (needSep) { 11753 pw.println(); 11754 needSep = false; 11755 } 11756 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11757 + " mDebugTransient=" + mDebugTransient 11758 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11759 } 11760 } 11761 if (mOpenGlTraceApp != null) { 11762 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11763 if (needSep) { 11764 pw.println(); 11765 needSep = false; 11766 } 11767 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11768 } 11769 } 11770 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11771 || mProfileFd != null) { 11772 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11773 if (needSep) { 11774 pw.println(); 11775 needSep = false; 11776 } 11777 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11778 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11779 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11780 + mAutoStopProfiler); 11781 } 11782 } 11783 if (dumpPackage == null) { 11784 if (mAlwaysFinishActivities || mController != null) { 11785 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11786 + " mController=" + mController); 11787 } 11788 if (dumpAll) { 11789 pw.println(" Total persistent processes: " + numPers); 11790 pw.println(" mProcessesReady=" + mProcessesReady 11791 + " mSystemReady=" + mSystemReady); 11792 pw.println(" mBooting=" + mBooting 11793 + " mBooted=" + mBooted 11794 + " mFactoryTest=" + mFactoryTest); 11795 pw.print(" mLastPowerCheckRealtime="); 11796 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11797 pw.println(""); 11798 pw.print(" mLastPowerCheckUptime="); 11799 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11800 pw.println(""); 11801 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11802 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11803 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11804 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11805 + " (" + mLruProcesses.size() + " total)" 11806 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11807 + " mNumServiceProcs=" + mNumServiceProcs 11808 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11809 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11810 + " mLastMemoryLevel" + mLastMemoryLevel 11811 + " mLastNumProcesses" + mLastNumProcesses); 11812 long now = SystemClock.uptimeMillis(); 11813 pw.print(" mLastIdleTime="); 11814 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11815 pw.print(" mLowRamSinceLastIdle="); 11816 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11817 pw.println(); 11818 } 11819 } 11820 11821 if (!printedAnything) { 11822 pw.println(" (nothing)"); 11823 } 11824 } 11825 11826 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11827 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11828 if (mProcessesToGc.size() > 0) { 11829 boolean printed = false; 11830 long now = SystemClock.uptimeMillis(); 11831 for (int i=0; i<mProcessesToGc.size(); i++) { 11832 ProcessRecord proc = mProcessesToGc.get(i); 11833 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11834 continue; 11835 } 11836 if (!printed) { 11837 if (needSep) pw.println(); 11838 needSep = true; 11839 pw.println(" Processes that are waiting to GC:"); 11840 printed = true; 11841 } 11842 pw.print(" Process "); pw.println(proc); 11843 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11844 pw.print(", last gced="); 11845 pw.print(now-proc.lastRequestedGc); 11846 pw.print(" ms ago, last lowMem="); 11847 pw.print(now-proc.lastLowMemory); 11848 pw.println(" ms ago"); 11849 11850 } 11851 } 11852 return needSep; 11853 } 11854 11855 void printOomLevel(PrintWriter pw, String name, int adj) { 11856 pw.print(" "); 11857 if (adj >= 0) { 11858 pw.print(' '); 11859 if (adj < 10) pw.print(' '); 11860 } else { 11861 if (adj > -10) pw.print(' '); 11862 } 11863 pw.print(adj); 11864 pw.print(": "); 11865 pw.print(name); 11866 pw.print(" ("); 11867 pw.print(mProcessList.getMemLevel(adj)/1024); 11868 pw.println(" kB)"); 11869 } 11870 11871 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11872 int opti, boolean dumpAll) { 11873 boolean needSep = false; 11874 11875 if (mLruProcesses.size() > 0) { 11876 if (needSep) pw.println(); 11877 needSep = true; 11878 pw.println(" OOM levels:"); 11879 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11880 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11881 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11882 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11883 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11884 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11885 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11886 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11887 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11888 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11889 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11890 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11891 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11892 11893 if (needSep) pw.println(); 11894 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11895 pw.print(" total, non-act at "); 11896 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11897 pw.print(", non-svc at "); 11898 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11899 pw.println("):"); 11900 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11901 needSep = true; 11902 } 11903 11904 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11905 11906 pw.println(); 11907 pw.println(" mHomeProcess: " + mHomeProcess); 11908 pw.println(" mPreviousProcess: " + mPreviousProcess); 11909 if (mHeavyWeightProcess != null) { 11910 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11911 } 11912 11913 return true; 11914 } 11915 11916 /** 11917 * There are three ways to call this: 11918 * - no provider specified: dump all the providers 11919 * - a flattened component name that matched an existing provider was specified as the 11920 * first arg: dump that one provider 11921 * - the first arg isn't the flattened component name of an existing provider: 11922 * dump all providers whose component contains the first arg as a substring 11923 */ 11924 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11925 int opti, boolean dumpAll) { 11926 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11927 } 11928 11929 static class ItemMatcher { 11930 ArrayList<ComponentName> components; 11931 ArrayList<String> strings; 11932 ArrayList<Integer> objects; 11933 boolean all; 11934 11935 ItemMatcher() { 11936 all = true; 11937 } 11938 11939 void build(String name) { 11940 ComponentName componentName = ComponentName.unflattenFromString(name); 11941 if (componentName != null) { 11942 if (components == null) { 11943 components = new ArrayList<ComponentName>(); 11944 } 11945 components.add(componentName); 11946 all = false; 11947 } else { 11948 int objectId = 0; 11949 // Not a '/' separated full component name; maybe an object ID? 11950 try { 11951 objectId = Integer.parseInt(name, 16); 11952 if (objects == null) { 11953 objects = new ArrayList<Integer>(); 11954 } 11955 objects.add(objectId); 11956 all = false; 11957 } catch (RuntimeException e) { 11958 // Not an integer; just do string match. 11959 if (strings == null) { 11960 strings = new ArrayList<String>(); 11961 } 11962 strings.add(name); 11963 all = false; 11964 } 11965 } 11966 } 11967 11968 int build(String[] args, int opti) { 11969 for (; opti<args.length; opti++) { 11970 String name = args[opti]; 11971 if ("--".equals(name)) { 11972 return opti+1; 11973 } 11974 build(name); 11975 } 11976 return opti; 11977 } 11978 11979 boolean match(Object object, ComponentName comp) { 11980 if (all) { 11981 return true; 11982 } 11983 if (components != null) { 11984 for (int i=0; i<components.size(); i++) { 11985 if (components.get(i).equals(comp)) { 11986 return true; 11987 } 11988 } 11989 } 11990 if (objects != null) { 11991 for (int i=0; i<objects.size(); i++) { 11992 if (System.identityHashCode(object) == objects.get(i)) { 11993 return true; 11994 } 11995 } 11996 } 11997 if (strings != null) { 11998 String flat = comp.flattenToString(); 11999 for (int i=0; i<strings.size(); i++) { 12000 if (flat.contains(strings.get(i))) { 12001 return true; 12002 } 12003 } 12004 } 12005 return false; 12006 } 12007 } 12008 12009 /** 12010 * There are three things that cmd can be: 12011 * - a flattened component name that matches an existing activity 12012 * - the cmd arg isn't the flattened component name of an existing activity: 12013 * dump all activity whose component contains the cmd as a substring 12014 * - A hex number of the ActivityRecord object instance. 12015 */ 12016 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12017 int opti, boolean dumpAll) { 12018 ArrayList<ActivityRecord> activities; 12019 12020 synchronized (this) { 12021 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12022 } 12023 12024 if (activities.size() <= 0) { 12025 return false; 12026 } 12027 12028 String[] newArgs = new String[args.length - opti]; 12029 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12030 12031 TaskRecord lastTask = null; 12032 boolean needSep = false; 12033 for (int i=activities.size()-1; i>=0; i--) { 12034 ActivityRecord r = activities.get(i); 12035 if (needSep) { 12036 pw.println(); 12037 } 12038 needSep = true; 12039 synchronized (this) { 12040 if (lastTask != r.task) { 12041 lastTask = r.task; 12042 pw.print("TASK "); pw.print(lastTask.affinity); 12043 pw.print(" id="); pw.println(lastTask.taskId); 12044 if (dumpAll) { 12045 lastTask.dump(pw, " "); 12046 } 12047 } 12048 } 12049 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12050 } 12051 return true; 12052 } 12053 12054 /** 12055 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12056 * there is a thread associated with the activity. 12057 */ 12058 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12059 final ActivityRecord r, String[] args, boolean dumpAll) { 12060 String innerPrefix = prefix + " "; 12061 synchronized (this) { 12062 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12063 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12064 pw.print(" pid="); 12065 if (r.app != null) pw.println(r.app.pid); 12066 else pw.println("(not running)"); 12067 if (dumpAll) { 12068 r.dump(pw, innerPrefix); 12069 } 12070 } 12071 if (r.app != null && r.app.thread != null) { 12072 // flush anything that is already in the PrintWriter since the thread is going 12073 // to write to the file descriptor directly 12074 pw.flush(); 12075 try { 12076 TransferPipe tp = new TransferPipe(); 12077 try { 12078 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12079 r.appToken, innerPrefix, args); 12080 tp.go(fd); 12081 } finally { 12082 tp.kill(); 12083 } 12084 } catch (IOException e) { 12085 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12086 } catch (RemoteException e) { 12087 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12088 } 12089 } 12090 } 12091 12092 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12093 int opti, boolean dumpAll, String dumpPackage) { 12094 boolean needSep = false; 12095 boolean onlyHistory = false; 12096 boolean printedAnything = false; 12097 12098 if ("history".equals(dumpPackage)) { 12099 if (opti < args.length && "-s".equals(args[opti])) { 12100 dumpAll = false; 12101 } 12102 onlyHistory = true; 12103 dumpPackage = null; 12104 } 12105 12106 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12107 if (!onlyHistory && dumpAll) { 12108 if (mRegisteredReceivers.size() > 0) { 12109 boolean printed = false; 12110 Iterator it = mRegisteredReceivers.values().iterator(); 12111 while (it.hasNext()) { 12112 ReceiverList r = (ReceiverList)it.next(); 12113 if (dumpPackage != null && (r.app == null || 12114 !dumpPackage.equals(r.app.info.packageName))) { 12115 continue; 12116 } 12117 if (!printed) { 12118 pw.println(" Registered Receivers:"); 12119 needSep = true; 12120 printed = true; 12121 printedAnything = true; 12122 } 12123 pw.print(" * "); pw.println(r); 12124 r.dump(pw, " "); 12125 } 12126 } 12127 12128 if (mReceiverResolver.dump(pw, needSep ? 12129 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12130 " ", dumpPackage, false)) { 12131 needSep = true; 12132 printedAnything = true; 12133 } 12134 } 12135 12136 for (BroadcastQueue q : mBroadcastQueues) { 12137 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12138 printedAnything |= needSep; 12139 } 12140 12141 needSep = true; 12142 12143 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12144 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12145 if (needSep) { 12146 pw.println(); 12147 } 12148 needSep = true; 12149 printedAnything = true; 12150 pw.print(" Sticky broadcasts for user "); 12151 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12152 StringBuilder sb = new StringBuilder(128); 12153 for (Map.Entry<String, ArrayList<Intent>> ent 12154 : mStickyBroadcasts.valueAt(user).entrySet()) { 12155 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12156 if (dumpAll) { 12157 pw.println(":"); 12158 ArrayList<Intent> intents = ent.getValue(); 12159 final int N = intents.size(); 12160 for (int i=0; i<N; i++) { 12161 sb.setLength(0); 12162 sb.append(" Intent: "); 12163 intents.get(i).toShortString(sb, false, true, false, false); 12164 pw.println(sb.toString()); 12165 Bundle bundle = intents.get(i).getExtras(); 12166 if (bundle != null) { 12167 pw.print(" "); 12168 pw.println(bundle.toString()); 12169 } 12170 } 12171 } else { 12172 pw.println(""); 12173 } 12174 } 12175 } 12176 } 12177 12178 if (!onlyHistory && dumpAll) { 12179 pw.println(); 12180 for (BroadcastQueue queue : mBroadcastQueues) { 12181 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12182 + queue.mBroadcastsScheduled); 12183 } 12184 pw.println(" mHandler:"); 12185 mHandler.dump(new PrintWriterPrinter(pw), " "); 12186 needSep = true; 12187 printedAnything = true; 12188 } 12189 12190 if (!printedAnything) { 12191 pw.println(" (nothing)"); 12192 } 12193 } 12194 12195 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12196 int opti, boolean dumpAll, String dumpPackage) { 12197 boolean needSep; 12198 boolean printedAnything = false; 12199 12200 ItemMatcher matcher = new ItemMatcher(); 12201 matcher.build(args, opti); 12202 12203 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12204 12205 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12206 printedAnything |= needSep; 12207 12208 if (mLaunchingProviders.size() > 0) { 12209 boolean printed = false; 12210 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12211 ContentProviderRecord r = mLaunchingProviders.get(i); 12212 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12213 continue; 12214 } 12215 if (!printed) { 12216 if (needSep) pw.println(); 12217 needSep = true; 12218 pw.println(" Launching content providers:"); 12219 printed = true; 12220 printedAnything = true; 12221 } 12222 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12223 pw.println(r); 12224 } 12225 } 12226 12227 if (mGrantedUriPermissions.size() > 0) { 12228 boolean printed = false; 12229 int dumpUid = -2; 12230 if (dumpPackage != null) { 12231 try { 12232 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12233 } catch (NameNotFoundException e) { 12234 dumpUid = -1; 12235 } 12236 } 12237 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12238 int uid = mGrantedUriPermissions.keyAt(i); 12239 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12240 continue; 12241 } 12242 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12243 if (!printed) { 12244 if (needSep) pw.println(); 12245 needSep = true; 12246 pw.println(" Granted Uri Permissions:"); 12247 printed = true; 12248 printedAnything = true; 12249 } 12250 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12251 for (UriPermission perm : perms.values()) { 12252 pw.print(" "); pw.println(perm); 12253 if (dumpAll) { 12254 perm.dump(pw, " "); 12255 } 12256 } 12257 } 12258 } 12259 12260 if (!printedAnything) { 12261 pw.println(" (nothing)"); 12262 } 12263 } 12264 12265 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12266 int opti, boolean dumpAll, String dumpPackage) { 12267 boolean printed = false; 12268 12269 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12270 12271 if (mIntentSenderRecords.size() > 0) { 12272 Iterator<WeakReference<PendingIntentRecord>> it 12273 = mIntentSenderRecords.values().iterator(); 12274 while (it.hasNext()) { 12275 WeakReference<PendingIntentRecord> ref = it.next(); 12276 PendingIntentRecord rec = ref != null ? ref.get(): null; 12277 if (dumpPackage != null && (rec == null 12278 || !dumpPackage.equals(rec.key.packageName))) { 12279 continue; 12280 } 12281 printed = true; 12282 if (rec != null) { 12283 pw.print(" * "); pw.println(rec); 12284 if (dumpAll) { 12285 rec.dump(pw, " "); 12286 } 12287 } else { 12288 pw.print(" * "); pw.println(ref); 12289 } 12290 } 12291 } 12292 12293 if (!printed) { 12294 pw.println(" (nothing)"); 12295 } 12296 } 12297 12298 private static final int dumpProcessList(PrintWriter pw, 12299 ActivityManagerService service, List list, 12300 String prefix, String normalLabel, String persistentLabel, 12301 String dumpPackage) { 12302 int numPers = 0; 12303 final int N = list.size()-1; 12304 for (int i=N; i>=0; i--) { 12305 ProcessRecord r = (ProcessRecord)list.get(i); 12306 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12307 continue; 12308 } 12309 pw.println(String.format("%s%s #%2d: %s", 12310 prefix, (r.persistent ? persistentLabel : normalLabel), 12311 i, r.toString())); 12312 if (r.persistent) { 12313 numPers++; 12314 } 12315 } 12316 return numPers; 12317 } 12318 12319 private static final boolean dumpProcessOomList(PrintWriter pw, 12320 ActivityManagerService service, List<ProcessRecord> origList, 12321 String prefix, String normalLabel, String persistentLabel, 12322 boolean inclDetails, String dumpPackage) { 12323 12324 ArrayList<Pair<ProcessRecord, Integer>> list 12325 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12326 for (int i=0; i<origList.size(); i++) { 12327 ProcessRecord r = origList.get(i); 12328 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12329 continue; 12330 } 12331 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12332 } 12333 12334 if (list.size() <= 0) { 12335 return false; 12336 } 12337 12338 Comparator<Pair<ProcessRecord, Integer>> comparator 12339 = new Comparator<Pair<ProcessRecord, Integer>>() { 12340 @Override 12341 public int compare(Pair<ProcessRecord, Integer> object1, 12342 Pair<ProcessRecord, Integer> object2) { 12343 if (object1.first.setAdj != object2.first.setAdj) { 12344 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12345 } 12346 if (object1.second.intValue() != object2.second.intValue()) { 12347 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12348 } 12349 return 0; 12350 } 12351 }; 12352 12353 Collections.sort(list, comparator); 12354 12355 final long curRealtime = SystemClock.elapsedRealtime(); 12356 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12357 final long curUptime = SystemClock.uptimeMillis(); 12358 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12359 12360 for (int i=list.size()-1; i>=0; i--) { 12361 ProcessRecord r = list.get(i).first; 12362 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12363 char schedGroup; 12364 switch (r.setSchedGroup) { 12365 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12366 schedGroup = 'B'; 12367 break; 12368 case Process.THREAD_GROUP_DEFAULT: 12369 schedGroup = 'F'; 12370 break; 12371 default: 12372 schedGroup = '?'; 12373 break; 12374 } 12375 char foreground; 12376 if (r.foregroundActivities) { 12377 foreground = 'A'; 12378 } else if (r.foregroundServices) { 12379 foreground = 'S'; 12380 } else { 12381 foreground = ' '; 12382 } 12383 String procState = ProcessList.makeProcStateString(r.curProcState); 12384 pw.print(prefix); 12385 pw.print(r.persistent ? persistentLabel : normalLabel); 12386 pw.print(" #"); 12387 int num = (origList.size()-1)-list.get(i).second; 12388 if (num < 10) pw.print(' '); 12389 pw.print(num); 12390 pw.print(": "); 12391 pw.print(oomAdj); 12392 pw.print(' '); 12393 pw.print(schedGroup); 12394 pw.print('/'); 12395 pw.print(foreground); 12396 pw.print('/'); 12397 pw.print(procState); 12398 pw.print(" trm:"); 12399 if (r.trimMemoryLevel < 10) pw.print(' '); 12400 pw.print(r.trimMemoryLevel); 12401 pw.print(' '); 12402 pw.print(r.toShortString()); 12403 pw.print(" ("); 12404 pw.print(r.adjType); 12405 pw.println(')'); 12406 if (r.adjSource != null || r.adjTarget != null) { 12407 pw.print(prefix); 12408 pw.print(" "); 12409 if (r.adjTarget instanceof ComponentName) { 12410 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12411 } else if (r.adjTarget != null) { 12412 pw.print(r.adjTarget.toString()); 12413 } else { 12414 pw.print("{null}"); 12415 } 12416 pw.print("<="); 12417 if (r.adjSource instanceof ProcessRecord) { 12418 pw.print("Proc{"); 12419 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12420 pw.println("}"); 12421 } else if (r.adjSource != null) { 12422 pw.println(r.adjSource.toString()); 12423 } else { 12424 pw.println("{null}"); 12425 } 12426 } 12427 if (inclDetails) { 12428 pw.print(prefix); 12429 pw.print(" "); 12430 pw.print("oom: max="); pw.print(r.maxAdj); 12431 pw.print(" curRaw="); pw.print(r.curRawAdj); 12432 pw.print(" setRaw="); pw.print(r.setRawAdj); 12433 pw.print(" cur="); pw.print(r.curAdj); 12434 pw.print(" set="); pw.println(r.setAdj); 12435 pw.print(prefix); 12436 pw.print(" "); 12437 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12438 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12439 pw.print(" lastPss="); pw.print(r.lastPss); 12440 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12441 pw.print(prefix); 12442 pw.print(" "); 12443 pw.print("cached="); pw.print(r.cached); 12444 pw.print(" empty="); pw.print(r.empty); 12445 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12446 12447 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12448 if (r.lastWakeTime != 0) { 12449 long wtime; 12450 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12451 synchronized (stats) { 12452 wtime = stats.getProcessWakeTime(r.info.uid, 12453 r.pid, curRealtime); 12454 } 12455 long timeUsed = wtime - r.lastWakeTime; 12456 pw.print(prefix); 12457 pw.print(" "); 12458 pw.print("keep awake over "); 12459 TimeUtils.formatDuration(realtimeSince, pw); 12460 pw.print(" used "); 12461 TimeUtils.formatDuration(timeUsed, pw); 12462 pw.print(" ("); 12463 pw.print((timeUsed*100)/realtimeSince); 12464 pw.println("%)"); 12465 } 12466 if (r.lastCpuTime != 0) { 12467 long timeUsed = r.curCpuTime - r.lastCpuTime; 12468 pw.print(prefix); 12469 pw.print(" "); 12470 pw.print("run cpu over "); 12471 TimeUtils.formatDuration(uptimeSince, pw); 12472 pw.print(" used "); 12473 TimeUtils.formatDuration(timeUsed, pw); 12474 pw.print(" ("); 12475 pw.print((timeUsed*100)/uptimeSince); 12476 pw.println("%)"); 12477 } 12478 } 12479 } 12480 } 12481 return true; 12482 } 12483 12484 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12485 ArrayList<ProcessRecord> procs; 12486 synchronized (this) { 12487 if (args != null && args.length > start 12488 && args[start].charAt(0) != '-') { 12489 procs = new ArrayList<ProcessRecord>(); 12490 int pid = -1; 12491 try { 12492 pid = Integer.parseInt(args[start]); 12493 } catch (NumberFormatException e) { 12494 } 12495 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12496 ProcessRecord proc = mLruProcesses.get(i); 12497 if (proc.pid == pid) { 12498 procs.add(proc); 12499 } else if (proc.processName.equals(args[start])) { 12500 procs.add(proc); 12501 } 12502 } 12503 if (procs.size() <= 0) { 12504 return null; 12505 } 12506 } else { 12507 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12508 } 12509 } 12510 return procs; 12511 } 12512 12513 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12514 PrintWriter pw, String[] args) { 12515 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12516 if (procs == null) { 12517 pw.println("No process found for: " + args[0]); 12518 return; 12519 } 12520 12521 long uptime = SystemClock.uptimeMillis(); 12522 long realtime = SystemClock.elapsedRealtime(); 12523 pw.println("Applications Graphics Acceleration Info:"); 12524 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12525 12526 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12527 ProcessRecord r = procs.get(i); 12528 if (r.thread != null) { 12529 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12530 pw.flush(); 12531 try { 12532 TransferPipe tp = new TransferPipe(); 12533 try { 12534 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12535 tp.go(fd); 12536 } finally { 12537 tp.kill(); 12538 } 12539 } catch (IOException e) { 12540 pw.println("Failure while dumping the app: " + r); 12541 pw.flush(); 12542 } catch (RemoteException e) { 12543 pw.println("Got a RemoteException while dumping the app " + r); 12544 pw.flush(); 12545 } 12546 } 12547 } 12548 } 12549 12550 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12551 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12552 if (procs == null) { 12553 pw.println("No process found for: " + args[0]); 12554 return; 12555 } 12556 12557 pw.println("Applications Database Info:"); 12558 12559 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12560 ProcessRecord r = procs.get(i); 12561 if (r.thread != null) { 12562 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12563 pw.flush(); 12564 try { 12565 TransferPipe tp = new TransferPipe(); 12566 try { 12567 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12568 tp.go(fd); 12569 } finally { 12570 tp.kill(); 12571 } 12572 } catch (IOException e) { 12573 pw.println("Failure while dumping the app: " + r); 12574 pw.flush(); 12575 } catch (RemoteException e) { 12576 pw.println("Got a RemoteException while dumping the app " + r); 12577 pw.flush(); 12578 } 12579 } 12580 } 12581 } 12582 12583 final static class MemItem { 12584 final boolean isProc; 12585 final String label; 12586 final String shortLabel; 12587 final long pss; 12588 final int id; 12589 final boolean hasActivities; 12590 ArrayList<MemItem> subitems; 12591 12592 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12593 boolean _hasActivities) { 12594 isProc = true; 12595 label = _label; 12596 shortLabel = _shortLabel; 12597 pss = _pss; 12598 id = _id; 12599 hasActivities = _hasActivities; 12600 } 12601 12602 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12603 isProc = false; 12604 label = _label; 12605 shortLabel = _shortLabel; 12606 pss = _pss; 12607 id = _id; 12608 hasActivities = false; 12609 } 12610 } 12611 12612 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12613 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12614 if (sort && !isCompact) { 12615 Collections.sort(items, new Comparator<MemItem>() { 12616 @Override 12617 public int compare(MemItem lhs, MemItem rhs) { 12618 if (lhs.pss < rhs.pss) { 12619 return 1; 12620 } else if (lhs.pss > rhs.pss) { 12621 return -1; 12622 } 12623 return 0; 12624 } 12625 }); 12626 } 12627 12628 for (int i=0; i<items.size(); i++) { 12629 MemItem mi = items.get(i); 12630 if (!isCompact) { 12631 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12632 } else if (mi.isProc) { 12633 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12634 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12635 pw.println(mi.hasActivities ? ",a" : ",e"); 12636 } else { 12637 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12638 pw.println(mi.pss); 12639 } 12640 if (mi.subitems != null) { 12641 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12642 true, isCompact); 12643 } 12644 } 12645 } 12646 12647 // These are in KB. 12648 static final long[] DUMP_MEM_BUCKETS = new long[] { 12649 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12650 120*1024, 160*1024, 200*1024, 12651 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12652 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12653 }; 12654 12655 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12656 boolean stackLike) { 12657 int start = label.lastIndexOf('.'); 12658 if (start >= 0) start++; 12659 else start = 0; 12660 int end = label.length(); 12661 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12662 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12663 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12664 out.append(bucket); 12665 out.append(stackLike ? "MB." : "MB "); 12666 out.append(label, start, end); 12667 return; 12668 } 12669 } 12670 out.append(memKB/1024); 12671 out.append(stackLike ? "MB." : "MB "); 12672 out.append(label, start, end); 12673 } 12674 12675 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12676 ProcessList.NATIVE_ADJ, 12677 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12678 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12679 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12680 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12681 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12682 }; 12683 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12684 "Native", 12685 "System", "Persistent", "Foreground", 12686 "Visible", "Perceptible", 12687 "Heavy Weight", "Backup", 12688 "A Services", "Home", 12689 "Previous", "B Services", "Cached" 12690 }; 12691 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12692 "native", 12693 "sys", "pers", "fore", 12694 "vis", "percept", 12695 "heavy", "backup", 12696 "servicea", "home", 12697 "prev", "serviceb", "cached" 12698 }; 12699 12700 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12701 long realtime, boolean isCheckinRequest, boolean isCompact) { 12702 if (isCheckinRequest || isCompact) { 12703 // short checkin version 12704 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12705 } else { 12706 pw.println("Applications Memory Usage (kB):"); 12707 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12708 } 12709 } 12710 12711 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12712 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12713 boolean dumpDetails = false; 12714 boolean dumpFullDetails = false; 12715 boolean dumpDalvik = false; 12716 boolean oomOnly = false; 12717 boolean isCompact = false; 12718 boolean localOnly = false; 12719 12720 int opti = 0; 12721 while (opti < args.length) { 12722 String opt = args[opti]; 12723 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12724 break; 12725 } 12726 opti++; 12727 if ("-a".equals(opt)) { 12728 dumpDetails = true; 12729 dumpFullDetails = true; 12730 dumpDalvik = true; 12731 } else if ("-d".equals(opt)) { 12732 dumpDalvik = true; 12733 } else if ("-c".equals(opt)) { 12734 isCompact = true; 12735 } else if ("--oom".equals(opt)) { 12736 oomOnly = true; 12737 } else if ("--local".equals(opt)) { 12738 localOnly = true; 12739 } else if ("-h".equals(opt)) { 12740 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12741 pw.println(" -a: include all available information for each process."); 12742 pw.println(" -d: include dalvik details when dumping process details."); 12743 pw.println(" -c: dump in a compact machine-parseable representation."); 12744 pw.println(" --oom: only show processes organized by oom adj."); 12745 pw.println(" --local: only collect details locally, don't call process."); 12746 pw.println("If [process] is specified it can be the name or "); 12747 pw.println("pid of a specific process to dump."); 12748 return; 12749 } else { 12750 pw.println("Unknown argument: " + opt + "; use -h for help"); 12751 } 12752 } 12753 12754 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12755 long uptime = SystemClock.uptimeMillis(); 12756 long realtime = SystemClock.elapsedRealtime(); 12757 final long[] tmpLong = new long[1]; 12758 12759 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12760 if (procs == null) { 12761 // No Java processes. Maybe they want to print a native process. 12762 if (args != null && args.length > opti 12763 && args[opti].charAt(0) != '-') { 12764 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12765 = new ArrayList<ProcessCpuTracker.Stats>(); 12766 updateCpuStatsNow(); 12767 int findPid = -1; 12768 try { 12769 findPid = Integer.parseInt(args[opti]); 12770 } catch (NumberFormatException e) { 12771 } 12772 synchronized (mProcessCpuThread) { 12773 final int N = mProcessCpuTracker.countStats(); 12774 for (int i=0; i<N; i++) { 12775 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12776 if (st.pid == findPid || (st.baseName != null 12777 && st.baseName.equals(args[opti]))) { 12778 nativeProcs.add(st); 12779 } 12780 } 12781 } 12782 if (nativeProcs.size() > 0) { 12783 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12784 isCompact); 12785 Debug.MemoryInfo mi = null; 12786 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12787 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12788 final int pid = r.pid; 12789 if (!isCheckinRequest && dumpDetails) { 12790 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12791 } 12792 if (mi == null) { 12793 mi = new Debug.MemoryInfo(); 12794 } 12795 if (dumpDetails || (!brief && !oomOnly)) { 12796 Debug.getMemoryInfo(pid, mi); 12797 } else { 12798 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12799 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12800 } 12801 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12802 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12803 if (isCheckinRequest) { 12804 pw.println(); 12805 } 12806 } 12807 return; 12808 } 12809 } 12810 pw.println("No process found for: " + args[opti]); 12811 return; 12812 } 12813 12814 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12815 dumpDetails = true; 12816 } 12817 12818 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12819 12820 String[] innerArgs = new String[args.length-opti]; 12821 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12822 12823 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12824 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12825 long nativePss=0, dalvikPss=0, otherPss=0; 12826 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12827 12828 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12829 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12830 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12831 12832 long totalPss = 0; 12833 long cachedPss = 0; 12834 12835 Debug.MemoryInfo mi = null; 12836 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12837 final ProcessRecord r = procs.get(i); 12838 final IApplicationThread thread; 12839 final int pid; 12840 final int oomAdj; 12841 final boolean hasActivities; 12842 synchronized (this) { 12843 thread = r.thread; 12844 pid = r.pid; 12845 oomAdj = r.getSetAdjWithServices(); 12846 hasActivities = r.activities.size() > 0; 12847 } 12848 if (thread != null) { 12849 if (!isCheckinRequest && dumpDetails) { 12850 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12851 } 12852 if (mi == null) { 12853 mi = new Debug.MemoryInfo(); 12854 } 12855 if (dumpDetails || (!brief && !oomOnly)) { 12856 Debug.getMemoryInfo(pid, mi); 12857 } else { 12858 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12859 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12860 } 12861 if (dumpDetails) { 12862 if (localOnly) { 12863 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12864 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12865 if (isCheckinRequest) { 12866 pw.println(); 12867 } 12868 } else { 12869 try { 12870 pw.flush(); 12871 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12872 dumpDalvik, innerArgs); 12873 } catch (RemoteException e) { 12874 if (!isCheckinRequest) { 12875 pw.println("Got RemoteException!"); 12876 pw.flush(); 12877 } 12878 } 12879 } 12880 } 12881 12882 final long myTotalPss = mi.getTotalPss(); 12883 final long myTotalUss = mi.getTotalUss(); 12884 12885 synchronized (this) { 12886 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12887 // Record this for posterity if the process has been stable. 12888 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12889 } 12890 } 12891 12892 if (!isCheckinRequest && mi != null) { 12893 totalPss += myTotalPss; 12894 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12895 (hasActivities ? " / activities)" : ")"), 12896 r.processName, myTotalPss, pid, hasActivities); 12897 procMems.add(pssItem); 12898 procMemsMap.put(pid, pssItem); 12899 12900 nativePss += mi.nativePss; 12901 dalvikPss += mi.dalvikPss; 12902 otherPss += mi.otherPss; 12903 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12904 long mem = mi.getOtherPss(j); 12905 miscPss[j] += mem; 12906 otherPss -= mem; 12907 } 12908 12909 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12910 cachedPss += myTotalPss; 12911 } 12912 12913 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12914 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12915 || oomIndex == (oomPss.length-1)) { 12916 oomPss[oomIndex] += myTotalPss; 12917 if (oomProcs[oomIndex] == null) { 12918 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12919 } 12920 oomProcs[oomIndex].add(pssItem); 12921 break; 12922 } 12923 } 12924 } 12925 } 12926 } 12927 12928 long nativeProcTotalPss = 0; 12929 12930 if (!isCheckinRequest && procs.size() > 1) { 12931 // If we are showing aggregations, also look for native processes to 12932 // include so that our aggregations are more accurate. 12933 updateCpuStatsNow(); 12934 synchronized (mProcessCpuThread) { 12935 final int N = mProcessCpuTracker.countStats(); 12936 for (int i=0; i<N; i++) { 12937 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12938 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12939 if (mi == null) { 12940 mi = new Debug.MemoryInfo(); 12941 } 12942 if (!brief && !oomOnly) { 12943 Debug.getMemoryInfo(st.pid, mi); 12944 } else { 12945 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12946 mi.nativePrivateDirty = (int)tmpLong[0]; 12947 } 12948 12949 final long myTotalPss = mi.getTotalPss(); 12950 totalPss += myTotalPss; 12951 nativeProcTotalPss += myTotalPss; 12952 12953 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12954 st.name, myTotalPss, st.pid, false); 12955 procMems.add(pssItem); 12956 12957 nativePss += mi.nativePss; 12958 dalvikPss += mi.dalvikPss; 12959 otherPss += mi.otherPss; 12960 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12961 long mem = mi.getOtherPss(j); 12962 miscPss[j] += mem; 12963 otherPss -= mem; 12964 } 12965 oomPss[0] += myTotalPss; 12966 if (oomProcs[0] == null) { 12967 oomProcs[0] = new ArrayList<MemItem>(); 12968 } 12969 oomProcs[0].add(pssItem); 12970 } 12971 } 12972 } 12973 12974 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12975 12976 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12977 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12978 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12979 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12980 String label = Debug.MemoryInfo.getOtherLabel(j); 12981 catMems.add(new MemItem(label, label, miscPss[j], j)); 12982 } 12983 12984 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12985 for (int j=0; j<oomPss.length; j++) { 12986 if (oomPss[j] != 0) { 12987 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12988 : DUMP_MEM_OOM_LABEL[j]; 12989 MemItem item = new MemItem(label, label, oomPss[j], 12990 DUMP_MEM_OOM_ADJ[j]); 12991 item.subitems = oomProcs[j]; 12992 oomMems.add(item); 12993 } 12994 } 12995 12996 if (!brief && !oomOnly && !isCompact) { 12997 pw.println(); 12998 pw.println("Total PSS by process:"); 12999 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13000 pw.println(); 13001 } 13002 if (!isCompact) { 13003 pw.println("Total PSS by OOM adjustment:"); 13004 } 13005 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13006 if (!brief && !oomOnly) { 13007 PrintWriter out = categoryPw != null ? categoryPw : pw; 13008 if (!isCompact) { 13009 out.println(); 13010 out.println("Total PSS by category:"); 13011 } 13012 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13013 } 13014 if (!isCompact) { 13015 pw.println(); 13016 } 13017 MemInfoReader memInfo = new MemInfoReader(); 13018 memInfo.readMemInfo(); 13019 if (nativeProcTotalPss > 0) { 13020 synchronized (this) { 13021 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13022 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13023 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13024 nativeProcTotalPss); 13025 } 13026 } 13027 if (!brief) { 13028 if (!isCompact) { 13029 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13030 pw.print(" kB (status "); 13031 switch (mLastMemoryLevel) { 13032 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13033 pw.println("normal)"); 13034 break; 13035 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13036 pw.println("moderate)"); 13037 break; 13038 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13039 pw.println("low)"); 13040 break; 13041 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13042 pw.println("critical)"); 13043 break; 13044 default: 13045 pw.print(mLastMemoryLevel); 13046 pw.println(")"); 13047 break; 13048 } 13049 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13050 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13051 pw.print(cachedPss); pw.print(" cached pss + "); 13052 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13053 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13054 } else { 13055 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13056 pw.print(cachedPss + memInfo.getCachedSizeKb() 13057 + memInfo.getFreeSizeKb()); pw.print(","); 13058 pw.println(totalPss - cachedPss); 13059 } 13060 } 13061 if (!isCompact) { 13062 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13063 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13064 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13065 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13066 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13067 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13068 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13069 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13070 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13071 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13072 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13073 } 13074 if (!brief) { 13075 if (memInfo.getZramTotalSizeKb() != 0) { 13076 if (!isCompact) { 13077 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13078 pw.print(" kB physical used for "); 13079 pw.print(memInfo.getSwapTotalSizeKb() 13080 - memInfo.getSwapFreeSizeKb()); 13081 pw.print(" kB in swap ("); 13082 pw.print(memInfo.getSwapTotalSizeKb()); 13083 pw.println(" kB total swap)"); 13084 } else { 13085 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13086 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13087 pw.println(memInfo.getSwapFreeSizeKb()); 13088 } 13089 } 13090 final int[] SINGLE_LONG_FORMAT = new int[] { 13091 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13092 }; 13093 long[] longOut = new long[1]; 13094 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13095 SINGLE_LONG_FORMAT, null, longOut, null); 13096 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13097 longOut[0] = 0; 13098 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13099 SINGLE_LONG_FORMAT, null, longOut, null); 13100 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13101 longOut[0] = 0; 13102 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13103 SINGLE_LONG_FORMAT, null, longOut, null); 13104 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13105 longOut[0] = 0; 13106 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13107 SINGLE_LONG_FORMAT, null, longOut, null); 13108 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13109 if (!isCompact) { 13110 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13111 pw.print(" KSM: "); pw.print(sharing); 13112 pw.print(" kB saved from shared "); 13113 pw.print(shared); pw.println(" kB"); 13114 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13115 pw.print(voltile); pw.println(" kB volatile"); 13116 } 13117 pw.print(" Tuning: "); 13118 pw.print(ActivityManager.staticGetMemoryClass()); 13119 pw.print(" (large "); 13120 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13121 pw.print("), oom "); 13122 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13123 pw.print(" kB"); 13124 pw.print(", restore limit "); 13125 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13126 pw.print(" kB"); 13127 if (ActivityManager.isLowRamDeviceStatic()) { 13128 pw.print(" (low-ram)"); 13129 } 13130 if (ActivityManager.isHighEndGfx()) { 13131 pw.print(" (high-end-gfx)"); 13132 } 13133 pw.println(); 13134 } else { 13135 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13136 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13137 pw.println(voltile); 13138 pw.print("tuning,"); 13139 pw.print(ActivityManager.staticGetMemoryClass()); 13140 pw.print(','); 13141 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13142 pw.print(','); 13143 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13144 if (ActivityManager.isLowRamDeviceStatic()) { 13145 pw.print(",low-ram"); 13146 } 13147 if (ActivityManager.isHighEndGfx()) { 13148 pw.print(",high-end-gfx"); 13149 } 13150 pw.println(); 13151 } 13152 } 13153 } 13154 } 13155 13156 /** 13157 * Searches array of arguments for the specified string 13158 * @param args array of argument strings 13159 * @param value value to search for 13160 * @return true if the value is contained in the array 13161 */ 13162 private static boolean scanArgs(String[] args, String value) { 13163 if (args != null) { 13164 for (String arg : args) { 13165 if (value.equals(arg)) { 13166 return true; 13167 } 13168 } 13169 } 13170 return false; 13171 } 13172 13173 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13174 ContentProviderRecord cpr, boolean always) { 13175 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13176 13177 if (!inLaunching || always) { 13178 synchronized (cpr) { 13179 cpr.launchingApp = null; 13180 cpr.notifyAll(); 13181 } 13182 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13183 String names[] = cpr.info.authority.split(";"); 13184 for (int j = 0; j < names.length; j++) { 13185 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13186 } 13187 } 13188 13189 for (int i=0; i<cpr.connections.size(); i++) { 13190 ContentProviderConnection conn = cpr.connections.get(i); 13191 if (conn.waiting) { 13192 // If this connection is waiting for the provider, then we don't 13193 // need to mess with its process unless we are always removing 13194 // or for some reason the provider is not currently launching. 13195 if (inLaunching && !always) { 13196 continue; 13197 } 13198 } 13199 ProcessRecord capp = conn.client; 13200 conn.dead = true; 13201 if (conn.stableCount > 0) { 13202 if (!capp.persistent && capp.thread != null 13203 && capp.pid != 0 13204 && capp.pid != MY_PID) { 13205 killUnneededProcessLocked(capp, "depends on provider " 13206 + cpr.name.flattenToShortString() 13207 + " in dying proc " + (proc != null ? proc.processName : "??")); 13208 } 13209 } else if (capp.thread != null && conn.provider.provider != null) { 13210 try { 13211 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13212 } catch (RemoteException e) { 13213 } 13214 // In the protocol here, we don't expect the client to correctly 13215 // clean up this connection, we'll just remove it. 13216 cpr.connections.remove(i); 13217 conn.client.conProviders.remove(conn); 13218 } 13219 } 13220 13221 if (inLaunching && always) { 13222 mLaunchingProviders.remove(cpr); 13223 } 13224 return inLaunching; 13225 } 13226 13227 /** 13228 * Main code for cleaning up a process when it has gone away. This is 13229 * called both as a result of the process dying, or directly when stopping 13230 * a process when running in single process mode. 13231 */ 13232 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13233 boolean restarting, boolean allowRestart, int index) { 13234 if (index >= 0) { 13235 removeLruProcessLocked(app); 13236 ProcessList.remove(app.pid); 13237 } 13238 13239 mProcessesToGc.remove(app); 13240 mPendingPssProcesses.remove(app); 13241 13242 // Dismiss any open dialogs. 13243 if (app.crashDialog != null && !app.forceCrashReport) { 13244 app.crashDialog.dismiss(); 13245 app.crashDialog = null; 13246 } 13247 if (app.anrDialog != null) { 13248 app.anrDialog.dismiss(); 13249 app.anrDialog = null; 13250 } 13251 if (app.waitDialog != null) { 13252 app.waitDialog.dismiss(); 13253 app.waitDialog = null; 13254 } 13255 13256 app.crashing = false; 13257 app.notResponding = false; 13258 13259 app.resetPackageList(mProcessStats); 13260 app.unlinkDeathRecipient(); 13261 app.makeInactive(mProcessStats); 13262 app.waitingToKill = null; 13263 app.forcingToForeground = null; 13264 updateProcessForegroundLocked(app, false, false); 13265 app.foregroundActivities = false; 13266 app.hasShownUi = false; 13267 app.treatLikeActivity = false; 13268 app.hasAboveClient = false; 13269 app.hasClientActivities = false; 13270 13271 mServices.killServicesLocked(app, allowRestart); 13272 13273 boolean restart = false; 13274 13275 // Remove published content providers. 13276 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13277 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13278 final boolean always = app.bad || !allowRestart; 13279 if (removeDyingProviderLocked(app, cpr, always) || always) { 13280 // We left the provider in the launching list, need to 13281 // restart it. 13282 restart = true; 13283 } 13284 13285 cpr.provider = null; 13286 cpr.proc = null; 13287 } 13288 app.pubProviders.clear(); 13289 13290 // Take care of any launching providers waiting for this process. 13291 if (checkAppInLaunchingProvidersLocked(app, false)) { 13292 restart = true; 13293 } 13294 13295 // Unregister from connected content providers. 13296 if (!app.conProviders.isEmpty()) { 13297 for (int i=0; i<app.conProviders.size(); i++) { 13298 ContentProviderConnection conn = app.conProviders.get(i); 13299 conn.provider.connections.remove(conn); 13300 } 13301 app.conProviders.clear(); 13302 } 13303 13304 // At this point there may be remaining entries in mLaunchingProviders 13305 // where we were the only one waiting, so they are no longer of use. 13306 // Look for these and clean up if found. 13307 // XXX Commented out for now. Trying to figure out a way to reproduce 13308 // the actual situation to identify what is actually going on. 13309 if (false) { 13310 for (int i=0; i<mLaunchingProviders.size(); i++) { 13311 ContentProviderRecord cpr = (ContentProviderRecord) 13312 mLaunchingProviders.get(i); 13313 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13314 synchronized (cpr) { 13315 cpr.launchingApp = null; 13316 cpr.notifyAll(); 13317 } 13318 } 13319 } 13320 } 13321 13322 skipCurrentReceiverLocked(app); 13323 13324 // Unregister any receivers. 13325 for (int i=app.receivers.size()-1; i>=0; i--) { 13326 removeReceiverLocked(app.receivers.valueAt(i)); 13327 } 13328 app.receivers.clear(); 13329 13330 // If the app is undergoing backup, tell the backup manager about it 13331 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13332 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13333 + mBackupTarget.appInfo + " died during backup"); 13334 try { 13335 IBackupManager bm = IBackupManager.Stub.asInterface( 13336 ServiceManager.getService(Context.BACKUP_SERVICE)); 13337 bm.agentDisconnected(app.info.packageName); 13338 } catch (RemoteException e) { 13339 // can't happen; backup manager is local 13340 } 13341 } 13342 13343 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13344 ProcessChangeItem item = mPendingProcessChanges.get(i); 13345 if (item.pid == app.pid) { 13346 mPendingProcessChanges.remove(i); 13347 mAvailProcessChanges.add(item); 13348 } 13349 } 13350 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13351 13352 // If the caller is restarting this app, then leave it in its 13353 // current lists and let the caller take care of it. 13354 if (restarting) { 13355 return; 13356 } 13357 13358 if (!app.persistent || app.isolated) { 13359 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13360 "Removing non-persistent process during cleanup: " + app); 13361 mProcessNames.remove(app.processName, app.uid); 13362 mIsolatedProcesses.remove(app.uid); 13363 if (mHeavyWeightProcess == app) { 13364 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13365 mHeavyWeightProcess.userId, 0)); 13366 mHeavyWeightProcess = null; 13367 } 13368 } else if (!app.removed) { 13369 // This app is persistent, so we need to keep its record around. 13370 // If it is not already on the pending app list, add it there 13371 // and start a new process for it. 13372 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13373 mPersistentStartingProcesses.add(app); 13374 restart = true; 13375 } 13376 } 13377 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13378 "Clean-up removing on hold: " + app); 13379 mProcessesOnHold.remove(app); 13380 13381 if (app == mHomeProcess) { 13382 mHomeProcess = null; 13383 } 13384 if (app == mPreviousProcess) { 13385 mPreviousProcess = null; 13386 } 13387 13388 if (restart && !app.isolated) { 13389 // We have components that still need to be running in the 13390 // process, so re-launch it. 13391 mProcessNames.put(app.processName, app.uid, app); 13392 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13393 } else if (app.pid > 0 && app.pid != MY_PID) { 13394 // Goodbye! 13395 boolean removed; 13396 synchronized (mPidsSelfLocked) { 13397 mPidsSelfLocked.remove(app.pid); 13398 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13399 } 13400 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13401 if (app.isolated) { 13402 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13403 } 13404 app.setPid(0); 13405 } 13406 } 13407 13408 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13409 // Look through the content providers we are waiting to have launched, 13410 // and if any run in this process then either schedule a restart of 13411 // the process or kill the client waiting for it if this process has 13412 // gone bad. 13413 int NL = mLaunchingProviders.size(); 13414 boolean restart = false; 13415 for (int i=0; i<NL; i++) { 13416 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13417 if (cpr.launchingApp == app) { 13418 if (!alwaysBad && !app.bad) { 13419 restart = true; 13420 } else { 13421 removeDyingProviderLocked(app, cpr, true); 13422 // cpr should have been removed from mLaunchingProviders 13423 NL = mLaunchingProviders.size(); 13424 i--; 13425 } 13426 } 13427 } 13428 return restart; 13429 } 13430 13431 // ========================================================= 13432 // SERVICES 13433 // ========================================================= 13434 13435 @Override 13436 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13437 int flags) { 13438 enforceNotIsolatedCaller("getServices"); 13439 synchronized (this) { 13440 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13441 } 13442 } 13443 13444 @Override 13445 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13446 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13447 synchronized (this) { 13448 return mServices.getRunningServiceControlPanelLocked(name); 13449 } 13450 } 13451 13452 @Override 13453 public ComponentName startService(IApplicationThread caller, Intent service, 13454 String resolvedType, int userId) { 13455 enforceNotIsolatedCaller("startService"); 13456 // Refuse possible leaked file descriptors 13457 if (service != null && service.hasFileDescriptors() == true) { 13458 throw new IllegalArgumentException("File descriptors passed in Intent"); 13459 } 13460 13461 if (DEBUG_SERVICE) 13462 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13463 synchronized(this) { 13464 final int callingPid = Binder.getCallingPid(); 13465 final int callingUid = Binder.getCallingUid(); 13466 final long origId = Binder.clearCallingIdentity(); 13467 ComponentName res = mServices.startServiceLocked(caller, service, 13468 resolvedType, callingPid, callingUid, userId); 13469 Binder.restoreCallingIdentity(origId); 13470 return res; 13471 } 13472 } 13473 13474 ComponentName startServiceInPackage(int uid, 13475 Intent service, String resolvedType, int userId) { 13476 synchronized(this) { 13477 if (DEBUG_SERVICE) 13478 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13479 final long origId = Binder.clearCallingIdentity(); 13480 ComponentName res = mServices.startServiceLocked(null, service, 13481 resolvedType, -1, uid, userId); 13482 Binder.restoreCallingIdentity(origId); 13483 return res; 13484 } 13485 } 13486 13487 @Override 13488 public int stopService(IApplicationThread caller, Intent service, 13489 String resolvedType, int userId) { 13490 enforceNotIsolatedCaller("stopService"); 13491 // Refuse possible leaked file descriptors 13492 if (service != null && service.hasFileDescriptors() == true) { 13493 throw new IllegalArgumentException("File descriptors passed in Intent"); 13494 } 13495 13496 synchronized(this) { 13497 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13498 } 13499 } 13500 13501 @Override 13502 public IBinder peekService(Intent service, String resolvedType) { 13503 enforceNotIsolatedCaller("peekService"); 13504 // Refuse possible leaked file descriptors 13505 if (service != null && service.hasFileDescriptors() == true) { 13506 throw new IllegalArgumentException("File descriptors passed in Intent"); 13507 } 13508 synchronized(this) { 13509 return mServices.peekServiceLocked(service, resolvedType); 13510 } 13511 } 13512 13513 @Override 13514 public boolean stopServiceToken(ComponentName className, IBinder token, 13515 int startId) { 13516 synchronized(this) { 13517 return mServices.stopServiceTokenLocked(className, token, startId); 13518 } 13519 } 13520 13521 @Override 13522 public void setServiceForeground(ComponentName className, IBinder token, 13523 int id, Notification notification, boolean removeNotification) { 13524 synchronized(this) { 13525 mServices.setServiceForegroundLocked(className, token, id, notification, 13526 removeNotification); 13527 } 13528 } 13529 13530 @Override 13531 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13532 boolean requireFull, String name, String callerPackage) { 13533 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13534 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13535 } 13536 13537 int unsafeConvertIncomingUser(int userId) { 13538 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13539 ? mCurrentUserId : userId; 13540 } 13541 13542 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13543 int allowMode, String name, String callerPackage) { 13544 final int callingUserId = UserHandle.getUserId(callingUid); 13545 if (callingUserId == userId) { 13546 return userId; 13547 } 13548 13549 // Note that we may be accessing mCurrentUserId outside of a lock... 13550 // shouldn't be a big deal, if this is being called outside 13551 // of a locked context there is intrinsically a race with 13552 // the value the caller will receive and someone else changing it. 13553 // We assume that USER_CURRENT_OR_SELF will use the current user; later 13554 // we will switch to the calling user if access to the current user fails. 13555 int targetUserId = unsafeConvertIncomingUser(userId); 13556 13557 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13558 final boolean allow; 13559 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 13560 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 13561 // If the caller has this permission, they always pass go. And collect $200. 13562 allow = true; 13563 } else if (allowMode == ALLOW_FULL_ONLY) { 13564 // We require full access, sucks to be you. 13565 allow = false; 13566 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 13567 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 13568 // If the caller does not have either permission, they are always doomed. 13569 allow = false; 13570 } else if (allowMode == ALLOW_NON_FULL) { 13571 // We are blanket allowing non-full access, you lucky caller! 13572 allow = true; 13573 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 13574 // We may or may not allow this depending on whether the two users are 13575 // in the same profile. 13576 synchronized (mUserProfileGroupIdsSelfLocked) { 13577 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 13578 UserInfo.NO_PROFILE_GROUP_ID); 13579 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 13580 UserInfo.NO_PROFILE_GROUP_ID); 13581 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 13582 && callingProfile == targetProfile; 13583 } 13584 } else { 13585 throw new IllegalArgumentException("Unknown mode: " + allowMode); 13586 } 13587 if (!allow) { 13588 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13589 // In this case, they would like to just execute as their 13590 // owner user instead of failing. 13591 targetUserId = callingUserId; 13592 } else { 13593 StringBuilder builder = new StringBuilder(128); 13594 builder.append("Permission Denial: "); 13595 builder.append(name); 13596 if (callerPackage != null) { 13597 builder.append(" from "); 13598 builder.append(callerPackage); 13599 } 13600 builder.append(" asks to run as user "); 13601 builder.append(userId); 13602 builder.append(" but is calling from user "); 13603 builder.append(UserHandle.getUserId(callingUid)); 13604 builder.append("; this requires "); 13605 builder.append(INTERACT_ACROSS_USERS_FULL); 13606 if (allowMode != ALLOW_FULL_ONLY) { 13607 builder.append(" or "); 13608 builder.append(INTERACT_ACROSS_USERS); 13609 } 13610 String msg = builder.toString(); 13611 Slog.w(TAG, msg); 13612 throw new SecurityException(msg); 13613 } 13614 } 13615 } 13616 if (!allowAll && targetUserId < 0) { 13617 throw new IllegalArgumentException( 13618 "Call does not support special user #" + targetUserId); 13619 } 13620 return targetUserId; 13621 } 13622 13623 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13624 String className, int flags) { 13625 boolean result = false; 13626 // For apps that don't have pre-defined UIDs, check for permission 13627 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13628 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13629 if (ActivityManager.checkUidPermission( 13630 INTERACT_ACROSS_USERS, 13631 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13632 ComponentName comp = new ComponentName(aInfo.packageName, className); 13633 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13634 + " requests FLAG_SINGLE_USER, but app does not hold " 13635 + INTERACT_ACROSS_USERS; 13636 Slog.w(TAG, msg); 13637 throw new SecurityException(msg); 13638 } 13639 // Permission passed 13640 result = true; 13641 } 13642 } else if ("system".equals(componentProcessName)) { 13643 result = true; 13644 } else { 13645 // App with pre-defined UID, check if it's a persistent app 13646 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13647 } 13648 if (DEBUG_MU) { 13649 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13650 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13651 } 13652 return result; 13653 } 13654 13655 /** 13656 * Checks to see if the caller is in the same app as the singleton 13657 * component, or the component is in a special app. It allows special apps 13658 * to export singleton components but prevents exporting singleton 13659 * components for regular apps. 13660 */ 13661 boolean isValidSingletonCall(int callingUid, int componentUid) { 13662 int componentAppId = UserHandle.getAppId(componentUid); 13663 return UserHandle.isSameApp(callingUid, componentUid) 13664 || componentAppId == Process.SYSTEM_UID 13665 || componentAppId == Process.PHONE_UID 13666 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13667 == PackageManager.PERMISSION_GRANTED; 13668 } 13669 13670 public int bindService(IApplicationThread caller, IBinder token, 13671 Intent service, String resolvedType, 13672 IServiceConnection connection, int flags, int userId) { 13673 enforceNotIsolatedCaller("bindService"); 13674 // Refuse possible leaked file descriptors 13675 if (service != null && service.hasFileDescriptors() == true) { 13676 throw new IllegalArgumentException("File descriptors passed in Intent"); 13677 } 13678 13679 synchronized(this) { 13680 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13681 connection, flags, userId); 13682 } 13683 } 13684 13685 public boolean unbindService(IServiceConnection connection) { 13686 synchronized (this) { 13687 return mServices.unbindServiceLocked(connection); 13688 } 13689 } 13690 13691 public void publishService(IBinder token, Intent intent, IBinder service) { 13692 // Refuse possible leaked file descriptors 13693 if (intent != null && intent.hasFileDescriptors() == true) { 13694 throw new IllegalArgumentException("File descriptors passed in Intent"); 13695 } 13696 13697 synchronized(this) { 13698 if (!(token instanceof ServiceRecord)) { 13699 throw new IllegalArgumentException("Invalid service token"); 13700 } 13701 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13702 } 13703 } 13704 13705 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13706 // Refuse possible leaked file descriptors 13707 if (intent != null && intent.hasFileDescriptors() == true) { 13708 throw new IllegalArgumentException("File descriptors passed in Intent"); 13709 } 13710 13711 synchronized(this) { 13712 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13713 } 13714 } 13715 13716 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13717 synchronized(this) { 13718 if (!(token instanceof ServiceRecord)) { 13719 throw new IllegalArgumentException("Invalid service token"); 13720 } 13721 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13722 } 13723 } 13724 13725 // ========================================================= 13726 // BACKUP AND RESTORE 13727 // ========================================================= 13728 13729 // Cause the target app to be launched if necessary and its backup agent 13730 // instantiated. The backup agent will invoke backupAgentCreated() on the 13731 // activity manager to announce its creation. 13732 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13733 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13734 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13735 13736 synchronized(this) { 13737 // !!! TODO: currently no check here that we're already bound 13738 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13739 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13740 synchronized (stats) { 13741 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13742 } 13743 13744 // Backup agent is now in use, its package can't be stopped. 13745 try { 13746 AppGlobals.getPackageManager().setPackageStoppedState( 13747 app.packageName, false, UserHandle.getUserId(app.uid)); 13748 } catch (RemoteException e) { 13749 } catch (IllegalArgumentException e) { 13750 Slog.w(TAG, "Failed trying to unstop package " 13751 + app.packageName + ": " + e); 13752 } 13753 13754 BackupRecord r = new BackupRecord(ss, app, backupMode); 13755 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13756 ? new ComponentName(app.packageName, app.backupAgentName) 13757 : new ComponentName("android", "FullBackupAgent"); 13758 // startProcessLocked() returns existing proc's record if it's already running 13759 ProcessRecord proc = startProcessLocked(app.processName, app, 13760 false, 0, "backup", hostingName, false, false, false); 13761 if (proc == null) { 13762 Slog.e(TAG, "Unable to start backup agent process " + r); 13763 return false; 13764 } 13765 13766 r.app = proc; 13767 mBackupTarget = r; 13768 mBackupAppName = app.packageName; 13769 13770 // Try not to kill the process during backup 13771 updateOomAdjLocked(proc); 13772 13773 // If the process is already attached, schedule the creation of the backup agent now. 13774 // If it is not yet live, this will be done when it attaches to the framework. 13775 if (proc.thread != null) { 13776 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13777 try { 13778 proc.thread.scheduleCreateBackupAgent(app, 13779 compatibilityInfoForPackageLocked(app), backupMode); 13780 } catch (RemoteException e) { 13781 // Will time out on the backup manager side 13782 } 13783 } else { 13784 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13785 } 13786 // Invariants: at this point, the target app process exists and the application 13787 // is either already running or in the process of coming up. mBackupTarget and 13788 // mBackupAppName describe the app, so that when it binds back to the AM we 13789 // know that it's scheduled for a backup-agent operation. 13790 } 13791 13792 return true; 13793 } 13794 13795 @Override 13796 public void clearPendingBackup() { 13797 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13798 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13799 13800 synchronized (this) { 13801 mBackupTarget = null; 13802 mBackupAppName = null; 13803 } 13804 } 13805 13806 // A backup agent has just come up 13807 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13808 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13809 + " = " + agent); 13810 13811 synchronized(this) { 13812 if (!agentPackageName.equals(mBackupAppName)) { 13813 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13814 return; 13815 } 13816 } 13817 13818 long oldIdent = Binder.clearCallingIdentity(); 13819 try { 13820 IBackupManager bm = IBackupManager.Stub.asInterface( 13821 ServiceManager.getService(Context.BACKUP_SERVICE)); 13822 bm.agentConnected(agentPackageName, agent); 13823 } catch (RemoteException e) { 13824 // can't happen; the backup manager service is local 13825 } catch (Exception e) { 13826 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13827 e.printStackTrace(); 13828 } finally { 13829 Binder.restoreCallingIdentity(oldIdent); 13830 } 13831 } 13832 13833 // done with this agent 13834 public void unbindBackupAgent(ApplicationInfo appInfo) { 13835 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13836 if (appInfo == null) { 13837 Slog.w(TAG, "unbind backup agent for null app"); 13838 return; 13839 } 13840 13841 synchronized(this) { 13842 try { 13843 if (mBackupAppName == null) { 13844 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13845 return; 13846 } 13847 13848 if (!mBackupAppName.equals(appInfo.packageName)) { 13849 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13850 return; 13851 } 13852 13853 // Not backing this app up any more; reset its OOM adjustment 13854 final ProcessRecord proc = mBackupTarget.app; 13855 updateOomAdjLocked(proc); 13856 13857 // If the app crashed during backup, 'thread' will be null here 13858 if (proc.thread != null) { 13859 try { 13860 proc.thread.scheduleDestroyBackupAgent(appInfo, 13861 compatibilityInfoForPackageLocked(appInfo)); 13862 } catch (Exception e) { 13863 Slog.e(TAG, "Exception when unbinding backup agent:"); 13864 e.printStackTrace(); 13865 } 13866 } 13867 } finally { 13868 mBackupTarget = null; 13869 mBackupAppName = null; 13870 } 13871 } 13872 } 13873 // ========================================================= 13874 // BROADCASTS 13875 // ========================================================= 13876 13877 private final List getStickiesLocked(String action, IntentFilter filter, 13878 List cur, int userId) { 13879 final ContentResolver resolver = mContext.getContentResolver(); 13880 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13881 if (stickies == null) { 13882 return cur; 13883 } 13884 final ArrayList<Intent> list = stickies.get(action); 13885 if (list == null) { 13886 return cur; 13887 } 13888 int N = list.size(); 13889 for (int i=0; i<N; i++) { 13890 Intent intent = list.get(i); 13891 if (filter.match(resolver, intent, true, TAG) >= 0) { 13892 if (cur == null) { 13893 cur = new ArrayList<Intent>(); 13894 } 13895 cur.add(intent); 13896 } 13897 } 13898 return cur; 13899 } 13900 13901 boolean isPendingBroadcastProcessLocked(int pid) { 13902 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13903 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13904 } 13905 13906 void skipPendingBroadcastLocked(int pid) { 13907 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13908 for (BroadcastQueue queue : mBroadcastQueues) { 13909 queue.skipPendingBroadcastLocked(pid); 13910 } 13911 } 13912 13913 // The app just attached; send any pending broadcasts that it should receive 13914 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13915 boolean didSomething = false; 13916 for (BroadcastQueue queue : mBroadcastQueues) { 13917 didSomething |= queue.sendPendingBroadcastsLocked(app); 13918 } 13919 return didSomething; 13920 } 13921 13922 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13923 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13924 enforceNotIsolatedCaller("registerReceiver"); 13925 int callingUid; 13926 int callingPid; 13927 synchronized(this) { 13928 ProcessRecord callerApp = null; 13929 if (caller != null) { 13930 callerApp = getRecordForAppLocked(caller); 13931 if (callerApp == null) { 13932 throw new SecurityException( 13933 "Unable to find app for caller " + caller 13934 + " (pid=" + Binder.getCallingPid() 13935 + ") when registering receiver " + receiver); 13936 } 13937 if (callerApp.info.uid != Process.SYSTEM_UID && 13938 !callerApp.pkgList.containsKey(callerPackage) && 13939 !"android".equals(callerPackage)) { 13940 throw new SecurityException("Given caller package " + callerPackage 13941 + " is not running in process " + callerApp); 13942 } 13943 callingUid = callerApp.info.uid; 13944 callingPid = callerApp.pid; 13945 } else { 13946 callerPackage = null; 13947 callingUid = Binder.getCallingUid(); 13948 callingPid = Binder.getCallingPid(); 13949 } 13950 13951 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13952 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 13953 13954 List allSticky = null; 13955 13956 // Look for any matching sticky broadcasts... 13957 Iterator actions = filter.actionsIterator(); 13958 if (actions != null) { 13959 while (actions.hasNext()) { 13960 String action = (String)actions.next(); 13961 allSticky = getStickiesLocked(action, filter, allSticky, 13962 UserHandle.USER_ALL); 13963 allSticky = getStickiesLocked(action, filter, allSticky, 13964 UserHandle.getUserId(callingUid)); 13965 } 13966 } else { 13967 allSticky = getStickiesLocked(null, filter, allSticky, 13968 UserHandle.USER_ALL); 13969 allSticky = getStickiesLocked(null, filter, allSticky, 13970 UserHandle.getUserId(callingUid)); 13971 } 13972 13973 // The first sticky in the list is returned directly back to 13974 // the client. 13975 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13976 13977 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13978 + ": " + sticky); 13979 13980 if (receiver == null) { 13981 return sticky; 13982 } 13983 13984 ReceiverList rl 13985 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13986 if (rl == null) { 13987 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13988 userId, receiver); 13989 if (rl.app != null) { 13990 rl.app.receivers.add(rl); 13991 } else { 13992 try { 13993 receiver.asBinder().linkToDeath(rl, 0); 13994 } catch (RemoteException e) { 13995 return sticky; 13996 } 13997 rl.linkedToDeath = true; 13998 } 13999 mRegisteredReceivers.put(receiver.asBinder(), rl); 14000 } else if (rl.uid != callingUid) { 14001 throw new IllegalArgumentException( 14002 "Receiver requested to register for uid " + callingUid 14003 + " was previously registered for uid " + rl.uid); 14004 } else if (rl.pid != callingPid) { 14005 throw new IllegalArgumentException( 14006 "Receiver requested to register for pid " + callingPid 14007 + " was previously registered for pid " + rl.pid); 14008 } else if (rl.userId != userId) { 14009 throw new IllegalArgumentException( 14010 "Receiver requested to register for user " + userId 14011 + " was previously registered for user " + rl.userId); 14012 } 14013 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14014 permission, callingUid, userId); 14015 rl.add(bf); 14016 if (!bf.debugCheck()) { 14017 Slog.w(TAG, "==> For Dynamic broadast"); 14018 } 14019 mReceiverResolver.addFilter(bf); 14020 14021 // Enqueue broadcasts for all existing stickies that match 14022 // this filter. 14023 if (allSticky != null) { 14024 ArrayList receivers = new ArrayList(); 14025 receivers.add(bf); 14026 14027 int N = allSticky.size(); 14028 for (int i=0; i<N; i++) { 14029 Intent intent = (Intent)allSticky.get(i); 14030 BroadcastQueue queue = broadcastQueueForIntent(intent); 14031 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14032 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14033 null, null, false, true, true, -1); 14034 queue.enqueueParallelBroadcastLocked(r); 14035 queue.scheduleBroadcastsLocked(); 14036 } 14037 } 14038 14039 return sticky; 14040 } 14041 } 14042 14043 public void unregisterReceiver(IIntentReceiver receiver) { 14044 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14045 14046 final long origId = Binder.clearCallingIdentity(); 14047 try { 14048 boolean doTrim = false; 14049 14050 synchronized(this) { 14051 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14052 if (rl != null) { 14053 if (rl.curBroadcast != null) { 14054 BroadcastRecord r = rl.curBroadcast; 14055 final boolean doNext = finishReceiverLocked( 14056 receiver.asBinder(), r.resultCode, r.resultData, 14057 r.resultExtras, r.resultAbort); 14058 if (doNext) { 14059 doTrim = true; 14060 r.queue.processNextBroadcast(false); 14061 } 14062 } 14063 14064 if (rl.app != null) { 14065 rl.app.receivers.remove(rl); 14066 } 14067 removeReceiverLocked(rl); 14068 if (rl.linkedToDeath) { 14069 rl.linkedToDeath = false; 14070 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14071 } 14072 } 14073 } 14074 14075 // If we actually concluded any broadcasts, we might now be able 14076 // to trim the recipients' apps from our working set 14077 if (doTrim) { 14078 trimApplications(); 14079 return; 14080 } 14081 14082 } finally { 14083 Binder.restoreCallingIdentity(origId); 14084 } 14085 } 14086 14087 void removeReceiverLocked(ReceiverList rl) { 14088 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14089 int N = rl.size(); 14090 for (int i=0; i<N; i++) { 14091 mReceiverResolver.removeFilter(rl.get(i)); 14092 } 14093 } 14094 14095 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14097 ProcessRecord r = mLruProcesses.get(i); 14098 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14099 try { 14100 r.thread.dispatchPackageBroadcast(cmd, packages); 14101 } catch (RemoteException ex) { 14102 } 14103 } 14104 } 14105 } 14106 14107 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14108 int[] users) { 14109 List<ResolveInfo> receivers = null; 14110 try { 14111 HashSet<ComponentName> singleUserReceivers = null; 14112 boolean scannedFirstReceivers = false; 14113 for (int user : users) { 14114 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14115 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14116 if (user != 0 && newReceivers != null) { 14117 // If this is not the primary user, we need to check for 14118 // any receivers that should be filtered out. 14119 for (int i=0; i<newReceivers.size(); i++) { 14120 ResolveInfo ri = newReceivers.get(i); 14121 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14122 newReceivers.remove(i); 14123 i--; 14124 } 14125 } 14126 } 14127 if (newReceivers != null && newReceivers.size() == 0) { 14128 newReceivers = null; 14129 } 14130 if (receivers == null) { 14131 receivers = newReceivers; 14132 } else if (newReceivers != null) { 14133 // We need to concatenate the additional receivers 14134 // found with what we have do far. This would be easy, 14135 // but we also need to de-dup any receivers that are 14136 // singleUser. 14137 if (!scannedFirstReceivers) { 14138 // Collect any single user receivers we had already retrieved. 14139 scannedFirstReceivers = true; 14140 for (int i=0; i<receivers.size(); i++) { 14141 ResolveInfo ri = receivers.get(i); 14142 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14143 ComponentName cn = new ComponentName( 14144 ri.activityInfo.packageName, ri.activityInfo.name); 14145 if (singleUserReceivers == null) { 14146 singleUserReceivers = new HashSet<ComponentName>(); 14147 } 14148 singleUserReceivers.add(cn); 14149 } 14150 } 14151 } 14152 // Add the new results to the existing results, tracking 14153 // and de-dupping single user receivers. 14154 for (int i=0; i<newReceivers.size(); i++) { 14155 ResolveInfo ri = newReceivers.get(i); 14156 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14157 ComponentName cn = new ComponentName( 14158 ri.activityInfo.packageName, ri.activityInfo.name); 14159 if (singleUserReceivers == null) { 14160 singleUserReceivers = new HashSet<ComponentName>(); 14161 } 14162 if (!singleUserReceivers.contains(cn)) { 14163 singleUserReceivers.add(cn); 14164 receivers.add(ri); 14165 } 14166 } else { 14167 receivers.add(ri); 14168 } 14169 } 14170 } 14171 } 14172 } catch (RemoteException ex) { 14173 // pm is in same process, this will never happen. 14174 } 14175 return receivers; 14176 } 14177 14178 private final int broadcastIntentLocked(ProcessRecord callerApp, 14179 String callerPackage, Intent intent, String resolvedType, 14180 IIntentReceiver resultTo, int resultCode, String resultData, 14181 Bundle map, String requiredPermission, int appOp, 14182 boolean ordered, boolean sticky, int callingPid, int callingUid, 14183 int userId) { 14184 intent = new Intent(intent); 14185 14186 // By default broadcasts do not go to stopped apps. 14187 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14188 14189 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14190 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14191 + " ordered=" + ordered + " userid=" + userId); 14192 if ((resultTo != null) && !ordered) { 14193 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14194 } 14195 14196 userId = handleIncomingUser(callingPid, callingUid, userId, 14197 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14198 14199 // Make sure that the user who is receiving this broadcast is started. 14200 // If not, we will just skip it. 14201 14202 14203 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14204 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14205 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14206 Slog.w(TAG, "Skipping broadcast of " + intent 14207 + ": user " + userId + " is stopped"); 14208 return ActivityManager.BROADCAST_SUCCESS; 14209 } 14210 } 14211 14212 /* 14213 * Prevent non-system code (defined here to be non-persistent 14214 * processes) from sending protected broadcasts. 14215 */ 14216 int callingAppId = UserHandle.getAppId(callingUid); 14217 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14218 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14219 || callingAppId == Process.NFC_UID || callingUid == 0) { 14220 // Always okay. 14221 } else if (callerApp == null || !callerApp.persistent) { 14222 try { 14223 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14224 intent.getAction())) { 14225 String msg = "Permission Denial: not allowed to send broadcast " 14226 + intent.getAction() + " from pid=" 14227 + callingPid + ", uid=" + callingUid; 14228 Slog.w(TAG, msg); 14229 throw new SecurityException(msg); 14230 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14231 // Special case for compatibility: we don't want apps to send this, 14232 // but historically it has not been protected and apps may be using it 14233 // to poke their own app widget. So, instead of making it protected, 14234 // just limit it to the caller. 14235 if (callerApp == null) { 14236 String msg = "Permission Denial: not allowed to send broadcast " 14237 + intent.getAction() + " from unknown caller."; 14238 Slog.w(TAG, msg); 14239 throw new SecurityException(msg); 14240 } else if (intent.getComponent() != null) { 14241 // They are good enough to send to an explicit component... verify 14242 // it is being sent to the calling app. 14243 if (!intent.getComponent().getPackageName().equals( 14244 callerApp.info.packageName)) { 14245 String msg = "Permission Denial: not allowed to send broadcast " 14246 + intent.getAction() + " to " 14247 + intent.getComponent().getPackageName() + " from " 14248 + callerApp.info.packageName; 14249 Slog.w(TAG, msg); 14250 throw new SecurityException(msg); 14251 } 14252 } else { 14253 // Limit broadcast to their own package. 14254 intent.setPackage(callerApp.info.packageName); 14255 } 14256 } 14257 } catch (RemoteException e) { 14258 Slog.w(TAG, "Remote exception", e); 14259 return ActivityManager.BROADCAST_SUCCESS; 14260 } 14261 } 14262 14263 // Handle special intents: if this broadcast is from the package 14264 // manager about a package being removed, we need to remove all of 14265 // its activities from the history stack. 14266 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14267 intent.getAction()); 14268 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14269 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14270 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14271 || uidRemoved) { 14272 if (checkComponentPermission( 14273 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14274 callingPid, callingUid, -1, true) 14275 == PackageManager.PERMISSION_GRANTED) { 14276 if (uidRemoved) { 14277 final Bundle intentExtras = intent.getExtras(); 14278 final int uid = intentExtras != null 14279 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14280 if (uid >= 0) { 14281 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14282 synchronized (bs) { 14283 bs.removeUidStatsLocked(uid); 14284 } 14285 mAppOpsService.uidRemoved(uid); 14286 } 14287 } else { 14288 // If resources are unavailable just force stop all 14289 // those packages and flush the attribute cache as well. 14290 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14291 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14292 if (list != null && (list.length > 0)) { 14293 for (String pkg : list) { 14294 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14295 "storage unmount"); 14296 } 14297 sendPackageBroadcastLocked( 14298 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14299 } 14300 } else { 14301 Uri data = intent.getData(); 14302 String ssp; 14303 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14304 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14305 intent.getAction()); 14306 boolean fullUninstall = removed && 14307 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14308 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14309 forceStopPackageLocked(ssp, UserHandle.getAppId( 14310 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14311 false, fullUninstall, userId, 14312 removed ? "pkg removed" : "pkg changed"); 14313 } 14314 if (removed) { 14315 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14316 new String[] {ssp}, userId); 14317 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14318 mAppOpsService.packageRemoved( 14319 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14320 14321 // Remove all permissions granted from/to this package 14322 removeUriPermissionsForPackageLocked(ssp, userId, true); 14323 } 14324 } 14325 } 14326 } 14327 } 14328 } else { 14329 String msg = "Permission Denial: " + intent.getAction() 14330 + " broadcast from " + callerPackage + " (pid=" + callingPid 14331 + ", uid=" + callingUid + ")" 14332 + " requires " 14333 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14334 Slog.w(TAG, msg); 14335 throw new SecurityException(msg); 14336 } 14337 14338 // Special case for adding a package: by default turn on compatibility 14339 // mode. 14340 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14341 Uri data = intent.getData(); 14342 String ssp; 14343 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14344 mCompatModePackages.handlePackageAddedLocked(ssp, 14345 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14346 } 14347 } 14348 14349 /* 14350 * If this is the time zone changed action, queue up a message that will reset the timezone 14351 * of all currently running processes. This message will get queued up before the broadcast 14352 * happens. 14353 */ 14354 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14355 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14356 } 14357 14358 /* 14359 * If the user set the time, let all running processes know. 14360 */ 14361 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14362 final int is24Hour = intent.getBooleanExtra( 14363 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14364 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14365 } 14366 14367 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14368 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14369 } 14370 14371 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14372 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14373 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14374 } 14375 14376 // Add to the sticky list if requested. 14377 if (sticky) { 14378 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14379 callingPid, callingUid) 14380 != PackageManager.PERMISSION_GRANTED) { 14381 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14382 + callingPid + ", uid=" + callingUid 14383 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14384 Slog.w(TAG, msg); 14385 throw new SecurityException(msg); 14386 } 14387 if (requiredPermission != null) { 14388 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14389 + " and enforce permission " + requiredPermission); 14390 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14391 } 14392 if (intent.getComponent() != null) { 14393 throw new SecurityException( 14394 "Sticky broadcasts can't target a specific component"); 14395 } 14396 // We use userId directly here, since the "all" target is maintained 14397 // as a separate set of sticky broadcasts. 14398 if (userId != UserHandle.USER_ALL) { 14399 // But first, if this is not a broadcast to all users, then 14400 // make sure it doesn't conflict with an existing broadcast to 14401 // all users. 14402 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14403 UserHandle.USER_ALL); 14404 if (stickies != null) { 14405 ArrayList<Intent> list = stickies.get(intent.getAction()); 14406 if (list != null) { 14407 int N = list.size(); 14408 int i; 14409 for (i=0; i<N; i++) { 14410 if (intent.filterEquals(list.get(i))) { 14411 throw new IllegalArgumentException( 14412 "Sticky broadcast " + intent + " for user " 14413 + userId + " conflicts with existing global broadcast"); 14414 } 14415 } 14416 } 14417 } 14418 } 14419 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14420 if (stickies == null) { 14421 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14422 mStickyBroadcasts.put(userId, stickies); 14423 } 14424 ArrayList<Intent> list = stickies.get(intent.getAction()); 14425 if (list == null) { 14426 list = new ArrayList<Intent>(); 14427 stickies.put(intent.getAction(), list); 14428 } 14429 int N = list.size(); 14430 int i; 14431 for (i=0; i<N; i++) { 14432 if (intent.filterEquals(list.get(i))) { 14433 // This sticky already exists, replace it. 14434 list.set(i, new Intent(intent)); 14435 break; 14436 } 14437 } 14438 if (i >= N) { 14439 list.add(new Intent(intent)); 14440 } 14441 } 14442 14443 int[] users; 14444 if (userId == UserHandle.USER_ALL) { 14445 // Caller wants broadcast to go to all started users. 14446 users = mStartedUserArray; 14447 } else { 14448 // Caller wants broadcast to go to one specific user. 14449 users = new int[] {userId}; 14450 } 14451 14452 // Figure out who all will receive this broadcast. 14453 List receivers = null; 14454 List<BroadcastFilter> registeredReceivers = null; 14455 // Need to resolve the intent to interested receivers... 14456 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14457 == 0) { 14458 receivers = collectReceiverComponents(intent, resolvedType, users); 14459 } 14460 if (intent.getComponent() == null) { 14461 registeredReceivers = mReceiverResolver.queryIntent(intent, 14462 resolvedType, false, userId); 14463 } 14464 14465 final boolean replacePending = 14466 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14467 14468 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14469 + " replacePending=" + replacePending); 14470 14471 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14472 if (!ordered && NR > 0) { 14473 // If we are not serializing this broadcast, then send the 14474 // registered receivers separately so they don't wait for the 14475 // components to be launched. 14476 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14477 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14478 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14479 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14480 ordered, sticky, false, userId); 14481 if (DEBUG_BROADCAST) Slog.v( 14482 TAG, "Enqueueing parallel broadcast " + r); 14483 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14484 if (!replaced) { 14485 queue.enqueueParallelBroadcastLocked(r); 14486 queue.scheduleBroadcastsLocked(); 14487 } 14488 registeredReceivers = null; 14489 NR = 0; 14490 } 14491 14492 // Merge into one list. 14493 int ir = 0; 14494 if (receivers != null) { 14495 // A special case for PACKAGE_ADDED: do not allow the package 14496 // being added to see this broadcast. This prevents them from 14497 // using this as a back door to get run as soon as they are 14498 // installed. Maybe in the future we want to have a special install 14499 // broadcast or such for apps, but we'd like to deliberately make 14500 // this decision. 14501 String skipPackages[] = null; 14502 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14503 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14504 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14505 Uri data = intent.getData(); 14506 if (data != null) { 14507 String pkgName = data.getSchemeSpecificPart(); 14508 if (pkgName != null) { 14509 skipPackages = new String[] { pkgName }; 14510 } 14511 } 14512 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14513 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14514 } 14515 if (skipPackages != null && (skipPackages.length > 0)) { 14516 for (String skipPackage : skipPackages) { 14517 if (skipPackage != null) { 14518 int NT = receivers.size(); 14519 for (int it=0; it<NT; it++) { 14520 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14521 if (curt.activityInfo.packageName.equals(skipPackage)) { 14522 receivers.remove(it); 14523 it--; 14524 NT--; 14525 } 14526 } 14527 } 14528 } 14529 } 14530 14531 int NT = receivers != null ? receivers.size() : 0; 14532 int it = 0; 14533 ResolveInfo curt = null; 14534 BroadcastFilter curr = null; 14535 while (it < NT && ir < NR) { 14536 if (curt == null) { 14537 curt = (ResolveInfo)receivers.get(it); 14538 } 14539 if (curr == null) { 14540 curr = registeredReceivers.get(ir); 14541 } 14542 if (curr.getPriority() >= curt.priority) { 14543 // Insert this broadcast record into the final list. 14544 receivers.add(it, curr); 14545 ir++; 14546 curr = null; 14547 it++; 14548 NT++; 14549 } else { 14550 // Skip to the next ResolveInfo in the final list. 14551 it++; 14552 curt = null; 14553 } 14554 } 14555 } 14556 while (ir < NR) { 14557 if (receivers == null) { 14558 receivers = new ArrayList(); 14559 } 14560 receivers.add(registeredReceivers.get(ir)); 14561 ir++; 14562 } 14563 14564 if ((receivers != null && receivers.size() > 0) 14565 || resultTo != null) { 14566 BroadcastQueue queue = broadcastQueueForIntent(intent); 14567 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14568 callerPackage, callingPid, callingUid, resolvedType, 14569 requiredPermission, appOp, receivers, resultTo, resultCode, 14570 resultData, map, ordered, sticky, false, userId); 14571 if (DEBUG_BROADCAST) Slog.v( 14572 TAG, "Enqueueing ordered broadcast " + r 14573 + ": prev had " + queue.mOrderedBroadcasts.size()); 14574 if (DEBUG_BROADCAST) { 14575 int seq = r.intent.getIntExtra("seq", -1); 14576 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14577 } 14578 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14579 if (!replaced) { 14580 queue.enqueueOrderedBroadcastLocked(r); 14581 queue.scheduleBroadcastsLocked(); 14582 } 14583 } 14584 14585 return ActivityManager.BROADCAST_SUCCESS; 14586 } 14587 14588 final Intent verifyBroadcastLocked(Intent intent) { 14589 // Refuse possible leaked file descriptors 14590 if (intent != null && intent.hasFileDescriptors() == true) { 14591 throw new IllegalArgumentException("File descriptors passed in Intent"); 14592 } 14593 14594 int flags = intent.getFlags(); 14595 14596 if (!mProcessesReady) { 14597 // if the caller really truly claims to know what they're doing, go 14598 // ahead and allow the broadcast without launching any receivers 14599 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14600 intent = new Intent(intent); 14601 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14602 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14603 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14604 + " before boot completion"); 14605 throw new IllegalStateException("Cannot broadcast before boot completed"); 14606 } 14607 } 14608 14609 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14610 throw new IllegalArgumentException( 14611 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14612 } 14613 14614 return intent; 14615 } 14616 14617 public final int broadcastIntent(IApplicationThread caller, 14618 Intent intent, String resolvedType, IIntentReceiver resultTo, 14619 int resultCode, String resultData, Bundle map, 14620 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14621 enforceNotIsolatedCaller("broadcastIntent"); 14622 synchronized(this) { 14623 intent = verifyBroadcastLocked(intent); 14624 14625 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14626 final int callingPid = Binder.getCallingPid(); 14627 final int callingUid = Binder.getCallingUid(); 14628 final long origId = Binder.clearCallingIdentity(); 14629 int res = broadcastIntentLocked(callerApp, 14630 callerApp != null ? callerApp.info.packageName : null, 14631 intent, resolvedType, resultTo, 14632 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14633 callingPid, callingUid, userId); 14634 Binder.restoreCallingIdentity(origId); 14635 return res; 14636 } 14637 } 14638 14639 int broadcastIntentInPackage(String packageName, int uid, 14640 Intent intent, String resolvedType, IIntentReceiver resultTo, 14641 int resultCode, String resultData, Bundle map, 14642 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14643 synchronized(this) { 14644 intent = verifyBroadcastLocked(intent); 14645 14646 final long origId = Binder.clearCallingIdentity(); 14647 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14648 resultTo, resultCode, resultData, map, requiredPermission, 14649 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14650 Binder.restoreCallingIdentity(origId); 14651 return res; 14652 } 14653 } 14654 14655 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14656 // Refuse possible leaked file descriptors 14657 if (intent != null && intent.hasFileDescriptors() == true) { 14658 throw new IllegalArgumentException("File descriptors passed in Intent"); 14659 } 14660 14661 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14662 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 14663 14664 synchronized(this) { 14665 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14666 != PackageManager.PERMISSION_GRANTED) { 14667 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14668 + Binder.getCallingPid() 14669 + ", uid=" + Binder.getCallingUid() 14670 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14671 Slog.w(TAG, msg); 14672 throw new SecurityException(msg); 14673 } 14674 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14675 if (stickies != null) { 14676 ArrayList<Intent> list = stickies.get(intent.getAction()); 14677 if (list != null) { 14678 int N = list.size(); 14679 int i; 14680 for (i=0; i<N; i++) { 14681 if (intent.filterEquals(list.get(i))) { 14682 list.remove(i); 14683 break; 14684 } 14685 } 14686 if (list.size() <= 0) { 14687 stickies.remove(intent.getAction()); 14688 } 14689 } 14690 if (stickies.size() <= 0) { 14691 mStickyBroadcasts.remove(userId); 14692 } 14693 } 14694 } 14695 } 14696 14697 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14698 String resultData, Bundle resultExtras, boolean resultAbort) { 14699 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14700 if (r == null) { 14701 Slog.w(TAG, "finishReceiver called but not found on queue"); 14702 return false; 14703 } 14704 14705 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14706 } 14707 14708 void backgroundServicesFinishedLocked(int userId) { 14709 for (BroadcastQueue queue : mBroadcastQueues) { 14710 queue.backgroundServicesFinishedLocked(userId); 14711 } 14712 } 14713 14714 public void finishReceiver(IBinder who, int resultCode, String resultData, 14715 Bundle resultExtras, boolean resultAbort) { 14716 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14717 14718 // Refuse possible leaked file descriptors 14719 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14720 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14721 } 14722 14723 final long origId = Binder.clearCallingIdentity(); 14724 try { 14725 boolean doNext = false; 14726 BroadcastRecord r; 14727 14728 synchronized(this) { 14729 r = broadcastRecordForReceiverLocked(who); 14730 if (r != null) { 14731 doNext = r.queue.finishReceiverLocked(r, resultCode, 14732 resultData, resultExtras, resultAbort, true); 14733 } 14734 } 14735 14736 if (doNext) { 14737 r.queue.processNextBroadcast(false); 14738 } 14739 trimApplications(); 14740 } finally { 14741 Binder.restoreCallingIdentity(origId); 14742 } 14743 } 14744 14745 // ========================================================= 14746 // INSTRUMENTATION 14747 // ========================================================= 14748 14749 public boolean startInstrumentation(ComponentName className, 14750 String profileFile, int flags, Bundle arguments, 14751 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14752 int userId, String abiOverride) { 14753 enforceNotIsolatedCaller("startInstrumentation"); 14754 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14755 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 14756 // Refuse possible leaked file descriptors 14757 if (arguments != null && arguments.hasFileDescriptors()) { 14758 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14759 } 14760 14761 synchronized(this) { 14762 InstrumentationInfo ii = null; 14763 ApplicationInfo ai = null; 14764 try { 14765 ii = mContext.getPackageManager().getInstrumentationInfo( 14766 className, STOCK_PM_FLAGS); 14767 ai = AppGlobals.getPackageManager().getApplicationInfo( 14768 ii.targetPackage, STOCK_PM_FLAGS, userId); 14769 } catch (PackageManager.NameNotFoundException e) { 14770 } catch (RemoteException e) { 14771 } 14772 if (ii == null) { 14773 reportStartInstrumentationFailure(watcher, className, 14774 "Unable to find instrumentation info for: " + className); 14775 return false; 14776 } 14777 if (ai == null) { 14778 reportStartInstrumentationFailure(watcher, className, 14779 "Unable to find instrumentation target package: " + ii.targetPackage); 14780 return false; 14781 } 14782 14783 int match = mContext.getPackageManager().checkSignatures( 14784 ii.targetPackage, ii.packageName); 14785 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14786 String msg = "Permission Denial: starting instrumentation " 14787 + className + " from pid=" 14788 + Binder.getCallingPid() 14789 + ", uid=" + Binder.getCallingPid() 14790 + " not allowed because package " + ii.packageName 14791 + " does not have a signature matching the target " 14792 + ii.targetPackage; 14793 reportStartInstrumentationFailure(watcher, className, msg); 14794 throw new SecurityException(msg); 14795 } 14796 14797 final long origId = Binder.clearCallingIdentity(); 14798 // Instrumentation can kill and relaunch even persistent processes 14799 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14800 "start instr"); 14801 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14802 app.instrumentationClass = className; 14803 app.instrumentationInfo = ai; 14804 app.instrumentationProfileFile = profileFile; 14805 app.instrumentationArguments = arguments; 14806 app.instrumentationWatcher = watcher; 14807 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14808 app.instrumentationResultClass = className; 14809 Binder.restoreCallingIdentity(origId); 14810 } 14811 14812 return true; 14813 } 14814 14815 /** 14816 * Report errors that occur while attempting to start Instrumentation. Always writes the 14817 * error to the logs, but if somebody is watching, send the report there too. This enables 14818 * the "am" command to report errors with more information. 14819 * 14820 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14821 * @param cn The component name of the instrumentation. 14822 * @param report The error report. 14823 */ 14824 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14825 ComponentName cn, String report) { 14826 Slog.w(TAG, report); 14827 try { 14828 if (watcher != null) { 14829 Bundle results = new Bundle(); 14830 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14831 results.putString("Error", report); 14832 watcher.instrumentationStatus(cn, -1, results); 14833 } 14834 } catch (RemoteException e) { 14835 Slog.w(TAG, e); 14836 } 14837 } 14838 14839 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14840 if (app.instrumentationWatcher != null) { 14841 try { 14842 // NOTE: IInstrumentationWatcher *must* be oneway here 14843 app.instrumentationWatcher.instrumentationFinished( 14844 app.instrumentationClass, 14845 resultCode, 14846 results); 14847 } catch (RemoteException e) { 14848 } 14849 } 14850 if (app.instrumentationUiAutomationConnection != null) { 14851 try { 14852 app.instrumentationUiAutomationConnection.shutdown(); 14853 } catch (RemoteException re) { 14854 /* ignore */ 14855 } 14856 // Only a UiAutomation can set this flag and now that 14857 // it is finished we make sure it is reset to its default. 14858 mUserIsMonkey = false; 14859 } 14860 app.instrumentationWatcher = null; 14861 app.instrumentationUiAutomationConnection = null; 14862 app.instrumentationClass = null; 14863 app.instrumentationInfo = null; 14864 app.instrumentationProfileFile = null; 14865 app.instrumentationArguments = null; 14866 14867 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14868 "finished inst"); 14869 } 14870 14871 public void finishInstrumentation(IApplicationThread target, 14872 int resultCode, Bundle results) { 14873 int userId = UserHandle.getCallingUserId(); 14874 // Refuse possible leaked file descriptors 14875 if (results != null && results.hasFileDescriptors()) { 14876 throw new IllegalArgumentException("File descriptors passed in Intent"); 14877 } 14878 14879 synchronized(this) { 14880 ProcessRecord app = getRecordForAppLocked(target); 14881 if (app == null) { 14882 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14883 return; 14884 } 14885 final long origId = Binder.clearCallingIdentity(); 14886 finishInstrumentationLocked(app, resultCode, results); 14887 Binder.restoreCallingIdentity(origId); 14888 } 14889 } 14890 14891 // ========================================================= 14892 // CONFIGURATION 14893 // ========================================================= 14894 14895 public ConfigurationInfo getDeviceConfigurationInfo() { 14896 ConfigurationInfo config = new ConfigurationInfo(); 14897 synchronized (this) { 14898 config.reqTouchScreen = mConfiguration.touchscreen; 14899 config.reqKeyboardType = mConfiguration.keyboard; 14900 config.reqNavigation = mConfiguration.navigation; 14901 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14902 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14903 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14904 } 14905 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14906 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14907 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14908 } 14909 config.reqGlEsVersion = GL_ES_VERSION; 14910 } 14911 return config; 14912 } 14913 14914 ActivityStack getFocusedStack() { 14915 return mStackSupervisor.getFocusedStack(); 14916 } 14917 14918 public Configuration getConfiguration() { 14919 Configuration ci; 14920 synchronized(this) { 14921 ci = new Configuration(mConfiguration); 14922 } 14923 return ci; 14924 } 14925 14926 public void updatePersistentConfiguration(Configuration values) { 14927 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14928 "updateConfiguration()"); 14929 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14930 "updateConfiguration()"); 14931 if (values == null) { 14932 throw new NullPointerException("Configuration must not be null"); 14933 } 14934 14935 synchronized(this) { 14936 final long origId = Binder.clearCallingIdentity(); 14937 updateConfigurationLocked(values, null, true, false); 14938 Binder.restoreCallingIdentity(origId); 14939 } 14940 } 14941 14942 public void updateConfiguration(Configuration values) { 14943 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14944 "updateConfiguration()"); 14945 14946 synchronized(this) { 14947 if (values == null && mWindowManager != null) { 14948 // sentinel: fetch the current configuration from the window manager 14949 values = mWindowManager.computeNewConfiguration(); 14950 } 14951 14952 if (mWindowManager != null) { 14953 mProcessList.applyDisplaySize(mWindowManager); 14954 } 14955 14956 final long origId = Binder.clearCallingIdentity(); 14957 if (values != null) { 14958 Settings.System.clearConfiguration(values); 14959 } 14960 updateConfigurationLocked(values, null, false, false); 14961 Binder.restoreCallingIdentity(origId); 14962 } 14963 } 14964 14965 /** 14966 * Do either or both things: (1) change the current configuration, and (2) 14967 * make sure the given activity is running with the (now) current 14968 * configuration. Returns true if the activity has been left running, or 14969 * false if <var>starting</var> is being destroyed to match the new 14970 * configuration. 14971 * @param persistent TODO 14972 */ 14973 boolean updateConfigurationLocked(Configuration values, 14974 ActivityRecord starting, boolean persistent, boolean initLocale) { 14975 int changes = 0; 14976 14977 if (values != null) { 14978 Configuration newConfig = new Configuration(mConfiguration); 14979 changes = newConfig.updateFrom(values); 14980 if (changes != 0) { 14981 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14982 Slog.i(TAG, "Updating configuration to: " + values); 14983 } 14984 14985 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14986 14987 if (values.locale != null && !initLocale) { 14988 saveLocaleLocked(values.locale, 14989 !values.locale.equals(mConfiguration.locale), 14990 values.userSetLocale); 14991 } 14992 14993 mConfigurationSeq++; 14994 if (mConfigurationSeq <= 0) { 14995 mConfigurationSeq = 1; 14996 } 14997 newConfig.seq = mConfigurationSeq; 14998 mConfiguration = newConfig; 14999 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15000 //mUsageStatsService.noteStartConfig(newConfig); 15001 15002 final Configuration configCopy = new Configuration(mConfiguration); 15003 15004 // TODO: If our config changes, should we auto dismiss any currently 15005 // showing dialogs? 15006 mShowDialogs = shouldShowDialogs(newConfig); 15007 15008 AttributeCache ac = AttributeCache.instance(); 15009 if (ac != null) { 15010 ac.updateConfiguration(configCopy); 15011 } 15012 15013 // Make sure all resources in our process are updated 15014 // right now, so that anyone who is going to retrieve 15015 // resource values after we return will be sure to get 15016 // the new ones. This is especially important during 15017 // boot, where the first config change needs to guarantee 15018 // all resources have that config before following boot 15019 // code is executed. 15020 mSystemThread.applyConfigurationToResources(configCopy); 15021 15022 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15023 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15024 msg.obj = new Configuration(configCopy); 15025 mHandler.sendMessage(msg); 15026 } 15027 15028 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15029 ProcessRecord app = mLruProcesses.get(i); 15030 try { 15031 if (app.thread != null) { 15032 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15033 + app.processName + " new config " + mConfiguration); 15034 app.thread.scheduleConfigurationChanged(configCopy); 15035 } 15036 } catch (Exception e) { 15037 } 15038 } 15039 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15040 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15041 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15042 | Intent.FLAG_RECEIVER_FOREGROUND); 15043 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15044 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15045 Process.SYSTEM_UID, UserHandle.USER_ALL); 15046 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15047 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15048 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15049 broadcastIntentLocked(null, null, intent, 15050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15051 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15052 } 15053 } 15054 } 15055 15056 boolean kept = true; 15057 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15058 // mainStack is null during startup. 15059 if (mainStack != null) { 15060 if (changes != 0 && starting == null) { 15061 // If the configuration changed, and the caller is not already 15062 // in the process of starting an activity, then find the top 15063 // activity to check if its configuration needs to change. 15064 starting = mainStack.topRunningActivityLocked(null); 15065 } 15066 15067 if (starting != null) { 15068 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15069 // And we need to make sure at this point that all other activities 15070 // are made visible with the correct configuration. 15071 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15072 } 15073 } 15074 15075 if (values != null && mWindowManager != null) { 15076 mWindowManager.setNewConfiguration(mConfiguration); 15077 } 15078 15079 return kept; 15080 } 15081 15082 /** 15083 * Decide based on the configuration whether we should shouw the ANR, 15084 * crash, etc dialogs. The idea is that if there is no affordnace to 15085 * press the on-screen buttons, we shouldn't show the dialog. 15086 * 15087 * A thought: SystemUI might also want to get told about this, the Power 15088 * dialog / global actions also might want different behaviors. 15089 */ 15090 private static final boolean shouldShowDialogs(Configuration config) { 15091 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15092 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15093 } 15094 15095 /** 15096 * Save the locale. You must be inside a synchronized (this) block. 15097 */ 15098 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15099 if(isDiff) { 15100 SystemProperties.set("user.language", l.getLanguage()); 15101 SystemProperties.set("user.region", l.getCountry()); 15102 } 15103 15104 if(isPersist) { 15105 SystemProperties.set("persist.sys.language", l.getLanguage()); 15106 SystemProperties.set("persist.sys.country", l.getCountry()); 15107 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15108 } 15109 } 15110 15111 @Override 15112 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15113 ActivityRecord srec = ActivityRecord.forToken(token); 15114 return srec != null && srec.task.affinity != null && 15115 srec.task.affinity.equals(destAffinity); 15116 } 15117 15118 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15119 Intent resultData) { 15120 15121 synchronized (this) { 15122 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15123 if (stack != null) { 15124 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15125 } 15126 return false; 15127 } 15128 } 15129 15130 public int getLaunchedFromUid(IBinder activityToken) { 15131 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15132 if (srec == null) { 15133 return -1; 15134 } 15135 return srec.launchedFromUid; 15136 } 15137 15138 public String getLaunchedFromPackage(IBinder activityToken) { 15139 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15140 if (srec == null) { 15141 return null; 15142 } 15143 return srec.launchedFromPackage; 15144 } 15145 15146 // ========================================================= 15147 // LIFETIME MANAGEMENT 15148 // ========================================================= 15149 15150 // Returns which broadcast queue the app is the current [or imminent] receiver 15151 // on, or 'null' if the app is not an active broadcast recipient. 15152 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15153 BroadcastRecord r = app.curReceiver; 15154 if (r != null) { 15155 return r.queue; 15156 } 15157 15158 // It's not the current receiver, but it might be starting up to become one 15159 synchronized (this) { 15160 for (BroadcastQueue queue : mBroadcastQueues) { 15161 r = queue.mPendingBroadcast; 15162 if (r != null && r.curApp == app) { 15163 // found it; report which queue it's in 15164 return queue; 15165 } 15166 } 15167 } 15168 15169 return null; 15170 } 15171 15172 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15173 boolean doingAll, long now) { 15174 if (mAdjSeq == app.adjSeq) { 15175 // This adjustment has already been computed. 15176 return app.curRawAdj; 15177 } 15178 15179 if (app.thread == null) { 15180 app.adjSeq = mAdjSeq; 15181 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15182 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15183 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15184 } 15185 15186 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15187 app.adjSource = null; 15188 app.adjTarget = null; 15189 app.empty = false; 15190 app.cached = false; 15191 15192 final int activitiesSize = app.activities.size(); 15193 15194 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15195 // The max adjustment doesn't allow this app to be anything 15196 // below foreground, so it is not worth doing work for it. 15197 app.adjType = "fixed"; 15198 app.adjSeq = mAdjSeq; 15199 app.curRawAdj = app.maxAdj; 15200 app.foregroundActivities = false; 15201 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15202 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15203 // System processes can do UI, and when they do we want to have 15204 // them trim their memory after the user leaves the UI. To 15205 // facilitate this, here we need to determine whether or not it 15206 // is currently showing UI. 15207 app.systemNoUi = true; 15208 if (app == TOP_APP) { 15209 app.systemNoUi = false; 15210 } else if (activitiesSize > 0) { 15211 for (int j = 0; j < activitiesSize; j++) { 15212 final ActivityRecord r = app.activities.get(j); 15213 if (r.visible) { 15214 app.systemNoUi = false; 15215 } 15216 } 15217 } 15218 if (!app.systemNoUi) { 15219 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15220 } 15221 return (app.curAdj=app.maxAdj); 15222 } 15223 15224 app.systemNoUi = false; 15225 15226 // Determine the importance of the process, starting with most 15227 // important to least, and assign an appropriate OOM adjustment. 15228 int adj; 15229 int schedGroup; 15230 int procState; 15231 boolean foregroundActivities = false; 15232 BroadcastQueue queue; 15233 if (app == TOP_APP) { 15234 // The last app on the list is the foreground app. 15235 adj = ProcessList.FOREGROUND_APP_ADJ; 15236 schedGroup = Process.THREAD_GROUP_DEFAULT; 15237 app.adjType = "top-activity"; 15238 foregroundActivities = true; 15239 procState = ActivityManager.PROCESS_STATE_TOP; 15240 } else if (app.instrumentationClass != null) { 15241 // Don't want to kill running instrumentation. 15242 adj = ProcessList.FOREGROUND_APP_ADJ; 15243 schedGroup = Process.THREAD_GROUP_DEFAULT; 15244 app.adjType = "instrumentation"; 15245 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15246 } else if ((queue = isReceivingBroadcast(app)) != null) { 15247 // An app that is currently receiving a broadcast also 15248 // counts as being in the foreground for OOM killer purposes. 15249 // It's placed in a sched group based on the nature of the 15250 // broadcast as reflected by which queue it's active in. 15251 adj = ProcessList.FOREGROUND_APP_ADJ; 15252 schedGroup = (queue == mFgBroadcastQueue) 15253 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15254 app.adjType = "broadcast"; 15255 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15256 } else if (app.executingServices.size() > 0) { 15257 // An app that is currently executing a service callback also 15258 // counts as being in the foreground. 15259 adj = ProcessList.FOREGROUND_APP_ADJ; 15260 schedGroup = app.execServicesFg ? 15261 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15262 app.adjType = "exec-service"; 15263 procState = ActivityManager.PROCESS_STATE_SERVICE; 15264 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15265 } else { 15266 // As far as we know the process is empty. We may change our mind later. 15267 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15268 // At this point we don't actually know the adjustment. Use the cached adj 15269 // value that the caller wants us to. 15270 adj = cachedAdj; 15271 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15272 app.cached = true; 15273 app.empty = true; 15274 app.adjType = "cch-empty"; 15275 } 15276 15277 // Examine all activities if not already foreground. 15278 if (!foregroundActivities && activitiesSize > 0) { 15279 for (int j = 0; j < activitiesSize; j++) { 15280 final ActivityRecord r = app.activities.get(j); 15281 if (r.app != app) { 15282 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15283 + app + "?!?"); 15284 continue; 15285 } 15286 if (r.visible) { 15287 // App has a visible activity; only upgrade adjustment. 15288 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15289 adj = ProcessList.VISIBLE_APP_ADJ; 15290 app.adjType = "visible"; 15291 } 15292 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15293 procState = ActivityManager.PROCESS_STATE_TOP; 15294 } 15295 schedGroup = Process.THREAD_GROUP_DEFAULT; 15296 app.cached = false; 15297 app.empty = false; 15298 foregroundActivities = true; 15299 break; 15300 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15301 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15302 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15303 app.adjType = "pausing"; 15304 } 15305 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15306 procState = ActivityManager.PROCESS_STATE_TOP; 15307 } 15308 schedGroup = Process.THREAD_GROUP_DEFAULT; 15309 app.cached = false; 15310 app.empty = false; 15311 foregroundActivities = true; 15312 } else if (r.state == ActivityState.STOPPING) { 15313 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15314 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15315 app.adjType = "stopping"; 15316 } 15317 // For the process state, we will at this point consider the 15318 // process to be cached. It will be cached either as an activity 15319 // or empty depending on whether the activity is finishing. We do 15320 // this so that we can treat the process as cached for purposes of 15321 // memory trimming (determing current memory level, trim command to 15322 // send to process) since there can be an arbitrary number of stopping 15323 // processes and they should soon all go into the cached state. 15324 if (!r.finishing) { 15325 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15326 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15327 } 15328 } 15329 app.cached = false; 15330 app.empty = false; 15331 foregroundActivities = true; 15332 } else { 15333 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15334 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15335 app.adjType = "cch-act"; 15336 } 15337 } 15338 } 15339 } 15340 15341 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15342 if (app.foregroundServices) { 15343 // The user is aware of this app, so make it visible. 15344 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15345 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15346 app.cached = false; 15347 app.adjType = "fg-service"; 15348 schedGroup = Process.THREAD_GROUP_DEFAULT; 15349 } else if (app.forcingToForeground != null) { 15350 // The user is aware of this app, so make it visible. 15351 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15352 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15353 app.cached = false; 15354 app.adjType = "force-fg"; 15355 app.adjSource = app.forcingToForeground; 15356 schedGroup = Process.THREAD_GROUP_DEFAULT; 15357 } 15358 } 15359 15360 if (app == mHeavyWeightProcess) { 15361 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15362 // We don't want to kill the current heavy-weight process. 15363 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15364 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15365 app.cached = false; 15366 app.adjType = "heavy"; 15367 } 15368 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15369 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15370 } 15371 } 15372 15373 if (app == mHomeProcess) { 15374 if (adj > ProcessList.HOME_APP_ADJ) { 15375 // This process is hosting what we currently consider to be the 15376 // home app, so we don't want to let it go into the background. 15377 adj = ProcessList.HOME_APP_ADJ; 15378 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15379 app.cached = false; 15380 app.adjType = "home"; 15381 } 15382 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15383 procState = ActivityManager.PROCESS_STATE_HOME; 15384 } 15385 } 15386 15387 if (app == mPreviousProcess && app.activities.size() > 0) { 15388 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15389 // This was the previous process that showed UI to the user. 15390 // We want to try to keep it around more aggressively, to give 15391 // a good experience around switching between two apps. 15392 adj = ProcessList.PREVIOUS_APP_ADJ; 15393 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15394 app.cached = false; 15395 app.adjType = "previous"; 15396 } 15397 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15398 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15399 } 15400 } 15401 15402 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15403 + " reason=" + app.adjType); 15404 15405 // By default, we use the computed adjustment. It may be changed if 15406 // there are applications dependent on our services or providers, but 15407 // this gives us a baseline and makes sure we don't get into an 15408 // infinite recursion. 15409 app.adjSeq = mAdjSeq; 15410 app.curRawAdj = adj; 15411 app.hasStartedServices = false; 15412 15413 if (mBackupTarget != null && app == mBackupTarget.app) { 15414 // If possible we want to avoid killing apps while they're being backed up 15415 if (adj > ProcessList.BACKUP_APP_ADJ) { 15416 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15417 adj = ProcessList.BACKUP_APP_ADJ; 15418 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15419 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15420 } 15421 app.adjType = "backup"; 15422 app.cached = false; 15423 } 15424 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15425 procState = ActivityManager.PROCESS_STATE_BACKUP; 15426 } 15427 } 15428 15429 boolean mayBeTop = false; 15430 15431 for (int is = app.services.size()-1; 15432 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15433 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15434 || procState > ActivityManager.PROCESS_STATE_TOP); 15435 is--) { 15436 ServiceRecord s = app.services.valueAt(is); 15437 if (s.startRequested) { 15438 app.hasStartedServices = true; 15439 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15440 procState = ActivityManager.PROCESS_STATE_SERVICE; 15441 } 15442 if (app.hasShownUi && app != mHomeProcess) { 15443 // If this process has shown some UI, let it immediately 15444 // go to the LRU list because it may be pretty heavy with 15445 // UI stuff. We'll tag it with a label just to help 15446 // debug and understand what is going on. 15447 if (adj > ProcessList.SERVICE_ADJ) { 15448 app.adjType = "cch-started-ui-services"; 15449 } 15450 } else { 15451 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15452 // This service has seen some activity within 15453 // recent memory, so we will keep its process ahead 15454 // of the background processes. 15455 if (adj > ProcessList.SERVICE_ADJ) { 15456 adj = ProcessList.SERVICE_ADJ; 15457 app.adjType = "started-services"; 15458 app.cached = false; 15459 } 15460 } 15461 // If we have let the service slide into the background 15462 // state, still have some text describing what it is doing 15463 // even though the service no longer has an impact. 15464 if (adj > ProcessList.SERVICE_ADJ) { 15465 app.adjType = "cch-started-services"; 15466 } 15467 } 15468 } 15469 for (int conni = s.connections.size()-1; 15470 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15471 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15472 || procState > ActivityManager.PROCESS_STATE_TOP); 15473 conni--) { 15474 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15475 for (int i = 0; 15476 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15477 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15478 || procState > ActivityManager.PROCESS_STATE_TOP); 15479 i++) { 15480 // XXX should compute this based on the max of 15481 // all connected clients. 15482 ConnectionRecord cr = clist.get(i); 15483 if (cr.binding.client == app) { 15484 // Binding to ourself is not interesting. 15485 continue; 15486 } 15487 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15488 ProcessRecord client = cr.binding.client; 15489 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15490 TOP_APP, doingAll, now); 15491 int clientProcState = client.curProcState; 15492 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15493 // If the other app is cached for any reason, for purposes here 15494 // we are going to consider it empty. The specific cached state 15495 // doesn't propagate except under certain conditions. 15496 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15497 } 15498 String adjType = null; 15499 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15500 // Not doing bind OOM management, so treat 15501 // this guy more like a started service. 15502 if (app.hasShownUi && app != mHomeProcess) { 15503 // If this process has shown some UI, let it immediately 15504 // go to the LRU list because it may be pretty heavy with 15505 // UI stuff. We'll tag it with a label just to help 15506 // debug and understand what is going on. 15507 if (adj > clientAdj) { 15508 adjType = "cch-bound-ui-services"; 15509 } 15510 app.cached = false; 15511 clientAdj = adj; 15512 clientProcState = procState; 15513 } else { 15514 if (now >= (s.lastActivity 15515 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15516 // This service has not seen activity within 15517 // recent memory, so allow it to drop to the 15518 // LRU list if there is no other reason to keep 15519 // it around. We'll also tag it with a label just 15520 // to help debug and undertand what is going on. 15521 if (adj > clientAdj) { 15522 adjType = "cch-bound-services"; 15523 } 15524 clientAdj = adj; 15525 } 15526 } 15527 } 15528 if (adj > clientAdj) { 15529 // If this process has recently shown UI, and 15530 // the process that is binding to it is less 15531 // important than being visible, then we don't 15532 // care about the binding as much as we care 15533 // about letting this process get into the LRU 15534 // list to be killed and restarted if needed for 15535 // memory. 15536 if (app.hasShownUi && app != mHomeProcess 15537 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15538 adjType = "cch-bound-ui-services"; 15539 } else { 15540 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15541 |Context.BIND_IMPORTANT)) != 0) { 15542 adj = clientAdj; 15543 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15544 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15545 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15546 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15547 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15548 adj = clientAdj; 15549 } else { 15550 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15551 adj = ProcessList.VISIBLE_APP_ADJ; 15552 } 15553 } 15554 if (!client.cached) { 15555 app.cached = false; 15556 } 15557 adjType = "service"; 15558 } 15559 } 15560 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15561 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15562 schedGroup = Process.THREAD_GROUP_DEFAULT; 15563 } 15564 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15565 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15566 // Special handling of clients who are in the top state. 15567 // We *may* want to consider this process to be in the 15568 // top state as well, but only if there is not another 15569 // reason for it to be running. Being on the top is a 15570 // special state, meaning you are specifically running 15571 // for the current top app. If the process is already 15572 // running in the background for some other reason, it 15573 // is more important to continue considering it to be 15574 // in the background state. 15575 mayBeTop = true; 15576 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15577 } else { 15578 // Special handling for above-top states (persistent 15579 // processes). These should not bring the current process 15580 // into the top state, since they are not on top. Instead 15581 // give them the best state after that. 15582 clientProcState = 15583 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15584 } 15585 } 15586 } else { 15587 if (clientProcState < 15588 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15589 clientProcState = 15590 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15591 } 15592 } 15593 if (procState > clientProcState) { 15594 procState = clientProcState; 15595 } 15596 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15597 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15598 app.pendingUiClean = true; 15599 } 15600 if (adjType != null) { 15601 app.adjType = adjType; 15602 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15603 .REASON_SERVICE_IN_USE; 15604 app.adjSource = cr.binding.client; 15605 app.adjSourceProcState = clientProcState; 15606 app.adjTarget = s.name; 15607 } 15608 } 15609 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15610 app.treatLikeActivity = true; 15611 } 15612 final ActivityRecord a = cr.activity; 15613 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15614 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15615 (a.visible || a.state == ActivityState.RESUMED 15616 || a.state == ActivityState.PAUSING)) { 15617 adj = ProcessList.FOREGROUND_APP_ADJ; 15618 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15619 schedGroup = Process.THREAD_GROUP_DEFAULT; 15620 } 15621 app.cached = false; 15622 app.adjType = "service"; 15623 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15624 .REASON_SERVICE_IN_USE; 15625 app.adjSource = a; 15626 app.adjSourceProcState = procState; 15627 app.adjTarget = s.name; 15628 } 15629 } 15630 } 15631 } 15632 } 15633 15634 for (int provi = app.pubProviders.size()-1; 15635 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15636 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15637 || procState > ActivityManager.PROCESS_STATE_TOP); 15638 provi--) { 15639 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15640 for (int i = cpr.connections.size()-1; 15641 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15642 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15643 || procState > ActivityManager.PROCESS_STATE_TOP); 15644 i--) { 15645 ContentProviderConnection conn = cpr.connections.get(i); 15646 ProcessRecord client = conn.client; 15647 if (client == app) { 15648 // Being our own client is not interesting. 15649 continue; 15650 } 15651 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15652 int clientProcState = client.curProcState; 15653 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15654 // If the other app is cached for any reason, for purposes here 15655 // we are going to consider it empty. 15656 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15657 } 15658 if (adj > clientAdj) { 15659 if (app.hasShownUi && app != mHomeProcess 15660 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15661 app.adjType = "cch-ui-provider"; 15662 } else { 15663 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15664 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15665 app.adjType = "provider"; 15666 } 15667 app.cached &= client.cached; 15668 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15669 .REASON_PROVIDER_IN_USE; 15670 app.adjSource = client; 15671 app.adjSourceProcState = clientProcState; 15672 app.adjTarget = cpr.name; 15673 } 15674 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15675 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15676 // Special handling of clients who are in the top state. 15677 // We *may* want to consider this process to be in the 15678 // top state as well, but only if there is not another 15679 // reason for it to be running. Being on the top is a 15680 // special state, meaning you are specifically running 15681 // for the current top app. If the process is already 15682 // running in the background for some other reason, it 15683 // is more important to continue considering it to be 15684 // in the background state. 15685 mayBeTop = true; 15686 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15687 } else { 15688 // Special handling for above-top states (persistent 15689 // processes). These should not bring the current process 15690 // into the top state, since they are not on top. Instead 15691 // give them the best state after that. 15692 clientProcState = 15693 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15694 } 15695 } 15696 if (procState > clientProcState) { 15697 procState = clientProcState; 15698 } 15699 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15700 schedGroup = Process.THREAD_GROUP_DEFAULT; 15701 } 15702 } 15703 // If the provider has external (non-framework) process 15704 // dependencies, ensure that its adjustment is at least 15705 // FOREGROUND_APP_ADJ. 15706 if (cpr.hasExternalProcessHandles()) { 15707 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15708 adj = ProcessList.FOREGROUND_APP_ADJ; 15709 schedGroup = Process.THREAD_GROUP_DEFAULT; 15710 app.cached = false; 15711 app.adjType = "provider"; 15712 app.adjTarget = cpr.name; 15713 } 15714 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15715 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15716 } 15717 } 15718 } 15719 15720 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15721 // A client of one of our services or providers is in the top state. We 15722 // *may* want to be in the top state, but not if we are already running in 15723 // the background for some other reason. For the decision here, we are going 15724 // to pick out a few specific states that we want to remain in when a client 15725 // is top (states that tend to be longer-term) and otherwise allow it to go 15726 // to the top state. 15727 switch (procState) { 15728 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15729 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15730 case ActivityManager.PROCESS_STATE_SERVICE: 15731 // These all are longer-term states, so pull them up to the top 15732 // of the background states, but not all the way to the top state. 15733 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15734 break; 15735 default: 15736 // Otherwise, top is a better choice, so take it. 15737 procState = ActivityManager.PROCESS_STATE_TOP; 15738 break; 15739 } 15740 } 15741 15742 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15743 if (app.hasClientActivities) { 15744 // This is a cached process, but with client activities. Mark it so. 15745 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15746 app.adjType = "cch-client-act"; 15747 } else if (app.treatLikeActivity) { 15748 // This is a cached process, but somebody wants us to treat it like it has 15749 // an activity, okay! 15750 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15751 app.adjType = "cch-as-act"; 15752 } 15753 } 15754 15755 if (adj == ProcessList.SERVICE_ADJ) { 15756 if (doingAll) { 15757 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15758 mNewNumServiceProcs++; 15759 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15760 if (!app.serviceb) { 15761 // This service isn't far enough down on the LRU list to 15762 // normally be a B service, but if we are low on RAM and it 15763 // is large we want to force it down since we would prefer to 15764 // keep launcher over it. 15765 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15766 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15767 app.serviceHighRam = true; 15768 app.serviceb = true; 15769 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15770 } else { 15771 mNewNumAServiceProcs++; 15772 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15773 } 15774 } else { 15775 app.serviceHighRam = false; 15776 } 15777 } 15778 if (app.serviceb) { 15779 adj = ProcessList.SERVICE_B_ADJ; 15780 } 15781 } 15782 15783 app.curRawAdj = adj; 15784 15785 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15786 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15787 if (adj > app.maxAdj) { 15788 adj = app.maxAdj; 15789 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15790 schedGroup = Process.THREAD_GROUP_DEFAULT; 15791 } 15792 } 15793 15794 // Do final modification to adj. Everything we do between here and applying 15795 // the final setAdj must be done in this function, because we will also use 15796 // it when computing the final cached adj later. Note that we don't need to 15797 // worry about this for max adj above, since max adj will always be used to 15798 // keep it out of the cached vaues. 15799 app.curAdj = app.modifyRawOomAdj(adj); 15800 app.curSchedGroup = schedGroup; 15801 app.curProcState = procState; 15802 app.foregroundActivities = foregroundActivities; 15803 15804 return app.curRawAdj; 15805 } 15806 15807 /** 15808 * Schedule PSS collection of a process. 15809 */ 15810 void requestPssLocked(ProcessRecord proc, int procState) { 15811 if (mPendingPssProcesses.contains(proc)) { 15812 return; 15813 } 15814 if (mPendingPssProcesses.size() == 0) { 15815 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15816 } 15817 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15818 proc.pssProcState = procState; 15819 mPendingPssProcesses.add(proc); 15820 } 15821 15822 /** 15823 * Schedule PSS collection of all processes. 15824 */ 15825 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15826 if (!always) { 15827 if (now < (mLastFullPssTime + 15828 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15829 return; 15830 } 15831 } 15832 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15833 mLastFullPssTime = now; 15834 mFullPssPending = true; 15835 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15836 mPendingPssProcesses.clear(); 15837 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15838 ProcessRecord app = mLruProcesses.get(i); 15839 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15840 app.pssProcState = app.setProcState; 15841 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15842 isSleeping(), now); 15843 mPendingPssProcesses.add(app); 15844 } 15845 } 15846 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15847 } 15848 15849 /** 15850 * Ask a given process to GC right now. 15851 */ 15852 final void performAppGcLocked(ProcessRecord app) { 15853 try { 15854 app.lastRequestedGc = SystemClock.uptimeMillis(); 15855 if (app.thread != null) { 15856 if (app.reportLowMemory) { 15857 app.reportLowMemory = false; 15858 app.thread.scheduleLowMemory(); 15859 } else { 15860 app.thread.processInBackground(); 15861 } 15862 } 15863 } catch (Exception e) { 15864 // whatever. 15865 } 15866 } 15867 15868 /** 15869 * Returns true if things are idle enough to perform GCs. 15870 */ 15871 private final boolean canGcNowLocked() { 15872 boolean processingBroadcasts = false; 15873 for (BroadcastQueue q : mBroadcastQueues) { 15874 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15875 processingBroadcasts = true; 15876 } 15877 } 15878 return !processingBroadcasts 15879 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15880 } 15881 15882 /** 15883 * Perform GCs on all processes that are waiting for it, but only 15884 * if things are idle. 15885 */ 15886 final void performAppGcsLocked() { 15887 final int N = mProcessesToGc.size(); 15888 if (N <= 0) { 15889 return; 15890 } 15891 if (canGcNowLocked()) { 15892 while (mProcessesToGc.size() > 0) { 15893 ProcessRecord proc = mProcessesToGc.remove(0); 15894 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15895 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15896 <= SystemClock.uptimeMillis()) { 15897 // To avoid spamming the system, we will GC processes one 15898 // at a time, waiting a few seconds between each. 15899 performAppGcLocked(proc); 15900 scheduleAppGcsLocked(); 15901 return; 15902 } else { 15903 // It hasn't been long enough since we last GCed this 15904 // process... put it in the list to wait for its time. 15905 addProcessToGcListLocked(proc); 15906 break; 15907 } 15908 } 15909 } 15910 15911 scheduleAppGcsLocked(); 15912 } 15913 } 15914 15915 /** 15916 * If all looks good, perform GCs on all processes waiting for them. 15917 */ 15918 final void performAppGcsIfAppropriateLocked() { 15919 if (canGcNowLocked()) { 15920 performAppGcsLocked(); 15921 return; 15922 } 15923 // Still not idle, wait some more. 15924 scheduleAppGcsLocked(); 15925 } 15926 15927 /** 15928 * Schedule the execution of all pending app GCs. 15929 */ 15930 final void scheduleAppGcsLocked() { 15931 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15932 15933 if (mProcessesToGc.size() > 0) { 15934 // Schedule a GC for the time to the next process. 15935 ProcessRecord proc = mProcessesToGc.get(0); 15936 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15937 15938 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15939 long now = SystemClock.uptimeMillis(); 15940 if (when < (now+GC_TIMEOUT)) { 15941 when = now + GC_TIMEOUT; 15942 } 15943 mHandler.sendMessageAtTime(msg, when); 15944 } 15945 } 15946 15947 /** 15948 * Add a process to the array of processes waiting to be GCed. Keeps the 15949 * list in sorted order by the last GC time. The process can't already be 15950 * on the list. 15951 */ 15952 final void addProcessToGcListLocked(ProcessRecord proc) { 15953 boolean added = false; 15954 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15955 if (mProcessesToGc.get(i).lastRequestedGc < 15956 proc.lastRequestedGc) { 15957 added = true; 15958 mProcessesToGc.add(i+1, proc); 15959 break; 15960 } 15961 } 15962 if (!added) { 15963 mProcessesToGc.add(0, proc); 15964 } 15965 } 15966 15967 /** 15968 * Set up to ask a process to GC itself. This will either do it 15969 * immediately, or put it on the list of processes to gc the next 15970 * time things are idle. 15971 */ 15972 final void scheduleAppGcLocked(ProcessRecord app) { 15973 long now = SystemClock.uptimeMillis(); 15974 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15975 return; 15976 } 15977 if (!mProcessesToGc.contains(app)) { 15978 addProcessToGcListLocked(app); 15979 scheduleAppGcsLocked(); 15980 } 15981 } 15982 15983 final void checkExcessivePowerUsageLocked(boolean doKills) { 15984 updateCpuStatsNow(); 15985 15986 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15987 boolean doWakeKills = doKills; 15988 boolean doCpuKills = doKills; 15989 if (mLastPowerCheckRealtime == 0) { 15990 doWakeKills = false; 15991 } 15992 if (mLastPowerCheckUptime == 0) { 15993 doCpuKills = false; 15994 } 15995 if (stats.isScreenOn()) { 15996 doWakeKills = false; 15997 } 15998 final long curRealtime = SystemClock.elapsedRealtime(); 15999 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16000 final long curUptime = SystemClock.uptimeMillis(); 16001 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16002 mLastPowerCheckRealtime = curRealtime; 16003 mLastPowerCheckUptime = curUptime; 16004 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16005 doWakeKills = false; 16006 } 16007 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16008 doCpuKills = false; 16009 } 16010 int i = mLruProcesses.size(); 16011 while (i > 0) { 16012 i--; 16013 ProcessRecord app = mLruProcesses.get(i); 16014 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16015 long wtime; 16016 synchronized (stats) { 16017 wtime = stats.getProcessWakeTime(app.info.uid, 16018 app.pid, curRealtime); 16019 } 16020 long wtimeUsed = wtime - app.lastWakeTime; 16021 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16022 if (DEBUG_POWER) { 16023 StringBuilder sb = new StringBuilder(128); 16024 sb.append("Wake for "); 16025 app.toShortString(sb); 16026 sb.append(": over "); 16027 TimeUtils.formatDuration(realtimeSince, sb); 16028 sb.append(" used "); 16029 TimeUtils.formatDuration(wtimeUsed, sb); 16030 sb.append(" ("); 16031 sb.append((wtimeUsed*100)/realtimeSince); 16032 sb.append("%)"); 16033 Slog.i(TAG, sb.toString()); 16034 sb.setLength(0); 16035 sb.append("CPU for "); 16036 app.toShortString(sb); 16037 sb.append(": over "); 16038 TimeUtils.formatDuration(uptimeSince, sb); 16039 sb.append(" used "); 16040 TimeUtils.formatDuration(cputimeUsed, sb); 16041 sb.append(" ("); 16042 sb.append((cputimeUsed*100)/uptimeSince); 16043 sb.append("%)"); 16044 Slog.i(TAG, sb.toString()); 16045 } 16046 // If a process has held a wake lock for more 16047 // than 50% of the time during this period, 16048 // that sounds bad. Kill! 16049 if (doWakeKills && realtimeSince > 0 16050 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16051 synchronized (stats) { 16052 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16053 realtimeSince, wtimeUsed); 16054 } 16055 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16056 + " during " + realtimeSince); 16057 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16058 } else if (doCpuKills && uptimeSince > 0 16059 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16060 synchronized (stats) { 16061 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16062 uptimeSince, cputimeUsed); 16063 } 16064 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16065 + " during " + uptimeSince); 16066 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16067 } else { 16068 app.lastWakeTime = wtime; 16069 app.lastCpuTime = app.curCpuTime; 16070 } 16071 } 16072 } 16073 } 16074 16075 private final boolean applyOomAdjLocked(ProcessRecord app, 16076 ProcessRecord TOP_APP, boolean doingAll, long now) { 16077 boolean success = true; 16078 16079 if (app.curRawAdj != app.setRawAdj) { 16080 app.setRawAdj = app.curRawAdj; 16081 } 16082 16083 int changes = 0; 16084 16085 if (app.curAdj != app.setAdj) { 16086 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16087 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16088 TAG, "Set " + app.pid + " " + app.processName + 16089 " adj " + app.curAdj + ": " + app.adjType); 16090 app.setAdj = app.curAdj; 16091 } 16092 16093 if (app.setSchedGroup != app.curSchedGroup) { 16094 app.setSchedGroup = app.curSchedGroup; 16095 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16096 "Setting process group of " + app.processName 16097 + " to " + app.curSchedGroup); 16098 if (app.waitingToKill != null && 16099 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16100 killUnneededProcessLocked(app, app.waitingToKill); 16101 success = false; 16102 } else { 16103 if (true) { 16104 long oldId = Binder.clearCallingIdentity(); 16105 try { 16106 Process.setProcessGroup(app.pid, app.curSchedGroup); 16107 } catch (Exception e) { 16108 Slog.w(TAG, "Failed setting process group of " + app.pid 16109 + " to " + app.curSchedGroup); 16110 e.printStackTrace(); 16111 } finally { 16112 Binder.restoreCallingIdentity(oldId); 16113 } 16114 } else { 16115 if (app.thread != null) { 16116 try { 16117 app.thread.setSchedulingGroup(app.curSchedGroup); 16118 } catch (RemoteException e) { 16119 } 16120 } 16121 } 16122 Process.setSwappiness(app.pid, 16123 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16124 } 16125 } 16126 if (app.repForegroundActivities != app.foregroundActivities) { 16127 app.repForegroundActivities = app.foregroundActivities; 16128 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16129 } 16130 if (app.repProcState != app.curProcState) { 16131 app.repProcState = app.curProcState; 16132 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16133 if (app.thread != null) { 16134 try { 16135 if (false) { 16136 //RuntimeException h = new RuntimeException("here"); 16137 Slog.i(TAG, "Sending new process state " + app.repProcState 16138 + " to " + app /*, h*/); 16139 } 16140 app.thread.setProcessState(app.repProcState); 16141 } catch (RemoteException e) { 16142 } 16143 } 16144 } 16145 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16146 app.setProcState)) { 16147 app.lastStateTime = now; 16148 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16149 isSleeping(), now); 16150 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16151 + ProcessList.makeProcStateString(app.setProcState) + " to " 16152 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16153 + (app.nextPssTime-now) + ": " + app); 16154 } else { 16155 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16156 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16157 requestPssLocked(app, app.setProcState); 16158 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16159 isSleeping(), now); 16160 } else if (false && DEBUG_PSS) { 16161 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16162 } 16163 } 16164 if (app.setProcState != app.curProcState) { 16165 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16166 "Proc state change of " + app.processName 16167 + " to " + app.curProcState); 16168 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16169 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16170 if (setImportant && !curImportant) { 16171 // This app is no longer something we consider important enough to allow to 16172 // use arbitrary amounts of battery power. Note 16173 // its current wake lock time to later know to kill it if 16174 // it is not behaving well. 16175 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16176 synchronized (stats) { 16177 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16178 app.pid, SystemClock.elapsedRealtime()); 16179 } 16180 app.lastCpuTime = app.curCpuTime; 16181 16182 } 16183 app.setProcState = app.curProcState; 16184 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16185 app.notCachedSinceIdle = false; 16186 } 16187 if (!doingAll) { 16188 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16189 } else { 16190 app.procStateChanged = true; 16191 } 16192 } 16193 16194 if (changes != 0) { 16195 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16196 int i = mPendingProcessChanges.size()-1; 16197 ProcessChangeItem item = null; 16198 while (i >= 0) { 16199 item = mPendingProcessChanges.get(i); 16200 if (item.pid == app.pid) { 16201 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16202 break; 16203 } 16204 i--; 16205 } 16206 if (i < 0) { 16207 // No existing item in pending changes; need a new one. 16208 final int NA = mAvailProcessChanges.size(); 16209 if (NA > 0) { 16210 item = mAvailProcessChanges.remove(NA-1); 16211 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16212 } else { 16213 item = new ProcessChangeItem(); 16214 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16215 } 16216 item.changes = 0; 16217 item.pid = app.pid; 16218 item.uid = app.info.uid; 16219 if (mPendingProcessChanges.size() == 0) { 16220 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16221 "*** Enqueueing dispatch processes changed!"); 16222 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16223 } 16224 mPendingProcessChanges.add(item); 16225 } 16226 item.changes |= changes; 16227 item.processState = app.repProcState; 16228 item.foregroundActivities = app.repForegroundActivities; 16229 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16230 + Integer.toHexString(System.identityHashCode(item)) 16231 + " " + app.toShortString() + ": changes=" + item.changes 16232 + " procState=" + item.processState 16233 + " foreground=" + item.foregroundActivities 16234 + " type=" + app.adjType + " source=" + app.adjSource 16235 + " target=" + app.adjTarget); 16236 } 16237 16238 return success; 16239 } 16240 16241 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16242 if (proc.thread != null) { 16243 if (proc.baseProcessTracker != null) { 16244 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16245 } 16246 if (proc.repProcState >= 0) { 16247 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16248 proc.repProcState); 16249 } 16250 } 16251 } 16252 16253 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16254 ProcessRecord TOP_APP, boolean doingAll, long now) { 16255 if (app.thread == null) { 16256 return false; 16257 } 16258 16259 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16260 16261 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16262 } 16263 16264 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16265 boolean oomAdj) { 16266 if (isForeground != proc.foregroundServices) { 16267 proc.foregroundServices = isForeground; 16268 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16269 proc.info.uid); 16270 if (isForeground) { 16271 if (curProcs == null) { 16272 curProcs = new ArrayList<ProcessRecord>(); 16273 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16274 } 16275 if (!curProcs.contains(proc)) { 16276 curProcs.add(proc); 16277 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16278 proc.info.packageName, proc.info.uid); 16279 } 16280 } else { 16281 if (curProcs != null) { 16282 if (curProcs.remove(proc)) { 16283 mBatteryStatsService.noteEvent( 16284 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16285 proc.info.packageName, proc.info.uid); 16286 if (curProcs.size() <= 0) { 16287 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16288 } 16289 } 16290 } 16291 } 16292 if (oomAdj) { 16293 updateOomAdjLocked(); 16294 } 16295 } 16296 } 16297 16298 private final ActivityRecord resumedAppLocked() { 16299 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16300 String pkg; 16301 int uid; 16302 if (act != null) { 16303 pkg = act.packageName; 16304 uid = act.info.applicationInfo.uid; 16305 } else { 16306 pkg = null; 16307 uid = -1; 16308 } 16309 // Has the UID or resumed package name changed? 16310 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16311 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16312 if (mCurResumedPackage != null) { 16313 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16314 mCurResumedPackage, mCurResumedUid); 16315 } 16316 mCurResumedPackage = pkg; 16317 mCurResumedUid = uid; 16318 if (mCurResumedPackage != null) { 16319 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16320 mCurResumedPackage, mCurResumedUid); 16321 } 16322 } 16323 return act; 16324 } 16325 16326 final boolean updateOomAdjLocked(ProcessRecord app) { 16327 final ActivityRecord TOP_ACT = resumedAppLocked(); 16328 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16329 final boolean wasCached = app.cached; 16330 16331 mAdjSeq++; 16332 16333 // This is the desired cached adjusment we want to tell it to use. 16334 // If our app is currently cached, we know it, and that is it. Otherwise, 16335 // we don't know it yet, and it needs to now be cached we will then 16336 // need to do a complete oom adj. 16337 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16338 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16339 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16340 SystemClock.uptimeMillis()); 16341 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16342 // Changed to/from cached state, so apps after it in the LRU 16343 // list may also be changed. 16344 updateOomAdjLocked(); 16345 } 16346 return success; 16347 } 16348 16349 final void updateOomAdjLocked() { 16350 final ActivityRecord TOP_ACT = resumedAppLocked(); 16351 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16352 final long now = SystemClock.uptimeMillis(); 16353 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16354 final int N = mLruProcesses.size(); 16355 16356 if (false) { 16357 RuntimeException e = new RuntimeException(); 16358 e.fillInStackTrace(); 16359 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16360 } 16361 16362 mAdjSeq++; 16363 mNewNumServiceProcs = 0; 16364 mNewNumAServiceProcs = 0; 16365 16366 final int emptyProcessLimit; 16367 final int cachedProcessLimit; 16368 if (mProcessLimit <= 0) { 16369 emptyProcessLimit = cachedProcessLimit = 0; 16370 } else if (mProcessLimit == 1) { 16371 emptyProcessLimit = 1; 16372 cachedProcessLimit = 0; 16373 } else { 16374 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16375 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16376 } 16377 16378 // Let's determine how many processes we have running vs. 16379 // how many slots we have for background processes; we may want 16380 // to put multiple processes in a slot of there are enough of 16381 // them. 16382 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16383 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16384 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16385 if (numEmptyProcs > cachedProcessLimit) { 16386 // If there are more empty processes than our limit on cached 16387 // processes, then use the cached process limit for the factor. 16388 // This ensures that the really old empty processes get pushed 16389 // down to the bottom, so if we are running low on memory we will 16390 // have a better chance at keeping around more cached processes 16391 // instead of a gazillion empty processes. 16392 numEmptyProcs = cachedProcessLimit; 16393 } 16394 int emptyFactor = numEmptyProcs/numSlots; 16395 if (emptyFactor < 1) emptyFactor = 1; 16396 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16397 if (cachedFactor < 1) cachedFactor = 1; 16398 int stepCached = 0; 16399 int stepEmpty = 0; 16400 int numCached = 0; 16401 int numEmpty = 0; 16402 int numTrimming = 0; 16403 16404 mNumNonCachedProcs = 0; 16405 mNumCachedHiddenProcs = 0; 16406 16407 // First update the OOM adjustment for each of the 16408 // application processes based on their current state. 16409 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16410 int nextCachedAdj = curCachedAdj+1; 16411 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16412 int nextEmptyAdj = curEmptyAdj+2; 16413 for (int i=N-1; i>=0; i--) { 16414 ProcessRecord app = mLruProcesses.get(i); 16415 if (!app.killedByAm && app.thread != null) { 16416 app.procStateChanged = false; 16417 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16418 16419 // If we haven't yet assigned the final cached adj 16420 // to the process, do that now. 16421 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16422 switch (app.curProcState) { 16423 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16424 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16425 // This process is a cached process holding activities... 16426 // assign it the next cached value for that type, and then 16427 // step that cached level. 16428 app.curRawAdj = curCachedAdj; 16429 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16430 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16431 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16432 + ")"); 16433 if (curCachedAdj != nextCachedAdj) { 16434 stepCached++; 16435 if (stepCached >= cachedFactor) { 16436 stepCached = 0; 16437 curCachedAdj = nextCachedAdj; 16438 nextCachedAdj += 2; 16439 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16440 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16441 } 16442 } 16443 } 16444 break; 16445 default: 16446 // For everything else, assign next empty cached process 16447 // level and bump that up. Note that this means that 16448 // long-running services that have dropped down to the 16449 // cached level will be treated as empty (since their process 16450 // state is still as a service), which is what we want. 16451 app.curRawAdj = curEmptyAdj; 16452 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16453 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16454 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16455 + ")"); 16456 if (curEmptyAdj != nextEmptyAdj) { 16457 stepEmpty++; 16458 if (stepEmpty >= emptyFactor) { 16459 stepEmpty = 0; 16460 curEmptyAdj = nextEmptyAdj; 16461 nextEmptyAdj += 2; 16462 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16463 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16464 } 16465 } 16466 } 16467 break; 16468 } 16469 } 16470 16471 applyOomAdjLocked(app, TOP_APP, true, now); 16472 16473 // Count the number of process types. 16474 switch (app.curProcState) { 16475 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16476 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16477 mNumCachedHiddenProcs++; 16478 numCached++; 16479 if (numCached > cachedProcessLimit) { 16480 killUnneededProcessLocked(app, "cached #" + numCached); 16481 } 16482 break; 16483 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16484 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16485 && app.lastActivityTime < oldTime) { 16486 killUnneededProcessLocked(app, "empty for " 16487 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16488 / 1000) + "s"); 16489 } else { 16490 numEmpty++; 16491 if (numEmpty > emptyProcessLimit) { 16492 killUnneededProcessLocked(app, "empty #" + numEmpty); 16493 } 16494 } 16495 break; 16496 default: 16497 mNumNonCachedProcs++; 16498 break; 16499 } 16500 16501 if (app.isolated && app.services.size() <= 0) { 16502 // If this is an isolated process, and there are no 16503 // services running in it, then the process is no longer 16504 // needed. We agressively kill these because we can by 16505 // definition not re-use the same process again, and it is 16506 // good to avoid having whatever code was running in them 16507 // left sitting around after no longer needed. 16508 killUnneededProcessLocked(app, "isolated not needed"); 16509 } 16510 16511 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16512 && !app.killedByAm) { 16513 numTrimming++; 16514 } 16515 } 16516 } 16517 16518 mNumServiceProcs = mNewNumServiceProcs; 16519 16520 // Now determine the memory trimming level of background processes. 16521 // Unfortunately we need to start at the back of the list to do this 16522 // properly. We only do this if the number of background apps we 16523 // are managing to keep around is less than half the maximum we desire; 16524 // if we are keeping a good number around, we'll let them use whatever 16525 // memory they want. 16526 final int numCachedAndEmpty = numCached + numEmpty; 16527 int memFactor; 16528 if (numCached <= ProcessList.TRIM_CACHED_APPS 16529 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16530 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16531 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16532 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16533 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16534 } else { 16535 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16536 } 16537 } else { 16538 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16539 } 16540 // We always allow the memory level to go up (better). We only allow it to go 16541 // down if we are in a state where that is allowed, *and* the total number of processes 16542 // has gone down since last time. 16543 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16544 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16545 + " last=" + mLastNumProcesses); 16546 if (memFactor > mLastMemoryLevel) { 16547 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16548 memFactor = mLastMemoryLevel; 16549 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16550 } 16551 } 16552 mLastMemoryLevel = memFactor; 16553 mLastNumProcesses = mLruProcesses.size(); 16554 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16555 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16556 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16557 if (mLowRamStartTime == 0) { 16558 mLowRamStartTime = now; 16559 } 16560 int step = 0; 16561 int fgTrimLevel; 16562 switch (memFactor) { 16563 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16564 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16565 break; 16566 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16567 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16568 break; 16569 default: 16570 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16571 break; 16572 } 16573 int factor = numTrimming/3; 16574 int minFactor = 2; 16575 if (mHomeProcess != null) minFactor++; 16576 if (mPreviousProcess != null) minFactor++; 16577 if (factor < minFactor) factor = minFactor; 16578 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16579 for (int i=N-1; i>=0; i--) { 16580 ProcessRecord app = mLruProcesses.get(i); 16581 if (allChanged || app.procStateChanged) { 16582 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16583 app.procStateChanged = false; 16584 } 16585 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16586 && !app.killedByAm) { 16587 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16588 try { 16589 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16590 "Trimming memory of " + app.processName 16591 + " to " + curLevel); 16592 app.thread.scheduleTrimMemory(curLevel); 16593 } catch (RemoteException e) { 16594 } 16595 if (false) { 16596 // For now we won't do this; our memory trimming seems 16597 // to be good enough at this point that destroying 16598 // activities causes more harm than good. 16599 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16600 && app != mHomeProcess && app != mPreviousProcess) { 16601 // Need to do this on its own message because the stack may not 16602 // be in a consistent state at this point. 16603 // For these apps we will also finish their activities 16604 // to help them free memory. 16605 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16606 } 16607 } 16608 } 16609 app.trimMemoryLevel = curLevel; 16610 step++; 16611 if (step >= factor) { 16612 step = 0; 16613 switch (curLevel) { 16614 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16615 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16616 break; 16617 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16618 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16619 break; 16620 } 16621 } 16622 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16623 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16624 && app.thread != null) { 16625 try { 16626 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16627 "Trimming memory of heavy-weight " + app.processName 16628 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16629 app.thread.scheduleTrimMemory( 16630 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16631 } catch (RemoteException e) { 16632 } 16633 } 16634 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16635 } else { 16636 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16637 || app.systemNoUi) && app.pendingUiClean) { 16638 // If this application is now in the background and it 16639 // had done UI, then give it the special trim level to 16640 // have it free UI resources. 16641 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16642 if (app.trimMemoryLevel < level && app.thread != null) { 16643 try { 16644 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16645 "Trimming memory of bg-ui " + app.processName 16646 + " to " + level); 16647 app.thread.scheduleTrimMemory(level); 16648 } catch (RemoteException e) { 16649 } 16650 } 16651 app.pendingUiClean = false; 16652 } 16653 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16654 try { 16655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16656 "Trimming memory of fg " + app.processName 16657 + " to " + fgTrimLevel); 16658 app.thread.scheduleTrimMemory(fgTrimLevel); 16659 } catch (RemoteException e) { 16660 } 16661 } 16662 app.trimMemoryLevel = fgTrimLevel; 16663 } 16664 } 16665 } else { 16666 if (mLowRamStartTime != 0) { 16667 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16668 mLowRamStartTime = 0; 16669 } 16670 for (int i=N-1; i>=0; i--) { 16671 ProcessRecord app = mLruProcesses.get(i); 16672 if (allChanged || app.procStateChanged) { 16673 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16674 app.procStateChanged = false; 16675 } 16676 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16677 || app.systemNoUi) && app.pendingUiClean) { 16678 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16679 && app.thread != null) { 16680 try { 16681 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16682 "Trimming memory of ui hidden " + app.processName 16683 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16684 app.thread.scheduleTrimMemory( 16685 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16686 } catch (RemoteException e) { 16687 } 16688 } 16689 app.pendingUiClean = false; 16690 } 16691 app.trimMemoryLevel = 0; 16692 } 16693 } 16694 16695 if (mAlwaysFinishActivities) { 16696 // Need to do this on its own message because the stack may not 16697 // be in a consistent state at this point. 16698 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16699 } 16700 16701 if (allChanged) { 16702 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16703 } 16704 16705 if (mProcessStats.shouldWriteNowLocked(now)) { 16706 mHandler.post(new Runnable() { 16707 @Override public void run() { 16708 synchronized (ActivityManagerService.this) { 16709 mProcessStats.writeStateAsyncLocked(); 16710 } 16711 } 16712 }); 16713 } 16714 16715 if (DEBUG_OOM_ADJ) { 16716 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16717 } 16718 } 16719 16720 final void trimApplications() { 16721 synchronized (this) { 16722 int i; 16723 16724 // First remove any unused application processes whose package 16725 // has been removed. 16726 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16727 final ProcessRecord app = mRemovedProcesses.get(i); 16728 if (app.activities.size() == 0 16729 && app.curReceiver == null && app.services.size() == 0) { 16730 Slog.i( 16731 TAG, "Exiting empty application process " 16732 + app.processName + " (" 16733 + (app.thread != null ? app.thread.asBinder() : null) 16734 + ")\n"); 16735 if (app.pid > 0 && app.pid != MY_PID) { 16736 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16737 app.processName, app.setAdj, "empty"); 16738 app.killedByAm = true; 16739 Process.killProcessQuiet(app.pid); 16740 Process.killProcessGroup(app.info.uid, app.pid); 16741 } else { 16742 try { 16743 app.thread.scheduleExit(); 16744 } catch (Exception e) { 16745 // Ignore exceptions. 16746 } 16747 } 16748 cleanUpApplicationRecordLocked(app, false, true, -1); 16749 mRemovedProcesses.remove(i); 16750 16751 if (app.persistent) { 16752 addAppLocked(app.info, false, null /* ABI override */); 16753 } 16754 } 16755 } 16756 16757 // Now update the oom adj for all processes. 16758 updateOomAdjLocked(); 16759 } 16760 } 16761 16762 /** This method sends the specified signal to each of the persistent apps */ 16763 public void signalPersistentProcesses(int sig) throws RemoteException { 16764 if (sig != Process.SIGNAL_USR1) { 16765 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16766 } 16767 16768 synchronized (this) { 16769 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16770 != PackageManager.PERMISSION_GRANTED) { 16771 throw new SecurityException("Requires permission " 16772 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16773 } 16774 16775 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16776 ProcessRecord r = mLruProcesses.get(i); 16777 if (r.thread != null && r.persistent) { 16778 Process.sendSignal(r.pid, sig); 16779 } 16780 } 16781 } 16782 } 16783 16784 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16785 if (proc == null || proc == mProfileProc) { 16786 proc = mProfileProc; 16787 path = mProfileFile; 16788 profileType = mProfileType; 16789 clearProfilerLocked(); 16790 } 16791 if (proc == null) { 16792 return; 16793 } 16794 try { 16795 proc.thread.profilerControl(false, path, null, profileType); 16796 } catch (RemoteException e) { 16797 throw new IllegalStateException("Process disappeared"); 16798 } 16799 } 16800 16801 private void clearProfilerLocked() { 16802 if (mProfileFd != null) { 16803 try { 16804 mProfileFd.close(); 16805 } catch (IOException e) { 16806 } 16807 } 16808 mProfileApp = null; 16809 mProfileProc = null; 16810 mProfileFile = null; 16811 mProfileType = 0; 16812 mAutoStopProfiler = false; 16813 } 16814 16815 public boolean profileControl(String process, int userId, boolean start, 16816 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16817 16818 try { 16819 synchronized (this) { 16820 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16821 // its own permission. 16822 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16823 != PackageManager.PERMISSION_GRANTED) { 16824 throw new SecurityException("Requires permission " 16825 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16826 } 16827 16828 if (start && fd == null) { 16829 throw new IllegalArgumentException("null fd"); 16830 } 16831 16832 ProcessRecord proc = null; 16833 if (process != null) { 16834 proc = findProcessLocked(process, userId, "profileControl"); 16835 } 16836 16837 if (start && (proc == null || proc.thread == null)) { 16838 throw new IllegalArgumentException("Unknown process: " + process); 16839 } 16840 16841 if (start) { 16842 stopProfilerLocked(null, null, 0); 16843 setProfileApp(proc.info, proc.processName, path, fd, false); 16844 mProfileProc = proc; 16845 mProfileType = profileType; 16846 try { 16847 fd = fd.dup(); 16848 } catch (IOException e) { 16849 fd = null; 16850 } 16851 proc.thread.profilerControl(start, path, fd, profileType); 16852 fd = null; 16853 mProfileFd = null; 16854 } else { 16855 stopProfilerLocked(proc, path, profileType); 16856 if (fd != null) { 16857 try { 16858 fd.close(); 16859 } catch (IOException e) { 16860 } 16861 } 16862 } 16863 16864 return true; 16865 } 16866 } catch (RemoteException e) { 16867 throw new IllegalStateException("Process disappeared"); 16868 } finally { 16869 if (fd != null) { 16870 try { 16871 fd.close(); 16872 } catch (IOException e) { 16873 } 16874 } 16875 } 16876 } 16877 16878 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16879 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16880 userId, true, ALLOW_FULL_ONLY, callName, null); 16881 ProcessRecord proc = null; 16882 try { 16883 int pid = Integer.parseInt(process); 16884 synchronized (mPidsSelfLocked) { 16885 proc = mPidsSelfLocked.get(pid); 16886 } 16887 } catch (NumberFormatException e) { 16888 } 16889 16890 if (proc == null) { 16891 ArrayMap<String, SparseArray<ProcessRecord>> all 16892 = mProcessNames.getMap(); 16893 SparseArray<ProcessRecord> procs = all.get(process); 16894 if (procs != null && procs.size() > 0) { 16895 proc = procs.valueAt(0); 16896 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16897 for (int i=1; i<procs.size(); i++) { 16898 ProcessRecord thisProc = procs.valueAt(i); 16899 if (thisProc.userId == userId) { 16900 proc = thisProc; 16901 break; 16902 } 16903 } 16904 } 16905 } 16906 } 16907 16908 return proc; 16909 } 16910 16911 public boolean dumpHeap(String process, int userId, boolean managed, 16912 String path, ParcelFileDescriptor fd) throws RemoteException { 16913 16914 try { 16915 synchronized (this) { 16916 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16917 // its own permission (same as profileControl). 16918 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16919 != PackageManager.PERMISSION_GRANTED) { 16920 throw new SecurityException("Requires permission " 16921 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16922 } 16923 16924 if (fd == null) { 16925 throw new IllegalArgumentException("null fd"); 16926 } 16927 16928 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16929 if (proc == null || proc.thread == null) { 16930 throw new IllegalArgumentException("Unknown process: " + process); 16931 } 16932 16933 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16934 if (!isDebuggable) { 16935 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16936 throw new SecurityException("Process not debuggable: " + proc); 16937 } 16938 } 16939 16940 proc.thread.dumpHeap(managed, path, fd); 16941 fd = null; 16942 return true; 16943 } 16944 } catch (RemoteException e) { 16945 throw new IllegalStateException("Process disappeared"); 16946 } finally { 16947 if (fd != null) { 16948 try { 16949 fd.close(); 16950 } catch (IOException e) { 16951 } 16952 } 16953 } 16954 } 16955 16956 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16957 public void monitor() { 16958 synchronized (this) { } 16959 } 16960 16961 void onCoreSettingsChange(Bundle settings) { 16962 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16963 ProcessRecord processRecord = mLruProcesses.get(i); 16964 try { 16965 if (processRecord.thread != null) { 16966 processRecord.thread.setCoreSettings(settings); 16967 } 16968 } catch (RemoteException re) { 16969 /* ignore */ 16970 } 16971 } 16972 } 16973 16974 // Multi-user methods 16975 16976 /** 16977 * Start user, if its not already running, but don't bring it to foreground. 16978 */ 16979 @Override 16980 public boolean startUserInBackground(final int userId) { 16981 return startUser(userId, /* foreground */ false); 16982 } 16983 16984 /** 16985 * Refreshes the list of users related to the current user when either a 16986 * user switch happens or when a new related user is started in the 16987 * background. 16988 */ 16989 private void updateCurrentProfileIdsLocked() { 16990 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16991 mCurrentUserId, false /* enabledOnly */); 16992 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16993 for (int i = 0; i < currentProfileIds.length; i++) { 16994 currentProfileIds[i] = profiles.get(i).id; 16995 } 16996 mCurrentProfileIds = currentProfileIds; 16997 16998 synchronized (mUserProfileGroupIdsSelfLocked) { 16999 mUserProfileGroupIdsSelfLocked.clear(); 17000 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17001 for (int i = 0; i < users.size(); i++) { 17002 UserInfo user = users.get(i); 17003 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17004 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17005 } 17006 } 17007 } 17008 } 17009 17010 private Set getProfileIdsLocked(int userId) { 17011 Set userIds = new HashSet<Integer>(); 17012 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17013 userId, false /* enabledOnly */); 17014 for (UserInfo user : profiles) { 17015 userIds.add(Integer.valueOf(user.id)); 17016 } 17017 return userIds; 17018 } 17019 17020 @Override 17021 public boolean switchUser(final int userId) { 17022 return startUser(userId, /* foregound */ true); 17023 } 17024 17025 private boolean startUser(final int userId, boolean foreground) { 17026 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17027 != PackageManager.PERMISSION_GRANTED) { 17028 String msg = "Permission Denial: switchUser() from pid=" 17029 + Binder.getCallingPid() 17030 + ", uid=" + Binder.getCallingUid() 17031 + " requires " + INTERACT_ACROSS_USERS_FULL; 17032 Slog.w(TAG, msg); 17033 throw new SecurityException(msg); 17034 } 17035 17036 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17037 17038 final long ident = Binder.clearCallingIdentity(); 17039 try { 17040 synchronized (this) { 17041 final int oldUserId = mCurrentUserId; 17042 if (oldUserId == userId) { 17043 return true; 17044 } 17045 17046 mStackSupervisor.setLockTaskModeLocked(null, false); 17047 17048 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17049 if (userInfo == null) { 17050 Slog.w(TAG, "No user info for user #" + userId); 17051 return false; 17052 } 17053 17054 if (foreground) { 17055 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17056 R.anim.screen_user_enter); 17057 } 17058 17059 boolean needStart = false; 17060 17061 // If the user we are switching to is not currently started, then 17062 // we need to start it now. 17063 if (mStartedUsers.get(userId) == null) { 17064 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17065 updateStartedUserArrayLocked(); 17066 needStart = true; 17067 } 17068 17069 final Integer userIdInt = Integer.valueOf(userId); 17070 mUserLru.remove(userIdInt); 17071 mUserLru.add(userIdInt); 17072 17073 if (foreground) { 17074 mCurrentUserId = userId; 17075 updateCurrentProfileIdsLocked(); 17076 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17077 // Once the internal notion of the active user has switched, we lock the device 17078 // with the option to show the user switcher on the keyguard. 17079 mWindowManager.lockNow(null); 17080 } else { 17081 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17082 updateCurrentProfileIdsLocked(); 17083 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17084 mUserLru.remove(currentUserIdInt); 17085 mUserLru.add(currentUserIdInt); 17086 } 17087 17088 final UserStartedState uss = mStartedUsers.get(userId); 17089 17090 // Make sure user is in the started state. If it is currently 17091 // stopping, we need to knock that off. 17092 if (uss.mState == UserStartedState.STATE_STOPPING) { 17093 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17094 // so we can just fairly silently bring the user back from 17095 // the almost-dead. 17096 uss.mState = UserStartedState.STATE_RUNNING; 17097 updateStartedUserArrayLocked(); 17098 needStart = true; 17099 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17100 // This means ACTION_SHUTDOWN has been sent, so we will 17101 // need to treat this as a new boot of the user. 17102 uss.mState = UserStartedState.STATE_BOOTING; 17103 updateStartedUserArrayLocked(); 17104 needStart = true; 17105 } 17106 17107 if (uss.mState == UserStartedState.STATE_BOOTING) { 17108 // Booting up a new user, need to tell system services about it. 17109 // Note that this is on the same handler as scheduling of broadcasts, 17110 // which is important because it needs to go first. 17111 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 17112 } 17113 17114 if (foreground) { 17115 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17116 oldUserId)); 17117 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17118 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17119 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17120 oldUserId, userId, uss)); 17121 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17122 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17123 } 17124 17125 if (needStart) { 17126 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17127 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17128 | Intent.FLAG_RECEIVER_FOREGROUND); 17129 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17130 broadcastIntentLocked(null, null, intent, 17131 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17132 false, false, MY_PID, Process.SYSTEM_UID, userId); 17133 } 17134 17135 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17136 if (userId != UserHandle.USER_OWNER) { 17137 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17138 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17139 broadcastIntentLocked(null, null, intent, null, 17140 new IIntentReceiver.Stub() { 17141 public void performReceive(Intent intent, int resultCode, 17142 String data, Bundle extras, boolean ordered, 17143 boolean sticky, int sendingUser) { 17144 userInitialized(uss, userId); 17145 } 17146 }, 0, null, null, null, AppOpsManager.OP_NONE, 17147 true, false, MY_PID, Process.SYSTEM_UID, 17148 userId); 17149 uss.initializing = true; 17150 } else { 17151 getUserManagerLocked().makeInitialized(userInfo.id); 17152 } 17153 } 17154 17155 if (foreground) { 17156 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17157 if (homeInFront) { 17158 startHomeActivityLocked(userId); 17159 } else { 17160 mStackSupervisor.resumeTopActivitiesLocked(); 17161 } 17162 EventLogTags.writeAmSwitchUser(userId); 17163 getUserManagerLocked().userForeground(userId); 17164 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17165 } else { 17166 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17167 } 17168 17169 if (needStart) { 17170 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17171 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17172 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17173 broadcastIntentLocked(null, null, intent, 17174 null, new IIntentReceiver.Stub() { 17175 @Override 17176 public void performReceive(Intent intent, int resultCode, String data, 17177 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17178 throws RemoteException { 17179 } 17180 }, 0, null, null, 17181 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17182 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17183 } 17184 } 17185 } finally { 17186 Binder.restoreCallingIdentity(ident); 17187 } 17188 17189 return true; 17190 } 17191 17192 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17193 long ident = Binder.clearCallingIdentity(); 17194 try { 17195 Intent intent; 17196 if (oldUserId >= 0) { 17197 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17198 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17199 int count = profiles.size(); 17200 for (int i = 0; i < count; i++) { 17201 int profileUserId = profiles.get(i).id; 17202 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17204 | Intent.FLAG_RECEIVER_FOREGROUND); 17205 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17206 broadcastIntentLocked(null, null, intent, 17207 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17208 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17209 } 17210 } 17211 if (newUserId >= 0) { 17212 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17213 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17214 int count = profiles.size(); 17215 for (int i = 0; i < count; i++) { 17216 int profileUserId = profiles.get(i).id; 17217 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17218 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17219 | Intent.FLAG_RECEIVER_FOREGROUND); 17220 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17221 broadcastIntentLocked(null, null, intent, 17222 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17223 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17224 } 17225 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17227 | Intent.FLAG_RECEIVER_FOREGROUND); 17228 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17229 broadcastIntentLocked(null, null, intent, 17230 null, null, 0, null, null, 17231 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17232 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17233 } 17234 } finally { 17235 Binder.restoreCallingIdentity(ident); 17236 } 17237 } 17238 17239 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17240 final int newUserId) { 17241 final int N = mUserSwitchObservers.beginBroadcast(); 17242 if (N > 0) { 17243 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17244 int mCount = 0; 17245 @Override 17246 public void sendResult(Bundle data) throws RemoteException { 17247 synchronized (ActivityManagerService.this) { 17248 if (mCurUserSwitchCallback == this) { 17249 mCount++; 17250 if (mCount == N) { 17251 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17252 } 17253 } 17254 } 17255 } 17256 }; 17257 synchronized (this) { 17258 uss.switching = true; 17259 mCurUserSwitchCallback = callback; 17260 } 17261 for (int i=0; i<N; i++) { 17262 try { 17263 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17264 newUserId, callback); 17265 } catch (RemoteException e) { 17266 } 17267 } 17268 } else { 17269 synchronized (this) { 17270 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17271 } 17272 } 17273 mUserSwitchObservers.finishBroadcast(); 17274 } 17275 17276 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17277 synchronized (this) { 17278 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17279 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17280 } 17281 } 17282 17283 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17284 mCurUserSwitchCallback = null; 17285 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17286 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17287 oldUserId, newUserId, uss)); 17288 } 17289 17290 void userInitialized(UserStartedState uss, int newUserId) { 17291 completeSwitchAndInitalize(uss, newUserId, true, false); 17292 } 17293 17294 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17295 completeSwitchAndInitalize(uss, newUserId, false, true); 17296 } 17297 17298 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17299 boolean clearInitializing, boolean clearSwitching) { 17300 boolean unfrozen = false; 17301 synchronized (this) { 17302 if (clearInitializing) { 17303 uss.initializing = false; 17304 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17305 } 17306 if (clearSwitching) { 17307 uss.switching = false; 17308 } 17309 if (!uss.switching && !uss.initializing) { 17310 mWindowManager.stopFreezingScreen(); 17311 unfrozen = true; 17312 } 17313 } 17314 if (unfrozen) { 17315 final int N = mUserSwitchObservers.beginBroadcast(); 17316 for (int i=0; i<N; i++) { 17317 try { 17318 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17319 } catch (RemoteException e) { 17320 } 17321 } 17322 mUserSwitchObservers.finishBroadcast(); 17323 } 17324 } 17325 17326 void scheduleStartProfilesLocked() { 17327 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17328 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17329 DateUtils.SECOND_IN_MILLIS); 17330 } 17331 } 17332 17333 void startProfilesLocked() { 17334 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17335 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17336 mCurrentUserId, false /* enabledOnly */); 17337 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17338 for (UserInfo user : profiles) { 17339 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17340 && user.id != mCurrentUserId) { 17341 toStart.add(user); 17342 } 17343 } 17344 final int n = toStart.size(); 17345 int i = 0; 17346 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17347 startUserInBackground(toStart.get(i).id); 17348 } 17349 if (i < n) { 17350 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17351 } 17352 } 17353 17354 void finishUserBoot(UserStartedState uss) { 17355 synchronized (this) { 17356 if (uss.mState == UserStartedState.STATE_BOOTING 17357 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17358 uss.mState = UserStartedState.STATE_RUNNING; 17359 final int userId = uss.mHandle.getIdentifier(); 17360 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17361 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17362 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17363 broadcastIntentLocked(null, null, intent, 17364 null, null, 0, null, null, 17365 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17366 true, false, MY_PID, Process.SYSTEM_UID, userId); 17367 } 17368 } 17369 } 17370 17371 void finishUserSwitch(UserStartedState uss) { 17372 synchronized (this) { 17373 finishUserBoot(uss); 17374 17375 startProfilesLocked(); 17376 17377 int num = mUserLru.size(); 17378 int i = 0; 17379 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17380 Integer oldUserId = mUserLru.get(i); 17381 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17382 if (oldUss == null) { 17383 // Shouldn't happen, but be sane if it does. 17384 mUserLru.remove(i); 17385 num--; 17386 continue; 17387 } 17388 if (oldUss.mState == UserStartedState.STATE_STOPPING 17389 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17390 // This user is already stopping, doesn't count. 17391 num--; 17392 i++; 17393 continue; 17394 } 17395 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17396 // Owner and current can't be stopped, but count as running. 17397 i++; 17398 continue; 17399 } 17400 // This is a user to be stopped. 17401 stopUserLocked(oldUserId, null); 17402 num--; 17403 i++; 17404 } 17405 } 17406 } 17407 17408 @Override 17409 public int stopUser(final int userId, final IStopUserCallback callback) { 17410 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17411 != PackageManager.PERMISSION_GRANTED) { 17412 String msg = "Permission Denial: switchUser() from pid=" 17413 + Binder.getCallingPid() 17414 + ", uid=" + Binder.getCallingUid() 17415 + " requires " + INTERACT_ACROSS_USERS_FULL; 17416 Slog.w(TAG, msg); 17417 throw new SecurityException(msg); 17418 } 17419 if (userId <= 0) { 17420 throw new IllegalArgumentException("Can't stop primary user " + userId); 17421 } 17422 synchronized (this) { 17423 return stopUserLocked(userId, callback); 17424 } 17425 } 17426 17427 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17428 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17429 if (mCurrentUserId == userId) { 17430 return ActivityManager.USER_OP_IS_CURRENT; 17431 } 17432 17433 final UserStartedState uss = mStartedUsers.get(userId); 17434 if (uss == null) { 17435 // User is not started, nothing to do... but we do need to 17436 // callback if requested. 17437 if (callback != null) { 17438 mHandler.post(new Runnable() { 17439 @Override 17440 public void run() { 17441 try { 17442 callback.userStopped(userId); 17443 } catch (RemoteException e) { 17444 } 17445 } 17446 }); 17447 } 17448 return ActivityManager.USER_OP_SUCCESS; 17449 } 17450 17451 if (callback != null) { 17452 uss.mStopCallbacks.add(callback); 17453 } 17454 17455 if (uss.mState != UserStartedState.STATE_STOPPING 17456 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17457 uss.mState = UserStartedState.STATE_STOPPING; 17458 updateStartedUserArrayLocked(); 17459 17460 long ident = Binder.clearCallingIdentity(); 17461 try { 17462 // We are going to broadcast ACTION_USER_STOPPING and then 17463 // once that is done send a final ACTION_SHUTDOWN and then 17464 // stop the user. 17465 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17466 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17467 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17468 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17469 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17470 // This is the result receiver for the final shutdown broadcast. 17471 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17472 @Override 17473 public void performReceive(Intent intent, int resultCode, String data, 17474 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17475 finishUserStop(uss); 17476 } 17477 }; 17478 // This is the result receiver for the initial stopping broadcast. 17479 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17480 @Override 17481 public void performReceive(Intent intent, int resultCode, String data, 17482 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17483 // On to the next. 17484 synchronized (ActivityManagerService.this) { 17485 if (uss.mState != UserStartedState.STATE_STOPPING) { 17486 // Whoops, we are being started back up. Abort, abort! 17487 return; 17488 } 17489 uss.mState = UserStartedState.STATE_SHUTDOWN; 17490 } 17491 mBatteryStatsService.noteEvent( 17492 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17493 Integer.toString(userId), userId); 17494 mSystemServiceManager.stopUser(userId); 17495 broadcastIntentLocked(null, null, shutdownIntent, 17496 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17497 true, false, MY_PID, Process.SYSTEM_UID, userId); 17498 } 17499 }; 17500 // Kick things off. 17501 broadcastIntentLocked(null, null, stoppingIntent, 17502 null, stoppingReceiver, 0, null, null, 17503 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17504 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17505 } finally { 17506 Binder.restoreCallingIdentity(ident); 17507 } 17508 } 17509 17510 return ActivityManager.USER_OP_SUCCESS; 17511 } 17512 17513 void finishUserStop(UserStartedState uss) { 17514 final int userId = uss.mHandle.getIdentifier(); 17515 boolean stopped; 17516 ArrayList<IStopUserCallback> callbacks; 17517 synchronized (this) { 17518 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17519 if (mStartedUsers.get(userId) != uss) { 17520 stopped = false; 17521 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17522 stopped = false; 17523 } else { 17524 stopped = true; 17525 // User can no longer run. 17526 mStartedUsers.remove(userId); 17527 mUserLru.remove(Integer.valueOf(userId)); 17528 updateStartedUserArrayLocked(); 17529 17530 // Clean up all state and processes associated with the user. 17531 // Kill all the processes for the user. 17532 forceStopUserLocked(userId, "finish user"); 17533 } 17534 } 17535 17536 for (int i=0; i<callbacks.size(); i++) { 17537 try { 17538 if (stopped) callbacks.get(i).userStopped(userId); 17539 else callbacks.get(i).userStopAborted(userId); 17540 } catch (RemoteException e) { 17541 } 17542 } 17543 17544 if (stopped) { 17545 mSystemServiceManager.cleanupUser(userId); 17546 synchronized (this) { 17547 mStackSupervisor.removeUserLocked(userId); 17548 } 17549 } 17550 } 17551 17552 @Override 17553 public UserInfo getCurrentUser() { 17554 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 17555 != PackageManager.PERMISSION_GRANTED) && ( 17556 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17557 != PackageManager.PERMISSION_GRANTED)) { 17558 String msg = "Permission Denial: getCurrentUser() from pid=" 17559 + Binder.getCallingPid() 17560 + ", uid=" + Binder.getCallingUid() 17561 + " requires " + INTERACT_ACROSS_USERS; 17562 Slog.w(TAG, msg); 17563 throw new SecurityException(msg); 17564 } 17565 synchronized (this) { 17566 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17567 } 17568 } 17569 17570 int getCurrentUserIdLocked() { 17571 return mCurrentUserId; 17572 } 17573 17574 @Override 17575 public boolean isUserRunning(int userId, boolean orStopped) { 17576 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17577 != PackageManager.PERMISSION_GRANTED) { 17578 String msg = "Permission Denial: isUserRunning() from pid=" 17579 + Binder.getCallingPid() 17580 + ", uid=" + Binder.getCallingUid() 17581 + " requires " + INTERACT_ACROSS_USERS; 17582 Slog.w(TAG, msg); 17583 throw new SecurityException(msg); 17584 } 17585 synchronized (this) { 17586 return isUserRunningLocked(userId, orStopped); 17587 } 17588 } 17589 17590 boolean isUserRunningLocked(int userId, boolean orStopped) { 17591 UserStartedState state = mStartedUsers.get(userId); 17592 if (state == null) { 17593 return false; 17594 } 17595 if (orStopped) { 17596 return true; 17597 } 17598 return state.mState != UserStartedState.STATE_STOPPING 17599 && state.mState != UserStartedState.STATE_SHUTDOWN; 17600 } 17601 17602 @Override 17603 public int[] getRunningUserIds() { 17604 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17605 != PackageManager.PERMISSION_GRANTED) { 17606 String msg = "Permission Denial: isUserRunning() from pid=" 17607 + Binder.getCallingPid() 17608 + ", uid=" + Binder.getCallingUid() 17609 + " requires " + INTERACT_ACROSS_USERS; 17610 Slog.w(TAG, msg); 17611 throw new SecurityException(msg); 17612 } 17613 synchronized (this) { 17614 return mStartedUserArray; 17615 } 17616 } 17617 17618 private void updateStartedUserArrayLocked() { 17619 int num = 0; 17620 for (int i=0; i<mStartedUsers.size(); i++) { 17621 UserStartedState uss = mStartedUsers.valueAt(i); 17622 // This list does not include stopping users. 17623 if (uss.mState != UserStartedState.STATE_STOPPING 17624 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17625 num++; 17626 } 17627 } 17628 mStartedUserArray = new int[num]; 17629 num = 0; 17630 for (int i=0; i<mStartedUsers.size(); i++) { 17631 UserStartedState uss = mStartedUsers.valueAt(i); 17632 if (uss.mState != UserStartedState.STATE_STOPPING 17633 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17634 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17635 num++; 17636 } 17637 } 17638 } 17639 17640 @Override 17641 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17642 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17643 != PackageManager.PERMISSION_GRANTED) { 17644 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17645 + Binder.getCallingPid() 17646 + ", uid=" + Binder.getCallingUid() 17647 + " requires " + INTERACT_ACROSS_USERS_FULL; 17648 Slog.w(TAG, msg); 17649 throw new SecurityException(msg); 17650 } 17651 17652 mUserSwitchObservers.register(observer); 17653 } 17654 17655 @Override 17656 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17657 mUserSwitchObservers.unregister(observer); 17658 } 17659 17660 private boolean userExists(int userId) { 17661 if (userId == 0) { 17662 return true; 17663 } 17664 UserManagerService ums = getUserManagerLocked(); 17665 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17666 } 17667 17668 int[] getUsersLocked() { 17669 UserManagerService ums = getUserManagerLocked(); 17670 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17671 } 17672 17673 UserManagerService getUserManagerLocked() { 17674 if (mUserManager == null) { 17675 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17676 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17677 } 17678 return mUserManager; 17679 } 17680 17681 private int applyUserId(int uid, int userId) { 17682 return UserHandle.getUid(userId, uid); 17683 } 17684 17685 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17686 if (info == null) return null; 17687 ApplicationInfo newInfo = new ApplicationInfo(info); 17688 newInfo.uid = applyUserId(info.uid, userId); 17689 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17690 + info.packageName; 17691 return newInfo; 17692 } 17693 17694 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17695 if (aInfo == null 17696 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17697 return aInfo; 17698 } 17699 17700 ActivityInfo info = new ActivityInfo(aInfo); 17701 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17702 return info; 17703 } 17704 17705 private final class LocalService extends ActivityManagerInternal { 17706 @Override 17707 public void goingToSleep() { 17708 ActivityManagerService.this.goingToSleep(); 17709 } 17710 17711 @Override 17712 public void wakingUp() { 17713 ActivityManagerService.this.wakingUp(); 17714 } 17715 } 17716 17717 /** 17718 * An implementation of IAppTask, that allows an app to manage its own tasks via 17719 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17720 * only the process that calls getAppTasks() can call the AppTask methods. 17721 */ 17722 class AppTaskImpl extends IAppTask.Stub { 17723 private int mTaskId; 17724 private int mCallingUid; 17725 17726 public AppTaskImpl(int taskId, int callingUid) { 17727 mTaskId = taskId; 17728 mCallingUid = callingUid; 17729 } 17730 17731 @Override 17732 public void finishAndRemoveTask() { 17733 // Ensure that we are called from the same process that created this AppTask 17734 if (mCallingUid != Binder.getCallingUid()) { 17735 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17736 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17737 return; 17738 } 17739 17740 synchronized (ActivityManagerService.this) { 17741 long origId = Binder.clearCallingIdentity(); 17742 try { 17743 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17744 if (tr != null) { 17745 // Only kill the process if we are not a new document 17746 int flags = tr.getBaseIntent().getFlags(); 17747 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17748 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17749 removeTaskByIdLocked(mTaskId, 17750 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17751 } 17752 } finally { 17753 Binder.restoreCallingIdentity(origId); 17754 } 17755 } 17756 } 17757 17758 @Override 17759 public ActivityManager.RecentTaskInfo getTaskInfo() { 17760 // Ensure that we are called from the same process that created this AppTask 17761 if (mCallingUid != Binder.getCallingUid()) { 17762 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17763 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17764 return null; 17765 } 17766 17767 synchronized (ActivityManagerService.this) { 17768 long origId = Binder.clearCallingIdentity(); 17769 try { 17770 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17771 if (tr != null) { 17772 return createRecentTaskInfoFromTaskRecord(tr); 17773 } 17774 } finally { 17775 Binder.restoreCallingIdentity(origId); 17776 } 17777 return null; 17778 } 17779 } 17780 } 17781} 17782