ActivityManagerService.java revision 9693d9534342c9785877a9f98ec5aff6fd9ac496
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.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.app.IAppTask; 36import android.app.admin.DevicePolicyManager; 37import android.appwidget.AppWidgetManager; 38import android.graphics.Rect; 39import android.os.BatteryStats; 40import android.os.PersistableBundle; 41import android.service.voice.IVoiceInteractionSession; 42import android.util.ArrayMap; 43 44import com.android.internal.R; 45import com.android.internal.annotations.GuardedBy; 46import com.android.internal.app.IAppOpsService; 47import com.android.internal.app.IVoiceInteractor; 48import com.android.internal.app.ProcessMap; 49import com.android.internal.app.ProcessStats; 50import com.android.internal.content.PackageMonitor; 51import com.android.internal.os.BackgroundThread; 52import com.android.internal.os.BatteryStatsImpl; 53import com.android.internal.os.ProcessCpuTracker; 54import com.android.internal.os.TransferPipe; 55import com.android.internal.os.Zygote; 56import com.android.internal.util.FastPrintWriter; 57import com.android.internal.util.FastXmlSerializer; 58import com.android.internal.util.MemInfoReader; 59import com.android.internal.util.Preconditions; 60import com.android.server.AppOpsService; 61import com.android.server.AttributeCache; 62import com.android.server.IntentResolver; 63import com.android.server.LocalServices; 64import com.android.server.ServiceThread; 65import com.android.server.SystemService; 66import com.android.server.SystemServiceManager; 67import com.android.server.Watchdog; 68import com.android.server.am.ActivityStack.ActivityState; 69import com.android.server.firewall.IntentFirewall; 70import com.android.server.pm.UserManagerService; 71import com.android.server.wm.AppTransition; 72import com.android.server.wm.WindowManagerService; 73import com.google.android.collect.Lists; 74import com.google.android.collect.Maps; 75 76import libcore.io.IoUtils; 77 78import org.xmlpull.v1.XmlPullParser; 79import org.xmlpull.v1.XmlPullParserException; 80import org.xmlpull.v1.XmlSerializer; 81 82import android.app.Activity; 83import android.app.ActivityManager; 84import android.app.ActivityManager.RunningTaskInfo; 85import android.app.ActivityManager.StackInfo; 86import android.app.ActivityManagerInternal; 87import android.app.ActivityManagerNative; 88import android.app.ActivityOptions; 89import android.app.ActivityThread; 90import android.app.AlertDialog; 91import android.app.AppGlobals; 92import android.app.ApplicationErrorReport; 93import android.app.Dialog; 94import android.app.IActivityController; 95import android.app.IApplicationThread; 96import android.app.IInstrumentationWatcher; 97import android.app.INotificationManager; 98import android.app.IProcessObserver; 99import android.app.IServiceConnection; 100import android.app.IStopUserCallback; 101import android.app.IUiAutomationConnection; 102import android.app.IUserSwitchObserver; 103import android.app.Instrumentation; 104import android.app.Notification; 105import android.app.NotificationManager; 106import android.app.PendingIntent; 107import android.app.backup.IBackupManager; 108import android.content.ActivityNotFoundException; 109import android.content.BroadcastReceiver; 110import android.content.ClipData; 111import android.content.ComponentCallbacks2; 112import android.content.ComponentName; 113import android.content.ContentProvider; 114import android.content.ContentResolver; 115import android.content.Context; 116import android.content.DialogInterface; 117import android.content.IContentProvider; 118import android.content.IIntentReceiver; 119import android.content.IIntentSender; 120import android.content.Intent; 121import android.content.IntentFilter; 122import android.content.IntentSender; 123import android.content.pm.ActivityInfo; 124import android.content.pm.ApplicationInfo; 125import android.content.pm.ConfigurationInfo; 126import android.content.pm.IPackageDataObserver; 127import android.content.pm.IPackageManager; 128import android.content.pm.InstrumentationInfo; 129import android.content.pm.PackageInfo; 130import android.content.pm.PackageManager; 131import android.content.pm.ParceledListSlice; 132import android.content.pm.UserInfo; 133import android.content.pm.PackageManager.NameNotFoundException; 134import android.content.pm.PathPermission; 135import android.content.pm.ProviderInfo; 136import android.content.pm.ResolveInfo; 137import android.content.pm.ServiceInfo; 138import android.content.res.CompatibilityInfo; 139import android.content.res.Configuration; 140import android.graphics.Bitmap; 141import android.net.Proxy; 142import android.net.ProxyInfo; 143import android.net.Uri; 144import android.os.Binder; 145import android.os.Build; 146import android.os.Bundle; 147import android.os.Debug; 148import android.os.DropBoxManager; 149import android.os.Environment; 150import android.os.FactoryTest; 151import android.os.FileObserver; 152import android.os.FileUtils; 153import android.os.Handler; 154import android.os.IBinder; 155import android.os.IPermissionController; 156import android.os.IRemoteCallback; 157import android.os.IUserManager; 158import android.os.Looper; 159import android.os.Message; 160import android.os.Parcel; 161import android.os.ParcelFileDescriptor; 162import android.os.Process; 163import android.os.RemoteCallbackList; 164import android.os.RemoteException; 165import android.os.SELinux; 166import android.os.ServiceManager; 167import android.os.StrictMode; 168import android.os.SystemClock; 169import android.os.SystemProperties; 170import android.os.UpdateLock; 171import android.os.UserHandle; 172import android.provider.Settings; 173import android.text.format.DateUtils; 174import android.text.format.Time; 175import android.util.AtomicFile; 176import android.util.EventLog; 177import android.util.Log; 178import android.util.Pair; 179import android.util.PrintWriterPrinter; 180import android.util.Slog; 181import android.util.SparseArray; 182import android.util.TimeUtils; 183import android.util.Xml; 184import android.view.Gravity; 185import android.view.LayoutInflater; 186import android.view.View; 187import android.view.WindowManager; 188 189import java.io.BufferedInputStream; 190import java.io.BufferedOutputStream; 191import java.io.DataInputStream; 192import java.io.DataOutputStream; 193import java.io.File; 194import java.io.FileDescriptor; 195import java.io.FileInputStream; 196import java.io.FileNotFoundException; 197import java.io.FileOutputStream; 198import java.io.IOException; 199import java.io.InputStreamReader; 200import java.io.PrintWriter; 201import java.io.StringWriter; 202import java.lang.ref.WeakReference; 203import java.util.ArrayList; 204import java.util.Arrays; 205import java.util.Collections; 206import java.util.Comparator; 207import java.util.HashMap; 208import java.util.HashSet; 209import java.util.Iterator; 210import java.util.List; 211import java.util.Locale; 212import java.util.Map; 213import java.util.Set; 214import java.util.concurrent.atomic.AtomicBoolean; 215import java.util.concurrent.atomic.AtomicLong; 216 217public final class ActivityManagerService extends ActivityManagerNative 218 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 219 private static final String USER_DATA_DIR = "/data/user/"; 220 static final String TAG = "ActivityManager"; 221 static final String TAG_MU = "ActivityManagerServiceMU"; 222 static final boolean DEBUG = false; 223 static final boolean localLOGV = DEBUG; 224 static final boolean DEBUG_BACKUP = localLOGV || false; 225 static final boolean DEBUG_BROADCAST = localLOGV || false; 226 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_CLEANUP = localLOGV || false; 229 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 230 static final boolean DEBUG_FOCUS = false; 231 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 232 static final boolean DEBUG_MU = localLOGV || false; 233 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 234 static final boolean DEBUG_LRU = localLOGV || false; 235 static final boolean DEBUG_PAUSE = localLOGV || false; 236 static final boolean DEBUG_POWER = localLOGV || false; 237 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 238 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 239 static final boolean DEBUG_PROCESSES = localLOGV || false; 240 static final boolean DEBUG_PROVIDER = localLOGV || false; 241 static final boolean DEBUG_RESULTS = localLOGV || false; 242 static final boolean DEBUG_SERVICE = localLOGV || false; 243 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 244 static final boolean DEBUG_STACK = localLOGV || false; 245 static final boolean DEBUG_SWITCH = localLOGV || false; 246 static final boolean DEBUG_TASKS = localLOGV || false; 247 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 248 static final boolean DEBUG_TRANSITION = localLOGV || false; 249 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 250 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 251 static final boolean DEBUG_VISBILITY = localLOGV || false; 252 static final boolean DEBUG_PSS = localLOGV || false; 253 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 254 static final boolean VALIDATE_TOKENS = false; 255 static final boolean SHOW_ACTIVITY_START_TIME = true; 256 257 // Control over CPU and battery monitoring. 258 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 259 static final boolean MONITOR_CPU_USAGE = true; 260 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 261 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 262 static final boolean MONITOR_THREAD_CPU_USAGE = false; 263 264 // The flags that are set for all calls we make to the package manager. 265 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 266 267 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 268 269 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 270 271 // Maximum number of recent tasks that we can remember. 272 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 273 274 // Amount of time after a call to stopAppSwitches() during which we will 275 // prevent further untrusted switches from happening. 276 static final long APP_SWITCH_DELAY_TIME = 5*1000; 277 278 // How long we wait for a launched process to attach to the activity manager 279 // before we decide it's never going to come up for real. 280 static final int PROC_START_TIMEOUT = 10*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real, when the process was 284 // started with a wrapper for instrumentation (such as Valgrind) because it 285 // could take much longer than usual. 286 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 287 288 // How long to wait after going idle before forcing apps to GC. 289 static final int GC_TIMEOUT = 5*1000; 290 291 // The minimum amount of time between successive GC requests for a process. 292 static final int GC_MIN_INTERVAL = 60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process. 295 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 296 297 // The minimum amount of time between successive PSS requests for a process 298 // when the request is due to the memory state being lowered. 299 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 300 301 // The rate at which we check for apps using excessive power -- 15 mins. 302 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 303 304 // The minimum sample duration we will allow before deciding we have 305 // enough data on wake locks to start killing things. 306 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on CPU usage to start killing things. 310 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // How long we allow a receiver to run before giving up on it. 313 static final int BROADCAST_FG_TIMEOUT = 10*1000; 314 static final int BROADCAST_BG_TIMEOUT = 60*1000; 315 316 // How long we wait until we timeout on key dispatching. 317 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 318 319 // How long we wait until we timeout on key dispatching during instrumentation. 320 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 321 322 // Amount of time we wait for observers to handle a user switch before 323 // giving up on them and unfreezing the screen. 324 static final int USER_SWITCH_TIMEOUT = 2*1000; 325 326 // Maximum number of users we allow to be running at a time. 327 static final int MAX_RUNNING_USERS = 3; 328 329 // How long to wait in getAssistContextExtras for the activity and foreground services 330 // to respond with the result. 331 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 332 333 // Maximum number of persisted Uri grants a package is allowed 334 static final int MAX_PERSISTED_URI_GRANTS = 128; 335 336 static final int MY_PID = Process.myPid(); 337 338 static final String[] EMPTY_STRING_ARRAY = new String[0]; 339 340 // How many bytes to write into the dropbox log before truncating 341 static final int DROPBOX_MAX_SIZE = 256 * 1024; 342 343 /** All system services */ 344 SystemServiceManager mSystemServiceManager; 345 346 /** Run all ActivityStacks through this */ 347 ActivityStackSupervisor mStackSupervisor; 348 349 public IntentFirewall mIntentFirewall; 350 351 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 352 // default actuion automatically. Important for devices without direct input 353 // devices. 354 private boolean mShowDialogs = true; 355 356 /** 357 * Description of a request to start a new activity, which has been held 358 * due to app switches being disabled. 359 */ 360 static class PendingActivityLaunch { 361 final ActivityRecord r; 362 final ActivityRecord sourceRecord; 363 final int startFlags; 364 final ActivityStack stack; 365 366 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 367 int _startFlags, ActivityStack _stack) { 368 r = _r; 369 sourceRecord = _sourceRecord; 370 startFlags = _startFlags; 371 stack = _stack; 372 } 373 } 374 375 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 376 = new ArrayList<PendingActivityLaunch>(); 377 378 BroadcastQueue mFgBroadcastQueue; 379 BroadcastQueue mBgBroadcastQueue; 380 // Convenient for easy iteration over the queues. Foreground is first 381 // so that dispatch of foreground broadcasts gets precedence. 382 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 383 384 BroadcastQueue broadcastQueueForIntent(Intent intent) { 385 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 386 if (DEBUG_BACKGROUND_BROADCAST) { 387 Slog.i(TAG, "Broadcast intent " + intent + " on " 388 + (isFg ? "foreground" : "background") 389 + " queue"); 390 } 391 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 392 } 393 394 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 395 for (BroadcastQueue queue : mBroadcastQueues) { 396 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 397 if (r != null) { 398 return r; 399 } 400 } 401 return null; 402 } 403 404 /** 405 * Activity we have told the window manager to have key focus. 406 */ 407 ActivityRecord mFocusedActivity = null; 408 409 /** 410 * List of intents that were used to start the most recent tasks. 411 */ 412 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 413 414 public class PendingAssistExtras extends Binder implements Runnable { 415 public final ActivityRecord activity; 416 public boolean haveResult = false; 417 public Bundle result = null; 418 public PendingAssistExtras(ActivityRecord _activity) { 419 activity = _activity; 420 } 421 @Override 422 public void run() { 423 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 424 synchronized (this) { 425 haveResult = true; 426 notifyAll(); 427 } 428 } 429 } 430 431 final ArrayList<PendingAssistExtras> mPendingAssistExtras 432 = new ArrayList<PendingAssistExtras>(); 433 434 /** 435 * Process management. 436 */ 437 final ProcessList mProcessList = new ProcessList(); 438 439 /** 440 * All of the applications we currently have running organized by name. 441 * The keys are strings of the application package name (as 442 * returned by the package manager), and the keys are ApplicationRecord 443 * objects. 444 */ 445 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 446 447 /** 448 * Tracking long-term execution of processes to look for abuse and other 449 * bad app behavior. 450 */ 451 final ProcessStatsService mProcessStats; 452 453 /** 454 * The currently running isolated processes. 455 */ 456 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 457 458 /** 459 * Counter for assigning isolated process uids, to avoid frequently reusing the 460 * same ones. 461 */ 462 int mNextIsolatedProcessUid = 0; 463 464 /** 465 * The currently running heavy-weight process, if any. 466 */ 467 ProcessRecord mHeavyWeightProcess = null; 468 469 /** 470 * The last time that various processes have crashed. 471 */ 472 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 473 474 /** 475 * Information about a process that is currently marked as bad. 476 */ 477 static final class BadProcessInfo { 478 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 479 this.time = time; 480 this.shortMsg = shortMsg; 481 this.longMsg = longMsg; 482 this.stack = stack; 483 } 484 485 final long time; 486 final String shortMsg; 487 final String longMsg; 488 final String stack; 489 } 490 491 /** 492 * Set of applications that we consider to be bad, and will reject 493 * incoming broadcasts from (which the user has no control over). 494 * Processes are added to this set when they have crashed twice within 495 * a minimum amount of time; they are removed from it when they are 496 * later restarted (hopefully due to some user action). The value is the 497 * time it was added to the list. 498 */ 499 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 500 501 /** 502 * All of the processes we currently have running organized by pid. 503 * The keys are the pid running the application. 504 * 505 * <p>NOTE: This object is protected by its own lock, NOT the global 506 * activity manager lock! 507 */ 508 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 509 510 /** 511 * All of the processes that have been forced to be foreground. The key 512 * is the pid of the caller who requested it (we hold a death 513 * link on it). 514 */ 515 abstract class ForegroundToken implements IBinder.DeathRecipient { 516 int pid; 517 IBinder token; 518 } 519 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 520 521 /** 522 * List of records for processes that someone had tried to start before the 523 * system was ready. We don't start them at that point, but ensure they 524 * are started by the time booting is complete. 525 */ 526 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 527 528 /** 529 * List of persistent applications that are in the process 530 * of being started. 531 */ 532 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 533 534 /** 535 * Processes that are being forcibly torn down. 536 */ 537 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 538 539 /** 540 * List of running applications, sorted by recent usage. 541 * The first entry in the list is the least recently used. 542 */ 543 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 544 545 /** 546 * Where in mLruProcesses that the processes hosting activities start. 547 */ 548 int mLruProcessActivityStart = 0; 549 550 /** 551 * Where in mLruProcesses that the processes hosting services start. 552 * This is after (lower index) than mLruProcessesActivityStart. 553 */ 554 int mLruProcessServiceStart = 0; 555 556 /** 557 * List of processes that should gc as soon as things are idle. 558 */ 559 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 560 561 /** 562 * Processes we want to collect PSS data from. 563 */ 564 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 565 566 /** 567 * Last time we requested PSS data of all processes. 568 */ 569 long mLastFullPssTime = SystemClock.uptimeMillis(); 570 571 /** 572 * This is the process holding what we currently consider to be 573 * the "home" activity. 574 */ 575 ProcessRecord mHomeProcess; 576 577 /** 578 * This is the process holding the activity the user last visited that 579 * is in a different process from the one they are currently in. 580 */ 581 ProcessRecord mPreviousProcess; 582 583 /** 584 * The time at which the previous process was last visible. 585 */ 586 long mPreviousProcessVisibleTime; 587 588 /** 589 * Which uses have been started, so are allowed to run code. 590 */ 591 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 592 593 /** 594 * LRU list of history of current users. Most recently current is at the end. 595 */ 596 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 597 598 /** 599 * Constant array of the users that are currently started. 600 */ 601 int[] mStartedUserArray = new int[] { 0 }; 602 603 /** 604 * Registered observers of the user switching mechanics. 605 */ 606 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 607 = new RemoteCallbackList<IUserSwitchObserver>(); 608 609 /** 610 * Currently active user switch. 611 */ 612 Object mCurUserSwitchCallback; 613 614 /** 615 * Packages that the user has asked to have run in screen size 616 * compatibility mode instead of filling the screen. 617 */ 618 final CompatModePackages mCompatModePackages; 619 620 /** 621 * Set of IntentSenderRecord objects that are currently active. 622 */ 623 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 624 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 625 626 /** 627 * Fingerprints (hashCode()) of stack traces that we've 628 * already logged DropBox entries for. Guarded by itself. If 629 * something (rogue user app) forces this over 630 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 631 */ 632 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 633 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 634 635 /** 636 * Strict Mode background batched logging state. 637 * 638 * The string buffer is guarded by itself, and its lock is also 639 * used to determine if another batched write is already 640 * in-flight. 641 */ 642 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 643 644 /** 645 * Keeps track of all IIntentReceivers that have been registered for 646 * broadcasts. Hash keys are the receiver IBinder, hash value is 647 * a ReceiverList. 648 */ 649 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 650 new HashMap<IBinder, ReceiverList>(); 651 652 /** 653 * Resolver for broadcast intents to registered receivers. 654 * Holds BroadcastFilter (subclass of IntentFilter). 655 */ 656 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 657 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 658 @Override 659 protected boolean allowFilterResult( 660 BroadcastFilter filter, List<BroadcastFilter> dest) { 661 IBinder target = filter.receiverList.receiver.asBinder(); 662 for (int i=dest.size()-1; i>=0; i--) { 663 if (dest.get(i).receiverList.receiver.asBinder() == target) { 664 return false; 665 } 666 } 667 return true; 668 } 669 670 @Override 671 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 672 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 673 || userId == filter.owningUserId) { 674 return super.newResult(filter, match, userId); 675 } 676 return null; 677 } 678 679 @Override 680 protected BroadcastFilter[] newArray(int size) { 681 return new BroadcastFilter[size]; 682 } 683 684 @Override 685 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 686 return packageName.equals(filter.packageName); 687 } 688 }; 689 690 /** 691 * State of all active sticky broadcasts per user. Keys are the action of the 692 * sticky Intent, values are an ArrayList of all broadcasted intents with 693 * that action (which should usually be one). The SparseArray is keyed 694 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 695 * for stickies that are sent to all users. 696 */ 697 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 698 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 699 700 final ActiveServices mServices; 701 702 /** 703 * Backup/restore process management 704 */ 705 String mBackupAppName = null; 706 BackupRecord mBackupTarget = null; 707 708 final ProviderMap mProviderMap; 709 710 /** 711 * List of content providers who have clients waiting for them. The 712 * application is currently being launched and the provider will be 713 * removed from this list once it is published. 714 */ 715 final ArrayList<ContentProviderRecord> mLaunchingProviders 716 = new ArrayList<ContentProviderRecord>(); 717 718 /** 719 * File storing persisted {@link #mGrantedUriPermissions}. 720 */ 721 private final AtomicFile mGrantFile; 722 723 /** XML constants used in {@link #mGrantFile} */ 724 private static final String TAG_URI_GRANTS = "uri-grants"; 725 private static final String TAG_URI_GRANT = "uri-grant"; 726 private static final String ATTR_USER_HANDLE = "userHandle"; 727 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 728 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 729 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 730 private static final String ATTR_TARGET_PKG = "targetPkg"; 731 private static final String ATTR_URI = "uri"; 732 private static final String ATTR_MODE_FLAGS = "modeFlags"; 733 private static final String ATTR_CREATED_TIME = "createdTime"; 734 private static final String ATTR_PREFIX = "prefix"; 735 736 /** 737 * Global set of specific {@link Uri} permissions that have been granted. 738 * This optimized lookup structure maps from {@link UriPermission#targetUid} 739 * to {@link UriPermission#uri} to {@link UriPermission}. 740 */ 741 @GuardedBy("this") 742 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 743 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 744 745 public static class GrantUri { 746 public final int sourceUserId; 747 public final Uri uri; 748 public boolean prefix; 749 750 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 751 this.sourceUserId = sourceUserId; 752 this.uri = uri; 753 this.prefix = prefix; 754 } 755 756 @Override 757 public int hashCode() { 758 return toString().hashCode(); 759 } 760 761 @Override 762 public boolean equals(Object o) { 763 if (o instanceof GrantUri) { 764 GrantUri other = (GrantUri) o; 765 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 766 && prefix == other.prefix; 767 } 768 return false; 769 } 770 771 @Override 772 public String toString() { 773 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 774 if (prefix) result += " [prefix]"; 775 return result; 776 } 777 778 public String toSafeString() { 779 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 780 if (prefix) result += " [prefix]"; 781 return result; 782 } 783 784 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 785 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 786 ContentProvider.getUriWithoutUserId(uri), false); 787 } 788 } 789 790 CoreSettingsObserver mCoreSettingsObserver; 791 792 /** 793 * Thread-local storage used to carry caller permissions over through 794 * indirect content-provider access. 795 */ 796 private class Identity { 797 public int pid; 798 public int uid; 799 800 Identity(int _pid, int _uid) { 801 pid = _pid; 802 uid = _uid; 803 } 804 } 805 806 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 807 808 /** 809 * All information we have collected about the runtime performance of 810 * any user id that can impact battery performance. 811 */ 812 final BatteryStatsService mBatteryStatsService; 813 814 /** 815 * Information about component usage 816 */ 817 final UsageStatsService mUsageStatsService; 818 819 /** 820 * Information about and control over application operations 821 */ 822 final AppOpsService mAppOpsService; 823 824 /** 825 * Current configuration information. HistoryRecord objects are given 826 * a reference to this object to indicate which configuration they are 827 * currently running in, so this object must be kept immutable. 828 */ 829 Configuration mConfiguration = new Configuration(); 830 831 /** 832 * Current sequencing integer of the configuration, for skipping old 833 * configurations. 834 */ 835 int mConfigurationSeq = 0; 836 837 /** 838 * Hardware-reported OpenGLES version. 839 */ 840 final int GL_ES_VERSION; 841 842 /** 843 * List of initialization arguments to pass to all processes when binding applications to them. 844 * For example, references to the commonly used services. 845 */ 846 HashMap<String, IBinder> mAppBindArgs; 847 848 /** 849 * Temporary to avoid allocations. Protected by main lock. 850 */ 851 final StringBuilder mStringBuilder = new StringBuilder(256); 852 853 /** 854 * Used to control how we initialize the service. 855 */ 856 ComponentName mTopComponent; 857 String mTopAction = Intent.ACTION_MAIN; 858 String mTopData; 859 boolean mProcessesReady = false; 860 boolean mSystemReady = false; 861 boolean mBooting = false; 862 boolean mWaitingUpdate = false; 863 boolean mDidUpdate = false; 864 boolean mOnBattery = false; 865 boolean mLaunchWarningShown = false; 866 867 Context mContext; 868 869 int mFactoryTest; 870 871 boolean mCheckedForSetup; 872 873 /** 874 * The time at which we will allow normal application switches again, 875 * after a call to {@link #stopAppSwitches()}. 876 */ 877 long mAppSwitchesAllowedTime; 878 879 /** 880 * This is set to true after the first switch after mAppSwitchesAllowedTime 881 * is set; any switches after that will clear the time. 882 */ 883 boolean mDidAppSwitch; 884 885 /** 886 * Last time (in realtime) at which we checked for power usage. 887 */ 888 long mLastPowerCheckRealtime; 889 890 /** 891 * Last time (in uptime) at which we checked for power usage. 892 */ 893 long mLastPowerCheckUptime; 894 895 /** 896 * Set while we are wanting to sleep, to prevent any 897 * activities from being started/resumed. 898 */ 899 private boolean mSleeping = false; 900 901 /** 902 * Set while we are running a voice interaction. This overrides 903 * sleeping while it is active. 904 */ 905 private boolean mRunningVoice = false; 906 907 /** 908 * State of external calls telling us if the device is asleep. 909 */ 910 private boolean mWentToSleep = false; 911 912 /** 913 * State of external call telling us if the lock screen is shown. 914 */ 915 private boolean mLockScreenShown = false; 916 917 /** 918 * Set if we are shutting down the system, similar to sleeping. 919 */ 920 boolean mShuttingDown = false; 921 922 /** 923 * Current sequence id for oom_adj computation traversal. 924 */ 925 int mAdjSeq = 0; 926 927 /** 928 * Current sequence id for process LRU updating. 929 */ 930 int mLruSeq = 0; 931 932 /** 933 * Keep track of the non-cached/empty process we last found, to help 934 * determine how to distribute cached/empty processes next time. 935 */ 936 int mNumNonCachedProcs = 0; 937 938 /** 939 * Keep track of the number of cached hidden procs, to balance oom adj 940 * distribution between those and empty procs. 941 */ 942 int mNumCachedHiddenProcs = 0; 943 944 /** 945 * Keep track of the number of service processes we last found, to 946 * determine on the next iteration which should be B services. 947 */ 948 int mNumServiceProcs = 0; 949 int mNewNumAServiceProcs = 0; 950 int mNewNumServiceProcs = 0; 951 952 /** 953 * Allow the current computed overall memory level of the system to go down? 954 * This is set to false when we are killing processes for reasons other than 955 * memory management, so that the now smaller process list will not be taken as 956 * an indication that memory is tighter. 957 */ 958 boolean mAllowLowerMemLevel = false; 959 960 /** 961 * The last computed memory level, for holding when we are in a state that 962 * processes are going away for other reasons. 963 */ 964 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 965 966 /** 967 * The last total number of process we have, to determine if changes actually look 968 * like a shrinking number of process due to lower RAM. 969 */ 970 int mLastNumProcesses; 971 972 /** 973 * The uptime of the last time we performed idle maintenance. 974 */ 975 long mLastIdleTime = SystemClock.uptimeMillis(); 976 977 /** 978 * Total time spent with RAM that has been added in the past since the last idle time. 979 */ 980 long mLowRamTimeSinceLastIdle = 0; 981 982 /** 983 * If RAM is currently low, when that horrible situation started. 984 */ 985 long mLowRamStartTime = 0; 986 987 /** 988 * For reporting to battery stats the current top application. 989 */ 990 private String mCurResumedPackage = null; 991 private int mCurResumedUid = -1; 992 993 /** 994 * For reporting to battery stats the apps currently running foreground 995 * service. The ProcessMap is package/uid tuples; each of these contain 996 * an array of the currently foreground processes. 997 */ 998 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 999 = new ProcessMap<ArrayList<ProcessRecord>>(); 1000 1001 /** 1002 * This is set if we had to do a delayed dexopt of an app before launching 1003 * it, to increase the ANR timeouts in that case. 1004 */ 1005 boolean mDidDexOpt; 1006 1007 /** 1008 * Set if the systemServer made a call to enterSafeMode. 1009 */ 1010 boolean mSafeMode; 1011 1012 String mDebugApp = null; 1013 boolean mWaitForDebugger = false; 1014 boolean mDebugTransient = false; 1015 String mOrigDebugApp = null; 1016 boolean mOrigWaitForDebugger = false; 1017 boolean mAlwaysFinishActivities = false; 1018 IActivityController mController = null; 1019 String mProfileApp = null; 1020 ProcessRecord mProfileProc = null; 1021 String mProfileFile; 1022 ParcelFileDescriptor mProfileFd; 1023 int mProfileType = 0; 1024 boolean mAutoStopProfiler = false; 1025 String mOpenGlTraceApp = null; 1026 1027 static class ProcessChangeItem { 1028 static final int CHANGE_ACTIVITIES = 1<<0; 1029 static final int CHANGE_PROCESS_STATE = 1<<1; 1030 int changes; 1031 int uid; 1032 int pid; 1033 int processState; 1034 boolean foregroundActivities; 1035 } 1036 1037 final RemoteCallbackList<IProcessObserver> mProcessObservers 1038 = new RemoteCallbackList<IProcessObserver>(); 1039 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1040 1041 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1042 = new ArrayList<ProcessChangeItem>(); 1043 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1044 = new ArrayList<ProcessChangeItem>(); 1045 1046 /** 1047 * Runtime CPU use collection thread. This object's lock is used to 1048 * protect all related state. 1049 */ 1050 final Thread mProcessCpuThread; 1051 1052 /** 1053 * Used to collect process stats when showing not responding dialog. 1054 * Protected by mProcessCpuThread. 1055 */ 1056 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1057 MONITOR_THREAD_CPU_USAGE); 1058 final AtomicLong mLastCpuTime = new AtomicLong(0); 1059 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1060 1061 long mLastWriteTime = 0; 1062 1063 /** 1064 * Used to retain an update lock when the foreground activity is in 1065 * immersive mode. 1066 */ 1067 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1068 1069 /** 1070 * Set to true after the system has finished booting. 1071 */ 1072 boolean mBooted = false; 1073 1074 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1075 int mProcessLimitOverride = -1; 1076 1077 WindowManagerService mWindowManager; 1078 1079 final ActivityThread mSystemThread; 1080 1081 int mCurrentUserId = 0; 1082 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1083 private UserManagerService mUserManager; 1084 1085 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1086 final ProcessRecord mApp; 1087 final int mPid; 1088 final IApplicationThread mAppThread; 1089 1090 AppDeathRecipient(ProcessRecord app, int pid, 1091 IApplicationThread thread) { 1092 if (localLOGV) Slog.v( 1093 TAG, "New death recipient " + this 1094 + " for thread " + thread.asBinder()); 1095 mApp = app; 1096 mPid = pid; 1097 mAppThread = thread; 1098 } 1099 1100 @Override 1101 public void binderDied() { 1102 if (localLOGV) Slog.v( 1103 TAG, "Death received in " + this 1104 + " for thread " + mAppThread.asBinder()); 1105 synchronized(ActivityManagerService.this) { 1106 appDiedLocked(mApp, mPid, mAppThread); 1107 } 1108 } 1109 } 1110 1111 static final int SHOW_ERROR_MSG = 1; 1112 static final int SHOW_NOT_RESPONDING_MSG = 2; 1113 static final int SHOW_FACTORY_ERROR_MSG = 3; 1114 static final int UPDATE_CONFIGURATION_MSG = 4; 1115 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1116 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1117 static final int SERVICE_TIMEOUT_MSG = 12; 1118 static final int UPDATE_TIME_ZONE = 13; 1119 static final int SHOW_UID_ERROR_MSG = 14; 1120 static final int IM_FEELING_LUCKY_MSG = 15; 1121 static final int PROC_START_TIMEOUT_MSG = 20; 1122 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1123 static final int KILL_APPLICATION_MSG = 22; 1124 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1125 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1126 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1127 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1128 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1129 static final int CLEAR_DNS_CACHE_MSG = 28; 1130 static final int UPDATE_HTTP_PROXY_MSG = 29; 1131 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1132 static final int DISPATCH_PROCESSES_CHANGED = 31; 1133 static final int DISPATCH_PROCESS_DIED = 32; 1134 static final int REPORT_MEM_USAGE_MSG = 33; 1135 static final int REPORT_USER_SWITCH_MSG = 34; 1136 static final int CONTINUE_USER_SWITCH_MSG = 35; 1137 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1138 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1139 static final int PERSIST_URI_GRANTS_MSG = 38; 1140 static final int REQUEST_ALL_PSS_MSG = 39; 1141 static final int START_PROFILES_MSG = 40; 1142 static final int UPDATE_TIME = 41; 1143 static final int SYSTEM_USER_START_MSG = 42; 1144 static final int SYSTEM_USER_CURRENT_MSG = 43; 1145 1146 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1147 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1148 static final int FIRST_COMPAT_MODE_MSG = 300; 1149 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1150 1151 AlertDialog mUidAlert; 1152 CompatModeDialog mCompatModeDialog; 1153 long mLastMemUsageReportTime = 0; 1154 1155 /** 1156 * Flag whether the current user is a "monkey", i.e. whether 1157 * the UI is driven by a UI automation tool. 1158 */ 1159 private boolean mUserIsMonkey; 1160 1161 final ServiceThread mHandlerThread; 1162 final MainHandler mHandler; 1163 1164 final class MainHandler extends Handler { 1165 public MainHandler(Looper looper) { 1166 super(looper, null, true); 1167 } 1168 1169 @Override 1170 public void handleMessage(Message msg) { 1171 switch (msg.what) { 1172 case SHOW_ERROR_MSG: { 1173 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1174 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1175 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1176 synchronized (ActivityManagerService.this) { 1177 ProcessRecord proc = (ProcessRecord)data.get("app"); 1178 AppErrorResult res = (AppErrorResult) data.get("result"); 1179 if (proc != null && proc.crashDialog != null) { 1180 Slog.e(TAG, "App already has crash dialog: " + proc); 1181 if (res != null) { 1182 res.set(0); 1183 } 1184 return; 1185 } 1186 if (!showBackground && UserHandle.getAppId(proc.uid) 1187 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1188 && proc.pid != MY_PID) { 1189 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1190 if (res != null) { 1191 res.set(0); 1192 } 1193 return; 1194 } 1195 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1196 Dialog d = new AppErrorDialog(mContext, 1197 ActivityManagerService.this, res, proc); 1198 d.show(); 1199 proc.crashDialog = d; 1200 } else { 1201 // The device is asleep, so just pretend that the user 1202 // saw a crash dialog and hit "force quit". 1203 if (res != null) { 1204 res.set(0); 1205 } 1206 } 1207 } 1208 1209 ensureBootCompleted(); 1210 } break; 1211 case SHOW_NOT_RESPONDING_MSG: { 1212 synchronized (ActivityManagerService.this) { 1213 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1214 ProcessRecord proc = (ProcessRecord)data.get("app"); 1215 if (proc != null && proc.anrDialog != null) { 1216 Slog.e(TAG, "App already has anr dialog: " + proc); 1217 return; 1218 } 1219 1220 Intent intent = new Intent("android.intent.action.ANR"); 1221 if (!mProcessesReady) { 1222 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1223 | Intent.FLAG_RECEIVER_FOREGROUND); 1224 } 1225 broadcastIntentLocked(null, null, intent, 1226 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1227 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1228 1229 if (mShowDialogs) { 1230 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1231 mContext, proc, (ActivityRecord)data.get("activity"), 1232 msg.arg1 != 0); 1233 d.show(); 1234 proc.anrDialog = d; 1235 } else { 1236 // Just kill the app if there is no dialog to be shown. 1237 killAppAtUsersRequest(proc, null); 1238 } 1239 } 1240 1241 ensureBootCompleted(); 1242 } break; 1243 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 synchronized (ActivityManagerService.this) { 1246 ProcessRecord proc = (ProcessRecord) data.get("app"); 1247 if (proc == null) { 1248 Slog.e(TAG, "App not found when showing strict mode dialog."); 1249 break; 1250 } 1251 if (proc.crashDialog != null) { 1252 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1253 return; 1254 } 1255 AppErrorResult res = (AppErrorResult) data.get("result"); 1256 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1257 Dialog d = new StrictModeViolationDialog(mContext, 1258 ActivityManagerService.this, res, proc); 1259 d.show(); 1260 proc.crashDialog = d; 1261 } else { 1262 // The device is asleep, so just pretend that the user 1263 // saw a crash dialog and hit "force quit". 1264 res.set(0); 1265 } 1266 } 1267 ensureBootCompleted(); 1268 } break; 1269 case SHOW_FACTORY_ERROR_MSG: { 1270 Dialog d = new FactoryErrorDialog( 1271 mContext, msg.getData().getCharSequence("msg")); 1272 d.show(); 1273 ensureBootCompleted(); 1274 } break; 1275 case UPDATE_CONFIGURATION_MSG: { 1276 final ContentResolver resolver = mContext.getContentResolver(); 1277 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1278 } break; 1279 case GC_BACKGROUND_PROCESSES_MSG: { 1280 synchronized (ActivityManagerService.this) { 1281 performAppGcsIfAppropriateLocked(); 1282 } 1283 } break; 1284 case WAIT_FOR_DEBUGGER_MSG: { 1285 synchronized (ActivityManagerService.this) { 1286 ProcessRecord app = (ProcessRecord)msg.obj; 1287 if (msg.arg1 != 0) { 1288 if (!app.waitedForDebugger) { 1289 Dialog d = new AppWaitingForDebuggerDialog( 1290 ActivityManagerService.this, 1291 mContext, app); 1292 app.waitDialog = d; 1293 app.waitedForDebugger = true; 1294 d.show(); 1295 } 1296 } else { 1297 if (app.waitDialog != null) { 1298 app.waitDialog.dismiss(); 1299 app.waitDialog = null; 1300 } 1301 } 1302 } 1303 } break; 1304 case SERVICE_TIMEOUT_MSG: { 1305 if (mDidDexOpt) { 1306 mDidDexOpt = false; 1307 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1308 nmsg.obj = msg.obj; 1309 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1310 return; 1311 } 1312 mServices.serviceTimeout((ProcessRecord)msg.obj); 1313 } break; 1314 case UPDATE_TIME_ZONE: { 1315 synchronized (ActivityManagerService.this) { 1316 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1317 ProcessRecord r = mLruProcesses.get(i); 1318 if (r.thread != null) { 1319 try { 1320 r.thread.updateTimeZone(); 1321 } catch (RemoteException ex) { 1322 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1323 } 1324 } 1325 } 1326 } 1327 } break; 1328 case CLEAR_DNS_CACHE_MSG: { 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.clearDnsCache(); 1335 } catch (RemoteException ex) { 1336 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1337 } 1338 } 1339 } 1340 } 1341 } break; 1342 case UPDATE_HTTP_PROXY_MSG: { 1343 ProxyInfo proxy = (ProxyInfo)msg.obj; 1344 String host = ""; 1345 String port = ""; 1346 String exclList = ""; 1347 Uri pacFileUrl = Uri.EMPTY; 1348 if (proxy != null) { 1349 host = proxy.getHost(); 1350 port = Integer.toString(proxy.getPort()); 1351 exclList = proxy.getExclusionListAsString(); 1352 pacFileUrl = proxy.getPacFileUrl(); 1353 } 1354 synchronized (ActivityManagerService.this) { 1355 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1356 ProcessRecord r = mLruProcesses.get(i); 1357 if (r.thread != null) { 1358 try { 1359 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1360 } catch (RemoteException ex) { 1361 Slog.w(TAG, "Failed to update http proxy for: " + 1362 r.info.processName); 1363 } 1364 } 1365 } 1366 } 1367 } break; 1368 case SHOW_UID_ERROR_MSG: { 1369 String title = "System UIDs Inconsistent"; 1370 String text = "UIDs on the system are inconsistent, you need to wipe your" 1371 + " data partition or your device will be unstable."; 1372 Log.e(TAG, title + ": " + text); 1373 if (mShowDialogs) { 1374 // XXX This is a temporary dialog, no need to localize. 1375 AlertDialog d = new BaseErrorDialog(mContext); 1376 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1377 d.setCancelable(false); 1378 d.setTitle(title); 1379 d.setMessage(text); 1380 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1381 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1382 mUidAlert = d; 1383 d.show(); 1384 } 1385 } break; 1386 case IM_FEELING_LUCKY_MSG: { 1387 if (mUidAlert != null) { 1388 mUidAlert.dismiss(); 1389 mUidAlert = null; 1390 } 1391 } break; 1392 case PROC_START_TIMEOUT_MSG: { 1393 if (mDidDexOpt) { 1394 mDidDexOpt = false; 1395 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1396 nmsg.obj = msg.obj; 1397 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1398 return; 1399 } 1400 ProcessRecord app = (ProcessRecord)msg.obj; 1401 synchronized (ActivityManagerService.this) { 1402 processStartTimedOutLocked(app); 1403 } 1404 } break; 1405 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1406 synchronized (ActivityManagerService.this) { 1407 doPendingActivityLaunchesLocked(true); 1408 } 1409 } break; 1410 case KILL_APPLICATION_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 int appid = msg.arg1; 1413 boolean restart = (msg.arg2 == 1); 1414 Bundle bundle = (Bundle)msg.obj; 1415 String pkg = bundle.getString("pkg"); 1416 String reason = bundle.getString("reason"); 1417 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1418 false, UserHandle.USER_ALL, reason); 1419 } 1420 } break; 1421 case FINALIZE_PENDING_INTENT_MSG: { 1422 ((PendingIntentRecord)msg.obj).completeFinalize(); 1423 } break; 1424 case POST_HEAVY_NOTIFICATION_MSG: { 1425 INotificationManager inm = NotificationManager.getService(); 1426 if (inm == null) { 1427 return; 1428 } 1429 1430 ActivityRecord root = (ActivityRecord)msg.obj; 1431 ProcessRecord process = root.app; 1432 if (process == null) { 1433 return; 1434 } 1435 1436 try { 1437 Context context = mContext.createPackageContext(process.info.packageName, 0); 1438 String text = mContext.getString(R.string.heavy_weight_notification, 1439 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1440 Notification notification = new Notification(); 1441 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1442 notification.when = 0; 1443 notification.flags = Notification.FLAG_ONGOING_EVENT; 1444 notification.tickerText = text; 1445 notification.defaults = 0; // please be quiet 1446 notification.sound = null; 1447 notification.vibrate = null; 1448 notification.setLatestEventInfo(context, text, 1449 mContext.getText(R.string.heavy_weight_notification_detail), 1450 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1451 PendingIntent.FLAG_CANCEL_CURRENT, null, 1452 new UserHandle(root.userId))); 1453 1454 try { 1455 int[] outId = new int[1]; 1456 inm.enqueueNotificationWithTag("android", "android", null, 1457 R.string.heavy_weight_notification, 1458 notification, outId, root.userId); 1459 } catch (RuntimeException e) { 1460 Slog.w(ActivityManagerService.TAG, 1461 "Error showing notification for heavy-weight app", e); 1462 } catch (RemoteException e) { 1463 } 1464 } catch (NameNotFoundException e) { 1465 Slog.w(TAG, "Unable to create context for heavy notification", e); 1466 } 1467 } break; 1468 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1469 INotificationManager inm = NotificationManager.getService(); 1470 if (inm == null) { 1471 return; 1472 } 1473 try { 1474 inm.cancelNotificationWithTag("android", null, 1475 R.string.heavy_weight_notification, msg.arg1); 1476 } catch (RuntimeException e) { 1477 Slog.w(ActivityManagerService.TAG, 1478 "Error canceling notification for service", e); 1479 } catch (RemoteException e) { 1480 } 1481 } break; 1482 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1483 synchronized (ActivityManagerService.this) { 1484 checkExcessivePowerUsageLocked(true); 1485 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1486 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1487 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1488 } 1489 } break; 1490 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1491 synchronized (ActivityManagerService.this) { 1492 ActivityRecord ar = (ActivityRecord)msg.obj; 1493 if (mCompatModeDialog != null) { 1494 if (mCompatModeDialog.mAppInfo.packageName.equals( 1495 ar.info.applicationInfo.packageName)) { 1496 return; 1497 } 1498 mCompatModeDialog.dismiss(); 1499 mCompatModeDialog = null; 1500 } 1501 if (ar != null && false) { 1502 if (mCompatModePackages.getPackageAskCompatModeLocked( 1503 ar.packageName)) { 1504 int mode = mCompatModePackages.computeCompatModeLocked( 1505 ar.info.applicationInfo); 1506 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1507 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1508 mCompatModeDialog = new CompatModeDialog( 1509 ActivityManagerService.this, mContext, 1510 ar.info.applicationInfo); 1511 mCompatModeDialog.show(); 1512 } 1513 } 1514 } 1515 } 1516 break; 1517 } 1518 case DISPATCH_PROCESSES_CHANGED: { 1519 dispatchProcessesChanged(); 1520 break; 1521 } 1522 case DISPATCH_PROCESS_DIED: { 1523 final int pid = msg.arg1; 1524 final int uid = msg.arg2; 1525 dispatchProcessDied(pid, uid); 1526 break; 1527 } 1528 case REPORT_MEM_USAGE_MSG: { 1529 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1530 Thread thread = new Thread() { 1531 @Override public void run() { 1532 final SparseArray<ProcessMemInfo> infoMap 1533 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1534 for (int i=0, N=memInfos.size(); i<N; i++) { 1535 ProcessMemInfo mi = memInfos.get(i); 1536 infoMap.put(mi.pid, mi); 1537 } 1538 updateCpuStatsNow(); 1539 synchronized (mProcessCpuThread) { 1540 final int N = mProcessCpuTracker.countStats(); 1541 for (int i=0; i<N; i++) { 1542 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1543 if (st.vsize > 0) { 1544 long pss = Debug.getPss(st.pid, null); 1545 if (pss > 0) { 1546 if (infoMap.indexOfKey(st.pid) < 0) { 1547 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1548 ProcessList.NATIVE_ADJ, -1, "native", null); 1549 mi.pss = pss; 1550 memInfos.add(mi); 1551 } 1552 } 1553 } 1554 } 1555 } 1556 1557 long totalPss = 0; 1558 for (int i=0, N=memInfos.size(); i<N; i++) { 1559 ProcessMemInfo mi = memInfos.get(i); 1560 if (mi.pss == 0) { 1561 mi.pss = Debug.getPss(mi.pid, null); 1562 } 1563 totalPss += mi.pss; 1564 } 1565 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1566 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1567 if (lhs.oomAdj != rhs.oomAdj) { 1568 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1569 } 1570 if (lhs.pss != rhs.pss) { 1571 return lhs.pss < rhs.pss ? 1 : -1; 1572 } 1573 return 0; 1574 } 1575 }); 1576 1577 StringBuilder tag = new StringBuilder(128); 1578 StringBuilder stack = new StringBuilder(128); 1579 tag.append("Low on memory -- "); 1580 appendMemBucket(tag, totalPss, "total", false); 1581 appendMemBucket(stack, totalPss, "total", true); 1582 1583 StringBuilder logBuilder = new StringBuilder(1024); 1584 logBuilder.append("Low on memory:\n"); 1585 1586 boolean firstLine = true; 1587 int lastOomAdj = Integer.MIN_VALUE; 1588 for (int i=0, N=memInfos.size(); i<N; i++) { 1589 ProcessMemInfo mi = memInfos.get(i); 1590 1591 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1592 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1593 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1594 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1595 if (lastOomAdj != mi.oomAdj) { 1596 lastOomAdj = mi.oomAdj; 1597 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1598 tag.append(" / "); 1599 } 1600 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1601 if (firstLine) { 1602 stack.append(":"); 1603 firstLine = false; 1604 } 1605 stack.append("\n\t at "); 1606 } else { 1607 stack.append("$"); 1608 } 1609 } else { 1610 tag.append(" "); 1611 stack.append("$"); 1612 } 1613 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1614 appendMemBucket(tag, mi.pss, mi.name, false); 1615 } 1616 appendMemBucket(stack, mi.pss, mi.name, true); 1617 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1618 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1619 stack.append("("); 1620 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1621 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1622 stack.append(DUMP_MEM_OOM_LABEL[k]); 1623 stack.append(":"); 1624 stack.append(DUMP_MEM_OOM_ADJ[k]); 1625 } 1626 } 1627 stack.append(")"); 1628 } 1629 } 1630 1631 logBuilder.append(" "); 1632 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1633 logBuilder.append(' '); 1634 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1635 logBuilder.append(' '); 1636 ProcessList.appendRamKb(logBuilder, mi.pss); 1637 logBuilder.append(" kB: "); 1638 logBuilder.append(mi.name); 1639 logBuilder.append(" ("); 1640 logBuilder.append(mi.pid); 1641 logBuilder.append(") "); 1642 logBuilder.append(mi.adjType); 1643 logBuilder.append('\n'); 1644 if (mi.adjReason != null) { 1645 logBuilder.append(" "); 1646 logBuilder.append(mi.adjReason); 1647 logBuilder.append('\n'); 1648 } 1649 } 1650 1651 logBuilder.append(" "); 1652 ProcessList.appendRamKb(logBuilder, totalPss); 1653 logBuilder.append(" kB: TOTAL\n"); 1654 1655 long[] infos = new long[Debug.MEMINFO_COUNT]; 1656 Debug.getMemInfo(infos); 1657 logBuilder.append(" MemInfo: "); 1658 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1659 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1660 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1661 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1662 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1663 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1664 logBuilder.append(" ZRAM: "); 1665 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1666 logBuilder.append(" kB RAM, "); 1667 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1668 logBuilder.append(" kB swap total, "); 1669 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1670 logBuilder.append(" kB swap free\n"); 1671 } 1672 Slog.i(TAG, logBuilder.toString()); 1673 1674 StringBuilder dropBuilder = new StringBuilder(1024); 1675 /* 1676 StringWriter oomSw = new StringWriter(); 1677 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1678 StringWriter catSw = new StringWriter(); 1679 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1680 String[] emptyArgs = new String[] { }; 1681 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1682 oomPw.flush(); 1683 String oomString = oomSw.toString(); 1684 */ 1685 dropBuilder.append(stack); 1686 dropBuilder.append('\n'); 1687 dropBuilder.append('\n'); 1688 dropBuilder.append(logBuilder); 1689 dropBuilder.append('\n'); 1690 /* 1691 dropBuilder.append(oomString); 1692 dropBuilder.append('\n'); 1693 */ 1694 StringWriter catSw = new StringWriter(); 1695 synchronized (ActivityManagerService.this) { 1696 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1697 String[] emptyArgs = new String[] { }; 1698 catPw.println(); 1699 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1700 catPw.println(); 1701 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1702 false, false, null); 1703 catPw.println(); 1704 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1705 catPw.flush(); 1706 } 1707 dropBuilder.append(catSw.toString()); 1708 addErrorToDropBox("lowmem", null, "system_server", null, 1709 null, tag.toString(), dropBuilder.toString(), null, null); 1710 //Slog.i(TAG, "Sent to dropbox:"); 1711 //Slog.i(TAG, dropBuilder.toString()); 1712 synchronized (ActivityManagerService.this) { 1713 long now = SystemClock.uptimeMillis(); 1714 if (mLastMemUsageReportTime < now) { 1715 mLastMemUsageReportTime = now; 1716 } 1717 } 1718 } 1719 }; 1720 thread.start(); 1721 break; 1722 } 1723 case REPORT_USER_SWITCH_MSG: { 1724 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1725 break; 1726 } 1727 case CONTINUE_USER_SWITCH_MSG: { 1728 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1729 break; 1730 } 1731 case USER_SWITCH_TIMEOUT_MSG: { 1732 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1733 break; 1734 } 1735 case IMMERSIVE_MODE_LOCK_MSG: { 1736 final boolean nextState = (msg.arg1 != 0); 1737 if (mUpdateLock.isHeld() != nextState) { 1738 if (DEBUG_IMMERSIVE) { 1739 final ActivityRecord r = (ActivityRecord) msg.obj; 1740 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1741 } 1742 if (nextState) { 1743 mUpdateLock.acquire(); 1744 } else { 1745 mUpdateLock.release(); 1746 } 1747 } 1748 break; 1749 } 1750 case PERSIST_URI_GRANTS_MSG: { 1751 writeGrantedUriPermissions(); 1752 break; 1753 } 1754 case REQUEST_ALL_PSS_MSG: { 1755 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1756 break; 1757 } 1758 case START_PROFILES_MSG: { 1759 synchronized (ActivityManagerService.this) { 1760 startProfilesLocked(); 1761 } 1762 break; 1763 } 1764 case UPDATE_TIME: { 1765 synchronized (ActivityManagerService.this) { 1766 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1767 ProcessRecord r = mLruProcesses.get(i); 1768 if (r.thread != null) { 1769 try { 1770 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1771 } catch (RemoteException ex) { 1772 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1773 } 1774 } 1775 } 1776 } 1777 break; 1778 } 1779 case SYSTEM_USER_START_MSG: { 1780 mSystemServiceManager.startUser(msg.arg1); 1781 break; 1782 } 1783 case SYSTEM_USER_CURRENT_MSG: { 1784 mSystemServiceManager.switchUser(msg.arg1); 1785 break; 1786 } 1787 } 1788 } 1789 }; 1790 1791 static final int COLLECT_PSS_BG_MSG = 1; 1792 1793 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1794 @Override 1795 public void handleMessage(Message msg) { 1796 switch (msg.what) { 1797 case COLLECT_PSS_BG_MSG: { 1798 int i=0, num=0; 1799 long start = SystemClock.uptimeMillis(); 1800 long[] tmp = new long[1]; 1801 do { 1802 ProcessRecord proc; 1803 int procState; 1804 int pid; 1805 synchronized (ActivityManagerService.this) { 1806 if (i >= mPendingPssProcesses.size()) { 1807 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1808 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1809 mPendingPssProcesses.clear(); 1810 return; 1811 } 1812 proc = mPendingPssProcesses.get(i); 1813 procState = proc.pssProcState; 1814 if (proc.thread != null && procState == proc.setProcState) { 1815 pid = proc.pid; 1816 } else { 1817 proc = null; 1818 pid = 0; 1819 } 1820 i++; 1821 } 1822 if (proc != null) { 1823 long pss = Debug.getPss(pid, tmp); 1824 synchronized (ActivityManagerService.this) { 1825 if (proc.thread != null && proc.setProcState == procState 1826 && proc.pid == pid) { 1827 num++; 1828 proc.lastPssTime = SystemClock.uptimeMillis(); 1829 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1830 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1831 + ": " + pss + " lastPss=" + proc.lastPss 1832 + " state=" + ProcessList.makeProcStateString(procState)); 1833 if (proc.initialIdlePss == 0) { 1834 proc.initialIdlePss = pss; 1835 } 1836 proc.lastPss = pss; 1837 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1838 proc.lastCachedPss = pss; 1839 } 1840 } 1841 } 1842 } 1843 } while (true); 1844 } 1845 } 1846 } 1847 }; 1848 1849 /** 1850 * Monitor for package changes and update our internal state. 1851 */ 1852 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1853 @Override 1854 public void onPackageRemoved(String packageName, int uid) { 1855 // Remove all tasks with activities in the specified package from the list of recent tasks 1856 synchronized (ActivityManagerService.this) { 1857 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1858 TaskRecord tr = mRecentTasks.get(i); 1859 ComponentName cn = tr.intent.getComponent(); 1860 if (cn != null && cn.getPackageName().equals(packageName)) { 1861 // If the package name matches, remove the task and kill the process 1862 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1863 } 1864 } 1865 } 1866 } 1867 1868 @Override 1869 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1870 onPackageModified(packageName); 1871 return true; 1872 } 1873 1874 @Override 1875 public void onPackageModified(String packageName) { 1876 final PackageManager pm = mContext.getPackageManager(); 1877 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1878 new ArrayList<Pair<Intent, Integer>>(); 1879 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1880 // Copy the list of recent tasks so that we don't hold onto the lock on 1881 // ActivityManagerService for long periods while checking if components exist. 1882 synchronized (ActivityManagerService.this) { 1883 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1884 TaskRecord tr = mRecentTasks.get(i); 1885 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1886 } 1887 } 1888 // Check the recent tasks and filter out all tasks with components that no longer exist. 1889 Intent tmpI = new Intent(); 1890 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1891 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1892 ComponentName cn = p.first.getComponent(); 1893 if (cn != null && cn.getPackageName().equals(packageName)) { 1894 try { 1895 // Add the task to the list to remove if the component no longer exists 1896 tmpI.setComponent(cn); 1897 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1898 tasksToRemove.add(p.second); 1899 } 1900 } catch (Exception e) {} 1901 } 1902 } 1903 // Prune all the tasks with removed components from the list of recent tasks 1904 synchronized (ActivityManagerService.this) { 1905 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1906 // Remove the task but don't kill the process (since other components in that 1907 // package may still be running and in the background) 1908 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1909 } 1910 } 1911 } 1912 1913 @Override 1914 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1915 // Force stop the specified packages 1916 if (packages != null) { 1917 for (String pkg : packages) { 1918 synchronized (ActivityManagerService.this) { 1919 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1920 "finished booting")) { 1921 return true; 1922 } 1923 } 1924 } 1925 } 1926 return false; 1927 } 1928 }; 1929 1930 public void setSystemProcess() { 1931 try { 1932 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1933 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1934 ServiceManager.addService("meminfo", new MemBinder(this)); 1935 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1936 ServiceManager.addService("dbinfo", new DbBinder(this)); 1937 if (MONITOR_CPU_USAGE) { 1938 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1939 } 1940 ServiceManager.addService("permission", new PermissionController(this)); 1941 1942 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1943 "android", STOCK_PM_FLAGS); 1944 mSystemThread.installSystemApplicationInfo(info); 1945 1946 synchronized (this) { 1947 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1948 app.persistent = true; 1949 app.pid = MY_PID; 1950 app.maxAdj = ProcessList.SYSTEM_ADJ; 1951 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1952 mProcessNames.put(app.processName, app.uid, app); 1953 synchronized (mPidsSelfLocked) { 1954 mPidsSelfLocked.put(app.pid, app); 1955 } 1956 updateLruProcessLocked(app, false, null); 1957 updateOomAdjLocked(); 1958 } 1959 } catch (PackageManager.NameNotFoundException e) { 1960 throw new RuntimeException( 1961 "Unable to find android system package", e); 1962 } 1963 } 1964 1965 public void setWindowManager(WindowManagerService wm) { 1966 mWindowManager = wm; 1967 mStackSupervisor.setWindowManager(wm); 1968 } 1969 1970 public void startObservingNativeCrashes() { 1971 final NativeCrashListener ncl = new NativeCrashListener(this); 1972 ncl.start(); 1973 } 1974 1975 public IAppOpsService getAppOpsService() { 1976 return mAppOpsService; 1977 } 1978 1979 static class MemBinder extends Binder { 1980 ActivityManagerService mActivityManagerService; 1981 MemBinder(ActivityManagerService activityManagerService) { 1982 mActivityManagerService = activityManagerService; 1983 } 1984 1985 @Override 1986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1987 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1988 != PackageManager.PERMISSION_GRANTED) { 1989 pw.println("Permission Denial: can't dump meminfo from from pid=" 1990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1991 + " without permission " + android.Manifest.permission.DUMP); 1992 return; 1993 } 1994 1995 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1996 } 1997 } 1998 1999 static class GraphicsBinder extends Binder { 2000 ActivityManagerService mActivityManagerService; 2001 GraphicsBinder(ActivityManagerService activityManagerService) { 2002 mActivityManagerService = activityManagerService; 2003 } 2004 2005 @Override 2006 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2007 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2008 != PackageManager.PERMISSION_GRANTED) { 2009 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2010 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2011 + " without permission " + android.Manifest.permission.DUMP); 2012 return; 2013 } 2014 2015 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2016 } 2017 } 2018 2019 static class DbBinder extends Binder { 2020 ActivityManagerService mActivityManagerService; 2021 DbBinder(ActivityManagerService activityManagerService) { 2022 mActivityManagerService = activityManagerService; 2023 } 2024 2025 @Override 2026 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2027 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2028 != PackageManager.PERMISSION_GRANTED) { 2029 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2030 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2031 + " without permission " + android.Manifest.permission.DUMP); 2032 return; 2033 } 2034 2035 mActivityManagerService.dumpDbInfo(fd, pw, args); 2036 } 2037 } 2038 2039 static class CpuBinder extends Binder { 2040 ActivityManagerService mActivityManagerService; 2041 CpuBinder(ActivityManagerService activityManagerService) { 2042 mActivityManagerService = activityManagerService; 2043 } 2044 2045 @Override 2046 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2047 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2048 != PackageManager.PERMISSION_GRANTED) { 2049 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2050 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2051 + " without permission " + android.Manifest.permission.DUMP); 2052 return; 2053 } 2054 2055 synchronized (mActivityManagerService.mProcessCpuThread) { 2056 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2057 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2058 SystemClock.uptimeMillis())); 2059 } 2060 } 2061 } 2062 2063 public static final class Lifecycle extends SystemService { 2064 private final ActivityManagerService mService; 2065 2066 public Lifecycle(Context context) { 2067 super(context); 2068 mService = new ActivityManagerService(context); 2069 } 2070 2071 @Override 2072 public void onStart() { 2073 mService.start(); 2074 } 2075 2076 public ActivityManagerService getService() { 2077 return mService; 2078 } 2079 } 2080 2081 // Note: This method is invoked on the main thread but may need to attach various 2082 // handlers to other threads. So take care to be explicit about the looper. 2083 public ActivityManagerService(Context systemContext) { 2084 mContext = systemContext; 2085 mFactoryTest = FactoryTest.getMode(); 2086 mSystemThread = ActivityThread.currentActivityThread(); 2087 2088 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2089 2090 mHandlerThread = new ServiceThread(TAG, 2091 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2092 mHandlerThread.start(); 2093 mHandler = new MainHandler(mHandlerThread.getLooper()); 2094 2095 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2096 "foreground", BROADCAST_FG_TIMEOUT, false); 2097 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2098 "background", BROADCAST_BG_TIMEOUT, true); 2099 mBroadcastQueues[0] = mFgBroadcastQueue; 2100 mBroadcastQueues[1] = mBgBroadcastQueue; 2101 2102 mServices = new ActiveServices(this); 2103 mProviderMap = new ProviderMap(this); 2104 2105 // TODO: Move creation of battery stats service outside of activity manager service. 2106 File dataDir = Environment.getDataDirectory(); 2107 File systemDir = new File(dataDir, "system"); 2108 systemDir.mkdirs(); 2109 mBatteryStatsService = new BatteryStatsService(new File( 2110 systemDir, "batterystats.bin").toString(), mHandler); 2111 mBatteryStatsService.getActiveStatistics().readLocked(); 2112 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2113 mOnBattery = DEBUG_POWER ? true 2114 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2115 mBatteryStatsService.getActiveStatistics().setCallback(this); 2116 2117 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2118 2119 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2120 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2121 2122 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2123 2124 // User 0 is the first and only user that runs at boot. 2125 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2126 mUserLru.add(Integer.valueOf(0)); 2127 updateStartedUserArrayLocked(); 2128 2129 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2130 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2131 2132 mConfiguration.setToDefaults(); 2133 mConfiguration.setLocale(Locale.getDefault()); 2134 2135 mConfigurationSeq = mConfiguration.seq = 1; 2136 mProcessCpuTracker.init(); 2137 2138 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2139 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2140 mStackSupervisor = new ActivityStackSupervisor(this); 2141 2142 mProcessCpuThread = new Thread("CpuTracker") { 2143 @Override 2144 public void run() { 2145 while (true) { 2146 try { 2147 try { 2148 synchronized(this) { 2149 final long now = SystemClock.uptimeMillis(); 2150 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2151 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2152 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2153 // + ", write delay=" + nextWriteDelay); 2154 if (nextWriteDelay < nextCpuDelay) { 2155 nextCpuDelay = nextWriteDelay; 2156 } 2157 if (nextCpuDelay > 0) { 2158 mProcessCpuMutexFree.set(true); 2159 this.wait(nextCpuDelay); 2160 } 2161 } 2162 } catch (InterruptedException e) { 2163 } 2164 updateCpuStatsNow(); 2165 } catch (Exception e) { 2166 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2167 } 2168 } 2169 } 2170 }; 2171 2172 Watchdog.getInstance().addMonitor(this); 2173 Watchdog.getInstance().addThread(mHandler); 2174 } 2175 2176 public void setSystemServiceManager(SystemServiceManager mgr) { 2177 mSystemServiceManager = mgr; 2178 } 2179 2180 private void start() { 2181 mProcessCpuThread.start(); 2182 2183 mBatteryStatsService.publish(mContext); 2184 mUsageStatsService.publish(mContext); 2185 mAppOpsService.publish(mContext); 2186 2187 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2188 } 2189 2190 @Override 2191 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2192 throws RemoteException { 2193 if (code == SYSPROPS_TRANSACTION) { 2194 // We need to tell all apps about the system property change. 2195 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2196 synchronized(this) { 2197 final int NP = mProcessNames.getMap().size(); 2198 for (int ip=0; ip<NP; ip++) { 2199 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2200 final int NA = apps.size(); 2201 for (int ia=0; ia<NA; ia++) { 2202 ProcessRecord app = apps.valueAt(ia); 2203 if (app.thread != null) { 2204 procs.add(app.thread.asBinder()); 2205 } 2206 } 2207 } 2208 } 2209 2210 int N = procs.size(); 2211 for (int i=0; i<N; i++) { 2212 Parcel data2 = Parcel.obtain(); 2213 try { 2214 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2215 } catch (RemoteException e) { 2216 } 2217 data2.recycle(); 2218 } 2219 } 2220 try { 2221 return super.onTransact(code, data, reply, flags); 2222 } catch (RuntimeException e) { 2223 // The activity manager only throws security exceptions, so let's 2224 // log all others. 2225 if (!(e instanceof SecurityException)) { 2226 Slog.wtf(TAG, "Activity Manager Crash", e); 2227 } 2228 throw e; 2229 } 2230 } 2231 2232 void updateCpuStats() { 2233 final long now = SystemClock.uptimeMillis(); 2234 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2235 return; 2236 } 2237 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2238 synchronized (mProcessCpuThread) { 2239 mProcessCpuThread.notify(); 2240 } 2241 } 2242 } 2243 2244 void updateCpuStatsNow() { 2245 synchronized (mProcessCpuThread) { 2246 mProcessCpuMutexFree.set(false); 2247 final long now = SystemClock.uptimeMillis(); 2248 boolean haveNewCpuStats = false; 2249 2250 if (MONITOR_CPU_USAGE && 2251 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2252 mLastCpuTime.set(now); 2253 haveNewCpuStats = true; 2254 mProcessCpuTracker.update(); 2255 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2256 //Slog.i(TAG, "Total CPU usage: " 2257 // + mProcessCpu.getTotalCpuPercent() + "%"); 2258 2259 // Slog the cpu usage if the property is set. 2260 if ("true".equals(SystemProperties.get("events.cpu"))) { 2261 int user = mProcessCpuTracker.getLastUserTime(); 2262 int system = mProcessCpuTracker.getLastSystemTime(); 2263 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2264 int irq = mProcessCpuTracker.getLastIrqTime(); 2265 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2266 int idle = mProcessCpuTracker.getLastIdleTime(); 2267 2268 int total = user + system + iowait + irq + softIrq + idle; 2269 if (total == 0) total = 1; 2270 2271 EventLog.writeEvent(EventLogTags.CPU, 2272 ((user+system+iowait+irq+softIrq) * 100) / total, 2273 (user * 100) / total, 2274 (system * 100) / total, 2275 (iowait * 100) / total, 2276 (irq * 100) / total, 2277 (softIrq * 100) / total); 2278 } 2279 } 2280 2281 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2282 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2283 synchronized(bstats) { 2284 synchronized(mPidsSelfLocked) { 2285 if (haveNewCpuStats) { 2286 if (mOnBattery) { 2287 int perc = bstats.startAddingCpuLocked(); 2288 int totalUTime = 0; 2289 int totalSTime = 0; 2290 final int N = mProcessCpuTracker.countStats(); 2291 for (int i=0; i<N; i++) { 2292 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2293 if (!st.working) { 2294 continue; 2295 } 2296 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2297 int otherUTime = (st.rel_utime*perc)/100; 2298 int otherSTime = (st.rel_stime*perc)/100; 2299 totalUTime += otherUTime; 2300 totalSTime += otherSTime; 2301 if (pr != null) { 2302 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2303 if (ps == null || !ps.isActive()) { 2304 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2305 pr.info.uid, pr.processName); 2306 } 2307 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2308 st.rel_stime-otherSTime); 2309 ps.addSpeedStepTimes(cpuSpeedTimes); 2310 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2311 } else { 2312 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2313 if (ps == null || !ps.isActive()) { 2314 st.batteryStats = ps = bstats.getProcessStatsLocked( 2315 bstats.mapUid(st.uid), st.name); 2316 } 2317 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2318 st.rel_stime-otherSTime); 2319 ps.addSpeedStepTimes(cpuSpeedTimes); 2320 } 2321 } 2322 bstats.finishAddingCpuLocked(perc, totalUTime, 2323 totalSTime, cpuSpeedTimes); 2324 } 2325 } 2326 } 2327 2328 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2329 mLastWriteTime = now; 2330 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2331 } 2332 } 2333 } 2334 } 2335 2336 @Override 2337 public void batteryNeedsCpuUpdate() { 2338 updateCpuStatsNow(); 2339 } 2340 2341 @Override 2342 public void batteryPowerChanged(boolean onBattery) { 2343 // When plugging in, update the CPU stats first before changing 2344 // the plug state. 2345 updateCpuStatsNow(); 2346 synchronized (this) { 2347 synchronized(mPidsSelfLocked) { 2348 mOnBattery = DEBUG_POWER ? true : onBattery; 2349 } 2350 } 2351 } 2352 2353 /** 2354 * Initialize the application bind args. These are passed to each 2355 * process when the bindApplication() IPC is sent to the process. They're 2356 * lazily setup to make sure the services are running when they're asked for. 2357 */ 2358 private HashMap<String, IBinder> getCommonServicesLocked() { 2359 if (mAppBindArgs == null) { 2360 mAppBindArgs = new HashMap<String, IBinder>(); 2361 2362 // Setup the application init args 2363 mAppBindArgs.put("package", ServiceManager.getService("package")); 2364 mAppBindArgs.put("window", ServiceManager.getService("window")); 2365 mAppBindArgs.put(Context.ALARM_SERVICE, 2366 ServiceManager.getService(Context.ALARM_SERVICE)); 2367 } 2368 return mAppBindArgs; 2369 } 2370 2371 final void setFocusedActivityLocked(ActivityRecord r) { 2372 if (mFocusedActivity != r) { 2373 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2374 mFocusedActivity = r; 2375 if (r.task != null && r.task.voiceInteractor != null) { 2376 startRunningVoiceLocked(); 2377 } else { 2378 finishRunningVoiceLocked(); 2379 } 2380 mStackSupervisor.setFocusedStack(r); 2381 if (r != null) { 2382 mWindowManager.setFocusedApp(r.appToken, true); 2383 } 2384 applyUpdateLockStateLocked(r); 2385 } 2386 } 2387 2388 final void clearFocusedActivity(ActivityRecord r) { 2389 if (mFocusedActivity == r) { 2390 mFocusedActivity = null; 2391 } 2392 } 2393 2394 @Override 2395 public void setFocusedStack(int stackId) { 2396 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2397 synchronized (ActivityManagerService.this) { 2398 ActivityStack stack = mStackSupervisor.getStack(stackId); 2399 if (stack != null) { 2400 ActivityRecord r = stack.topRunningActivityLocked(null); 2401 if (r != null) { 2402 setFocusedActivityLocked(r); 2403 } 2404 } 2405 } 2406 } 2407 2408 @Override 2409 public void notifyActivityDrawn(IBinder token) { 2410 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2411 synchronized (this) { 2412 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2413 if (r != null) { 2414 r.task.stack.notifyActivityDrawnLocked(r); 2415 } 2416 } 2417 } 2418 2419 final void applyUpdateLockStateLocked(ActivityRecord r) { 2420 // Modifications to the UpdateLock state are done on our handler, outside 2421 // the activity manager's locks. The new state is determined based on the 2422 // state *now* of the relevant activity record. The object is passed to 2423 // the handler solely for logging detail, not to be consulted/modified. 2424 final boolean nextState = r != null && r.immersive; 2425 mHandler.sendMessage( 2426 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2427 } 2428 2429 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2430 Message msg = Message.obtain(); 2431 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2432 msg.obj = r.task.askedCompatMode ? null : r; 2433 mHandler.sendMessage(msg); 2434 } 2435 2436 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2437 String what, Object obj, ProcessRecord srcApp) { 2438 app.lastActivityTime = now; 2439 2440 if (app.activities.size() > 0) { 2441 // Don't want to touch dependent processes that are hosting activities. 2442 return index; 2443 } 2444 2445 int lrui = mLruProcesses.lastIndexOf(app); 2446 if (lrui < 0) { 2447 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2448 + what + " " + obj + " from " + srcApp); 2449 return index; 2450 } 2451 2452 if (lrui >= index) { 2453 // Don't want to cause this to move dependent processes *back* in the 2454 // list as if they were less frequently used. 2455 return index; 2456 } 2457 2458 if (lrui >= mLruProcessActivityStart) { 2459 // Don't want to touch dependent processes that are hosting activities. 2460 return index; 2461 } 2462 2463 mLruProcesses.remove(lrui); 2464 if (index > 0) { 2465 index--; 2466 } 2467 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2468 + " in LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 return index; 2471 } 2472 2473 final void removeLruProcessLocked(ProcessRecord app) { 2474 int lrui = mLruProcesses.lastIndexOf(app); 2475 if (lrui >= 0) { 2476 if (lrui <= mLruProcessActivityStart) { 2477 mLruProcessActivityStart--; 2478 } 2479 if (lrui <= mLruProcessServiceStart) { 2480 mLruProcessServiceStart--; 2481 } 2482 mLruProcesses.remove(lrui); 2483 } 2484 } 2485 2486 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2487 ProcessRecord client) { 2488 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2489 || app.treatLikeActivity; 2490 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2491 if (!activityChange && hasActivity) { 2492 // The process has activities, so we are only allowing activity-based adjustments 2493 // to move it. It should be kept in the front of the list with other 2494 // processes that have activities, and we don't want those to change their 2495 // order except due to activity operations. 2496 return; 2497 } 2498 2499 mLruSeq++; 2500 final long now = SystemClock.uptimeMillis(); 2501 app.lastActivityTime = now; 2502 2503 // First a quick reject: if the app is already at the position we will 2504 // put it, then there is nothing to do. 2505 if (hasActivity) { 2506 final int N = mLruProcesses.size(); 2507 if (N > 0 && mLruProcesses.get(N-1) == app) { 2508 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2509 return; 2510 } 2511 } else { 2512 if (mLruProcessServiceStart > 0 2513 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2514 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2515 return; 2516 } 2517 } 2518 2519 int lrui = mLruProcesses.lastIndexOf(app); 2520 2521 if (app.persistent && lrui >= 0) { 2522 // We don't care about the position of persistent processes, as long as 2523 // they are in the list. 2524 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2525 return; 2526 } 2527 2528 /* In progress: compute new position first, so we can avoid doing work 2529 if the process is not actually going to move. Not yet working. 2530 int addIndex; 2531 int nextIndex; 2532 boolean inActivity = false, inService = false; 2533 if (hasActivity) { 2534 // Process has activities, put it at the very tipsy-top. 2535 addIndex = mLruProcesses.size(); 2536 nextIndex = mLruProcessServiceStart; 2537 inActivity = true; 2538 } else if (hasService) { 2539 // Process has services, put it at the top of the service list. 2540 addIndex = mLruProcessActivityStart; 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 inService = true; 2544 } else { 2545 // Process not otherwise of interest, it goes to the top of the non-service area. 2546 addIndex = mLruProcessServiceStart; 2547 if (client != null) { 2548 int clientIndex = mLruProcesses.lastIndexOf(client); 2549 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2550 + app); 2551 if (clientIndex >= 0 && addIndex > clientIndex) { 2552 addIndex = clientIndex; 2553 } 2554 } 2555 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2556 } 2557 2558 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2559 + mLruProcessActivityStart + "): " + app); 2560 */ 2561 2562 if (lrui >= 0) { 2563 if (lrui < mLruProcessActivityStart) { 2564 mLruProcessActivityStart--; 2565 } 2566 if (lrui < mLruProcessServiceStart) { 2567 mLruProcessServiceStart--; 2568 } 2569 /* 2570 if (addIndex > lrui) { 2571 addIndex--; 2572 } 2573 if (nextIndex > lrui) { 2574 nextIndex--; 2575 } 2576 */ 2577 mLruProcesses.remove(lrui); 2578 } 2579 2580 /* 2581 mLruProcesses.add(addIndex, app); 2582 if (inActivity) { 2583 mLruProcessActivityStart++; 2584 } 2585 if (inService) { 2586 mLruProcessActivityStart++; 2587 } 2588 */ 2589 2590 int nextIndex; 2591 if (hasActivity) { 2592 final int N = mLruProcesses.size(); 2593 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2594 // Process doesn't have activities, but has clients with 2595 // activities... move it up, but one below the top (the top 2596 // should always have a real activity). 2597 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2598 mLruProcesses.add(N-1, app); 2599 // To keep it from spamming the LRU list (by making a bunch of clients), 2600 // we will push down any other entries owned by the app. 2601 final int uid = app.info.uid; 2602 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2603 ProcessRecord subProc = mLruProcesses.get(i); 2604 if (subProc.info.uid == uid) { 2605 // We want to push this one down the list. If the process after 2606 // it is for the same uid, however, don't do so, because we don't 2607 // want them internally to be re-ordered. 2608 if (mLruProcesses.get(i-1).info.uid != uid) { 2609 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2610 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2611 ProcessRecord tmp = mLruProcesses.get(i); 2612 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2613 mLruProcesses.set(i-1, tmp); 2614 i--; 2615 } 2616 } else { 2617 // A gap, we can stop here. 2618 break; 2619 } 2620 } 2621 } else { 2622 // Process has activities, put it at the very tipsy-top. 2623 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2624 mLruProcesses.add(app); 2625 } 2626 nextIndex = mLruProcessServiceStart; 2627 } else if (hasService) { 2628 // Process has services, put it at the top of the service list. 2629 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2630 mLruProcesses.add(mLruProcessActivityStart, app); 2631 nextIndex = mLruProcessServiceStart; 2632 mLruProcessActivityStart++; 2633 } else { 2634 // Process not otherwise of interest, it goes to the top of the non-service area. 2635 int index = mLruProcessServiceStart; 2636 if (client != null) { 2637 // If there is a client, don't allow the process to be moved up higher 2638 // in the list than that client. 2639 int clientIndex = mLruProcesses.lastIndexOf(client); 2640 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2641 + " when updating " + app); 2642 if (clientIndex <= lrui) { 2643 // Don't allow the client index restriction to push it down farther in the 2644 // list than it already is. 2645 clientIndex = lrui; 2646 } 2647 if (clientIndex >= 0 && index > clientIndex) { 2648 index = clientIndex; 2649 } 2650 } 2651 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2652 mLruProcesses.add(index, app); 2653 nextIndex = index-1; 2654 mLruProcessActivityStart++; 2655 mLruProcessServiceStart++; 2656 } 2657 2658 // If the app is currently using a content provider or service, 2659 // bump those processes as well. 2660 for (int j=app.connections.size()-1; j>=0; j--) { 2661 ConnectionRecord cr = app.connections.valueAt(j); 2662 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2663 && cr.binding.service.app != null 2664 && cr.binding.service.app.lruSeq != mLruSeq 2665 && !cr.binding.service.app.persistent) { 2666 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2667 "service connection", cr, app); 2668 } 2669 } 2670 for (int j=app.conProviders.size()-1; j>=0; j--) { 2671 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2672 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2673 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2674 "provider reference", cpr, app); 2675 } 2676 } 2677 } 2678 2679 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2680 if (uid == Process.SYSTEM_UID) { 2681 // The system gets to run in any process. If there are multiple 2682 // processes with the same uid, just pick the first (this 2683 // should never happen). 2684 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2685 if (procs == null) return null; 2686 final int N = procs.size(); 2687 for (int i = 0; i < N; i++) { 2688 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2689 } 2690 } 2691 ProcessRecord proc = mProcessNames.get(processName, uid); 2692 if (false && proc != null && !keepIfLarge 2693 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2694 && proc.lastCachedPss >= 4000) { 2695 // Turn this condition on to cause killing to happen regularly, for testing. 2696 if (proc.baseProcessTracker != null) { 2697 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2698 } 2699 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2700 + "k from cached"); 2701 } else if (proc != null && !keepIfLarge 2702 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2703 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2704 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2705 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2706 if (proc.baseProcessTracker != null) { 2707 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2708 } 2709 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2710 + "k from cached"); 2711 } 2712 } 2713 return proc; 2714 } 2715 2716 void ensurePackageDexOpt(String packageName) { 2717 IPackageManager pm = AppGlobals.getPackageManager(); 2718 try { 2719 if (pm.performDexOpt(packageName)) { 2720 mDidDexOpt = true; 2721 } 2722 } catch (RemoteException e) { 2723 } 2724 } 2725 2726 boolean isNextTransitionForward() { 2727 int transit = mWindowManager.getPendingAppTransition(); 2728 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2729 || transit == AppTransition.TRANSIT_TASK_OPEN 2730 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2731 } 2732 2733 final ProcessRecord startProcessLocked(String processName, 2734 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2735 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2736 boolean isolated, boolean keepIfLarge) { 2737 ProcessRecord app; 2738 if (!isolated) { 2739 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2740 } else { 2741 // If this is an isolated process, it can't re-use an existing process. 2742 app = null; 2743 } 2744 // We don't have to do anything more if: 2745 // (1) There is an existing application record; and 2746 // (2) The caller doesn't think it is dead, OR there is no thread 2747 // object attached to it so we know it couldn't have crashed; and 2748 // (3) There is a pid assigned to it, so it is either starting or 2749 // already running. 2750 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2751 + " app=" + app + " knownToBeDead=" + knownToBeDead 2752 + " thread=" + (app != null ? app.thread : null) 2753 + " pid=" + (app != null ? app.pid : -1)); 2754 if (app != null && app.pid > 0) { 2755 if (!knownToBeDead || app.thread == null) { 2756 // We already have the app running, or are waiting for it to 2757 // come up (we have a pid but not yet its thread), so keep it. 2758 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2759 // If this is a new package in the process, add the package to the list 2760 app.addPackage(info.packageName, mProcessStats); 2761 return app; 2762 } 2763 2764 // An application record is attached to a previous process, 2765 // clean it up now. 2766 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2767 handleAppDiedLocked(app, true, true); 2768 } 2769 2770 String hostingNameStr = hostingName != null 2771 ? hostingName.flattenToShortString() : null; 2772 2773 if (!isolated) { 2774 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2775 // If we are in the background, then check to see if this process 2776 // is bad. If so, we will just silently fail. 2777 if (mBadProcesses.get(info.processName, info.uid) != null) { 2778 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2779 + "/" + info.processName); 2780 return null; 2781 } 2782 } else { 2783 // When the user is explicitly starting a process, then clear its 2784 // crash count so that we won't make it bad until they see at 2785 // least one crash dialog again, and make the process good again 2786 // if it had been bad. 2787 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2788 + "/" + info.processName); 2789 mProcessCrashTimes.remove(info.processName, info.uid); 2790 if (mBadProcesses.get(info.processName, info.uid) != null) { 2791 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2792 UserHandle.getUserId(info.uid), info.uid, 2793 info.processName); 2794 mBadProcesses.remove(info.processName, info.uid); 2795 if (app != null) { 2796 app.bad = false; 2797 } 2798 } 2799 } 2800 } 2801 2802 if (app == null) { 2803 app = newProcessRecordLocked(info, processName, isolated); 2804 if (app == null) { 2805 Slog.w(TAG, "Failed making new process record for " 2806 + processName + "/" + info.uid + " isolated=" + isolated); 2807 return null; 2808 } 2809 mProcessNames.put(processName, app.uid, app); 2810 if (isolated) { 2811 mIsolatedProcesses.put(app.uid, app); 2812 } 2813 } else { 2814 // If this is a new package in the process, add the package to the list 2815 app.addPackage(info.packageName, mProcessStats); 2816 } 2817 2818 // If the system is not ready yet, then hold off on starting this 2819 // process until it is. 2820 if (!mProcessesReady 2821 && !isAllowedWhileBooting(info) 2822 && !allowWhileBooting) { 2823 if (!mProcessesOnHold.contains(app)) { 2824 mProcessesOnHold.add(app); 2825 } 2826 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2827 return app; 2828 } 2829 2830 startProcessLocked(app, hostingType, hostingNameStr); 2831 return (app.pid != 0) ? app : null; 2832 } 2833 2834 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2835 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2836 } 2837 2838 private final void startProcessLocked(ProcessRecord app, 2839 String hostingType, String hostingNameStr) { 2840 if (app.pid > 0 && app.pid != MY_PID) { 2841 synchronized (mPidsSelfLocked) { 2842 mPidsSelfLocked.remove(app.pid); 2843 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2844 } 2845 app.setPid(0); 2846 } 2847 2848 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2849 "startProcessLocked removing on hold: " + app); 2850 mProcessesOnHold.remove(app); 2851 2852 updateCpuStats(); 2853 2854 try { 2855 int uid = app.uid; 2856 2857 int[] gids = null; 2858 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2859 if (!app.isolated) { 2860 int[] permGids = null; 2861 try { 2862 final PackageManager pm = mContext.getPackageManager(); 2863 permGids = pm.getPackageGids(app.info.packageName); 2864 2865 if (Environment.isExternalStorageEmulated()) { 2866 if (pm.checkPermission( 2867 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2868 app.info.packageName) == PERMISSION_GRANTED) { 2869 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2870 } else { 2871 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2872 } 2873 } 2874 } catch (PackageManager.NameNotFoundException e) { 2875 Slog.w(TAG, "Unable to retrieve gids", e); 2876 } 2877 2878 /* 2879 * Add shared application GID so applications can share some 2880 * resources like shared libraries 2881 */ 2882 if (permGids == null) { 2883 gids = new int[1]; 2884 } else { 2885 gids = new int[permGids.length + 1]; 2886 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2887 } 2888 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2889 } 2890 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2891 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2892 && mTopComponent != null 2893 && app.processName.equals(mTopComponent.getPackageName())) { 2894 uid = 0; 2895 } 2896 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2897 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2898 uid = 0; 2899 } 2900 } 2901 int debugFlags = 0; 2902 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2903 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2904 // Also turn on CheckJNI for debuggable apps. It's quite 2905 // awkward to turn on otherwise. 2906 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2907 } 2908 // Run the app in safe mode if its manifest requests so or the 2909 // system is booted in safe mode. 2910 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2911 mSafeMode == true) { 2912 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2913 } 2914 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2915 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2916 } 2917 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2918 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2919 } 2920 if ("1".equals(SystemProperties.get("debug.assert"))) { 2921 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2922 } 2923 2924 String requiredAbi = app.info.cpuAbi; 2925 if (requiredAbi == null) { 2926 requiredAbi = Build.SUPPORTED_ABIS[0]; 2927 } 2928 2929 // Start the process. It will either succeed and return a result containing 2930 // the PID of the new process, or else throw a RuntimeException. 2931 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2932 app.processName, uid, uid, gids, debugFlags, mountExternal, 2933 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2934 2935 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2936 synchronized (bs) { 2937 if (bs.isOnBattery()) { 2938 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2939 } 2940 } 2941 2942 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2943 UserHandle.getUserId(uid), startResult.pid, uid, 2944 app.processName, hostingType, 2945 hostingNameStr != null ? hostingNameStr : ""); 2946 2947 if (app.persistent) { 2948 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2949 } 2950 2951 StringBuilder buf = mStringBuilder; 2952 buf.setLength(0); 2953 buf.append("Start proc "); 2954 buf.append(app.processName); 2955 buf.append(" for "); 2956 buf.append(hostingType); 2957 if (hostingNameStr != null) { 2958 buf.append(" "); 2959 buf.append(hostingNameStr); 2960 } 2961 buf.append(": pid="); 2962 buf.append(startResult.pid); 2963 buf.append(" uid="); 2964 buf.append(uid); 2965 buf.append(" gids={"); 2966 if (gids != null) { 2967 for (int gi=0; gi<gids.length; gi++) { 2968 if (gi != 0) buf.append(", "); 2969 buf.append(gids[gi]); 2970 2971 } 2972 } 2973 buf.append("}"); 2974 Slog.i(TAG, buf.toString()); 2975 app.setPid(startResult.pid); 2976 app.usingWrapper = startResult.usingWrapper; 2977 app.removed = false; 2978 synchronized (mPidsSelfLocked) { 2979 this.mPidsSelfLocked.put(startResult.pid, app); 2980 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2981 msg.obj = app; 2982 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2983 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2984 } 2985 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2986 app.processName, app.info.uid); 2987 if (app.isolated) { 2988 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2989 } 2990 } catch (RuntimeException e) { 2991 // XXX do better error recovery. 2992 app.setPid(0); 2993 Slog.e(TAG, "Failure starting process " + app.processName, e); 2994 } 2995 } 2996 2997 void updateUsageStats(ActivityRecord component, boolean resumed) { 2998 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2999 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3000 if (resumed) { 3001 mUsageStatsService.noteResumeComponent(component.realActivity); 3002 synchronized (stats) { 3003 stats.noteActivityResumedLocked(component.app.uid); 3004 } 3005 } else { 3006 mUsageStatsService.notePauseComponent(component.realActivity); 3007 synchronized (stats) { 3008 stats.noteActivityPausedLocked(component.app.uid); 3009 } 3010 } 3011 } 3012 3013 Intent getHomeIntent() { 3014 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3015 intent.setComponent(mTopComponent); 3016 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3017 intent.addCategory(Intent.CATEGORY_HOME); 3018 } 3019 return intent; 3020 } 3021 3022 boolean startHomeActivityLocked(int userId) { 3023 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3024 && mTopAction == null) { 3025 // We are running in factory test mode, but unable to find 3026 // the factory test app, so just sit around displaying the 3027 // error message and don't try to start anything. 3028 return false; 3029 } 3030 Intent intent = getHomeIntent(); 3031 ActivityInfo aInfo = 3032 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3033 if (aInfo != null) { 3034 intent.setComponent(new ComponentName( 3035 aInfo.applicationInfo.packageName, aInfo.name)); 3036 // Don't do this if the home app is currently being 3037 // instrumented. 3038 aInfo = new ActivityInfo(aInfo); 3039 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3040 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3041 aInfo.applicationInfo.uid, true); 3042 if (app == null || app.instrumentationClass == null) { 3043 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3044 mStackSupervisor.startHomeActivity(intent, aInfo); 3045 } 3046 } 3047 3048 return true; 3049 } 3050 3051 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3052 ActivityInfo ai = null; 3053 ComponentName comp = intent.getComponent(); 3054 try { 3055 if (comp != null) { 3056 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3057 } else { 3058 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3059 intent, 3060 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3061 flags, userId); 3062 3063 if (info != null) { 3064 ai = info.activityInfo; 3065 } 3066 } 3067 } catch (RemoteException e) { 3068 // ignore 3069 } 3070 3071 return ai; 3072 } 3073 3074 /** 3075 * Starts the "new version setup screen" if appropriate. 3076 */ 3077 void startSetupActivityLocked() { 3078 // Only do this once per boot. 3079 if (mCheckedForSetup) { 3080 return; 3081 } 3082 3083 // We will show this screen if the current one is a different 3084 // version than the last one shown, and we are not running in 3085 // low-level factory test mode. 3086 final ContentResolver resolver = mContext.getContentResolver(); 3087 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3088 Settings.Global.getInt(resolver, 3089 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3090 mCheckedForSetup = true; 3091 3092 // See if we should be showing the platform update setup UI. 3093 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3094 List<ResolveInfo> ris = mContext.getPackageManager() 3095 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3096 3097 // We don't allow third party apps to replace this. 3098 ResolveInfo ri = null; 3099 for (int i=0; ris != null && i<ris.size(); i++) { 3100 if ((ris.get(i).activityInfo.applicationInfo.flags 3101 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3102 ri = ris.get(i); 3103 break; 3104 } 3105 } 3106 3107 if (ri != null) { 3108 String vers = ri.activityInfo.metaData != null 3109 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3110 : null; 3111 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3112 vers = ri.activityInfo.applicationInfo.metaData.getString( 3113 Intent.METADATA_SETUP_VERSION); 3114 } 3115 String lastVers = Settings.Secure.getString( 3116 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3117 if (vers != null && !vers.equals(lastVers)) { 3118 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3119 intent.setComponent(new ComponentName( 3120 ri.activityInfo.packageName, ri.activityInfo.name)); 3121 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3122 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3123 } 3124 } 3125 } 3126 } 3127 3128 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3129 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3130 } 3131 3132 void enforceNotIsolatedCaller(String caller) { 3133 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3134 throw new SecurityException("Isolated process not allowed to call " + caller); 3135 } 3136 } 3137 3138 @Override 3139 public int getFrontActivityScreenCompatMode() { 3140 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3141 synchronized (this) { 3142 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3143 } 3144 } 3145 3146 @Override 3147 public void setFrontActivityScreenCompatMode(int mode) { 3148 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3149 "setFrontActivityScreenCompatMode"); 3150 synchronized (this) { 3151 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3152 } 3153 } 3154 3155 @Override 3156 public int getPackageScreenCompatMode(String packageName) { 3157 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3158 synchronized (this) { 3159 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3160 } 3161 } 3162 3163 @Override 3164 public void setPackageScreenCompatMode(String packageName, int mode) { 3165 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3166 "setPackageScreenCompatMode"); 3167 synchronized (this) { 3168 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3169 } 3170 } 3171 3172 @Override 3173 public boolean getPackageAskScreenCompat(String packageName) { 3174 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3175 synchronized (this) { 3176 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3177 } 3178 } 3179 3180 @Override 3181 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3182 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3183 "setPackageAskScreenCompat"); 3184 synchronized (this) { 3185 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3186 } 3187 } 3188 3189 private void dispatchProcessesChanged() { 3190 int N; 3191 synchronized (this) { 3192 N = mPendingProcessChanges.size(); 3193 if (mActiveProcessChanges.length < N) { 3194 mActiveProcessChanges = new ProcessChangeItem[N]; 3195 } 3196 mPendingProcessChanges.toArray(mActiveProcessChanges); 3197 mAvailProcessChanges.addAll(mPendingProcessChanges); 3198 mPendingProcessChanges.clear(); 3199 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3200 } 3201 3202 int i = mProcessObservers.beginBroadcast(); 3203 while (i > 0) { 3204 i--; 3205 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3206 if (observer != null) { 3207 try { 3208 for (int j=0; j<N; j++) { 3209 ProcessChangeItem item = mActiveProcessChanges[j]; 3210 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3211 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3212 + item.pid + " uid=" + item.uid + ": " 3213 + item.foregroundActivities); 3214 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3215 item.foregroundActivities); 3216 } 3217 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3218 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3219 + item.pid + " uid=" + item.uid + ": " + item.processState); 3220 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3221 } 3222 } 3223 } catch (RemoteException e) { 3224 } 3225 } 3226 } 3227 mProcessObservers.finishBroadcast(); 3228 } 3229 3230 private void dispatchProcessDied(int pid, int uid) { 3231 int i = mProcessObservers.beginBroadcast(); 3232 while (i > 0) { 3233 i--; 3234 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3235 if (observer != null) { 3236 try { 3237 observer.onProcessDied(pid, uid); 3238 } catch (RemoteException e) { 3239 } 3240 } 3241 } 3242 mProcessObservers.finishBroadcast(); 3243 } 3244 3245 final void doPendingActivityLaunchesLocked(boolean doResume) { 3246 final int N = mPendingActivityLaunches.size(); 3247 if (N <= 0) { 3248 return; 3249 } 3250 for (int i=0; i<N; i++) { 3251 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3252 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3253 doResume && i == (N-1), null); 3254 } 3255 mPendingActivityLaunches.clear(); 3256 } 3257 3258 @Override 3259 public final int startActivity(IApplicationThread caller, String callingPackage, 3260 Intent intent, String resolvedType, IBinder resultTo, 3261 String resultWho, int requestCode, int startFlags, 3262 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3263 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3264 resultWho, requestCode, 3265 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3266 } 3267 3268 @Override 3269 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3270 Intent intent, String resolvedType, IBinder resultTo, 3271 String resultWho, int requestCode, int startFlags, 3272 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3273 enforceNotIsolatedCaller("startActivity"); 3274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3275 false, true, "startActivity", null); 3276 // TODO: Switch to user app stacks here. 3277 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3278 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3279 null, null, options, userId, null); 3280 } 3281 3282 @Override 3283 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3284 Intent intent, String resolvedType, IBinder resultTo, 3285 String resultWho, int requestCode, int startFlags, String profileFile, 3286 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3287 enforceNotIsolatedCaller("startActivityAndWait"); 3288 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3289 false, true, "startActivityAndWait", null); 3290 WaitResult res = new WaitResult(); 3291 // TODO: Switch to user app stacks here. 3292 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3293 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3294 res, null, options, UserHandle.getCallingUserId(), null); 3295 return res; 3296 } 3297 3298 @Override 3299 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3300 Intent intent, String resolvedType, IBinder resultTo, 3301 String resultWho, int requestCode, int startFlags, Configuration config, 3302 Bundle options, int userId) { 3303 enforceNotIsolatedCaller("startActivityWithConfig"); 3304 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3305 false, true, "startActivityWithConfig", null); 3306 // TODO: Switch to user app stacks here. 3307 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3308 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3309 null, null, null, config, options, userId, null); 3310 return ret; 3311 } 3312 3313 @Override 3314 public int startActivityIntentSender(IApplicationThread caller, 3315 IntentSender intent, Intent fillInIntent, String resolvedType, 3316 IBinder resultTo, String resultWho, int requestCode, 3317 int flagsMask, int flagsValues, Bundle options) { 3318 enforceNotIsolatedCaller("startActivityIntentSender"); 3319 // Refuse possible leaked file descriptors 3320 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3321 throw new IllegalArgumentException("File descriptors passed in Intent"); 3322 } 3323 3324 IIntentSender sender = intent.getTarget(); 3325 if (!(sender instanceof PendingIntentRecord)) { 3326 throw new IllegalArgumentException("Bad PendingIntent object"); 3327 } 3328 3329 PendingIntentRecord pir = (PendingIntentRecord)sender; 3330 3331 synchronized (this) { 3332 // If this is coming from the currently resumed activity, it is 3333 // effectively saying that app switches are allowed at this point. 3334 final ActivityStack stack = getFocusedStack(); 3335 if (stack.mResumedActivity != null && 3336 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3337 mAppSwitchesAllowedTime = 0; 3338 } 3339 } 3340 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3341 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3342 return ret; 3343 } 3344 3345 @Override 3346 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3347 Intent intent, String resolvedType, IVoiceInteractionSession session, 3348 IVoiceInteractor interactor, int startFlags, String profileFile, 3349 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3350 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3351 != PackageManager.PERMISSION_GRANTED) { 3352 String msg = "Permission Denial: startVoiceActivity() from pid=" 3353 + Binder.getCallingPid() 3354 + ", uid=" + Binder.getCallingUid() 3355 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3356 Slog.w(TAG, msg); 3357 throw new SecurityException(msg); 3358 } 3359 if (session == null || interactor == null) { 3360 throw new NullPointerException("null session or interactor"); 3361 } 3362 userId = handleIncomingUser(callingPid, callingUid, userId, 3363 false, true, "startVoiceActivity", null); 3364 // TODO: Switch to user app stacks here. 3365 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3366 resolvedType, session, interactor, null, null, 0, startFlags, 3367 profileFile, profileFd, null, null, options, userId, null); 3368 } 3369 3370 @Override 3371 public boolean startNextMatchingActivity(IBinder callingActivity, 3372 Intent intent, Bundle options) { 3373 // Refuse possible leaked file descriptors 3374 if (intent != null && intent.hasFileDescriptors() == true) { 3375 throw new IllegalArgumentException("File descriptors passed in Intent"); 3376 } 3377 3378 synchronized (this) { 3379 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3380 if (r == null) { 3381 ActivityOptions.abort(options); 3382 return false; 3383 } 3384 if (r.app == null || r.app.thread == null) { 3385 // The caller is not running... d'oh! 3386 ActivityOptions.abort(options); 3387 return false; 3388 } 3389 intent = new Intent(intent); 3390 // The caller is not allowed to change the data. 3391 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3392 // And we are resetting to find the next component... 3393 intent.setComponent(null); 3394 3395 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3396 3397 ActivityInfo aInfo = null; 3398 try { 3399 List<ResolveInfo> resolves = 3400 AppGlobals.getPackageManager().queryIntentActivities( 3401 intent, r.resolvedType, 3402 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3403 UserHandle.getCallingUserId()); 3404 3405 // Look for the original activity in the list... 3406 final int N = resolves != null ? resolves.size() : 0; 3407 for (int i=0; i<N; i++) { 3408 ResolveInfo rInfo = resolves.get(i); 3409 if (rInfo.activityInfo.packageName.equals(r.packageName) 3410 && rInfo.activityInfo.name.equals(r.info.name)) { 3411 // We found the current one... the next matching is 3412 // after it. 3413 i++; 3414 if (i<N) { 3415 aInfo = resolves.get(i).activityInfo; 3416 } 3417 if (debug) { 3418 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3419 + "/" + r.info.name); 3420 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3421 + "/" + aInfo.name); 3422 } 3423 break; 3424 } 3425 } 3426 } catch (RemoteException e) { 3427 } 3428 3429 if (aInfo == null) { 3430 // Nobody who is next! 3431 ActivityOptions.abort(options); 3432 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3433 return false; 3434 } 3435 3436 intent.setComponent(new ComponentName( 3437 aInfo.applicationInfo.packageName, aInfo.name)); 3438 intent.setFlags(intent.getFlags()&~( 3439 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3440 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3441 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3442 Intent.FLAG_ACTIVITY_NEW_TASK)); 3443 3444 // Okay now we need to start the new activity, replacing the 3445 // currently running activity. This is a little tricky because 3446 // we want to start the new one as if the current one is finished, 3447 // but not finish the current one first so that there is no flicker. 3448 // And thus... 3449 final boolean wasFinishing = r.finishing; 3450 r.finishing = true; 3451 3452 // Propagate reply information over to the new activity. 3453 final ActivityRecord resultTo = r.resultTo; 3454 final String resultWho = r.resultWho; 3455 final int requestCode = r.requestCode; 3456 r.resultTo = null; 3457 if (resultTo != null) { 3458 resultTo.removeResultsLocked(r, resultWho, requestCode); 3459 } 3460 3461 final long origId = Binder.clearCallingIdentity(); 3462 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3463 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3464 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3465 options, false, null, null); 3466 Binder.restoreCallingIdentity(origId); 3467 3468 r.finishing = wasFinishing; 3469 if (res != ActivityManager.START_SUCCESS) { 3470 return false; 3471 } 3472 return true; 3473 } 3474 } 3475 3476 final int startActivityInPackage(int uid, String callingPackage, 3477 Intent intent, String resolvedType, IBinder resultTo, 3478 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3479 IActivityContainer container) { 3480 3481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3482 false, true, "startActivityInPackage", null); 3483 3484 // TODO: Switch to user app stacks here. 3485 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3486 null, null, resultTo, resultWho, requestCode, startFlags, 3487 null, null, null, null, options, userId, container); 3488 return ret; 3489 } 3490 3491 @Override 3492 public final int startActivities(IApplicationThread caller, String callingPackage, 3493 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3494 int userId) { 3495 enforceNotIsolatedCaller("startActivities"); 3496 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3497 false, true, "startActivity", null); 3498 // TODO: Switch to user app stacks here. 3499 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3500 resolvedTypes, resultTo, options, userId); 3501 return ret; 3502 } 3503 3504 final int startActivitiesInPackage(int uid, String callingPackage, 3505 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3506 Bundle options, int userId) { 3507 3508 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3509 false, true, "startActivityInPackage", null); 3510 // TODO: Switch to user app stacks here. 3511 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3512 resultTo, options, userId); 3513 return ret; 3514 } 3515 3516 final void addRecentTaskLocked(TaskRecord task) { 3517 int N = mRecentTasks.size(); 3518 // Quick case: check if the top-most recent task is the same. 3519 if (N > 0 && mRecentTasks.get(0) == task) { 3520 return; 3521 } 3522 // Another quick case: never add voice sessions. 3523 if (task.voiceSession != null) { 3524 return; 3525 } 3526 // Remove any existing entries that are the same kind of task. 3527 final Intent intent = task.intent; 3528 final boolean document = intent != null && intent.isDocument(); 3529 for (int i=0; i<N; i++) { 3530 TaskRecord tr = mRecentTasks.get(i); 3531 if (task != tr) { 3532 if (task.userId != tr.userId) { 3533 continue; 3534 } 3535 final Intent trIntent = tr.intent; 3536 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3537 (intent == null || !intent.filterEquals(trIntent))) { 3538 continue; 3539 } 3540 if (document || trIntent != null && trIntent.isDocument()) { 3541 // Document tasks do not match other tasks. 3542 continue; 3543 } 3544 } 3545 3546 // Either task and tr are the same or, their affinities match or their intents match 3547 // and neither of them is a document. 3548 tr.disposeThumbnail(); 3549 mRecentTasks.remove(i); 3550 i--; 3551 N--; 3552 if (task.intent == null) { 3553 // If the new recent task we are adding is not fully 3554 // specified, then replace it with the existing recent task. 3555 task = tr; 3556 } 3557 } 3558 if (N >= MAX_RECENT_TASKS) { 3559 mRecentTasks.remove(N-1).disposeThumbnail(); 3560 } 3561 mRecentTasks.add(0, task); 3562 } 3563 3564 @Override 3565 public void reportActivityFullyDrawn(IBinder token) { 3566 synchronized (this) { 3567 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3568 if (r == null) { 3569 return; 3570 } 3571 r.reportFullyDrawnLocked(); 3572 } 3573 } 3574 3575 @Override 3576 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3577 synchronized (this) { 3578 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3579 if (r == null) { 3580 return; 3581 } 3582 final long origId = Binder.clearCallingIdentity(); 3583 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3584 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3585 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3586 if (config != null) { 3587 r.frozenBeforeDestroy = true; 3588 if (!updateConfigurationLocked(config, r, false, false)) { 3589 mStackSupervisor.resumeTopActivitiesLocked(); 3590 } 3591 } 3592 Binder.restoreCallingIdentity(origId); 3593 } 3594 } 3595 3596 @Override 3597 public int getRequestedOrientation(IBinder token) { 3598 synchronized (this) { 3599 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3600 if (r == null) { 3601 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3602 } 3603 return mWindowManager.getAppOrientation(r.appToken); 3604 } 3605 } 3606 3607 /** 3608 * This is the internal entry point for handling Activity.finish(). 3609 * 3610 * @param token The Binder token referencing the Activity we want to finish. 3611 * @param resultCode Result code, if any, from this Activity. 3612 * @param resultData Result data (Intent), if any, from this Activity. 3613 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3614 * the root Activity in the task. 3615 * 3616 * @return Returns true if the activity successfully finished, or false if it is still running. 3617 */ 3618 @Override 3619 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3620 boolean finishTask) { 3621 // Refuse possible leaked file descriptors 3622 if (resultData != null && resultData.hasFileDescriptors() == true) { 3623 throw new IllegalArgumentException("File descriptors passed in Intent"); 3624 } 3625 3626 synchronized(this) { 3627 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3628 if (r == null) { 3629 return true; 3630 } 3631 // Keep track of the root activity of the task before we finish it 3632 TaskRecord tr = r.task; 3633 ActivityRecord rootR = tr.getRootActivity(); 3634 if (mController != null) { 3635 // Find the first activity that is not finishing. 3636 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3637 if (next != null) { 3638 // ask watcher if this is allowed 3639 boolean resumeOK = true; 3640 try { 3641 resumeOK = mController.activityResuming(next.packageName); 3642 } catch (RemoteException e) { 3643 mController = null; 3644 Watchdog.getInstance().setActivityController(null); 3645 } 3646 3647 if (!resumeOK) { 3648 return false; 3649 } 3650 } 3651 } 3652 final long origId = Binder.clearCallingIdentity(); 3653 try { 3654 boolean res; 3655 if (finishTask && r == rootR) { 3656 // If requested, remove the task that is associated to this activity only if it 3657 // was the root activity in the task. The result code and data is ignored because 3658 // we don't support returning them across task boundaries. 3659 res = removeTaskByIdLocked(tr.taskId, 0); 3660 } else { 3661 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3662 resultData, "app-request", true); 3663 } 3664 return res; 3665 } finally { 3666 Binder.restoreCallingIdentity(origId); 3667 } 3668 } 3669 } 3670 3671 @Override 3672 public final void finishHeavyWeightApp() { 3673 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3674 != PackageManager.PERMISSION_GRANTED) { 3675 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3676 + Binder.getCallingPid() 3677 + ", uid=" + Binder.getCallingUid() 3678 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3679 Slog.w(TAG, msg); 3680 throw new SecurityException(msg); 3681 } 3682 3683 synchronized(this) { 3684 if (mHeavyWeightProcess == null) { 3685 return; 3686 } 3687 3688 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3689 mHeavyWeightProcess.activities); 3690 for (int i=0; i<activities.size(); i++) { 3691 ActivityRecord r = activities.get(i); 3692 if (!r.finishing) { 3693 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3694 null, "finish-heavy", true); 3695 } 3696 } 3697 3698 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3699 mHeavyWeightProcess.userId, 0)); 3700 mHeavyWeightProcess = null; 3701 } 3702 } 3703 3704 @Override 3705 public void crashApplication(int uid, int initialPid, String packageName, 3706 String message) { 3707 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3708 != PackageManager.PERMISSION_GRANTED) { 3709 String msg = "Permission Denial: crashApplication() from pid=" 3710 + Binder.getCallingPid() 3711 + ", uid=" + Binder.getCallingUid() 3712 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3713 Slog.w(TAG, msg); 3714 throw new SecurityException(msg); 3715 } 3716 3717 synchronized(this) { 3718 ProcessRecord proc = null; 3719 3720 // Figure out which process to kill. We don't trust that initialPid 3721 // still has any relation to current pids, so must scan through the 3722 // list. 3723 synchronized (mPidsSelfLocked) { 3724 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3725 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3726 if (p.uid != uid) { 3727 continue; 3728 } 3729 if (p.pid == initialPid) { 3730 proc = p; 3731 break; 3732 } 3733 if (p.pkgList.containsKey(packageName)) { 3734 proc = p; 3735 } 3736 } 3737 } 3738 3739 if (proc == null) { 3740 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3741 + " initialPid=" + initialPid 3742 + " packageName=" + packageName); 3743 return; 3744 } 3745 3746 if (proc.thread != null) { 3747 if (proc.pid == Process.myPid()) { 3748 Log.w(TAG, "crashApplication: trying to crash self!"); 3749 return; 3750 } 3751 long ident = Binder.clearCallingIdentity(); 3752 try { 3753 proc.thread.scheduleCrash(message); 3754 } catch (RemoteException e) { 3755 } 3756 Binder.restoreCallingIdentity(ident); 3757 } 3758 } 3759 } 3760 3761 @Override 3762 public final void finishSubActivity(IBinder token, String resultWho, 3763 int requestCode) { 3764 synchronized(this) { 3765 final long origId = Binder.clearCallingIdentity(); 3766 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3767 if (r != null) { 3768 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3769 } 3770 Binder.restoreCallingIdentity(origId); 3771 } 3772 } 3773 3774 @Override 3775 public boolean finishActivityAffinity(IBinder token) { 3776 synchronized(this) { 3777 final long origId = Binder.clearCallingIdentity(); 3778 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3779 boolean res = false; 3780 if (r != null) { 3781 res = r.task.stack.finishActivityAffinityLocked(r); 3782 } 3783 Binder.restoreCallingIdentity(origId); 3784 return res; 3785 } 3786 } 3787 3788 @Override 3789 public boolean willActivityBeVisible(IBinder token) { 3790 synchronized(this) { 3791 ActivityStack stack = ActivityRecord.getStackLocked(token); 3792 if (stack != null) { 3793 return stack.willActivityBeVisibleLocked(token); 3794 } 3795 return false; 3796 } 3797 } 3798 3799 @Override 3800 public void overridePendingTransition(IBinder token, String packageName, 3801 int enterAnim, int exitAnim) { 3802 synchronized(this) { 3803 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3804 if (self == null) { 3805 return; 3806 } 3807 3808 final long origId = Binder.clearCallingIdentity(); 3809 3810 if (self.state == ActivityState.RESUMED 3811 || self.state == ActivityState.PAUSING) { 3812 mWindowManager.overridePendingAppTransition(packageName, 3813 enterAnim, exitAnim, null); 3814 } 3815 3816 Binder.restoreCallingIdentity(origId); 3817 } 3818 } 3819 3820 /** 3821 * Main function for removing an existing process from the activity manager 3822 * as a result of that process going away. Clears out all connections 3823 * to the process. 3824 */ 3825 private final void handleAppDiedLocked(ProcessRecord app, 3826 boolean restarting, boolean allowRestart) { 3827 int pid = app.pid; 3828 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3829 if (!restarting) { 3830 removeLruProcessLocked(app); 3831 if (pid > 0) { 3832 ProcessList.remove(pid); 3833 } 3834 } 3835 3836 if (mProfileProc == app) { 3837 clearProfilerLocked(); 3838 } 3839 3840 // Remove this application's activities from active lists. 3841 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3842 3843 app.activities.clear(); 3844 3845 if (app.instrumentationClass != null) { 3846 Slog.w(TAG, "Crash of app " + app.processName 3847 + " running instrumentation " + app.instrumentationClass); 3848 Bundle info = new Bundle(); 3849 info.putString("shortMsg", "Process crashed."); 3850 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3851 } 3852 3853 if (!restarting) { 3854 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3855 // If there was nothing to resume, and we are not already 3856 // restarting this process, but there is a visible activity that 3857 // is hosted by the process... then make sure all visible 3858 // activities are running, taking care of restarting this 3859 // process. 3860 if (hasVisibleActivities) { 3861 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3862 } 3863 } 3864 } 3865 } 3866 3867 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3868 IBinder threadBinder = thread.asBinder(); 3869 // Find the application record. 3870 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3871 ProcessRecord rec = mLruProcesses.get(i); 3872 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3873 return i; 3874 } 3875 } 3876 return -1; 3877 } 3878 3879 final ProcessRecord getRecordForAppLocked( 3880 IApplicationThread thread) { 3881 if (thread == null) { 3882 return null; 3883 } 3884 3885 int appIndex = getLRURecordIndexForAppLocked(thread); 3886 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3887 } 3888 3889 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3890 // If there are no longer any background processes running, 3891 // and the app that died was not running instrumentation, 3892 // then tell everyone we are now low on memory. 3893 boolean haveBg = false; 3894 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3895 ProcessRecord rec = mLruProcesses.get(i); 3896 if (rec.thread != null 3897 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3898 haveBg = true; 3899 break; 3900 } 3901 } 3902 3903 if (!haveBg) { 3904 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3905 if (doReport) { 3906 long now = SystemClock.uptimeMillis(); 3907 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3908 doReport = false; 3909 } else { 3910 mLastMemUsageReportTime = now; 3911 } 3912 } 3913 final ArrayList<ProcessMemInfo> memInfos 3914 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3915 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3916 long now = SystemClock.uptimeMillis(); 3917 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3918 ProcessRecord rec = mLruProcesses.get(i); 3919 if (rec == dyingProc || rec.thread == null) { 3920 continue; 3921 } 3922 if (doReport) { 3923 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3924 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3925 } 3926 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3927 // The low memory report is overriding any current 3928 // state for a GC request. Make sure to do 3929 // heavy/important/visible/foreground processes first. 3930 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3931 rec.lastRequestedGc = 0; 3932 } else { 3933 rec.lastRequestedGc = rec.lastLowMemory; 3934 } 3935 rec.reportLowMemory = true; 3936 rec.lastLowMemory = now; 3937 mProcessesToGc.remove(rec); 3938 addProcessToGcListLocked(rec); 3939 } 3940 } 3941 if (doReport) { 3942 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3943 mHandler.sendMessage(msg); 3944 } 3945 scheduleAppGcsLocked(); 3946 } 3947 } 3948 3949 final void appDiedLocked(ProcessRecord app, int pid, 3950 IApplicationThread thread) { 3951 3952 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3953 synchronized (stats) { 3954 stats.noteProcessDiedLocked(app.info.uid, pid); 3955 } 3956 3957 // Clean up already done if the process has been re-started. 3958 if (app.pid == pid && app.thread != null && 3959 app.thread.asBinder() == thread.asBinder()) { 3960 boolean doLowMem = app.instrumentationClass == null; 3961 boolean doOomAdj = doLowMem; 3962 if (!app.killedByAm) { 3963 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3964 + ") has died."); 3965 mAllowLowerMemLevel = true; 3966 } else { 3967 // Note that we always want to do oom adj to update our state with the 3968 // new number of procs. 3969 mAllowLowerMemLevel = false; 3970 doLowMem = false; 3971 } 3972 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3973 if (DEBUG_CLEANUP) Slog.v( 3974 TAG, "Dying app: " + app + ", pid: " + pid 3975 + ", thread: " + thread.asBinder()); 3976 handleAppDiedLocked(app, false, true); 3977 3978 if (doOomAdj) { 3979 updateOomAdjLocked(); 3980 } 3981 if (doLowMem) { 3982 doLowMemReportIfNeededLocked(app); 3983 } 3984 } else if (app.pid != pid) { 3985 // A new process has already been started. 3986 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3987 + ") has died and restarted (pid " + app.pid + ")."); 3988 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3989 } else if (DEBUG_PROCESSES) { 3990 Slog.d(TAG, "Received spurious death notification for thread " 3991 + thread.asBinder()); 3992 } 3993 } 3994 3995 /** 3996 * If a stack trace dump file is configured, dump process stack traces. 3997 * @param clearTraces causes the dump file to be erased prior to the new 3998 * traces being written, if true; when false, the new traces will be 3999 * appended to any existing file content. 4000 * @param firstPids of dalvik VM processes to dump stack traces for first 4001 * @param lastPids of dalvik VM processes to dump stack traces for last 4002 * @param nativeProcs optional list of native process names to dump stack crawls 4003 * @return file containing stack traces, or null if no dump file is configured 4004 */ 4005 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4006 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4007 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4008 if (tracesPath == null || tracesPath.length() == 0) { 4009 return null; 4010 } 4011 4012 File tracesFile = new File(tracesPath); 4013 try { 4014 File tracesDir = tracesFile.getParentFile(); 4015 if (!tracesDir.exists()) { 4016 tracesFile.mkdirs(); 4017 if (!SELinux.restorecon(tracesDir)) { 4018 return null; 4019 } 4020 } 4021 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4022 4023 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4024 tracesFile.createNewFile(); 4025 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4026 } catch (IOException e) { 4027 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4028 return null; 4029 } 4030 4031 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4032 return tracesFile; 4033 } 4034 4035 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4036 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4037 // Use a FileObserver to detect when traces finish writing. 4038 // The order of traces is considered important to maintain for legibility. 4039 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4040 @Override 4041 public synchronized void onEvent(int event, String path) { notify(); } 4042 }; 4043 4044 try { 4045 observer.startWatching(); 4046 4047 // First collect all of the stacks of the most important pids. 4048 if (firstPids != null) { 4049 try { 4050 int num = firstPids.size(); 4051 for (int i = 0; i < num; i++) { 4052 synchronized (observer) { 4053 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4054 observer.wait(200); // Wait for write-close, give up after 200msec 4055 } 4056 } 4057 } catch (InterruptedException e) { 4058 Log.wtf(TAG, e); 4059 } 4060 } 4061 4062 // Next collect the stacks of the native pids 4063 if (nativeProcs != null) { 4064 int[] pids = Process.getPidsForCommands(nativeProcs); 4065 if (pids != null) { 4066 for (int pid : pids) { 4067 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4068 } 4069 } 4070 } 4071 4072 // Lastly, measure CPU usage. 4073 if (processCpuTracker != null) { 4074 processCpuTracker.init(); 4075 System.gc(); 4076 processCpuTracker.update(); 4077 try { 4078 synchronized (processCpuTracker) { 4079 processCpuTracker.wait(500); // measure over 1/2 second. 4080 } 4081 } catch (InterruptedException e) { 4082 } 4083 processCpuTracker.update(); 4084 4085 // We'll take the stack crawls of just the top apps using CPU. 4086 final int N = processCpuTracker.countWorkingStats(); 4087 int numProcs = 0; 4088 for (int i=0; i<N && numProcs<5; i++) { 4089 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4090 if (lastPids.indexOfKey(stats.pid) >= 0) { 4091 numProcs++; 4092 try { 4093 synchronized (observer) { 4094 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4095 observer.wait(200); // Wait for write-close, give up after 200msec 4096 } 4097 } catch (InterruptedException e) { 4098 Log.wtf(TAG, e); 4099 } 4100 4101 } 4102 } 4103 } 4104 } finally { 4105 observer.stopWatching(); 4106 } 4107 } 4108 4109 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4110 if (true || IS_USER_BUILD) { 4111 return; 4112 } 4113 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4114 if (tracesPath == null || tracesPath.length() == 0) { 4115 return; 4116 } 4117 4118 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4119 StrictMode.allowThreadDiskWrites(); 4120 try { 4121 final File tracesFile = new File(tracesPath); 4122 final File tracesDir = tracesFile.getParentFile(); 4123 final File tracesTmp = new File(tracesDir, "__tmp__"); 4124 try { 4125 if (!tracesDir.exists()) { 4126 tracesFile.mkdirs(); 4127 if (!SELinux.restorecon(tracesDir.getPath())) { 4128 return; 4129 } 4130 } 4131 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4132 4133 if (tracesFile.exists()) { 4134 tracesTmp.delete(); 4135 tracesFile.renameTo(tracesTmp); 4136 } 4137 StringBuilder sb = new StringBuilder(); 4138 Time tobj = new Time(); 4139 tobj.set(System.currentTimeMillis()); 4140 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4141 sb.append(": "); 4142 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4143 sb.append(" since "); 4144 sb.append(msg); 4145 FileOutputStream fos = new FileOutputStream(tracesFile); 4146 fos.write(sb.toString().getBytes()); 4147 if (app == null) { 4148 fos.write("\n*** No application process!".getBytes()); 4149 } 4150 fos.close(); 4151 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4152 } catch (IOException e) { 4153 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4154 return; 4155 } 4156 4157 if (app != null) { 4158 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4159 firstPids.add(app.pid); 4160 dumpStackTraces(tracesPath, firstPids, null, null, null); 4161 } 4162 4163 File lastTracesFile = null; 4164 File curTracesFile = null; 4165 for (int i=9; i>=0; i--) { 4166 String name = String.format(Locale.US, "slow%02d.txt", i); 4167 curTracesFile = new File(tracesDir, name); 4168 if (curTracesFile.exists()) { 4169 if (lastTracesFile != null) { 4170 curTracesFile.renameTo(lastTracesFile); 4171 } else { 4172 curTracesFile.delete(); 4173 } 4174 } 4175 lastTracesFile = curTracesFile; 4176 } 4177 tracesFile.renameTo(curTracesFile); 4178 if (tracesTmp.exists()) { 4179 tracesTmp.renameTo(tracesFile); 4180 } 4181 } finally { 4182 StrictMode.setThreadPolicy(oldPolicy); 4183 } 4184 } 4185 4186 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4187 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4188 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4189 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4190 4191 if (mController != null) { 4192 try { 4193 // 0 == continue, -1 = kill process immediately 4194 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4195 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4196 } catch (RemoteException e) { 4197 mController = null; 4198 Watchdog.getInstance().setActivityController(null); 4199 } 4200 } 4201 4202 long anrTime = SystemClock.uptimeMillis(); 4203 if (MONITOR_CPU_USAGE) { 4204 updateCpuStatsNow(); 4205 } 4206 4207 synchronized (this) { 4208 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4209 if (mShuttingDown) { 4210 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4211 return; 4212 } else if (app.notResponding) { 4213 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4214 return; 4215 } else if (app.crashing) { 4216 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4217 return; 4218 } 4219 4220 // In case we come through here for the same app before completing 4221 // this one, mark as anring now so we will bail out. 4222 app.notResponding = true; 4223 4224 // Log the ANR to the event log. 4225 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4226 app.processName, app.info.flags, annotation); 4227 4228 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4229 firstPids.add(app.pid); 4230 4231 int parentPid = app.pid; 4232 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4233 if (parentPid != app.pid) firstPids.add(parentPid); 4234 4235 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4236 4237 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4238 ProcessRecord r = mLruProcesses.get(i); 4239 if (r != null && r.thread != null) { 4240 int pid = r.pid; 4241 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4242 if (r.persistent) { 4243 firstPids.add(pid); 4244 } else { 4245 lastPids.put(pid, Boolean.TRUE); 4246 } 4247 } 4248 } 4249 } 4250 } 4251 4252 // Log the ANR to the main log. 4253 StringBuilder info = new StringBuilder(); 4254 info.setLength(0); 4255 info.append("ANR in ").append(app.processName); 4256 if (activity != null && activity.shortComponentName != null) { 4257 info.append(" (").append(activity.shortComponentName).append(")"); 4258 } 4259 info.append("\n"); 4260 info.append("PID: ").append(app.pid).append("\n"); 4261 if (annotation != null) { 4262 info.append("Reason: ").append(annotation).append("\n"); 4263 } 4264 if (parent != null && parent != activity) { 4265 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4266 } 4267 4268 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4269 4270 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4271 NATIVE_STACKS_OF_INTEREST); 4272 4273 String cpuInfo = null; 4274 if (MONITOR_CPU_USAGE) { 4275 updateCpuStatsNow(); 4276 synchronized (mProcessCpuThread) { 4277 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4278 } 4279 info.append(processCpuTracker.printCurrentLoad()); 4280 info.append(cpuInfo); 4281 } 4282 4283 info.append(processCpuTracker.printCurrentState(anrTime)); 4284 4285 Slog.e(TAG, info.toString()); 4286 if (tracesFile == null) { 4287 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4288 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4289 } 4290 4291 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4292 cpuInfo, tracesFile, null); 4293 4294 if (mController != null) { 4295 try { 4296 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4297 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4298 if (res != 0) { 4299 if (res < 0 && app.pid != MY_PID) { 4300 Process.killProcess(app.pid); 4301 } else { 4302 synchronized (this) { 4303 mServices.scheduleServiceTimeoutLocked(app); 4304 } 4305 } 4306 return; 4307 } 4308 } catch (RemoteException e) { 4309 mController = null; 4310 Watchdog.getInstance().setActivityController(null); 4311 } 4312 } 4313 4314 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4315 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4316 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4317 4318 synchronized (this) { 4319 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4320 killUnneededProcessLocked(app, "background ANR"); 4321 return; 4322 } 4323 4324 // Set the app's notResponding state, and look up the errorReportReceiver 4325 makeAppNotRespondingLocked(app, 4326 activity != null ? activity.shortComponentName : null, 4327 annotation != null ? "ANR " + annotation : "ANR", 4328 info.toString()); 4329 4330 // Bring up the infamous App Not Responding dialog 4331 Message msg = Message.obtain(); 4332 HashMap<String, Object> map = new HashMap<String, Object>(); 4333 msg.what = SHOW_NOT_RESPONDING_MSG; 4334 msg.obj = map; 4335 msg.arg1 = aboveSystem ? 1 : 0; 4336 map.put("app", app); 4337 if (activity != null) { 4338 map.put("activity", activity); 4339 } 4340 4341 mHandler.sendMessage(msg); 4342 } 4343 } 4344 4345 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4346 if (!mLaunchWarningShown) { 4347 mLaunchWarningShown = true; 4348 mHandler.post(new Runnable() { 4349 @Override 4350 public void run() { 4351 synchronized (ActivityManagerService.this) { 4352 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4353 d.show(); 4354 mHandler.postDelayed(new Runnable() { 4355 @Override 4356 public void run() { 4357 synchronized (ActivityManagerService.this) { 4358 d.dismiss(); 4359 mLaunchWarningShown = false; 4360 } 4361 } 4362 }, 4000); 4363 } 4364 } 4365 }); 4366 } 4367 } 4368 4369 @Override 4370 public boolean clearApplicationUserData(final String packageName, 4371 final IPackageDataObserver observer, int userId) { 4372 enforceNotIsolatedCaller("clearApplicationUserData"); 4373 int uid = Binder.getCallingUid(); 4374 int pid = Binder.getCallingPid(); 4375 userId = handleIncomingUser(pid, uid, 4376 userId, false, true, "clearApplicationUserData", null); 4377 long callingId = Binder.clearCallingIdentity(); 4378 try { 4379 IPackageManager pm = AppGlobals.getPackageManager(); 4380 int pkgUid = -1; 4381 synchronized(this) { 4382 try { 4383 pkgUid = pm.getPackageUid(packageName, userId); 4384 } catch (RemoteException e) { 4385 } 4386 if (pkgUid == -1) { 4387 Slog.w(TAG, "Invalid packageName: " + packageName); 4388 if (observer != null) { 4389 try { 4390 observer.onRemoveCompleted(packageName, false); 4391 } catch (RemoteException e) { 4392 Slog.i(TAG, "Observer no longer exists."); 4393 } 4394 } 4395 return false; 4396 } 4397 if (uid == pkgUid || checkComponentPermission( 4398 android.Manifest.permission.CLEAR_APP_USER_DATA, 4399 pid, uid, -1, true) 4400 == PackageManager.PERMISSION_GRANTED) { 4401 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4402 } else { 4403 throw new SecurityException("PID " + pid + " does not have permission " 4404 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4405 + " of package " + packageName); 4406 } 4407 } 4408 4409 try { 4410 // Clear application user data 4411 pm.clearApplicationUserData(packageName, observer, userId); 4412 4413 // Remove all permissions granted from/to this package 4414 removeUriPermissionsForPackageLocked(packageName, userId, true); 4415 4416 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4417 Uri.fromParts("package", packageName, null)); 4418 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4419 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4420 null, null, 0, null, null, null, false, false, userId); 4421 } catch (RemoteException e) { 4422 } 4423 } finally { 4424 Binder.restoreCallingIdentity(callingId); 4425 } 4426 return true; 4427 } 4428 4429 @Override 4430 public void killBackgroundProcesses(final String packageName, int userId) { 4431 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4432 != PackageManager.PERMISSION_GRANTED && 4433 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4434 != PackageManager.PERMISSION_GRANTED) { 4435 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4436 + Binder.getCallingPid() 4437 + ", uid=" + Binder.getCallingUid() 4438 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4439 Slog.w(TAG, msg); 4440 throw new SecurityException(msg); 4441 } 4442 4443 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4444 userId, true, true, "killBackgroundProcesses", null); 4445 long callingId = Binder.clearCallingIdentity(); 4446 try { 4447 IPackageManager pm = AppGlobals.getPackageManager(); 4448 synchronized(this) { 4449 int appId = -1; 4450 try { 4451 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4452 } catch (RemoteException e) { 4453 } 4454 if (appId == -1) { 4455 Slog.w(TAG, "Invalid packageName: " + packageName); 4456 return; 4457 } 4458 killPackageProcessesLocked(packageName, appId, userId, 4459 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4460 } 4461 } finally { 4462 Binder.restoreCallingIdentity(callingId); 4463 } 4464 } 4465 4466 @Override 4467 public void killAllBackgroundProcesses() { 4468 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4469 != PackageManager.PERMISSION_GRANTED) { 4470 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4471 + Binder.getCallingPid() 4472 + ", uid=" + Binder.getCallingUid() 4473 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4474 Slog.w(TAG, msg); 4475 throw new SecurityException(msg); 4476 } 4477 4478 long callingId = Binder.clearCallingIdentity(); 4479 try { 4480 synchronized(this) { 4481 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4482 final int NP = mProcessNames.getMap().size(); 4483 for (int ip=0; ip<NP; ip++) { 4484 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4485 final int NA = apps.size(); 4486 for (int ia=0; ia<NA; ia++) { 4487 ProcessRecord app = apps.valueAt(ia); 4488 if (app.persistent) { 4489 // we don't kill persistent processes 4490 continue; 4491 } 4492 if (app.removed) { 4493 procs.add(app); 4494 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4495 app.removed = true; 4496 procs.add(app); 4497 } 4498 } 4499 } 4500 4501 int N = procs.size(); 4502 for (int i=0; i<N; i++) { 4503 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4504 } 4505 mAllowLowerMemLevel = true; 4506 updateOomAdjLocked(); 4507 doLowMemReportIfNeededLocked(null); 4508 } 4509 } finally { 4510 Binder.restoreCallingIdentity(callingId); 4511 } 4512 } 4513 4514 @Override 4515 public void forceStopPackage(final String packageName, int userId) { 4516 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4517 != PackageManager.PERMISSION_GRANTED) { 4518 String msg = "Permission Denial: forceStopPackage() from pid=" 4519 + Binder.getCallingPid() 4520 + ", uid=" + Binder.getCallingUid() 4521 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4522 Slog.w(TAG, msg); 4523 throw new SecurityException(msg); 4524 } 4525 final int callingPid = Binder.getCallingPid(); 4526 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4527 userId, true, true, "forceStopPackage", null); 4528 long callingId = Binder.clearCallingIdentity(); 4529 try { 4530 IPackageManager pm = AppGlobals.getPackageManager(); 4531 synchronized(this) { 4532 int[] users = userId == UserHandle.USER_ALL 4533 ? getUsersLocked() : new int[] { userId }; 4534 for (int user : users) { 4535 int pkgUid = -1; 4536 try { 4537 pkgUid = pm.getPackageUid(packageName, user); 4538 } catch (RemoteException e) { 4539 } 4540 if (pkgUid == -1) { 4541 Slog.w(TAG, "Invalid packageName: " + packageName); 4542 continue; 4543 } 4544 try { 4545 pm.setPackageStoppedState(packageName, true, user); 4546 } catch (RemoteException e) { 4547 } catch (IllegalArgumentException e) { 4548 Slog.w(TAG, "Failed trying to unstop package " 4549 + packageName + ": " + e); 4550 } 4551 if (isUserRunningLocked(user, false)) { 4552 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4553 } 4554 } 4555 } 4556 } finally { 4557 Binder.restoreCallingIdentity(callingId); 4558 } 4559 } 4560 4561 /* 4562 * The pkg name and app id have to be specified. 4563 */ 4564 @Override 4565 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4566 if (pkg == null) { 4567 return; 4568 } 4569 // Make sure the uid is valid. 4570 if (appid < 0) { 4571 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4572 return; 4573 } 4574 int callerUid = Binder.getCallingUid(); 4575 // Only the system server can kill an application 4576 if (callerUid == Process.SYSTEM_UID) { 4577 // Post an aysnc message to kill the application 4578 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4579 msg.arg1 = appid; 4580 msg.arg2 = 0; 4581 Bundle bundle = new Bundle(); 4582 bundle.putString("pkg", pkg); 4583 bundle.putString("reason", reason); 4584 msg.obj = bundle; 4585 mHandler.sendMessage(msg); 4586 } else { 4587 throw new SecurityException(callerUid + " cannot kill pkg: " + 4588 pkg); 4589 } 4590 } 4591 4592 @Override 4593 public void closeSystemDialogs(String reason) { 4594 enforceNotIsolatedCaller("closeSystemDialogs"); 4595 4596 final int pid = Binder.getCallingPid(); 4597 final int uid = Binder.getCallingUid(); 4598 final long origId = Binder.clearCallingIdentity(); 4599 try { 4600 synchronized (this) { 4601 // Only allow this from foreground processes, so that background 4602 // applications can't abuse it to prevent system UI from being shown. 4603 if (uid >= Process.FIRST_APPLICATION_UID) { 4604 ProcessRecord proc; 4605 synchronized (mPidsSelfLocked) { 4606 proc = mPidsSelfLocked.get(pid); 4607 } 4608 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4609 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4610 + " from background process " + proc); 4611 return; 4612 } 4613 } 4614 closeSystemDialogsLocked(reason); 4615 } 4616 } finally { 4617 Binder.restoreCallingIdentity(origId); 4618 } 4619 } 4620 4621 void closeSystemDialogsLocked(String reason) { 4622 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4623 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4624 | Intent.FLAG_RECEIVER_FOREGROUND); 4625 if (reason != null) { 4626 intent.putExtra("reason", reason); 4627 } 4628 mWindowManager.closeSystemDialogs(reason); 4629 4630 mStackSupervisor.closeSystemDialogsLocked(); 4631 4632 broadcastIntentLocked(null, null, intent, null, 4633 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4634 Process.SYSTEM_UID, UserHandle.USER_ALL); 4635 } 4636 4637 @Override 4638 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4639 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4640 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4641 for (int i=pids.length-1; i>=0; i--) { 4642 ProcessRecord proc; 4643 int oomAdj; 4644 synchronized (this) { 4645 synchronized (mPidsSelfLocked) { 4646 proc = mPidsSelfLocked.get(pids[i]); 4647 oomAdj = proc != null ? proc.setAdj : 0; 4648 } 4649 } 4650 infos[i] = new Debug.MemoryInfo(); 4651 Debug.getMemoryInfo(pids[i], infos[i]); 4652 if (proc != null) { 4653 synchronized (this) { 4654 if (proc.thread != null && proc.setAdj == oomAdj) { 4655 // Record this for posterity if the process has been stable. 4656 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4657 infos[i].getTotalUss(), false, proc.pkgList); 4658 } 4659 } 4660 } 4661 } 4662 return infos; 4663 } 4664 4665 @Override 4666 public long[] getProcessPss(int[] pids) { 4667 enforceNotIsolatedCaller("getProcessPss"); 4668 long[] pss = new long[pids.length]; 4669 for (int i=pids.length-1; i>=0; i--) { 4670 ProcessRecord proc; 4671 int oomAdj; 4672 synchronized (this) { 4673 synchronized (mPidsSelfLocked) { 4674 proc = mPidsSelfLocked.get(pids[i]); 4675 oomAdj = proc != null ? proc.setAdj : 0; 4676 } 4677 } 4678 long[] tmpUss = new long[1]; 4679 pss[i] = Debug.getPss(pids[i], tmpUss); 4680 if (proc != null) { 4681 synchronized (this) { 4682 if (proc.thread != null && proc.setAdj == oomAdj) { 4683 // Record this for posterity if the process has been stable. 4684 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4685 } 4686 } 4687 } 4688 } 4689 return pss; 4690 } 4691 4692 @Override 4693 public void killApplicationProcess(String processName, int uid) { 4694 if (processName == null) { 4695 return; 4696 } 4697 4698 int callerUid = Binder.getCallingUid(); 4699 // Only the system server can kill an application 4700 if (callerUid == Process.SYSTEM_UID) { 4701 synchronized (this) { 4702 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4703 if (app != null && app.thread != null) { 4704 try { 4705 app.thread.scheduleSuicide(); 4706 } catch (RemoteException e) { 4707 // If the other end already died, then our work here is done. 4708 } 4709 } else { 4710 Slog.w(TAG, "Process/uid not found attempting kill of " 4711 + processName + " / " + uid); 4712 } 4713 } 4714 } else { 4715 throw new SecurityException(callerUid + " cannot kill app process: " + 4716 processName); 4717 } 4718 } 4719 4720 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4721 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4722 false, true, false, false, UserHandle.getUserId(uid), reason); 4723 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4724 Uri.fromParts("package", packageName, null)); 4725 if (!mProcessesReady) { 4726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4727 | Intent.FLAG_RECEIVER_FOREGROUND); 4728 } 4729 intent.putExtra(Intent.EXTRA_UID, uid); 4730 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4731 broadcastIntentLocked(null, null, intent, 4732 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4733 false, false, 4734 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4735 } 4736 4737 private void forceStopUserLocked(int userId, String reason) { 4738 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4739 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4740 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4741 | Intent.FLAG_RECEIVER_FOREGROUND); 4742 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4743 broadcastIntentLocked(null, null, intent, 4744 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4745 false, false, 4746 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4747 } 4748 4749 private final boolean killPackageProcessesLocked(String packageName, int appId, 4750 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4751 boolean doit, boolean evenPersistent, String reason) { 4752 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4753 4754 // Remove all processes this package may have touched: all with the 4755 // same UID (except for the system or root user), and all whose name 4756 // matches the package name. 4757 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4758 final int NP = mProcessNames.getMap().size(); 4759 for (int ip=0; ip<NP; ip++) { 4760 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4761 final int NA = apps.size(); 4762 for (int ia=0; ia<NA; ia++) { 4763 ProcessRecord app = apps.valueAt(ia); 4764 if (app.persistent && !evenPersistent) { 4765 // we don't kill persistent processes 4766 continue; 4767 } 4768 if (app.removed) { 4769 if (doit) { 4770 procs.add(app); 4771 } 4772 continue; 4773 } 4774 4775 // Skip process if it doesn't meet our oom adj requirement. 4776 if (app.setAdj < minOomAdj) { 4777 continue; 4778 } 4779 4780 // If no package is specified, we call all processes under the 4781 // give user id. 4782 if (packageName == null) { 4783 if (app.userId != userId) { 4784 continue; 4785 } 4786 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4787 continue; 4788 } 4789 // Package has been specified, we want to hit all processes 4790 // that match it. We need to qualify this by the processes 4791 // that are running under the specified app and user ID. 4792 } else { 4793 if (UserHandle.getAppId(app.uid) != appId) { 4794 continue; 4795 } 4796 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4797 continue; 4798 } 4799 if (!app.pkgList.containsKey(packageName)) { 4800 continue; 4801 } 4802 } 4803 4804 // Process has passed all conditions, kill it! 4805 if (!doit) { 4806 return true; 4807 } 4808 app.removed = true; 4809 procs.add(app); 4810 } 4811 } 4812 4813 int N = procs.size(); 4814 for (int i=0; i<N; i++) { 4815 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4816 } 4817 updateOomAdjLocked(); 4818 return N > 0; 4819 } 4820 4821 private final boolean forceStopPackageLocked(String name, int appId, 4822 boolean callerWillRestart, boolean purgeCache, boolean doit, 4823 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4824 int i; 4825 int N; 4826 4827 if (userId == UserHandle.USER_ALL && name == null) { 4828 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4829 } 4830 4831 if (appId < 0 && name != null) { 4832 try { 4833 appId = UserHandle.getAppId( 4834 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4835 } catch (RemoteException e) { 4836 } 4837 } 4838 4839 if (doit) { 4840 if (name != null) { 4841 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4842 + " user=" + userId + ": " + reason); 4843 } else { 4844 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4845 } 4846 4847 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4848 for (int ip=pmap.size()-1; ip>=0; ip--) { 4849 SparseArray<Long> ba = pmap.valueAt(ip); 4850 for (i=ba.size()-1; i>=0; i--) { 4851 boolean remove = false; 4852 final int entUid = ba.keyAt(i); 4853 if (name != null) { 4854 if (userId == UserHandle.USER_ALL) { 4855 if (UserHandle.getAppId(entUid) == appId) { 4856 remove = true; 4857 } 4858 } else { 4859 if (entUid == UserHandle.getUid(userId, appId)) { 4860 remove = true; 4861 } 4862 } 4863 } else if (UserHandle.getUserId(entUid) == userId) { 4864 remove = true; 4865 } 4866 if (remove) { 4867 ba.removeAt(i); 4868 } 4869 } 4870 if (ba.size() == 0) { 4871 pmap.removeAt(ip); 4872 } 4873 } 4874 } 4875 4876 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4877 -100, callerWillRestart, true, doit, evenPersistent, 4878 name == null ? ("stop user " + userId) : ("stop " + name)); 4879 4880 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4881 if (!doit) { 4882 return true; 4883 } 4884 didSomething = true; 4885 } 4886 4887 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4888 if (!doit) { 4889 return true; 4890 } 4891 didSomething = true; 4892 } 4893 4894 if (name == null) { 4895 // Remove all sticky broadcasts from this user. 4896 mStickyBroadcasts.remove(userId); 4897 } 4898 4899 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4900 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4901 userId, providers)) { 4902 if (!doit) { 4903 return true; 4904 } 4905 didSomething = true; 4906 } 4907 N = providers.size(); 4908 for (i=0; i<N; i++) { 4909 removeDyingProviderLocked(null, providers.get(i), true); 4910 } 4911 4912 // Remove transient permissions granted from/to this package/user 4913 removeUriPermissionsForPackageLocked(name, userId, false); 4914 4915 if (name == null || uninstalling) { 4916 // Remove pending intents. For now we only do this when force 4917 // stopping users, because we have some problems when doing this 4918 // for packages -- app widgets are not currently cleaned up for 4919 // such packages, so they can be left with bad pending intents. 4920 if (mIntentSenderRecords.size() > 0) { 4921 Iterator<WeakReference<PendingIntentRecord>> it 4922 = mIntentSenderRecords.values().iterator(); 4923 while (it.hasNext()) { 4924 WeakReference<PendingIntentRecord> wpir = it.next(); 4925 if (wpir == null) { 4926 it.remove(); 4927 continue; 4928 } 4929 PendingIntentRecord pir = wpir.get(); 4930 if (pir == null) { 4931 it.remove(); 4932 continue; 4933 } 4934 if (name == null) { 4935 // Stopping user, remove all objects for the user. 4936 if (pir.key.userId != userId) { 4937 // Not the same user, skip it. 4938 continue; 4939 } 4940 } else { 4941 if (UserHandle.getAppId(pir.uid) != appId) { 4942 // Different app id, skip it. 4943 continue; 4944 } 4945 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4946 // Different user, skip it. 4947 continue; 4948 } 4949 if (!pir.key.packageName.equals(name)) { 4950 // Different package, skip it. 4951 continue; 4952 } 4953 } 4954 if (!doit) { 4955 return true; 4956 } 4957 didSomething = true; 4958 it.remove(); 4959 pir.canceled = true; 4960 if (pir.key.activity != null) { 4961 pir.key.activity.pendingResults.remove(pir.ref); 4962 } 4963 } 4964 } 4965 } 4966 4967 if (doit) { 4968 if (purgeCache && name != null) { 4969 AttributeCache ac = AttributeCache.instance(); 4970 if (ac != null) { 4971 ac.removePackage(name); 4972 } 4973 } 4974 if (mBooted) { 4975 mStackSupervisor.resumeTopActivitiesLocked(); 4976 mStackSupervisor.scheduleIdleLocked(); 4977 } 4978 } 4979 4980 return didSomething; 4981 } 4982 4983 private final boolean removeProcessLocked(ProcessRecord app, 4984 boolean callerWillRestart, boolean allowRestart, String reason) { 4985 final String name = app.processName; 4986 final int uid = app.uid; 4987 if (DEBUG_PROCESSES) Slog.d( 4988 TAG, "Force removing proc " + app.toShortString() + " (" + name 4989 + "/" + uid + ")"); 4990 4991 mProcessNames.remove(name, uid); 4992 mIsolatedProcesses.remove(app.uid); 4993 if (mHeavyWeightProcess == app) { 4994 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4995 mHeavyWeightProcess.userId, 0)); 4996 mHeavyWeightProcess = null; 4997 } 4998 boolean needRestart = false; 4999 if (app.pid > 0 && app.pid != MY_PID) { 5000 int pid = app.pid; 5001 synchronized (mPidsSelfLocked) { 5002 mPidsSelfLocked.remove(pid); 5003 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5004 } 5005 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5006 app.processName, app.info.uid); 5007 if (app.isolated) { 5008 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5009 } 5010 killUnneededProcessLocked(app, reason); 5011 handleAppDiedLocked(app, true, allowRestart); 5012 removeLruProcessLocked(app); 5013 5014 if (app.persistent && !app.isolated) { 5015 if (!callerWillRestart) { 5016 addAppLocked(app.info, false); 5017 } else { 5018 needRestart = true; 5019 } 5020 } 5021 } else { 5022 mRemovedProcesses.add(app); 5023 } 5024 5025 return needRestart; 5026 } 5027 5028 private final void processStartTimedOutLocked(ProcessRecord app) { 5029 final int pid = app.pid; 5030 boolean gone = false; 5031 synchronized (mPidsSelfLocked) { 5032 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5033 if (knownApp != null && knownApp.thread == null) { 5034 mPidsSelfLocked.remove(pid); 5035 gone = true; 5036 } 5037 } 5038 5039 if (gone) { 5040 Slog.w(TAG, "Process " + app + " failed to attach"); 5041 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5042 pid, app.uid, app.processName); 5043 mProcessNames.remove(app.processName, app.uid); 5044 mIsolatedProcesses.remove(app.uid); 5045 if (mHeavyWeightProcess == app) { 5046 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5047 mHeavyWeightProcess.userId, 0)); 5048 mHeavyWeightProcess = null; 5049 } 5050 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5051 app.processName, app.info.uid); 5052 if (app.isolated) { 5053 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5054 } 5055 // Take care of any launching providers waiting for this process. 5056 checkAppInLaunchingProvidersLocked(app, true); 5057 // Take care of any services that are waiting for the process. 5058 mServices.processStartTimedOutLocked(app); 5059 killUnneededProcessLocked(app, "start timeout"); 5060 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5061 Slog.w(TAG, "Unattached app died before backup, skipping"); 5062 try { 5063 IBackupManager bm = IBackupManager.Stub.asInterface( 5064 ServiceManager.getService(Context.BACKUP_SERVICE)); 5065 bm.agentDisconnected(app.info.packageName); 5066 } catch (RemoteException e) { 5067 // Can't happen; the backup manager is local 5068 } 5069 } 5070 if (isPendingBroadcastProcessLocked(pid)) { 5071 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5072 skipPendingBroadcastLocked(pid); 5073 } 5074 } else { 5075 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5076 } 5077 } 5078 5079 private final boolean attachApplicationLocked(IApplicationThread thread, 5080 int pid) { 5081 5082 // Find the application record that is being attached... either via 5083 // the pid if we are running in multiple processes, or just pull the 5084 // next app record if we are emulating process with anonymous threads. 5085 ProcessRecord app; 5086 if (pid != MY_PID && pid >= 0) { 5087 synchronized (mPidsSelfLocked) { 5088 app = mPidsSelfLocked.get(pid); 5089 } 5090 } else { 5091 app = null; 5092 } 5093 5094 if (app == null) { 5095 Slog.w(TAG, "No pending application record for pid " + pid 5096 + " (IApplicationThread " + thread + "); dropping process"); 5097 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5098 if (pid > 0 && pid != MY_PID) { 5099 Process.killProcessQuiet(pid); 5100 } else { 5101 try { 5102 thread.scheduleExit(); 5103 } catch (Exception e) { 5104 // Ignore exceptions. 5105 } 5106 } 5107 return false; 5108 } 5109 5110 // If this application record is still attached to a previous 5111 // process, clean it up now. 5112 if (app.thread != null) { 5113 handleAppDiedLocked(app, true, true); 5114 } 5115 5116 // Tell the process all about itself. 5117 5118 if (localLOGV) Slog.v( 5119 TAG, "Binding process pid " + pid + " to record " + app); 5120 5121 final String processName = app.processName; 5122 try { 5123 AppDeathRecipient adr = new AppDeathRecipient( 5124 app, pid, thread); 5125 thread.asBinder().linkToDeath(adr, 0); 5126 app.deathRecipient = adr; 5127 } catch (RemoteException e) { 5128 app.resetPackageList(mProcessStats); 5129 startProcessLocked(app, "link fail", processName); 5130 return false; 5131 } 5132 5133 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5134 5135 app.makeActive(thread, mProcessStats); 5136 app.curAdj = app.setAdj = -100; 5137 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5138 app.forcingToForeground = null; 5139 updateProcessForegroundLocked(app, false, false); 5140 app.hasShownUi = false; 5141 app.debugging = false; 5142 app.cached = false; 5143 5144 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5145 5146 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5147 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5148 5149 if (!normalMode) { 5150 Slog.i(TAG, "Launching preboot mode app: " + app); 5151 } 5152 5153 if (localLOGV) Slog.v( 5154 TAG, "New app record " + app 5155 + " thread=" + thread.asBinder() + " pid=" + pid); 5156 try { 5157 int testMode = IApplicationThread.DEBUG_OFF; 5158 if (mDebugApp != null && mDebugApp.equals(processName)) { 5159 testMode = mWaitForDebugger 5160 ? IApplicationThread.DEBUG_WAIT 5161 : IApplicationThread.DEBUG_ON; 5162 app.debugging = true; 5163 if (mDebugTransient) { 5164 mDebugApp = mOrigDebugApp; 5165 mWaitForDebugger = mOrigWaitForDebugger; 5166 } 5167 } 5168 String profileFile = app.instrumentationProfileFile; 5169 ParcelFileDescriptor profileFd = null; 5170 boolean profileAutoStop = false; 5171 if (mProfileApp != null && mProfileApp.equals(processName)) { 5172 mProfileProc = app; 5173 profileFile = mProfileFile; 5174 profileFd = mProfileFd; 5175 profileAutoStop = mAutoStopProfiler; 5176 } 5177 boolean enableOpenGlTrace = false; 5178 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5179 enableOpenGlTrace = true; 5180 mOpenGlTraceApp = null; 5181 } 5182 5183 // If the app is being launched for restore or full backup, set it up specially 5184 boolean isRestrictedBackupMode = false; 5185 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5186 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5187 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5188 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5189 } 5190 5191 ensurePackageDexOpt(app.instrumentationInfo != null 5192 ? app.instrumentationInfo.packageName 5193 : app.info.packageName); 5194 if (app.instrumentationClass != null) { 5195 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5196 } 5197 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5198 + processName + " with config " + mConfiguration); 5199 ApplicationInfo appInfo = app.instrumentationInfo != null 5200 ? app.instrumentationInfo : app.info; 5201 app.compat = compatibilityInfoForPackageLocked(appInfo); 5202 if (profileFd != null) { 5203 profileFd = profileFd.dup(); 5204 } 5205 thread.bindApplication(processName, appInfo, providers, 5206 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5207 app.instrumentationArguments, app.instrumentationWatcher, 5208 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5209 isRestrictedBackupMode || !normalMode, app.persistent, 5210 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5211 mCoreSettingsObserver.getCoreSettingsLocked()); 5212 updateLruProcessLocked(app, false, null); 5213 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5214 } catch (Exception e) { 5215 // todo: Yikes! What should we do? For now we will try to 5216 // start another process, but that could easily get us in 5217 // an infinite loop of restarting processes... 5218 Slog.w(TAG, "Exception thrown during bind!", e); 5219 5220 app.resetPackageList(mProcessStats); 5221 app.unlinkDeathRecipient(); 5222 startProcessLocked(app, "bind fail", processName); 5223 return false; 5224 } 5225 5226 // Remove this record from the list of starting applications. 5227 mPersistentStartingProcesses.remove(app); 5228 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5229 "Attach application locked removing on hold: " + app); 5230 mProcessesOnHold.remove(app); 5231 5232 boolean badApp = false; 5233 boolean didSomething = false; 5234 5235 // See if the top visible activity is waiting to run in this process... 5236 if (normalMode) { 5237 try { 5238 if (mStackSupervisor.attachApplicationLocked(app)) { 5239 didSomething = true; 5240 } 5241 } catch (Exception e) { 5242 badApp = true; 5243 } 5244 } 5245 5246 // Find any services that should be running in this process... 5247 if (!badApp) { 5248 try { 5249 didSomething |= mServices.attachApplicationLocked(app, processName); 5250 } catch (Exception e) { 5251 badApp = true; 5252 } 5253 } 5254 5255 // Check if a next-broadcast receiver is in this process... 5256 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5257 try { 5258 didSomething |= sendPendingBroadcastsLocked(app); 5259 } catch (Exception e) { 5260 // If the app died trying to launch the receiver we declare it 'bad' 5261 badApp = true; 5262 } 5263 } 5264 5265 // Check whether the next backup agent is in this process... 5266 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5267 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5268 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5269 try { 5270 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5271 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5272 mBackupTarget.backupMode); 5273 } catch (Exception e) { 5274 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5275 e.printStackTrace(); 5276 } 5277 } 5278 5279 if (badApp) { 5280 // todo: Also need to kill application to deal with all 5281 // kinds of exceptions. 5282 handleAppDiedLocked(app, false, true); 5283 return false; 5284 } 5285 5286 if (!didSomething) { 5287 updateOomAdjLocked(); 5288 } 5289 5290 return true; 5291 } 5292 5293 @Override 5294 public final void attachApplication(IApplicationThread thread) { 5295 synchronized (this) { 5296 int callingPid = Binder.getCallingPid(); 5297 final long origId = Binder.clearCallingIdentity(); 5298 attachApplicationLocked(thread, callingPid); 5299 Binder.restoreCallingIdentity(origId); 5300 } 5301 } 5302 5303 @Override 5304 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5305 final long origId = Binder.clearCallingIdentity(); 5306 synchronized (this) { 5307 ActivityStack stack = ActivityRecord.getStackLocked(token); 5308 if (stack != null) { 5309 ActivityRecord r = 5310 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5311 if (stopProfiling) { 5312 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5313 try { 5314 mProfileFd.close(); 5315 } catch (IOException e) { 5316 } 5317 clearProfilerLocked(); 5318 } 5319 } 5320 } 5321 } 5322 Binder.restoreCallingIdentity(origId); 5323 } 5324 5325 void enableScreenAfterBoot() { 5326 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5327 SystemClock.uptimeMillis()); 5328 mWindowManager.enableScreenAfterBoot(); 5329 5330 synchronized (this) { 5331 updateEventDispatchingLocked(); 5332 } 5333 } 5334 5335 @Override 5336 public void showBootMessage(final CharSequence msg, final boolean always) { 5337 enforceNotIsolatedCaller("showBootMessage"); 5338 mWindowManager.showBootMessage(msg, always); 5339 } 5340 5341 @Override 5342 public void dismissKeyguardOnNextActivity() { 5343 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5344 final long token = Binder.clearCallingIdentity(); 5345 try { 5346 synchronized (this) { 5347 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5348 if (mLockScreenShown) { 5349 mLockScreenShown = false; 5350 comeOutOfSleepIfNeededLocked(); 5351 } 5352 mStackSupervisor.setDismissKeyguard(true); 5353 } 5354 } finally { 5355 Binder.restoreCallingIdentity(token); 5356 } 5357 } 5358 5359 final void finishBooting() { 5360 // Register receivers to handle package update events 5361 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5362 5363 synchronized (this) { 5364 // Ensure that any processes we had put on hold are now started 5365 // up. 5366 final int NP = mProcessesOnHold.size(); 5367 if (NP > 0) { 5368 ArrayList<ProcessRecord> procs = 5369 new ArrayList<ProcessRecord>(mProcessesOnHold); 5370 for (int ip=0; ip<NP; ip++) { 5371 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5372 + procs.get(ip)); 5373 startProcessLocked(procs.get(ip), "on-hold", null); 5374 } 5375 } 5376 5377 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5378 // Start looking for apps that are abusing wake locks. 5379 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5380 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5381 // Tell anyone interested that we are done booting! 5382 SystemProperties.set("sys.boot_completed", "1"); 5383 SystemProperties.set("dev.bootcomplete", "1"); 5384 for (int i=0; i<mStartedUsers.size(); i++) { 5385 UserStartedState uss = mStartedUsers.valueAt(i); 5386 if (uss.mState == UserStartedState.STATE_BOOTING) { 5387 uss.mState = UserStartedState.STATE_RUNNING; 5388 final int userId = mStartedUsers.keyAt(i); 5389 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5390 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5391 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5392 broadcastIntentLocked(null, null, intent, null, 5393 new IIntentReceiver.Stub() { 5394 @Override 5395 public void performReceive(Intent intent, int resultCode, 5396 String data, Bundle extras, boolean ordered, 5397 boolean sticky, int sendingUser) { 5398 synchronized (ActivityManagerService.this) { 5399 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5400 true, false); 5401 } 5402 } 5403 }, 5404 0, null, null, 5405 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5406 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5407 userId); 5408 } 5409 } 5410 scheduleStartProfilesLocked(); 5411 } 5412 } 5413 } 5414 5415 final void ensureBootCompleted() { 5416 boolean booting; 5417 boolean enableScreen; 5418 synchronized (this) { 5419 booting = mBooting; 5420 mBooting = false; 5421 enableScreen = !mBooted; 5422 mBooted = true; 5423 } 5424 5425 if (booting) { 5426 finishBooting(); 5427 } 5428 5429 if (enableScreen) { 5430 enableScreenAfterBoot(); 5431 } 5432 } 5433 5434 @Override 5435 public final void activityResumed(IBinder token) { 5436 final long origId = Binder.clearCallingIdentity(); 5437 synchronized(this) { 5438 ActivityStack stack = ActivityRecord.getStackLocked(token); 5439 if (stack != null) { 5440 ActivityRecord.activityResumedLocked(token); 5441 } 5442 } 5443 Binder.restoreCallingIdentity(origId); 5444 } 5445 5446 @Override 5447 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5448 final long origId = Binder.clearCallingIdentity(); 5449 synchronized(this) { 5450 ActivityStack stack = ActivityRecord.getStackLocked(token); 5451 if (stack != null) { 5452 stack.activityPausedLocked(token, false, persistentState); 5453 } 5454 } 5455 Binder.restoreCallingIdentity(origId); 5456 } 5457 5458 @Override 5459 public final void activityStopped(IBinder token, Bundle icicle, 5460 PersistableBundle persistentState, CharSequence description) { 5461 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5462 5463 // Refuse possible leaked file descriptors 5464 if (icicle != null && icicle.hasFileDescriptors()) { 5465 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5466 } 5467 5468 final long origId = Binder.clearCallingIdentity(); 5469 5470 synchronized (this) { 5471 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5472 if (r != null) { 5473 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5474 } 5475 } 5476 5477 trimApplications(); 5478 5479 Binder.restoreCallingIdentity(origId); 5480 } 5481 5482 @Override 5483 public final void activityDestroyed(IBinder token) { 5484 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5485 synchronized (this) { 5486 ActivityStack stack = ActivityRecord.getStackLocked(token); 5487 if (stack != null) { 5488 stack.activityDestroyedLocked(token); 5489 } 5490 } 5491 } 5492 5493 @Override 5494 public String getCallingPackage(IBinder token) { 5495 synchronized (this) { 5496 ActivityRecord r = getCallingRecordLocked(token); 5497 return r != null ? r.info.packageName : null; 5498 } 5499 } 5500 5501 @Override 5502 public ComponentName getCallingActivity(IBinder token) { 5503 synchronized (this) { 5504 ActivityRecord r = getCallingRecordLocked(token); 5505 return r != null ? r.intent.getComponent() : null; 5506 } 5507 } 5508 5509 private ActivityRecord getCallingRecordLocked(IBinder token) { 5510 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5511 if (r == null) { 5512 return null; 5513 } 5514 return r.resultTo; 5515 } 5516 5517 @Override 5518 public ComponentName getActivityClassForToken(IBinder token) { 5519 synchronized(this) { 5520 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5521 if (r == null) { 5522 return null; 5523 } 5524 return r.intent.getComponent(); 5525 } 5526 } 5527 5528 @Override 5529 public String getPackageForToken(IBinder token) { 5530 synchronized(this) { 5531 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5532 if (r == null) { 5533 return null; 5534 } 5535 return r.packageName; 5536 } 5537 } 5538 5539 @Override 5540 public IIntentSender getIntentSender(int type, 5541 String packageName, IBinder token, String resultWho, 5542 int requestCode, Intent[] intents, String[] resolvedTypes, 5543 int flags, Bundle options, int userId) { 5544 enforceNotIsolatedCaller("getIntentSender"); 5545 // Refuse possible leaked file descriptors 5546 if (intents != null) { 5547 if (intents.length < 1) { 5548 throw new IllegalArgumentException("Intents array length must be >= 1"); 5549 } 5550 for (int i=0; i<intents.length; i++) { 5551 Intent intent = intents[i]; 5552 if (intent != null) { 5553 if (intent.hasFileDescriptors()) { 5554 throw new IllegalArgumentException("File descriptors passed in Intent"); 5555 } 5556 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5557 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5558 throw new IllegalArgumentException( 5559 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5560 } 5561 intents[i] = new Intent(intent); 5562 } 5563 } 5564 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5565 throw new IllegalArgumentException( 5566 "Intent array length does not match resolvedTypes length"); 5567 } 5568 } 5569 if (options != null) { 5570 if (options.hasFileDescriptors()) { 5571 throw new IllegalArgumentException("File descriptors passed in options"); 5572 } 5573 } 5574 5575 synchronized(this) { 5576 int callingUid = Binder.getCallingUid(); 5577 int origUserId = userId; 5578 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5579 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5580 "getIntentSender", null); 5581 if (origUserId == UserHandle.USER_CURRENT) { 5582 // We don't want to evaluate this until the pending intent is 5583 // actually executed. However, we do want to always do the 5584 // security checking for it above. 5585 userId = UserHandle.USER_CURRENT; 5586 } 5587 try { 5588 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5589 int uid = AppGlobals.getPackageManager() 5590 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5591 if (!UserHandle.isSameApp(callingUid, uid)) { 5592 String msg = "Permission Denial: getIntentSender() from pid=" 5593 + Binder.getCallingPid() 5594 + ", uid=" + Binder.getCallingUid() 5595 + ", (need uid=" + uid + ")" 5596 + " is not allowed to send as package " + packageName; 5597 Slog.w(TAG, msg); 5598 throw new SecurityException(msg); 5599 } 5600 } 5601 5602 return getIntentSenderLocked(type, packageName, callingUid, userId, 5603 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5604 5605 } catch (RemoteException e) { 5606 throw new SecurityException(e); 5607 } 5608 } 5609 } 5610 5611 IIntentSender getIntentSenderLocked(int type, String packageName, 5612 int callingUid, int userId, IBinder token, String resultWho, 5613 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5614 Bundle options) { 5615 if (DEBUG_MU) 5616 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5617 ActivityRecord activity = null; 5618 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5619 activity = ActivityRecord.isInStackLocked(token); 5620 if (activity == null) { 5621 return null; 5622 } 5623 if (activity.finishing) { 5624 return null; 5625 } 5626 } 5627 5628 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5629 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5630 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5631 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5632 |PendingIntent.FLAG_UPDATE_CURRENT); 5633 5634 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5635 type, packageName, activity, resultWho, 5636 requestCode, intents, resolvedTypes, flags, options, userId); 5637 WeakReference<PendingIntentRecord> ref; 5638 ref = mIntentSenderRecords.get(key); 5639 PendingIntentRecord rec = ref != null ? ref.get() : null; 5640 if (rec != null) { 5641 if (!cancelCurrent) { 5642 if (updateCurrent) { 5643 if (rec.key.requestIntent != null) { 5644 rec.key.requestIntent.replaceExtras(intents != null ? 5645 intents[intents.length - 1] : null); 5646 } 5647 if (intents != null) { 5648 intents[intents.length-1] = rec.key.requestIntent; 5649 rec.key.allIntents = intents; 5650 rec.key.allResolvedTypes = resolvedTypes; 5651 } else { 5652 rec.key.allIntents = null; 5653 rec.key.allResolvedTypes = null; 5654 } 5655 } 5656 return rec; 5657 } 5658 rec.canceled = true; 5659 mIntentSenderRecords.remove(key); 5660 } 5661 if (noCreate) { 5662 return rec; 5663 } 5664 rec = new PendingIntentRecord(this, key, callingUid); 5665 mIntentSenderRecords.put(key, rec.ref); 5666 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5667 if (activity.pendingResults == null) { 5668 activity.pendingResults 5669 = new HashSet<WeakReference<PendingIntentRecord>>(); 5670 } 5671 activity.pendingResults.add(rec.ref); 5672 } 5673 return rec; 5674 } 5675 5676 @Override 5677 public void cancelIntentSender(IIntentSender sender) { 5678 if (!(sender instanceof PendingIntentRecord)) { 5679 return; 5680 } 5681 synchronized(this) { 5682 PendingIntentRecord rec = (PendingIntentRecord)sender; 5683 try { 5684 int uid = AppGlobals.getPackageManager() 5685 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5686 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5687 String msg = "Permission Denial: cancelIntentSender() from pid=" 5688 + Binder.getCallingPid() 5689 + ", uid=" + Binder.getCallingUid() 5690 + " is not allowed to cancel packges " 5691 + rec.key.packageName; 5692 Slog.w(TAG, msg); 5693 throw new SecurityException(msg); 5694 } 5695 } catch (RemoteException e) { 5696 throw new SecurityException(e); 5697 } 5698 cancelIntentSenderLocked(rec, true); 5699 } 5700 } 5701 5702 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5703 rec.canceled = true; 5704 mIntentSenderRecords.remove(rec.key); 5705 if (cleanActivity && rec.key.activity != null) { 5706 rec.key.activity.pendingResults.remove(rec.ref); 5707 } 5708 } 5709 5710 @Override 5711 public String getPackageForIntentSender(IIntentSender pendingResult) { 5712 if (!(pendingResult instanceof PendingIntentRecord)) { 5713 return null; 5714 } 5715 try { 5716 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5717 return res.key.packageName; 5718 } catch (ClassCastException e) { 5719 } 5720 return null; 5721 } 5722 5723 @Override 5724 public int getUidForIntentSender(IIntentSender sender) { 5725 if (sender instanceof PendingIntentRecord) { 5726 try { 5727 PendingIntentRecord res = (PendingIntentRecord)sender; 5728 return res.uid; 5729 } catch (ClassCastException e) { 5730 } 5731 } 5732 return -1; 5733 } 5734 5735 @Override 5736 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5737 if (!(pendingResult instanceof PendingIntentRecord)) { 5738 return false; 5739 } 5740 try { 5741 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5742 if (res.key.allIntents == null) { 5743 return false; 5744 } 5745 for (int i=0; i<res.key.allIntents.length; i++) { 5746 Intent intent = res.key.allIntents[i]; 5747 if (intent.getPackage() != null && intent.getComponent() != null) { 5748 return false; 5749 } 5750 } 5751 return true; 5752 } catch (ClassCastException e) { 5753 } 5754 return false; 5755 } 5756 5757 @Override 5758 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5759 if (!(pendingResult instanceof PendingIntentRecord)) { 5760 return false; 5761 } 5762 try { 5763 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5764 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5765 return true; 5766 } 5767 return false; 5768 } catch (ClassCastException e) { 5769 } 5770 return false; 5771 } 5772 5773 @Override 5774 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5775 if (!(pendingResult instanceof PendingIntentRecord)) { 5776 return null; 5777 } 5778 try { 5779 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5780 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5781 } catch (ClassCastException e) { 5782 } 5783 return null; 5784 } 5785 5786 @Override 5787 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5788 if (!(pendingResult instanceof PendingIntentRecord)) { 5789 return null; 5790 } 5791 try { 5792 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5793 Intent intent = res.key.requestIntent; 5794 if (intent != null) { 5795 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5796 || res.lastTagPrefix.equals(prefix))) { 5797 return res.lastTag; 5798 } 5799 res.lastTagPrefix = prefix; 5800 StringBuilder sb = new StringBuilder(128); 5801 if (prefix != null) { 5802 sb.append(prefix); 5803 } 5804 if (intent.getAction() != null) { 5805 sb.append(intent.getAction()); 5806 } else if (intent.getComponent() != null) { 5807 intent.getComponent().appendShortString(sb); 5808 } else { 5809 sb.append("?"); 5810 } 5811 return res.lastTag = sb.toString(); 5812 } 5813 } catch (ClassCastException e) { 5814 } 5815 return null; 5816 } 5817 5818 @Override 5819 public void setProcessLimit(int max) { 5820 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5821 "setProcessLimit()"); 5822 synchronized (this) { 5823 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5824 mProcessLimitOverride = max; 5825 } 5826 trimApplications(); 5827 } 5828 5829 @Override 5830 public int getProcessLimit() { 5831 synchronized (this) { 5832 return mProcessLimitOverride; 5833 } 5834 } 5835 5836 void foregroundTokenDied(ForegroundToken token) { 5837 synchronized (ActivityManagerService.this) { 5838 synchronized (mPidsSelfLocked) { 5839 ForegroundToken cur 5840 = mForegroundProcesses.get(token.pid); 5841 if (cur != token) { 5842 return; 5843 } 5844 mForegroundProcesses.remove(token.pid); 5845 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5846 if (pr == null) { 5847 return; 5848 } 5849 pr.forcingToForeground = null; 5850 updateProcessForegroundLocked(pr, false, false); 5851 } 5852 updateOomAdjLocked(); 5853 } 5854 } 5855 5856 @Override 5857 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5858 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5859 "setProcessForeground()"); 5860 synchronized(this) { 5861 boolean changed = false; 5862 5863 synchronized (mPidsSelfLocked) { 5864 ProcessRecord pr = mPidsSelfLocked.get(pid); 5865 if (pr == null && isForeground) { 5866 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5867 return; 5868 } 5869 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5870 if (oldToken != null) { 5871 oldToken.token.unlinkToDeath(oldToken, 0); 5872 mForegroundProcesses.remove(pid); 5873 if (pr != null) { 5874 pr.forcingToForeground = null; 5875 } 5876 changed = true; 5877 } 5878 if (isForeground && token != null) { 5879 ForegroundToken newToken = new ForegroundToken() { 5880 @Override 5881 public void binderDied() { 5882 foregroundTokenDied(this); 5883 } 5884 }; 5885 newToken.pid = pid; 5886 newToken.token = token; 5887 try { 5888 token.linkToDeath(newToken, 0); 5889 mForegroundProcesses.put(pid, newToken); 5890 pr.forcingToForeground = token; 5891 changed = true; 5892 } catch (RemoteException e) { 5893 // If the process died while doing this, we will later 5894 // do the cleanup with the process death link. 5895 } 5896 } 5897 } 5898 5899 if (changed) { 5900 updateOomAdjLocked(); 5901 } 5902 } 5903 } 5904 5905 // ========================================================= 5906 // PERMISSIONS 5907 // ========================================================= 5908 5909 static class PermissionController extends IPermissionController.Stub { 5910 ActivityManagerService mActivityManagerService; 5911 PermissionController(ActivityManagerService activityManagerService) { 5912 mActivityManagerService = activityManagerService; 5913 } 5914 5915 @Override 5916 public boolean checkPermission(String permission, int pid, int uid) { 5917 return mActivityManagerService.checkPermission(permission, pid, 5918 uid) == PackageManager.PERMISSION_GRANTED; 5919 } 5920 } 5921 5922 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5923 @Override 5924 public int checkComponentPermission(String permission, int pid, int uid, 5925 int owningUid, boolean exported) { 5926 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5927 owningUid, exported); 5928 } 5929 5930 @Override 5931 public Object getAMSLock() { 5932 return ActivityManagerService.this; 5933 } 5934 } 5935 5936 /** 5937 * This can be called with or without the global lock held. 5938 */ 5939 int checkComponentPermission(String permission, int pid, int uid, 5940 int owningUid, boolean exported) { 5941 // We might be performing an operation on behalf of an indirect binder 5942 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5943 // client identity accordingly before proceeding. 5944 Identity tlsIdentity = sCallerIdentity.get(); 5945 if (tlsIdentity != null) { 5946 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5947 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5948 uid = tlsIdentity.uid; 5949 pid = tlsIdentity.pid; 5950 } 5951 5952 if (pid == MY_PID) { 5953 return PackageManager.PERMISSION_GRANTED; 5954 } 5955 5956 return ActivityManager.checkComponentPermission(permission, uid, 5957 owningUid, exported); 5958 } 5959 5960 /** 5961 * As the only public entry point for permissions checking, this method 5962 * can enforce the semantic that requesting a check on a null global 5963 * permission is automatically denied. (Internally a null permission 5964 * string is used when calling {@link #checkComponentPermission} in cases 5965 * when only uid-based security is needed.) 5966 * 5967 * This can be called with or without the global lock held. 5968 */ 5969 @Override 5970 public int checkPermission(String permission, int pid, int uid) { 5971 if (permission == null) { 5972 return PackageManager.PERMISSION_DENIED; 5973 } 5974 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5975 } 5976 5977 /** 5978 * Binder IPC calls go through the public entry point. 5979 * This can be called with or without the global lock held. 5980 */ 5981 int checkCallingPermission(String permission) { 5982 return checkPermission(permission, 5983 Binder.getCallingPid(), 5984 UserHandle.getAppId(Binder.getCallingUid())); 5985 } 5986 5987 /** 5988 * This can be called with or without the global lock held. 5989 */ 5990 void enforceCallingPermission(String permission, String func) { 5991 if (checkCallingPermission(permission) 5992 == PackageManager.PERMISSION_GRANTED) { 5993 return; 5994 } 5995 5996 String msg = "Permission Denial: " + func + " from pid=" 5997 + Binder.getCallingPid() 5998 + ", uid=" + Binder.getCallingUid() 5999 + " requires " + permission; 6000 Slog.w(TAG, msg); 6001 throw new SecurityException(msg); 6002 } 6003 6004 /** 6005 * Determine if UID is holding permissions required to access {@link Uri} in 6006 * the given {@link ProviderInfo}. Final permission checking is always done 6007 * in {@link ContentProvider}. 6008 */ 6009 private final boolean checkHoldingPermissionsLocked( 6010 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6011 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6012 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6013 6014 if (pi.applicationInfo.uid == uid) { 6015 return true; 6016 } else if (!pi.exported) { 6017 return false; 6018 } 6019 6020 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6021 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6022 try { 6023 // check if target holds top-level <provider> permissions 6024 if (!readMet && pi.readPermission != null 6025 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6026 readMet = true; 6027 } 6028 if (!writeMet && pi.writePermission != null 6029 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6030 writeMet = true; 6031 } 6032 6033 // track if unprotected read/write is allowed; any denied 6034 // <path-permission> below removes this ability 6035 boolean allowDefaultRead = pi.readPermission == null; 6036 boolean allowDefaultWrite = pi.writePermission == null; 6037 6038 // check if target holds any <path-permission> that match uri 6039 final PathPermission[] pps = pi.pathPermissions; 6040 if (pps != null) { 6041 final String path = grantUri.uri.getPath(); 6042 int i = pps.length; 6043 while (i > 0 && (!readMet || !writeMet)) { 6044 i--; 6045 PathPermission pp = pps[i]; 6046 if (pp.match(path)) { 6047 if (!readMet) { 6048 final String pprperm = pp.getReadPermission(); 6049 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6050 + pprperm + " for " + pp.getPath() 6051 + ": match=" + pp.match(path) 6052 + " check=" + pm.checkUidPermission(pprperm, uid)); 6053 if (pprperm != null) { 6054 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6055 readMet = true; 6056 } else { 6057 allowDefaultRead = false; 6058 } 6059 } 6060 } 6061 if (!writeMet) { 6062 final String ppwperm = pp.getWritePermission(); 6063 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6064 + ppwperm + " for " + pp.getPath() 6065 + ": match=" + pp.match(path) 6066 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6067 if (ppwperm != null) { 6068 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6069 writeMet = true; 6070 } else { 6071 allowDefaultWrite = false; 6072 } 6073 } 6074 } 6075 } 6076 } 6077 } 6078 6079 // grant unprotected <provider> read/write, if not blocked by 6080 // <path-permission> above 6081 if (allowDefaultRead) readMet = true; 6082 if (allowDefaultWrite) writeMet = true; 6083 6084 } catch (RemoteException e) { 6085 return false; 6086 } 6087 6088 return readMet && writeMet; 6089 } 6090 6091 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6092 ProviderInfo pi = null; 6093 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6094 if (cpr != null) { 6095 pi = cpr.info; 6096 } else { 6097 try { 6098 pi = AppGlobals.getPackageManager().resolveContentProvider( 6099 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6100 } catch (RemoteException ex) { 6101 } 6102 } 6103 return pi; 6104 } 6105 6106 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6107 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6108 if (targetUris != null) { 6109 return targetUris.get(grantUri); 6110 } 6111 return null; 6112 } 6113 6114 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6115 String targetPkg, int targetUid, GrantUri grantUri) { 6116 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6117 if (targetUris == null) { 6118 targetUris = Maps.newArrayMap(); 6119 mGrantedUriPermissions.put(targetUid, targetUris); 6120 } 6121 6122 UriPermission perm = targetUris.get(grantUri); 6123 if (perm == null) { 6124 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6125 targetUris.put(grantUri, perm); 6126 } 6127 6128 return perm; 6129 } 6130 6131 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6132 final int modeFlags) { 6133 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6134 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6135 : UriPermission.STRENGTH_OWNED; 6136 6137 // Root gets to do everything. 6138 if (uid == 0) { 6139 return true; 6140 } 6141 6142 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6143 if (perms == null) return false; 6144 6145 // First look for exact match 6146 final UriPermission exactPerm = perms.get(grantUri); 6147 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6148 return true; 6149 } 6150 6151 // No exact match, look for prefixes 6152 final int N = perms.size(); 6153 for (int i = 0; i < N; i++) { 6154 final UriPermission perm = perms.valueAt(i); 6155 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6156 && perm.getStrength(modeFlags) >= minStrength) { 6157 return true; 6158 } 6159 } 6160 6161 return false; 6162 } 6163 6164 @Override 6165 public int checkUriPermission(Uri uri, int pid, int uid, 6166 final int modeFlags, int userId) { 6167 enforceNotIsolatedCaller("checkUriPermission"); 6168 6169 // Another redirected-binder-call permissions check as in 6170 // {@link checkComponentPermission}. 6171 Identity tlsIdentity = sCallerIdentity.get(); 6172 if (tlsIdentity != null) { 6173 uid = tlsIdentity.uid; 6174 pid = tlsIdentity.pid; 6175 } 6176 6177 // Our own process gets to do everything. 6178 if (pid == MY_PID) { 6179 return PackageManager.PERMISSION_GRANTED; 6180 } 6181 synchronized (this) { 6182 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6183 ? PackageManager.PERMISSION_GRANTED 6184 : PackageManager.PERMISSION_DENIED; 6185 } 6186 } 6187 6188 /** 6189 * Check if the targetPkg can be granted permission to access uri by 6190 * the callingUid using the given modeFlags. Throws a security exception 6191 * if callingUid is not allowed to do this. Returns the uid of the target 6192 * if the URI permission grant should be performed; returns -1 if it is not 6193 * needed (for example targetPkg already has permission to access the URI). 6194 * If you already know the uid of the target, you can supply it in 6195 * lastTargetUid else set that to -1. 6196 */ 6197 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6198 final int modeFlags, int lastTargetUid) { 6199 if (!Intent.isAccessUriMode(modeFlags)) { 6200 return -1; 6201 } 6202 6203 if (targetPkg != null) { 6204 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6205 "Checking grant " + targetPkg + " permission to " + grantUri); 6206 } 6207 6208 final IPackageManager pm = AppGlobals.getPackageManager(); 6209 6210 // If this is not a content: uri, we can't do anything with it. 6211 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6212 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6213 "Can't grant URI permission for non-content URI: " + grantUri); 6214 return -1; 6215 } 6216 6217 final String authority = grantUri.uri.getAuthority(); 6218 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6219 if (pi == null) { 6220 Slog.w(TAG, "No content provider found for permission check: " + 6221 grantUri.uri.toSafeString()); 6222 return -1; 6223 } 6224 6225 int targetUid = lastTargetUid; 6226 if (targetUid < 0 && targetPkg != null) { 6227 try { 6228 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6229 if (targetUid < 0) { 6230 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6231 "Can't grant URI permission no uid for: " + targetPkg); 6232 return -1; 6233 } 6234 } catch (RemoteException ex) { 6235 return -1; 6236 } 6237 } 6238 6239 if (targetUid >= 0) { 6240 // First... does the target actually need this permission? 6241 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6242 // No need to grant the target this permission. 6243 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6244 "Target " + targetPkg + " already has full permission to " + grantUri); 6245 return -1; 6246 } 6247 } else { 6248 // First... there is no target package, so can anyone access it? 6249 boolean allowed = pi.exported; 6250 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6251 if (pi.readPermission != null) { 6252 allowed = false; 6253 } 6254 } 6255 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6256 if (pi.writePermission != null) { 6257 allowed = false; 6258 } 6259 } 6260 if (allowed) { 6261 return -1; 6262 } 6263 } 6264 6265 // Second... is the provider allowing granting of URI permissions? 6266 if (!pi.grantUriPermissions) { 6267 throw new SecurityException("Provider " + pi.packageName 6268 + "/" + pi.name 6269 + " does not allow granting of Uri permissions (uri " 6270 + grantUri + ")"); 6271 } 6272 if (pi.uriPermissionPatterns != null) { 6273 final int N = pi.uriPermissionPatterns.length; 6274 boolean allowed = false; 6275 for (int i=0; i<N; i++) { 6276 if (pi.uriPermissionPatterns[i] != null 6277 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6278 allowed = true; 6279 break; 6280 } 6281 } 6282 if (!allowed) { 6283 throw new SecurityException("Provider " + pi.packageName 6284 + "/" + pi.name 6285 + " does not allow granting of permission to path of Uri " 6286 + grantUri); 6287 } 6288 } 6289 6290 // Third... does the caller itself have permission to access 6291 // this uri? 6292 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6293 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6294 // Require they hold a strong enough Uri permission 6295 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6296 throw new SecurityException("Uid " + callingUid 6297 + " does not have permission to uri " + grantUri); 6298 } 6299 } 6300 } 6301 return targetUid; 6302 } 6303 6304 @Override 6305 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6306 final int modeFlags, int userId) { 6307 enforceNotIsolatedCaller("checkGrantUriPermission"); 6308 synchronized(this) { 6309 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6310 new GrantUri(userId, uri, false), modeFlags, -1); 6311 } 6312 } 6313 6314 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6315 final int modeFlags, UriPermissionOwner owner) { 6316 if (!Intent.isAccessUriMode(modeFlags)) { 6317 return; 6318 } 6319 6320 // So here we are: the caller has the assumed permission 6321 // to the uri, and the target doesn't. Let's now give this to 6322 // the target. 6323 6324 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6325 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6326 6327 final String authority = grantUri.uri.getAuthority(); 6328 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6329 if (pi == null) { 6330 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6331 return; 6332 } 6333 6334 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6335 grantUri.prefix = true; 6336 } 6337 final UriPermission perm = findOrCreateUriPermissionLocked( 6338 pi.packageName, targetPkg, targetUid, grantUri); 6339 perm.grantModes(modeFlags, owner); 6340 } 6341 6342 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6343 final int modeFlags, UriPermissionOwner owner) { 6344 if (targetPkg == null) { 6345 throw new NullPointerException("targetPkg"); 6346 } 6347 6348 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6349 -1); 6350 if (targetUid < 0) { 6351 return; 6352 } 6353 6354 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6355 owner); 6356 } 6357 6358 static class NeededUriGrants extends ArrayList<GrantUri> { 6359 final String targetPkg; 6360 final int targetUid; 6361 final int flags; 6362 6363 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6364 this.targetPkg = targetPkg; 6365 this.targetUid = targetUid; 6366 this.flags = flags; 6367 } 6368 } 6369 6370 /** 6371 * Like checkGrantUriPermissionLocked, but takes an Intent. 6372 */ 6373 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6374 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6375 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6376 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6377 + " clip=" + (intent != null ? intent.getClipData() : null) 6378 + " from " + intent + "; flags=0x" 6379 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6380 6381 if (targetPkg == null) { 6382 throw new NullPointerException("targetPkg"); 6383 } 6384 6385 if (intent == null) { 6386 return null; 6387 } 6388 Uri data = intent.getData(); 6389 ClipData clip = intent.getClipData(); 6390 if (data == null && clip == null) { 6391 return null; 6392 } 6393 6394 if (data != null) { 6395 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6396 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6397 needed != null ? needed.targetUid : -1); 6398 if (targetUid > 0) { 6399 if (needed == null) { 6400 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6401 } 6402 needed.add(grantUri); 6403 } 6404 } 6405 if (clip != null) { 6406 for (int i=0; i<clip.getItemCount(); i++) { 6407 Uri uri = clip.getItemAt(i).getUri(); 6408 if (uri != null) { 6409 int targetUid = -1; 6410 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6411 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6412 needed != null ? needed.targetUid : -1); 6413 if (targetUid > 0) { 6414 if (needed == null) { 6415 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6416 } 6417 needed.add(grantUri); 6418 } 6419 } else { 6420 Intent clipIntent = clip.getItemAt(i).getIntent(); 6421 if (clipIntent != null) { 6422 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6423 callingUid, targetPkg, clipIntent, mode, needed); 6424 if (newNeeded != null) { 6425 needed = newNeeded; 6426 } 6427 } 6428 } 6429 } 6430 } 6431 6432 return needed; 6433 } 6434 6435 /** 6436 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6437 */ 6438 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6439 UriPermissionOwner owner) { 6440 if (needed != null) { 6441 for (int i=0; i<needed.size(); i++) { 6442 GrantUri grantUri = needed.get(i); 6443 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6444 grantUri, needed.flags, owner); 6445 } 6446 } 6447 } 6448 6449 void grantUriPermissionFromIntentLocked(int callingUid, 6450 String targetPkg, Intent intent, UriPermissionOwner owner) { 6451 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6452 intent, intent != null ? intent.getFlags() : 0, null); 6453 if (needed == null) { 6454 return; 6455 } 6456 6457 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6458 } 6459 6460 @Override 6461 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6462 final int modeFlags, int userId) { 6463 enforceNotIsolatedCaller("grantUriPermission"); 6464 GrantUri grantUri = new GrantUri(userId, uri, false); 6465 synchronized(this) { 6466 final ProcessRecord r = getRecordForAppLocked(caller); 6467 if (r == null) { 6468 throw new SecurityException("Unable to find app for caller " 6469 + caller 6470 + " when granting permission to uri " + grantUri); 6471 } 6472 if (targetPkg == null) { 6473 throw new IllegalArgumentException("null target"); 6474 } 6475 if (grantUri == null) { 6476 throw new IllegalArgumentException("null uri"); 6477 } 6478 6479 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6480 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6481 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6482 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6483 6484 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6485 } 6486 } 6487 6488 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6489 if (perm.modeFlags == 0) { 6490 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6491 perm.targetUid); 6492 if (perms != null) { 6493 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6494 "Removing " + perm.targetUid + " permission to " + perm.uri); 6495 6496 perms.remove(perm.uri); 6497 if (perms.isEmpty()) { 6498 mGrantedUriPermissions.remove(perm.targetUid); 6499 } 6500 } 6501 } 6502 } 6503 6504 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6505 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6506 6507 final IPackageManager pm = AppGlobals.getPackageManager(); 6508 final String authority = grantUri.uri.getAuthority(); 6509 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6510 if (pi == null) { 6511 Slog.w(TAG, "No content provider found for permission revoke: " 6512 + grantUri.toSafeString()); 6513 return; 6514 } 6515 6516 // Does the caller have this permission on the URI? 6517 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6518 // Right now, if you are not the original owner of the permission, 6519 // you are not allowed to revoke it. 6520 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6521 throw new SecurityException("Uid " + callingUid 6522 + " does not have permission to uri " + grantUri); 6523 //} 6524 } 6525 6526 boolean persistChanged = false; 6527 6528 // Go through all of the permissions and remove any that match. 6529 int N = mGrantedUriPermissions.size(); 6530 for (int i = 0; i < N; i++) { 6531 final int targetUid = mGrantedUriPermissions.keyAt(i); 6532 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6533 6534 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6535 final UriPermission perm = it.next(); 6536 if (perm.uri.sourceUserId == grantUri.sourceUserId 6537 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6538 if (DEBUG_URI_PERMISSION) 6539 Slog.v(TAG, 6540 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6541 persistChanged |= perm.revokeModes( 6542 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6543 if (perm.modeFlags == 0) { 6544 it.remove(); 6545 } 6546 } 6547 } 6548 6549 if (perms.isEmpty()) { 6550 mGrantedUriPermissions.remove(targetUid); 6551 N--; 6552 i--; 6553 } 6554 } 6555 6556 if (persistChanged) { 6557 schedulePersistUriGrants(); 6558 } 6559 } 6560 6561 @Override 6562 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6563 int userId) { 6564 enforceNotIsolatedCaller("revokeUriPermission"); 6565 synchronized(this) { 6566 final ProcessRecord r = getRecordForAppLocked(caller); 6567 if (r == null) { 6568 throw new SecurityException("Unable to find app for caller " 6569 + caller 6570 + " when revoking permission to uri " + uri); 6571 } 6572 if (uri == null) { 6573 Slog.w(TAG, "revokeUriPermission: null uri"); 6574 return; 6575 } 6576 6577 if (!Intent.isAccessUriMode(modeFlags)) { 6578 return; 6579 } 6580 6581 final IPackageManager pm = AppGlobals.getPackageManager(); 6582 final String authority = uri.getAuthority(); 6583 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6584 if (pi == null) { 6585 Slog.w(TAG, "No content provider found for permission revoke: " 6586 + uri.toSafeString()); 6587 return; 6588 } 6589 6590 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6591 } 6592 } 6593 6594 /** 6595 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6596 * given package. 6597 * 6598 * @param packageName Package name to match, or {@code null} to apply to all 6599 * packages. 6600 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6601 * to all users. 6602 * @param persistable If persistable grants should be removed. 6603 */ 6604 private void removeUriPermissionsForPackageLocked( 6605 String packageName, int userHandle, boolean persistable) { 6606 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6607 throw new IllegalArgumentException("Must narrow by either package or user"); 6608 } 6609 6610 boolean persistChanged = false; 6611 6612 int N = mGrantedUriPermissions.size(); 6613 for (int i = 0; i < N; i++) { 6614 final int targetUid = mGrantedUriPermissions.keyAt(i); 6615 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6616 6617 // Only inspect grants matching user 6618 if (userHandle == UserHandle.USER_ALL 6619 || userHandle == UserHandle.getUserId(targetUid)) { 6620 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6621 final UriPermission perm = it.next(); 6622 6623 // Only inspect grants matching package 6624 if (packageName == null || perm.sourcePkg.equals(packageName) 6625 || perm.targetPkg.equals(packageName)) { 6626 persistChanged |= perm.revokeModes( 6627 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6628 6629 // Only remove when no modes remain; any persisted grants 6630 // will keep this alive. 6631 if (perm.modeFlags == 0) { 6632 it.remove(); 6633 } 6634 } 6635 } 6636 6637 if (perms.isEmpty()) { 6638 mGrantedUriPermissions.remove(targetUid); 6639 N--; 6640 i--; 6641 } 6642 } 6643 } 6644 6645 if (persistChanged) { 6646 schedulePersistUriGrants(); 6647 } 6648 } 6649 6650 @Override 6651 public IBinder newUriPermissionOwner(String name) { 6652 enforceNotIsolatedCaller("newUriPermissionOwner"); 6653 synchronized(this) { 6654 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6655 return owner.getExternalTokenLocked(); 6656 } 6657 } 6658 6659 @Override 6660 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6661 final int modeFlags, int userId) { 6662 synchronized(this) { 6663 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6664 if (owner == null) { 6665 throw new IllegalArgumentException("Unknown owner: " + token); 6666 } 6667 if (fromUid != Binder.getCallingUid()) { 6668 if (Binder.getCallingUid() != Process.myUid()) { 6669 // Only system code can grant URI permissions on behalf 6670 // of other users. 6671 throw new SecurityException("nice try"); 6672 } 6673 } 6674 if (targetPkg == null) { 6675 throw new IllegalArgumentException("null target"); 6676 } 6677 if (uri == null) { 6678 throw new IllegalArgumentException("null uri"); 6679 } 6680 6681 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6682 modeFlags, owner); 6683 } 6684 } 6685 6686 @Override 6687 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6688 synchronized(this) { 6689 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6690 if (owner == null) { 6691 throw new IllegalArgumentException("Unknown owner: " + token); 6692 } 6693 6694 if (uri == null) { 6695 owner.removeUriPermissionsLocked(mode); 6696 } else { 6697 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6698 } 6699 } 6700 } 6701 6702 private void schedulePersistUriGrants() { 6703 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6704 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6705 10 * DateUtils.SECOND_IN_MILLIS); 6706 } 6707 } 6708 6709 private void writeGrantedUriPermissions() { 6710 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6711 6712 // Snapshot permissions so we can persist without lock 6713 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6714 synchronized (this) { 6715 final int size = mGrantedUriPermissions.size(); 6716 for (int i = 0; i < size; i++) { 6717 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6718 for (UriPermission perm : perms.values()) { 6719 if (perm.persistedModeFlags != 0) { 6720 persist.add(perm.snapshot()); 6721 } 6722 } 6723 } 6724 } 6725 6726 FileOutputStream fos = null; 6727 try { 6728 fos = mGrantFile.startWrite(); 6729 6730 XmlSerializer out = new FastXmlSerializer(); 6731 out.setOutput(fos, "utf-8"); 6732 out.startDocument(null, true); 6733 out.startTag(null, TAG_URI_GRANTS); 6734 for (UriPermission.Snapshot perm : persist) { 6735 out.startTag(null, TAG_URI_GRANT); 6736 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6737 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6738 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6739 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6740 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6741 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6742 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6743 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6744 out.endTag(null, TAG_URI_GRANT); 6745 } 6746 out.endTag(null, TAG_URI_GRANTS); 6747 out.endDocument(); 6748 6749 mGrantFile.finishWrite(fos); 6750 } catch (IOException e) { 6751 if (fos != null) { 6752 mGrantFile.failWrite(fos); 6753 } 6754 } 6755 } 6756 6757 private void readGrantedUriPermissionsLocked() { 6758 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6759 6760 final long now = System.currentTimeMillis(); 6761 6762 FileInputStream fis = null; 6763 try { 6764 fis = mGrantFile.openRead(); 6765 final XmlPullParser in = Xml.newPullParser(); 6766 in.setInput(fis, null); 6767 6768 int type; 6769 while ((type = in.next()) != END_DOCUMENT) { 6770 final String tag = in.getName(); 6771 if (type == START_TAG) { 6772 if (TAG_URI_GRANT.equals(tag)) { 6773 final int sourceUserId; 6774 final int targetUserId; 6775 final int userHandle = readIntAttribute(in, 6776 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6777 if (userHandle != UserHandle.USER_NULL) { 6778 // For backwards compatibility. 6779 sourceUserId = userHandle; 6780 targetUserId = userHandle; 6781 } else { 6782 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6783 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6784 } 6785 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6786 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6787 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6788 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6789 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6790 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6791 6792 // Sanity check that provider still belongs to source package 6793 final ProviderInfo pi = getProviderInfoLocked( 6794 uri.getAuthority(), sourceUserId); 6795 if (pi != null && sourcePkg.equals(pi.packageName)) { 6796 int targetUid = -1; 6797 try { 6798 targetUid = AppGlobals.getPackageManager() 6799 .getPackageUid(targetPkg, targetUserId); 6800 } catch (RemoteException e) { 6801 } 6802 if (targetUid != -1) { 6803 final UriPermission perm = findOrCreateUriPermissionLocked( 6804 sourcePkg, targetPkg, targetUid, 6805 new GrantUri(sourceUserId, uri, prefix)); 6806 perm.initPersistedModes(modeFlags, createdTime); 6807 } 6808 } else { 6809 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6810 + " but instead found " + pi); 6811 } 6812 } 6813 } 6814 } 6815 } catch (FileNotFoundException e) { 6816 // Missing grants is okay 6817 } catch (IOException e) { 6818 Log.wtf(TAG, "Failed reading Uri grants", e); 6819 } catch (XmlPullParserException e) { 6820 Log.wtf(TAG, "Failed reading Uri grants", e); 6821 } finally { 6822 IoUtils.closeQuietly(fis); 6823 } 6824 } 6825 6826 @Override 6827 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6828 enforceNotIsolatedCaller("takePersistableUriPermission"); 6829 6830 Preconditions.checkFlagsArgument(modeFlags, 6831 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6832 6833 synchronized (this) { 6834 final int callingUid = Binder.getCallingUid(); 6835 boolean persistChanged = false; 6836 GrantUri grantUri = new GrantUri(userId, uri, false); 6837 6838 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6839 new GrantUri(userId, uri, false)); 6840 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6841 new GrantUri(userId, uri, true)); 6842 6843 final boolean exactValid = (exactPerm != null) 6844 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6845 final boolean prefixValid = (prefixPerm != null) 6846 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6847 6848 if (!(exactValid || prefixValid)) { 6849 throw new SecurityException("No persistable permission grants found for UID " 6850 + callingUid + " and Uri " + grantUri.toSafeString()); 6851 } 6852 6853 if (exactValid) { 6854 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6855 } 6856 if (prefixValid) { 6857 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6858 } 6859 6860 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6861 6862 if (persistChanged) { 6863 schedulePersistUriGrants(); 6864 } 6865 } 6866 } 6867 6868 @Override 6869 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6870 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6871 6872 Preconditions.checkFlagsArgument(modeFlags, 6873 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6874 6875 synchronized (this) { 6876 final int callingUid = Binder.getCallingUid(); 6877 boolean persistChanged = false; 6878 6879 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6880 new GrantUri(userId, uri, false)); 6881 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6882 new GrantUri(userId, uri, true)); 6883 if (exactPerm == null && prefixPerm == null) { 6884 throw new SecurityException("No permission grants found for UID " + callingUid 6885 + " and Uri " + uri.toSafeString()); 6886 } 6887 6888 if (exactPerm != null) { 6889 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6890 removeUriPermissionIfNeededLocked(exactPerm); 6891 } 6892 if (prefixPerm != null) { 6893 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6894 removeUriPermissionIfNeededLocked(prefixPerm); 6895 } 6896 6897 if (persistChanged) { 6898 schedulePersistUriGrants(); 6899 } 6900 } 6901 } 6902 6903 /** 6904 * Prune any older {@link UriPermission} for the given UID until outstanding 6905 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6906 * 6907 * @return if any mutations occured that require persisting. 6908 */ 6909 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6910 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6911 if (perms == null) return false; 6912 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6913 6914 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6915 for (UriPermission perm : perms.values()) { 6916 if (perm.persistedModeFlags != 0) { 6917 persisted.add(perm); 6918 } 6919 } 6920 6921 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6922 if (trimCount <= 0) return false; 6923 6924 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6925 for (int i = 0; i < trimCount; i++) { 6926 final UriPermission perm = persisted.get(i); 6927 6928 if (DEBUG_URI_PERMISSION) { 6929 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6930 } 6931 6932 perm.releasePersistableModes(~0); 6933 removeUriPermissionIfNeededLocked(perm); 6934 } 6935 6936 return true; 6937 } 6938 6939 @Override 6940 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6941 String packageName, boolean incoming) { 6942 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6943 Preconditions.checkNotNull(packageName, "packageName"); 6944 6945 final int callingUid = Binder.getCallingUid(); 6946 final IPackageManager pm = AppGlobals.getPackageManager(); 6947 try { 6948 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6949 if (packageUid != callingUid) { 6950 throw new SecurityException( 6951 "Package " + packageName + " does not belong to calling UID " + callingUid); 6952 } 6953 } catch (RemoteException e) { 6954 throw new SecurityException("Failed to verify package name ownership"); 6955 } 6956 6957 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6958 synchronized (this) { 6959 if (incoming) { 6960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6961 callingUid); 6962 if (perms == null) { 6963 Slog.w(TAG, "No permission grants found for " + packageName); 6964 } else { 6965 for (UriPermission perm : perms.values()) { 6966 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6967 result.add(perm.buildPersistedPublicApiObject()); 6968 } 6969 } 6970 } 6971 } else { 6972 final int size = mGrantedUriPermissions.size(); 6973 for (int i = 0; i < size; i++) { 6974 final ArrayMap<GrantUri, UriPermission> perms = 6975 mGrantedUriPermissions.valueAt(i); 6976 for (UriPermission perm : perms.values()) { 6977 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6978 result.add(perm.buildPersistedPublicApiObject()); 6979 } 6980 } 6981 } 6982 } 6983 } 6984 return new ParceledListSlice<android.content.UriPermission>(result); 6985 } 6986 6987 @Override 6988 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6989 synchronized (this) { 6990 ProcessRecord app = 6991 who != null ? getRecordForAppLocked(who) : null; 6992 if (app == null) return; 6993 6994 Message msg = Message.obtain(); 6995 msg.what = WAIT_FOR_DEBUGGER_MSG; 6996 msg.obj = app; 6997 msg.arg1 = waiting ? 1 : 0; 6998 mHandler.sendMessage(msg); 6999 } 7000 } 7001 7002 @Override 7003 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7004 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7005 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7006 outInfo.availMem = Process.getFreeMemory(); 7007 outInfo.totalMem = Process.getTotalMemory(); 7008 outInfo.threshold = homeAppMem; 7009 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7010 outInfo.hiddenAppThreshold = cachedAppMem; 7011 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7012 ProcessList.SERVICE_ADJ); 7013 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7014 ProcessList.VISIBLE_APP_ADJ); 7015 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7016 ProcessList.FOREGROUND_APP_ADJ); 7017 } 7018 7019 // ========================================================= 7020 // TASK MANAGEMENT 7021 // ========================================================= 7022 7023 @Override 7024 public List<IAppTask> getAppTasks() { 7025 int callingUid = Binder.getCallingUid(); 7026 long ident = Binder.clearCallingIdentity(); 7027 synchronized(this) { 7028 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7029 try { 7030 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7031 7032 final int N = mRecentTasks.size(); 7033 for (int i = 0; i < N; i++) { 7034 TaskRecord tr = mRecentTasks.get(i); 7035 // Skip tasks that are not created by the caller 7036 if (tr.creatorUid == callingUid) { 7037 ActivityManager.RecentTaskInfo taskInfo = 7038 createRecentTaskInfoFromTaskRecord(tr); 7039 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7040 list.add(taskImpl); 7041 } 7042 } 7043 } finally { 7044 Binder.restoreCallingIdentity(ident); 7045 } 7046 return list; 7047 } 7048 } 7049 7050 @Override 7051 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7052 final int callingUid = Binder.getCallingUid(); 7053 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7054 7055 synchronized(this) { 7056 if (localLOGV) Slog.v( 7057 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7058 7059 final boolean allowed = checkCallingPermission( 7060 android.Manifest.permission.GET_TASKS) 7061 == PackageManager.PERMISSION_GRANTED; 7062 if (!allowed) { 7063 Slog.w(TAG, "getTasks: caller " + callingUid 7064 + " does not hold GET_TASKS; limiting output"); 7065 } 7066 7067 // TODO: Improve with MRU list from all ActivityStacks. 7068 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7069 } 7070 7071 return list; 7072 } 7073 7074 TaskRecord getMostRecentTask() { 7075 return mRecentTasks.get(0); 7076 } 7077 7078 /** 7079 * Creates a new RecentTaskInfo from a TaskRecord. 7080 */ 7081 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7082 // Update the task description to reflect any changes in the task stack 7083 tr.updateTaskDescription(); 7084 7085 // Compose the recent task info 7086 ActivityManager.RecentTaskInfo rti 7087 = new ActivityManager.RecentTaskInfo(); 7088 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7089 rti.persistentId = tr.taskId; 7090 rti.baseIntent = new Intent(tr.getBaseIntent()); 7091 rti.origActivity = tr.origActivity; 7092 rti.description = tr.lastDescription; 7093 rti.stackId = tr.stack.mStackId; 7094 rti.userId = tr.userId; 7095 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7096 return rti; 7097 } 7098 7099 @Override 7100 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7101 int flags, int userId) { 7102 final int callingUid = Binder.getCallingUid(); 7103 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7104 false, true, "getRecentTasks", null); 7105 7106 synchronized (this) { 7107 final boolean allowed = checkCallingPermission( 7108 android.Manifest.permission.GET_TASKS) 7109 == PackageManager.PERMISSION_GRANTED; 7110 if (!allowed) { 7111 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7112 + " does not hold GET_TASKS; limiting output"); 7113 } 7114 final boolean detailed = checkCallingPermission( 7115 android.Manifest.permission.GET_DETAILED_TASKS) 7116 == PackageManager.PERMISSION_GRANTED; 7117 7118 IPackageManager pm = AppGlobals.getPackageManager(); 7119 7120 final int N = mRecentTasks.size(); 7121 ArrayList<ActivityManager.RecentTaskInfo> res 7122 = new ArrayList<ActivityManager.RecentTaskInfo>( 7123 maxNum < N ? maxNum : N); 7124 7125 final Set<Integer> includedUsers; 7126 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7127 includedUsers = getProfileIdsLocked(userId); 7128 } else { 7129 includedUsers = new HashSet<Integer>(); 7130 } 7131 includedUsers.add(Integer.valueOf(userId)); 7132 for (int i=0; i<N && maxNum > 0; i++) { 7133 TaskRecord tr = mRecentTasks.get(i); 7134 // Only add calling user or related users recent tasks 7135 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7136 7137 // Return the entry if desired by the caller. We always return 7138 // the first entry, because callers always expect this to be the 7139 // foreground app. We may filter others if the caller has 7140 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7141 // we should exclude the entry. 7142 7143 if (i == 0 7144 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7145 || (tr.intent == null) 7146 || ((tr.intent.getFlags() 7147 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7148 if (!allowed) { 7149 // If the caller doesn't have the GET_TASKS permission, then only 7150 // allow them to see a small subset of tasks -- their own and home. 7151 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7152 continue; 7153 } 7154 } 7155 7156 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7157 if (!detailed) { 7158 rti.baseIntent.replaceExtras((Bundle)null); 7159 } 7160 7161 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7162 // Check whether this activity is currently available. 7163 try { 7164 if (rti.origActivity != null) { 7165 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7166 == null) { 7167 continue; 7168 } 7169 } else if (rti.baseIntent != null) { 7170 if (pm.queryIntentActivities(rti.baseIntent, 7171 null, 0, userId) == null) { 7172 continue; 7173 } 7174 } 7175 } catch (RemoteException e) { 7176 // Will never happen. 7177 } 7178 } 7179 7180 res.add(rti); 7181 maxNum--; 7182 } 7183 } 7184 return res; 7185 } 7186 } 7187 7188 private TaskRecord recentTaskForIdLocked(int id) { 7189 final int N = mRecentTasks.size(); 7190 for (int i=0; i<N; i++) { 7191 TaskRecord tr = mRecentTasks.get(i); 7192 if (tr.taskId == id) { 7193 return tr; 7194 } 7195 } 7196 return null; 7197 } 7198 7199 @Override 7200 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7201 synchronized (this) { 7202 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7203 "getTaskThumbnails()"); 7204 TaskRecord tr = recentTaskForIdLocked(id); 7205 if (tr != null) { 7206 return tr.getTaskThumbnailsLocked(); 7207 } 7208 } 7209 return null; 7210 } 7211 7212 @Override 7213 public Bitmap getTaskTopThumbnail(int id) { 7214 synchronized (this) { 7215 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7216 "getTaskTopThumbnail()"); 7217 TaskRecord tr = recentTaskForIdLocked(id); 7218 if (tr != null) { 7219 return tr.getTaskTopThumbnailLocked(); 7220 } 7221 } 7222 return null; 7223 } 7224 7225 @Override 7226 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7227 synchronized (this) { 7228 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7229 if (r != null) { 7230 r.taskDescription = td; 7231 r.task.updateTaskDescription(); 7232 } 7233 } 7234 } 7235 7236 @Override 7237 public boolean removeSubTask(int taskId, int subTaskIndex) { 7238 synchronized (this) { 7239 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7240 "removeSubTask()"); 7241 long ident = Binder.clearCallingIdentity(); 7242 try { 7243 TaskRecord tr = recentTaskForIdLocked(taskId); 7244 if (tr != null) { 7245 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7246 } 7247 return false; 7248 } finally { 7249 Binder.restoreCallingIdentity(ident); 7250 } 7251 } 7252 } 7253 7254 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7255 if (!pr.killedByAm) { 7256 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7257 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7258 pr.processName, pr.setAdj, reason); 7259 pr.killedByAm = true; 7260 Process.killProcessQuiet(pr.pid); 7261 } 7262 } 7263 7264 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7265 tr.disposeThumbnail(); 7266 mRecentTasks.remove(tr); 7267 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7268 Intent baseIntent = new Intent( 7269 tr.intent != null ? tr.intent : tr.affinityIntent); 7270 ComponentName component = baseIntent.getComponent(); 7271 if (component == null) { 7272 Slog.w(TAG, "Now component for base intent of task: " + tr); 7273 return; 7274 } 7275 7276 // Find any running services associated with this app. 7277 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7278 7279 if (killProcesses) { 7280 // Find any running processes associated with this app. 7281 final String pkg = component.getPackageName(); 7282 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7283 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7284 for (int i=0; i<pmap.size(); i++) { 7285 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7286 for (int j=0; j<uids.size(); j++) { 7287 ProcessRecord proc = uids.valueAt(j); 7288 if (proc.userId != tr.userId) { 7289 continue; 7290 } 7291 if (!proc.pkgList.containsKey(pkg)) { 7292 continue; 7293 } 7294 procs.add(proc); 7295 } 7296 } 7297 7298 // Kill the running processes. 7299 for (int i=0; i<procs.size(); i++) { 7300 ProcessRecord pr = procs.get(i); 7301 if (pr == mHomeProcess) { 7302 // Don't kill the home process along with tasks from the same package. 7303 continue; 7304 } 7305 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7306 killUnneededProcessLocked(pr, "remove task"); 7307 } else { 7308 pr.waitingToKill = "remove task"; 7309 } 7310 } 7311 } 7312 } 7313 7314 /** 7315 * Removes the task with the specified task id. 7316 * 7317 * @param taskId Identifier of the task to be removed. 7318 * @param flags Additional operational flags. May be 0 or 7319 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7320 * @return Returns true if the given task was found and removed. 7321 */ 7322 private boolean removeTaskByIdLocked(int taskId, int flags) { 7323 TaskRecord tr = recentTaskForIdLocked(taskId); 7324 if (tr != null) { 7325 tr.removeTaskActivitiesLocked(-1, false); 7326 cleanUpRemovedTaskLocked(tr, flags); 7327 return true; 7328 } 7329 return false; 7330 } 7331 7332 @Override 7333 public boolean removeTask(int taskId, int flags) { 7334 synchronized (this) { 7335 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7336 "removeTask()"); 7337 long ident = Binder.clearCallingIdentity(); 7338 try { 7339 return removeTaskByIdLocked(taskId, flags); 7340 } finally { 7341 Binder.restoreCallingIdentity(ident); 7342 } 7343 } 7344 } 7345 7346 /** 7347 * TODO: Add mController hook 7348 */ 7349 @Override 7350 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7351 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7352 "moveTaskToFront()"); 7353 7354 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7355 synchronized(this) { 7356 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7357 Binder.getCallingUid(), "Task to front")) { 7358 ActivityOptions.abort(options); 7359 return; 7360 } 7361 final long origId = Binder.clearCallingIdentity(); 7362 try { 7363 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7364 if (task == null) { 7365 return; 7366 } 7367 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7368 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7369 return; 7370 } 7371 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7372 } finally { 7373 Binder.restoreCallingIdentity(origId); 7374 } 7375 ActivityOptions.abort(options); 7376 } 7377 } 7378 7379 @Override 7380 public void moveTaskToBack(int taskId) { 7381 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7382 "moveTaskToBack()"); 7383 7384 synchronized(this) { 7385 TaskRecord tr = recentTaskForIdLocked(taskId); 7386 if (tr != null) { 7387 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7388 ActivityStack stack = tr.stack; 7389 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7390 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7391 Binder.getCallingUid(), "Task to back")) { 7392 return; 7393 } 7394 } 7395 final long origId = Binder.clearCallingIdentity(); 7396 try { 7397 stack.moveTaskToBackLocked(taskId, null); 7398 } finally { 7399 Binder.restoreCallingIdentity(origId); 7400 } 7401 } 7402 } 7403 } 7404 7405 /** 7406 * Moves an activity, and all of the other activities within the same task, to the bottom 7407 * of the history stack. The activity's order within the task is unchanged. 7408 * 7409 * @param token A reference to the activity we wish to move 7410 * @param nonRoot If false then this only works if the activity is the root 7411 * of a task; if true it will work for any activity in a task. 7412 * @return Returns true if the move completed, false if not. 7413 */ 7414 @Override 7415 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7416 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7417 synchronized(this) { 7418 final long origId = Binder.clearCallingIdentity(); 7419 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7420 if (taskId >= 0) { 7421 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7422 } 7423 Binder.restoreCallingIdentity(origId); 7424 } 7425 return false; 7426 } 7427 7428 @Override 7429 public void moveTaskBackwards(int task) { 7430 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7431 "moveTaskBackwards()"); 7432 7433 synchronized(this) { 7434 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7435 Binder.getCallingUid(), "Task backwards")) { 7436 return; 7437 } 7438 final long origId = Binder.clearCallingIdentity(); 7439 moveTaskBackwardsLocked(task); 7440 Binder.restoreCallingIdentity(origId); 7441 } 7442 } 7443 7444 private final void moveTaskBackwardsLocked(int task) { 7445 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7446 } 7447 7448 @Override 7449 public IBinder getHomeActivityToken() throws RemoteException { 7450 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7451 "getHomeActivityToken()"); 7452 synchronized (this) { 7453 return mStackSupervisor.getHomeActivityToken(); 7454 } 7455 } 7456 7457 @Override 7458 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7459 IActivityContainerCallback callback) throws RemoteException { 7460 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7461 "createActivityContainer()"); 7462 synchronized (this) { 7463 if (parentActivityToken == null) { 7464 throw new IllegalArgumentException("parent token must not be null"); 7465 } 7466 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7467 if (r == null) { 7468 return null; 7469 } 7470 if (callback == null) { 7471 throw new IllegalArgumentException("callback must not be null"); 7472 } 7473 return mStackSupervisor.createActivityContainer(r, callback); 7474 } 7475 } 7476 7477 @Override 7478 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7479 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7480 "deleteActivityContainer()"); 7481 synchronized (this) { 7482 mStackSupervisor.deleteActivityContainer(container); 7483 } 7484 } 7485 7486 @Override 7487 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7488 throws RemoteException { 7489 synchronized (this) { 7490 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7491 if (stack != null) { 7492 return stack.mActivityContainer; 7493 } 7494 return null; 7495 } 7496 } 7497 7498 @Override 7499 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7500 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7501 "moveTaskToStack()"); 7502 if (stackId == HOME_STACK_ID) { 7503 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7504 new RuntimeException("here").fillInStackTrace()); 7505 } 7506 synchronized (this) { 7507 long ident = Binder.clearCallingIdentity(); 7508 try { 7509 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7510 + stackId + " toTop=" + toTop); 7511 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7512 } finally { 7513 Binder.restoreCallingIdentity(ident); 7514 } 7515 } 7516 } 7517 7518 @Override 7519 public void resizeStack(int stackBoxId, Rect bounds) { 7520 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7521 "resizeStackBox()"); 7522 long ident = Binder.clearCallingIdentity(); 7523 try { 7524 mWindowManager.resizeStack(stackBoxId, bounds); 7525 } finally { 7526 Binder.restoreCallingIdentity(ident); 7527 } 7528 } 7529 7530 @Override 7531 public List<StackInfo> getAllStackInfos() { 7532 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7533 "getAllStackInfos()"); 7534 long ident = Binder.clearCallingIdentity(); 7535 try { 7536 synchronized (this) { 7537 return mStackSupervisor.getAllStackInfosLocked(); 7538 } 7539 } finally { 7540 Binder.restoreCallingIdentity(ident); 7541 } 7542 } 7543 7544 @Override 7545 public StackInfo getStackInfo(int stackId) { 7546 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7547 "getStackInfo()"); 7548 long ident = Binder.clearCallingIdentity(); 7549 try { 7550 synchronized (this) { 7551 return mStackSupervisor.getStackInfoLocked(stackId); 7552 } 7553 } finally { 7554 Binder.restoreCallingIdentity(ident); 7555 } 7556 } 7557 7558 @Override 7559 public boolean isInHomeStack(int taskId) { 7560 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7561 "getStackInfo()"); 7562 long ident = Binder.clearCallingIdentity(); 7563 try { 7564 synchronized (this) { 7565 TaskRecord tr = recentTaskForIdLocked(taskId); 7566 if (tr != null) { 7567 return tr.stack.isHomeStack(); 7568 } 7569 } 7570 } finally { 7571 Binder.restoreCallingIdentity(ident); 7572 } 7573 return false; 7574 } 7575 7576 @Override 7577 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7578 synchronized(this) { 7579 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7580 } 7581 } 7582 7583 private boolean isLockTaskAuthorized(ComponentName name) { 7584 final DevicePolicyManager dpm = (DevicePolicyManager) 7585 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7586 return dpm != null && dpm.isLockTaskPermitted(name); 7587 } 7588 7589 private void startLockTaskMode(TaskRecord task) { 7590 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7591 return; 7592 } 7593 long ident = Binder.clearCallingIdentity(); 7594 try { 7595 synchronized (this) { 7596 // Since we lost lock on task, make sure it is still there. 7597 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7598 if (task != null) { 7599 mStackSupervisor.setLockTaskModeLocked(task); 7600 } 7601 } 7602 } finally { 7603 Binder.restoreCallingIdentity(ident); 7604 } 7605 } 7606 7607 @Override 7608 public void startLockTaskMode(int taskId) { 7609 long ident = Binder.clearCallingIdentity(); 7610 try { 7611 final TaskRecord task; 7612 synchronized (this) { 7613 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7614 } 7615 if (task != null) { 7616 startLockTaskMode(task); 7617 } 7618 } finally { 7619 Binder.restoreCallingIdentity(ident); 7620 } 7621 } 7622 7623 @Override 7624 public void startLockTaskMode(IBinder token) { 7625 long ident = Binder.clearCallingIdentity(); 7626 try { 7627 final TaskRecord task; 7628 synchronized (this) { 7629 final ActivityRecord r = ActivityRecord.forToken(token); 7630 if (r == null) { 7631 return; 7632 } 7633 task = r.task; 7634 } 7635 if (task != null) { 7636 startLockTaskMode(task); 7637 } 7638 } finally { 7639 Binder.restoreCallingIdentity(ident); 7640 } 7641 } 7642 7643 @Override 7644 public void stopLockTaskMode() { 7645 // Check if the calling task is eligible to use lock task 7646 final int uid = Binder.getCallingUid(); 7647 try { 7648 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7649 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7650 return; 7651 } 7652 } catch (RemoteException e) { 7653 Log.d(TAG, "stopLockTaskMode " + e); 7654 return; 7655 } 7656 // Stop lock task 7657 synchronized (this) { 7658 mStackSupervisor.setLockTaskModeLocked(null); 7659 } 7660 } 7661 7662 @Override 7663 public boolean isInLockTaskMode() { 7664 synchronized (this) { 7665 return mStackSupervisor.isInLockTaskMode(); 7666 } 7667 } 7668 7669 // ========================================================= 7670 // CONTENT PROVIDERS 7671 // ========================================================= 7672 7673 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7674 List<ProviderInfo> providers = null; 7675 try { 7676 providers = AppGlobals.getPackageManager(). 7677 queryContentProviders(app.processName, app.uid, 7678 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7679 } catch (RemoteException ex) { 7680 } 7681 if (DEBUG_MU) 7682 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7683 int userId = app.userId; 7684 if (providers != null) { 7685 int N = providers.size(); 7686 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7687 for (int i=0; i<N; i++) { 7688 ProviderInfo cpi = 7689 (ProviderInfo)providers.get(i); 7690 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7691 cpi.name, cpi.flags); 7692 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7693 // This is a singleton provider, but a user besides the 7694 // default user is asking to initialize a process it runs 7695 // in... well, no, it doesn't actually run in this process, 7696 // it runs in the process of the default user. Get rid of it. 7697 providers.remove(i); 7698 N--; 7699 i--; 7700 continue; 7701 } 7702 7703 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7704 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7705 if (cpr == null) { 7706 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7707 mProviderMap.putProviderByClass(comp, cpr); 7708 } 7709 if (DEBUG_MU) 7710 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7711 app.pubProviders.put(cpi.name, cpr); 7712 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7713 // Don't add this if it is a platform component that is marked 7714 // to run in multiple processes, because this is actually 7715 // part of the framework so doesn't make sense to track as a 7716 // separate apk in the process. 7717 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7718 } 7719 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7720 } 7721 } 7722 return providers; 7723 } 7724 7725 /** 7726 * Check if {@link ProcessRecord} has a possible chance at accessing the 7727 * given {@link ProviderInfo}. Final permission checking is always done 7728 * in {@link ContentProvider}. 7729 */ 7730 private final String checkContentProviderPermissionLocked( 7731 ProviderInfo cpi, ProcessRecord r, int userId) { 7732 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7733 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7734 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7735 // Looking for cross-user grants before to enforce the typical cross-users permissions 7736 if (userId != UserHandle.getUserId(callingUid)) { 7737 if (perms != null) { 7738 for (GrantUri grantUri : perms.keySet()) { 7739 if (grantUri.sourceUserId == userId) { 7740 String authority = grantUri.uri.getAuthority(); 7741 if (authority.equals(cpi.authority)) { 7742 return null; 7743 } 7744 } 7745 } 7746 } 7747 } 7748 userId = handleIncomingUser(callingPid, callingUid, userId, 7749 false, true, "checkContentProviderPermissionLocked", null); 7750 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7751 cpi.applicationInfo.uid, cpi.exported) 7752 == PackageManager.PERMISSION_GRANTED) { 7753 return null; 7754 } 7755 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7756 cpi.applicationInfo.uid, cpi.exported) 7757 == PackageManager.PERMISSION_GRANTED) { 7758 return null; 7759 } 7760 7761 PathPermission[] pps = cpi.pathPermissions; 7762 if (pps != null) { 7763 int i = pps.length; 7764 while (i > 0) { 7765 i--; 7766 PathPermission pp = pps[i]; 7767 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7768 cpi.applicationInfo.uid, cpi.exported) 7769 == PackageManager.PERMISSION_GRANTED) { 7770 return null; 7771 } 7772 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7773 cpi.applicationInfo.uid, cpi.exported) 7774 == PackageManager.PERMISSION_GRANTED) { 7775 return null; 7776 } 7777 } 7778 } 7779 7780 if (perms != null) { 7781 for (GrantUri grantUri : perms.keySet()) { 7782 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7783 return null; 7784 } 7785 } 7786 } 7787 7788 String msg; 7789 if (!cpi.exported) { 7790 msg = "Permission Denial: opening provider " + cpi.name 7791 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7792 + ", uid=" + callingUid + ") that is not exported from uid " 7793 + cpi.applicationInfo.uid; 7794 } else { 7795 msg = "Permission Denial: opening provider " + cpi.name 7796 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7797 + ", uid=" + callingUid + ") requires " 7798 + cpi.readPermission + " or " + cpi.writePermission; 7799 } 7800 Slog.w(TAG, msg); 7801 return msg; 7802 } 7803 7804 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7805 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7806 if (r != null) { 7807 for (int i=0; i<r.conProviders.size(); i++) { 7808 ContentProviderConnection conn = r.conProviders.get(i); 7809 if (conn.provider == cpr) { 7810 if (DEBUG_PROVIDER) Slog.v(TAG, 7811 "Adding provider requested by " 7812 + r.processName + " from process " 7813 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7814 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7815 if (stable) { 7816 conn.stableCount++; 7817 conn.numStableIncs++; 7818 } else { 7819 conn.unstableCount++; 7820 conn.numUnstableIncs++; 7821 } 7822 return conn; 7823 } 7824 } 7825 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7826 if (stable) { 7827 conn.stableCount = 1; 7828 conn.numStableIncs = 1; 7829 } else { 7830 conn.unstableCount = 1; 7831 conn.numUnstableIncs = 1; 7832 } 7833 cpr.connections.add(conn); 7834 r.conProviders.add(conn); 7835 return conn; 7836 } 7837 cpr.addExternalProcessHandleLocked(externalProcessToken); 7838 return null; 7839 } 7840 7841 boolean decProviderCountLocked(ContentProviderConnection conn, 7842 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7843 if (conn != null) { 7844 cpr = conn.provider; 7845 if (DEBUG_PROVIDER) Slog.v(TAG, 7846 "Removing provider requested by " 7847 + conn.client.processName + " from process " 7848 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7849 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7850 if (stable) { 7851 conn.stableCount--; 7852 } else { 7853 conn.unstableCount--; 7854 } 7855 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7856 cpr.connections.remove(conn); 7857 conn.client.conProviders.remove(conn); 7858 return true; 7859 } 7860 return false; 7861 } 7862 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7863 return false; 7864 } 7865 7866 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7867 String name, IBinder token, boolean stable, int userId) { 7868 ContentProviderRecord cpr; 7869 ContentProviderConnection conn = null; 7870 ProviderInfo cpi = null; 7871 7872 synchronized(this) { 7873 ProcessRecord r = null; 7874 if (caller != null) { 7875 r = getRecordForAppLocked(caller); 7876 if (r == null) { 7877 throw new SecurityException( 7878 "Unable to find app for caller " + caller 7879 + " (pid=" + Binder.getCallingPid() 7880 + ") when getting content provider " + name); 7881 } 7882 } 7883 7884 // First check if this content provider has been published... 7885 cpr = mProviderMap.getProviderByName(name, userId); 7886 boolean providerRunning = cpr != null; 7887 if (providerRunning) { 7888 cpi = cpr.info; 7889 String msg; 7890 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7891 throw new SecurityException(msg); 7892 } 7893 7894 if (r != null && cpr.canRunHere(r)) { 7895 // This provider has been published or is in the process 7896 // of being published... but it is also allowed to run 7897 // in the caller's process, so don't make a connection 7898 // and just let the caller instantiate its own instance. 7899 ContentProviderHolder holder = cpr.newHolder(null); 7900 // don't give caller the provider object, it needs 7901 // to make its own. 7902 holder.provider = null; 7903 return holder; 7904 } 7905 7906 final long origId = Binder.clearCallingIdentity(); 7907 7908 // In this case the provider instance already exists, so we can 7909 // return it right away. 7910 conn = incProviderCountLocked(r, cpr, token, stable); 7911 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7912 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7913 // If this is a perceptible app accessing the provider, 7914 // make sure to count it as being accessed and thus 7915 // back up on the LRU list. This is good because 7916 // content providers are often expensive to start. 7917 updateLruProcessLocked(cpr.proc, false, null); 7918 } 7919 } 7920 7921 if (cpr.proc != null) { 7922 if (false) { 7923 if (cpr.name.flattenToShortString().equals( 7924 "com.android.providers.calendar/.CalendarProvider2")) { 7925 Slog.v(TAG, "****************** KILLING " 7926 + cpr.name.flattenToShortString()); 7927 Process.killProcess(cpr.proc.pid); 7928 } 7929 } 7930 boolean success = updateOomAdjLocked(cpr.proc); 7931 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7932 // NOTE: there is still a race here where a signal could be 7933 // pending on the process even though we managed to update its 7934 // adj level. Not sure what to do about this, but at least 7935 // the race is now smaller. 7936 if (!success) { 7937 // Uh oh... it looks like the provider's process 7938 // has been killed on us. We need to wait for a new 7939 // process to be started, and make sure its death 7940 // doesn't kill our process. 7941 Slog.i(TAG, 7942 "Existing provider " + cpr.name.flattenToShortString() 7943 + " is crashing; detaching " + r); 7944 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7945 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7946 if (!lastRef) { 7947 // This wasn't the last ref our process had on 7948 // the provider... we have now been killed, bail. 7949 return null; 7950 } 7951 providerRunning = false; 7952 conn = null; 7953 } 7954 } 7955 7956 Binder.restoreCallingIdentity(origId); 7957 } 7958 7959 boolean singleton; 7960 if (!providerRunning) { 7961 try { 7962 cpi = AppGlobals.getPackageManager(). 7963 resolveContentProvider(name, 7964 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7965 } catch (RemoteException ex) { 7966 } 7967 if (cpi == null) { 7968 return null; 7969 } 7970 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7971 cpi.name, cpi.flags); 7972 if (singleton) { 7973 userId = 0; 7974 } 7975 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7976 7977 String msg; 7978 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7979 throw new SecurityException(msg); 7980 } 7981 7982 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7983 && !cpi.processName.equals("system")) { 7984 // If this content provider does not run in the system 7985 // process, and the system is not yet ready to run other 7986 // processes, then fail fast instead of hanging. 7987 throw new IllegalArgumentException( 7988 "Attempt to launch content provider before system ready"); 7989 } 7990 7991 // Make sure that the user who owns this provider is started. If not, 7992 // we don't want to allow it to run. 7993 if (mStartedUsers.get(userId) == null) { 7994 Slog.w(TAG, "Unable to launch app " 7995 + cpi.applicationInfo.packageName + "/" 7996 + cpi.applicationInfo.uid + " for provider " 7997 + name + ": user " + userId + " is stopped"); 7998 return null; 7999 } 8000 8001 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8002 cpr = mProviderMap.getProviderByClass(comp, userId); 8003 final boolean firstClass = cpr == null; 8004 if (firstClass) { 8005 try { 8006 ApplicationInfo ai = 8007 AppGlobals.getPackageManager(). 8008 getApplicationInfo( 8009 cpi.applicationInfo.packageName, 8010 STOCK_PM_FLAGS, userId); 8011 if (ai == null) { 8012 Slog.w(TAG, "No package info for content provider " 8013 + cpi.name); 8014 return null; 8015 } 8016 ai = getAppInfoForUser(ai, userId); 8017 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8018 } catch (RemoteException ex) { 8019 // pm is in same process, this will never happen. 8020 } 8021 } 8022 8023 if (r != null && cpr.canRunHere(r)) { 8024 // If this is a multiprocess provider, then just return its 8025 // info and allow the caller to instantiate it. Only do 8026 // this if the provider is the same user as the caller's 8027 // process, or can run as root (so can be in any process). 8028 return cpr.newHolder(null); 8029 } 8030 8031 if (DEBUG_PROVIDER) { 8032 RuntimeException e = new RuntimeException("here"); 8033 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8034 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8035 } 8036 8037 // This is single process, and our app is now connecting to it. 8038 // See if we are already in the process of launching this 8039 // provider. 8040 final int N = mLaunchingProviders.size(); 8041 int i; 8042 for (i=0; i<N; i++) { 8043 if (mLaunchingProviders.get(i) == cpr) { 8044 break; 8045 } 8046 } 8047 8048 // If the provider is not already being launched, then get it 8049 // started. 8050 if (i >= N) { 8051 final long origId = Binder.clearCallingIdentity(); 8052 8053 try { 8054 // Content provider is now in use, its package can't be stopped. 8055 try { 8056 AppGlobals.getPackageManager().setPackageStoppedState( 8057 cpr.appInfo.packageName, false, userId); 8058 } catch (RemoteException e) { 8059 } catch (IllegalArgumentException e) { 8060 Slog.w(TAG, "Failed trying to unstop package " 8061 + cpr.appInfo.packageName + ": " + e); 8062 } 8063 8064 // Use existing process if already started 8065 ProcessRecord proc = getProcessRecordLocked( 8066 cpi.processName, cpr.appInfo.uid, false); 8067 if (proc != null && proc.thread != null) { 8068 if (DEBUG_PROVIDER) { 8069 Slog.d(TAG, "Installing in existing process " + proc); 8070 } 8071 proc.pubProviders.put(cpi.name, cpr); 8072 try { 8073 proc.thread.scheduleInstallProvider(cpi); 8074 } catch (RemoteException e) { 8075 } 8076 } else { 8077 proc = startProcessLocked(cpi.processName, 8078 cpr.appInfo, false, 0, "content provider", 8079 new ComponentName(cpi.applicationInfo.packageName, 8080 cpi.name), false, false, false); 8081 if (proc == null) { 8082 Slog.w(TAG, "Unable to launch app " 8083 + cpi.applicationInfo.packageName + "/" 8084 + cpi.applicationInfo.uid + " for provider " 8085 + name + ": process is bad"); 8086 return null; 8087 } 8088 } 8089 cpr.launchingApp = proc; 8090 mLaunchingProviders.add(cpr); 8091 } finally { 8092 Binder.restoreCallingIdentity(origId); 8093 } 8094 } 8095 8096 // Make sure the provider is published (the same provider class 8097 // may be published under multiple names). 8098 if (firstClass) { 8099 mProviderMap.putProviderByClass(comp, cpr); 8100 } 8101 8102 mProviderMap.putProviderByName(name, cpr); 8103 conn = incProviderCountLocked(r, cpr, token, stable); 8104 if (conn != null) { 8105 conn.waiting = true; 8106 } 8107 } 8108 } 8109 8110 // Wait for the provider to be published... 8111 synchronized (cpr) { 8112 while (cpr.provider == null) { 8113 if (cpr.launchingApp == null) { 8114 Slog.w(TAG, "Unable to launch app " 8115 + cpi.applicationInfo.packageName + "/" 8116 + cpi.applicationInfo.uid + " for provider " 8117 + name + ": launching app became null"); 8118 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8119 UserHandle.getUserId(cpi.applicationInfo.uid), 8120 cpi.applicationInfo.packageName, 8121 cpi.applicationInfo.uid, name); 8122 return null; 8123 } 8124 try { 8125 if (DEBUG_MU) { 8126 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8127 + cpr.launchingApp); 8128 } 8129 if (conn != null) { 8130 conn.waiting = true; 8131 } 8132 cpr.wait(); 8133 } catch (InterruptedException ex) { 8134 } finally { 8135 if (conn != null) { 8136 conn.waiting = false; 8137 } 8138 } 8139 } 8140 } 8141 return cpr != null ? cpr.newHolder(conn) : null; 8142 } 8143 8144 @Override 8145 public final ContentProviderHolder getContentProvider( 8146 IApplicationThread caller, String name, int userId, boolean stable) { 8147 enforceNotIsolatedCaller("getContentProvider"); 8148 if (caller == null) { 8149 String msg = "null IApplicationThread when getting content provider " 8150 + name; 8151 Slog.w(TAG, msg); 8152 throw new SecurityException(msg); 8153 } 8154 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8155 // with cross-user grant. 8156 return getContentProviderImpl(caller, name, null, stable, userId); 8157 } 8158 8159 public ContentProviderHolder getContentProviderExternal( 8160 String name, int userId, IBinder token) { 8161 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8162 "Do not have permission in call getContentProviderExternal()"); 8163 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8164 false, true, "getContentProvider", null); 8165 return getContentProviderExternalUnchecked(name, token, userId); 8166 } 8167 8168 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8169 IBinder token, int userId) { 8170 return getContentProviderImpl(null, name, token, true, userId); 8171 } 8172 8173 /** 8174 * Drop a content provider from a ProcessRecord's bookkeeping 8175 */ 8176 public void removeContentProvider(IBinder connection, boolean stable) { 8177 enforceNotIsolatedCaller("removeContentProvider"); 8178 long ident = Binder.clearCallingIdentity(); 8179 try { 8180 synchronized (this) { 8181 ContentProviderConnection conn; 8182 try { 8183 conn = (ContentProviderConnection)connection; 8184 } catch (ClassCastException e) { 8185 String msg ="removeContentProvider: " + connection 8186 + " not a ContentProviderConnection"; 8187 Slog.w(TAG, msg); 8188 throw new IllegalArgumentException(msg); 8189 } 8190 if (conn == null) { 8191 throw new NullPointerException("connection is null"); 8192 } 8193 if (decProviderCountLocked(conn, null, null, stable)) { 8194 updateOomAdjLocked(); 8195 } 8196 } 8197 } finally { 8198 Binder.restoreCallingIdentity(ident); 8199 } 8200 } 8201 8202 public void removeContentProviderExternal(String name, IBinder token) { 8203 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8204 "Do not have permission in call removeContentProviderExternal()"); 8205 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8206 } 8207 8208 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8209 synchronized (this) { 8210 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8211 if(cpr == null) { 8212 //remove from mProvidersByClass 8213 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8214 return; 8215 } 8216 8217 //update content provider record entry info 8218 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8219 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8220 if (localCpr.hasExternalProcessHandles()) { 8221 if (localCpr.removeExternalProcessHandleLocked(token)) { 8222 updateOomAdjLocked(); 8223 } else { 8224 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8225 + " with no external reference for token: " 8226 + token + "."); 8227 } 8228 } else { 8229 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8230 + " with no external references."); 8231 } 8232 } 8233 } 8234 8235 public final void publishContentProviders(IApplicationThread caller, 8236 List<ContentProviderHolder> providers) { 8237 if (providers == null) { 8238 return; 8239 } 8240 8241 enforceNotIsolatedCaller("publishContentProviders"); 8242 synchronized (this) { 8243 final ProcessRecord r = getRecordForAppLocked(caller); 8244 if (DEBUG_MU) 8245 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8246 if (r == null) { 8247 throw new SecurityException( 8248 "Unable to find app for caller " + caller 8249 + " (pid=" + Binder.getCallingPid() 8250 + ") when publishing content providers"); 8251 } 8252 8253 final long origId = Binder.clearCallingIdentity(); 8254 8255 final int N = providers.size(); 8256 for (int i=0; i<N; i++) { 8257 ContentProviderHolder src = providers.get(i); 8258 if (src == null || src.info == null || src.provider == null) { 8259 continue; 8260 } 8261 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8262 if (DEBUG_MU) 8263 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8264 if (dst != null) { 8265 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8266 mProviderMap.putProviderByClass(comp, dst); 8267 String names[] = dst.info.authority.split(";"); 8268 for (int j = 0; j < names.length; j++) { 8269 mProviderMap.putProviderByName(names[j], dst); 8270 } 8271 8272 int NL = mLaunchingProviders.size(); 8273 int j; 8274 for (j=0; j<NL; j++) { 8275 if (mLaunchingProviders.get(j) == dst) { 8276 mLaunchingProviders.remove(j); 8277 j--; 8278 NL--; 8279 } 8280 } 8281 synchronized (dst) { 8282 dst.provider = src.provider; 8283 dst.proc = r; 8284 dst.notifyAll(); 8285 } 8286 updateOomAdjLocked(r); 8287 } 8288 } 8289 8290 Binder.restoreCallingIdentity(origId); 8291 } 8292 } 8293 8294 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8295 ContentProviderConnection conn; 8296 try { 8297 conn = (ContentProviderConnection)connection; 8298 } catch (ClassCastException e) { 8299 String msg ="refContentProvider: " + connection 8300 + " not a ContentProviderConnection"; 8301 Slog.w(TAG, msg); 8302 throw new IllegalArgumentException(msg); 8303 } 8304 if (conn == null) { 8305 throw new NullPointerException("connection is null"); 8306 } 8307 8308 synchronized (this) { 8309 if (stable > 0) { 8310 conn.numStableIncs += stable; 8311 } 8312 stable = conn.stableCount + stable; 8313 if (stable < 0) { 8314 throw new IllegalStateException("stableCount < 0: " + stable); 8315 } 8316 8317 if (unstable > 0) { 8318 conn.numUnstableIncs += unstable; 8319 } 8320 unstable = conn.unstableCount + unstable; 8321 if (unstable < 0) { 8322 throw new IllegalStateException("unstableCount < 0: " + unstable); 8323 } 8324 8325 if ((stable+unstable) <= 0) { 8326 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8327 + stable + " unstable=" + unstable); 8328 } 8329 conn.stableCount = stable; 8330 conn.unstableCount = unstable; 8331 return !conn.dead; 8332 } 8333 } 8334 8335 public void unstableProviderDied(IBinder connection) { 8336 ContentProviderConnection conn; 8337 try { 8338 conn = (ContentProviderConnection)connection; 8339 } catch (ClassCastException e) { 8340 String msg ="refContentProvider: " + connection 8341 + " not a ContentProviderConnection"; 8342 Slog.w(TAG, msg); 8343 throw new IllegalArgumentException(msg); 8344 } 8345 if (conn == null) { 8346 throw new NullPointerException("connection is null"); 8347 } 8348 8349 // Safely retrieve the content provider associated with the connection. 8350 IContentProvider provider; 8351 synchronized (this) { 8352 provider = conn.provider.provider; 8353 } 8354 8355 if (provider == null) { 8356 // Um, yeah, we're way ahead of you. 8357 return; 8358 } 8359 8360 // Make sure the caller is being honest with us. 8361 if (provider.asBinder().pingBinder()) { 8362 // Er, no, still looks good to us. 8363 synchronized (this) { 8364 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8365 + " says " + conn + " died, but we don't agree"); 8366 return; 8367 } 8368 } 8369 8370 // Well look at that! It's dead! 8371 synchronized (this) { 8372 if (conn.provider.provider != provider) { 8373 // But something changed... good enough. 8374 return; 8375 } 8376 8377 ProcessRecord proc = conn.provider.proc; 8378 if (proc == null || proc.thread == null) { 8379 // Seems like the process is already cleaned up. 8380 return; 8381 } 8382 8383 // As far as we're concerned, this is just like receiving a 8384 // death notification... just a bit prematurely. 8385 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8386 + ") early provider death"); 8387 final long ident = Binder.clearCallingIdentity(); 8388 try { 8389 appDiedLocked(proc, proc.pid, proc.thread); 8390 } finally { 8391 Binder.restoreCallingIdentity(ident); 8392 } 8393 } 8394 } 8395 8396 @Override 8397 public void appNotRespondingViaProvider(IBinder connection) { 8398 enforceCallingPermission( 8399 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8400 8401 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8402 if (conn == null) { 8403 Slog.w(TAG, "ContentProviderConnection is null"); 8404 return; 8405 } 8406 8407 final ProcessRecord host = conn.provider.proc; 8408 if (host == null) { 8409 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8410 return; 8411 } 8412 8413 final long token = Binder.clearCallingIdentity(); 8414 try { 8415 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8416 } finally { 8417 Binder.restoreCallingIdentity(token); 8418 } 8419 } 8420 8421 public final void installSystemProviders() { 8422 List<ProviderInfo> providers; 8423 synchronized (this) { 8424 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8425 providers = generateApplicationProvidersLocked(app); 8426 if (providers != null) { 8427 for (int i=providers.size()-1; i>=0; i--) { 8428 ProviderInfo pi = (ProviderInfo)providers.get(i); 8429 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8430 Slog.w(TAG, "Not installing system proc provider " + pi.name 8431 + ": not system .apk"); 8432 providers.remove(i); 8433 } 8434 } 8435 } 8436 } 8437 if (providers != null) { 8438 mSystemThread.installSystemProviders(providers); 8439 } 8440 8441 mCoreSettingsObserver = new CoreSettingsObserver(this); 8442 8443 mUsageStatsService.monitorPackages(); 8444 } 8445 8446 /** 8447 * Allows app to retrieve the MIME type of a URI without having permission 8448 * to access its content provider. 8449 * 8450 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8451 * 8452 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8453 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8454 */ 8455 public String getProviderMimeType(Uri uri, int userId) { 8456 enforceNotIsolatedCaller("getProviderMimeType"); 8457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8458 userId, false, true, "getProviderMimeType", null); 8459 final String name = uri.getAuthority(); 8460 final long ident = Binder.clearCallingIdentity(); 8461 ContentProviderHolder holder = null; 8462 8463 try { 8464 holder = getContentProviderExternalUnchecked(name, null, userId); 8465 if (holder != null) { 8466 return holder.provider.getType(uri); 8467 } 8468 } catch (RemoteException e) { 8469 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8470 return null; 8471 } finally { 8472 if (holder != null) { 8473 removeContentProviderExternalUnchecked(name, null, userId); 8474 } 8475 Binder.restoreCallingIdentity(ident); 8476 } 8477 8478 return null; 8479 } 8480 8481 // ========================================================= 8482 // GLOBAL MANAGEMENT 8483 // ========================================================= 8484 8485 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8486 boolean isolated) { 8487 String proc = customProcess != null ? customProcess : info.processName; 8488 BatteryStatsImpl.Uid.Proc ps = null; 8489 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8490 int uid = info.uid; 8491 if (isolated) { 8492 int userId = UserHandle.getUserId(uid); 8493 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8494 while (true) { 8495 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8496 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8497 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8498 } 8499 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8500 mNextIsolatedProcessUid++; 8501 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8502 // No process for this uid, use it. 8503 break; 8504 } 8505 stepsLeft--; 8506 if (stepsLeft <= 0) { 8507 return null; 8508 } 8509 } 8510 } 8511 return new ProcessRecord(stats, info, proc, uid); 8512 } 8513 8514 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8515 ProcessRecord app; 8516 if (!isolated) { 8517 app = getProcessRecordLocked(info.processName, info.uid, true); 8518 } else { 8519 app = null; 8520 } 8521 8522 if (app == null) { 8523 app = newProcessRecordLocked(info, null, isolated); 8524 mProcessNames.put(info.processName, app.uid, app); 8525 if (isolated) { 8526 mIsolatedProcesses.put(app.uid, app); 8527 } 8528 updateLruProcessLocked(app, false, null); 8529 updateOomAdjLocked(); 8530 } 8531 8532 // This package really, really can not be stopped. 8533 try { 8534 AppGlobals.getPackageManager().setPackageStoppedState( 8535 info.packageName, false, UserHandle.getUserId(app.uid)); 8536 } catch (RemoteException e) { 8537 } catch (IllegalArgumentException e) { 8538 Slog.w(TAG, "Failed trying to unstop package " 8539 + info.packageName + ": " + e); 8540 } 8541 8542 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8543 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8544 app.persistent = true; 8545 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8546 } 8547 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8548 mPersistentStartingProcesses.add(app); 8549 startProcessLocked(app, "added application", app.processName); 8550 } 8551 8552 return app; 8553 } 8554 8555 public void unhandledBack() { 8556 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8557 "unhandledBack()"); 8558 8559 synchronized(this) { 8560 final long origId = Binder.clearCallingIdentity(); 8561 try { 8562 getFocusedStack().unhandledBackLocked(); 8563 } finally { 8564 Binder.restoreCallingIdentity(origId); 8565 } 8566 } 8567 } 8568 8569 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8570 enforceNotIsolatedCaller("openContentUri"); 8571 final int userId = UserHandle.getCallingUserId(); 8572 String name = uri.getAuthority(); 8573 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8574 ParcelFileDescriptor pfd = null; 8575 if (cph != null) { 8576 // We record the binder invoker's uid in thread-local storage before 8577 // going to the content provider to open the file. Later, in the code 8578 // that handles all permissions checks, we look for this uid and use 8579 // that rather than the Activity Manager's own uid. The effect is that 8580 // we do the check against the caller's permissions even though it looks 8581 // to the content provider like the Activity Manager itself is making 8582 // the request. 8583 sCallerIdentity.set(new Identity( 8584 Binder.getCallingPid(), Binder.getCallingUid())); 8585 try { 8586 pfd = cph.provider.openFile(null, uri, "r", null); 8587 } catch (FileNotFoundException e) { 8588 // do nothing; pfd will be returned null 8589 } finally { 8590 // Ensure that whatever happens, we clean up the identity state 8591 sCallerIdentity.remove(); 8592 } 8593 8594 // We've got the fd now, so we're done with the provider. 8595 removeContentProviderExternalUnchecked(name, null, userId); 8596 } else { 8597 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8598 } 8599 return pfd; 8600 } 8601 8602 // Actually is sleeping or shutting down or whatever else in the future 8603 // is an inactive state. 8604 public boolean isSleepingOrShuttingDown() { 8605 return mSleeping || mShuttingDown; 8606 } 8607 8608 public boolean isSleeping() { 8609 return mSleeping; 8610 } 8611 8612 void goingToSleep() { 8613 synchronized(this) { 8614 mWentToSleep = true; 8615 updateEventDispatchingLocked(); 8616 goToSleepIfNeededLocked(); 8617 } 8618 } 8619 8620 void finishRunningVoiceLocked() { 8621 if (mRunningVoice) { 8622 mRunningVoice = false; 8623 goToSleepIfNeededLocked(); 8624 } 8625 } 8626 8627 void goToSleepIfNeededLocked() { 8628 if (mWentToSleep && !mRunningVoice) { 8629 if (!mSleeping) { 8630 mSleeping = true; 8631 mStackSupervisor.goingToSleepLocked(); 8632 8633 // Initialize the wake times of all processes. 8634 checkExcessivePowerUsageLocked(false); 8635 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8636 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8637 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8638 } 8639 } 8640 } 8641 8642 @Override 8643 public boolean shutdown(int timeout) { 8644 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8645 != PackageManager.PERMISSION_GRANTED) { 8646 throw new SecurityException("Requires permission " 8647 + android.Manifest.permission.SHUTDOWN); 8648 } 8649 8650 boolean timedout = false; 8651 8652 synchronized(this) { 8653 mShuttingDown = true; 8654 updateEventDispatchingLocked(); 8655 timedout = mStackSupervisor.shutdownLocked(timeout); 8656 } 8657 8658 mAppOpsService.shutdown(); 8659 mUsageStatsService.shutdown(); 8660 mBatteryStatsService.shutdown(); 8661 synchronized (this) { 8662 mProcessStats.shutdownLocked(); 8663 } 8664 8665 return timedout; 8666 } 8667 8668 public final void activitySlept(IBinder token) { 8669 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8670 8671 final long origId = Binder.clearCallingIdentity(); 8672 8673 synchronized (this) { 8674 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8675 if (r != null) { 8676 mStackSupervisor.activitySleptLocked(r); 8677 } 8678 } 8679 8680 Binder.restoreCallingIdentity(origId); 8681 } 8682 8683 void logLockScreen(String msg) { 8684 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8685 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8686 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8687 mStackSupervisor.mDismissKeyguardOnNextActivity); 8688 } 8689 8690 private void comeOutOfSleepIfNeededLocked() { 8691 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8692 if (mSleeping) { 8693 mSleeping = false; 8694 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8695 } 8696 } 8697 } 8698 8699 void wakingUp() { 8700 synchronized(this) { 8701 mWentToSleep = false; 8702 updateEventDispatchingLocked(); 8703 comeOutOfSleepIfNeededLocked(); 8704 } 8705 } 8706 8707 void startRunningVoiceLocked() { 8708 if (!mRunningVoice) { 8709 mRunningVoice = true; 8710 comeOutOfSleepIfNeededLocked(); 8711 } 8712 } 8713 8714 private void updateEventDispatchingLocked() { 8715 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8716 } 8717 8718 public void setLockScreenShown(boolean shown) { 8719 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8720 != PackageManager.PERMISSION_GRANTED) { 8721 throw new SecurityException("Requires permission " 8722 + android.Manifest.permission.DEVICE_POWER); 8723 } 8724 8725 synchronized(this) { 8726 long ident = Binder.clearCallingIdentity(); 8727 try { 8728 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8729 mLockScreenShown = shown; 8730 comeOutOfSleepIfNeededLocked(); 8731 } finally { 8732 Binder.restoreCallingIdentity(ident); 8733 } 8734 } 8735 } 8736 8737 public void stopAppSwitches() { 8738 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8739 != PackageManager.PERMISSION_GRANTED) { 8740 throw new SecurityException("Requires permission " 8741 + android.Manifest.permission.STOP_APP_SWITCHES); 8742 } 8743 8744 synchronized(this) { 8745 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8746 + APP_SWITCH_DELAY_TIME; 8747 mDidAppSwitch = false; 8748 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8749 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8750 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8751 } 8752 } 8753 8754 public void resumeAppSwitches() { 8755 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8756 != PackageManager.PERMISSION_GRANTED) { 8757 throw new SecurityException("Requires permission " 8758 + android.Manifest.permission.STOP_APP_SWITCHES); 8759 } 8760 8761 synchronized(this) { 8762 // Note that we don't execute any pending app switches... we will 8763 // let those wait until either the timeout, or the next start 8764 // activity request. 8765 mAppSwitchesAllowedTime = 0; 8766 } 8767 } 8768 8769 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8770 String name) { 8771 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8772 return true; 8773 } 8774 8775 final int perm = checkComponentPermission( 8776 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8777 callingUid, -1, true); 8778 if (perm == PackageManager.PERMISSION_GRANTED) { 8779 return true; 8780 } 8781 8782 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8783 return false; 8784 } 8785 8786 public void setDebugApp(String packageName, boolean waitForDebugger, 8787 boolean persistent) { 8788 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8789 "setDebugApp()"); 8790 8791 long ident = Binder.clearCallingIdentity(); 8792 try { 8793 // Note that this is not really thread safe if there are multiple 8794 // callers into it at the same time, but that's not a situation we 8795 // care about. 8796 if (persistent) { 8797 final ContentResolver resolver = mContext.getContentResolver(); 8798 Settings.Global.putString( 8799 resolver, Settings.Global.DEBUG_APP, 8800 packageName); 8801 Settings.Global.putInt( 8802 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8803 waitForDebugger ? 1 : 0); 8804 } 8805 8806 synchronized (this) { 8807 if (!persistent) { 8808 mOrigDebugApp = mDebugApp; 8809 mOrigWaitForDebugger = mWaitForDebugger; 8810 } 8811 mDebugApp = packageName; 8812 mWaitForDebugger = waitForDebugger; 8813 mDebugTransient = !persistent; 8814 if (packageName != null) { 8815 forceStopPackageLocked(packageName, -1, false, false, true, true, 8816 false, UserHandle.USER_ALL, "set debug app"); 8817 } 8818 } 8819 } finally { 8820 Binder.restoreCallingIdentity(ident); 8821 } 8822 } 8823 8824 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8825 synchronized (this) { 8826 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8827 if (!isDebuggable) { 8828 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8829 throw new SecurityException("Process not debuggable: " + app.packageName); 8830 } 8831 } 8832 8833 mOpenGlTraceApp = processName; 8834 } 8835 } 8836 8837 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8838 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8839 synchronized (this) { 8840 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8841 if (!isDebuggable) { 8842 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8843 throw new SecurityException("Process not debuggable: " + app.packageName); 8844 } 8845 } 8846 mProfileApp = processName; 8847 mProfileFile = profileFile; 8848 if (mProfileFd != null) { 8849 try { 8850 mProfileFd.close(); 8851 } catch (IOException e) { 8852 } 8853 mProfileFd = null; 8854 } 8855 mProfileFd = profileFd; 8856 mProfileType = 0; 8857 mAutoStopProfiler = autoStopProfiler; 8858 } 8859 } 8860 8861 @Override 8862 public void setAlwaysFinish(boolean enabled) { 8863 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8864 "setAlwaysFinish()"); 8865 8866 Settings.Global.putInt( 8867 mContext.getContentResolver(), 8868 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8869 8870 synchronized (this) { 8871 mAlwaysFinishActivities = enabled; 8872 } 8873 } 8874 8875 @Override 8876 public void setActivityController(IActivityController controller) { 8877 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8878 "setActivityController()"); 8879 synchronized (this) { 8880 mController = controller; 8881 Watchdog.getInstance().setActivityController(controller); 8882 } 8883 } 8884 8885 @Override 8886 public void setUserIsMonkey(boolean userIsMonkey) { 8887 synchronized (this) { 8888 synchronized (mPidsSelfLocked) { 8889 final int callingPid = Binder.getCallingPid(); 8890 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8891 if (precessRecord == null) { 8892 throw new SecurityException("Unknown process: " + callingPid); 8893 } 8894 if (precessRecord.instrumentationUiAutomationConnection == null) { 8895 throw new SecurityException("Only an instrumentation process " 8896 + "with a UiAutomation can call setUserIsMonkey"); 8897 } 8898 } 8899 mUserIsMonkey = userIsMonkey; 8900 } 8901 } 8902 8903 @Override 8904 public boolean isUserAMonkey() { 8905 synchronized (this) { 8906 // If there is a controller also implies the user is a monkey. 8907 return (mUserIsMonkey || mController != null); 8908 } 8909 } 8910 8911 public void requestBugReport() { 8912 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8913 SystemProperties.set("ctl.start", "bugreport"); 8914 } 8915 8916 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8917 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8918 } 8919 8920 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8921 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8922 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8923 } 8924 return KEY_DISPATCHING_TIMEOUT; 8925 } 8926 8927 @Override 8928 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8929 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8930 != PackageManager.PERMISSION_GRANTED) { 8931 throw new SecurityException("Requires permission " 8932 + android.Manifest.permission.FILTER_EVENTS); 8933 } 8934 ProcessRecord proc; 8935 long timeout; 8936 synchronized (this) { 8937 synchronized (mPidsSelfLocked) { 8938 proc = mPidsSelfLocked.get(pid); 8939 } 8940 timeout = getInputDispatchingTimeoutLocked(proc); 8941 } 8942 8943 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8944 return -1; 8945 } 8946 8947 return timeout; 8948 } 8949 8950 /** 8951 * Handle input dispatching timeouts. 8952 * Returns whether input dispatching should be aborted or not. 8953 */ 8954 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8955 final ActivityRecord activity, final ActivityRecord parent, 8956 final boolean aboveSystem, String reason) { 8957 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8958 != PackageManager.PERMISSION_GRANTED) { 8959 throw new SecurityException("Requires permission " 8960 + android.Manifest.permission.FILTER_EVENTS); 8961 } 8962 8963 final String annotation; 8964 if (reason == null) { 8965 annotation = "Input dispatching timed out"; 8966 } else { 8967 annotation = "Input dispatching timed out (" + reason + ")"; 8968 } 8969 8970 if (proc != null) { 8971 synchronized (this) { 8972 if (proc.debugging) { 8973 return false; 8974 } 8975 8976 if (mDidDexOpt) { 8977 // Give more time since we were dexopting. 8978 mDidDexOpt = false; 8979 return false; 8980 } 8981 8982 if (proc.instrumentationClass != null) { 8983 Bundle info = new Bundle(); 8984 info.putString("shortMsg", "keyDispatchingTimedOut"); 8985 info.putString("longMsg", annotation); 8986 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8987 return true; 8988 } 8989 } 8990 mHandler.post(new Runnable() { 8991 @Override 8992 public void run() { 8993 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8994 } 8995 }); 8996 } 8997 8998 return true; 8999 } 9000 9001 public Bundle getAssistContextExtras(int requestType) { 9002 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9003 "getAssistContextExtras()"); 9004 PendingAssistExtras pae; 9005 Bundle extras = new Bundle(); 9006 synchronized (this) { 9007 ActivityRecord activity = getFocusedStack().mResumedActivity; 9008 if (activity == null) { 9009 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9010 return null; 9011 } 9012 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9013 if (activity.app == null || activity.app.thread == null) { 9014 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9015 return extras; 9016 } 9017 if (activity.app.pid == Binder.getCallingPid()) { 9018 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9019 return extras; 9020 } 9021 pae = new PendingAssistExtras(activity); 9022 try { 9023 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9024 requestType); 9025 mPendingAssistExtras.add(pae); 9026 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9027 } catch (RemoteException e) { 9028 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9029 return extras; 9030 } 9031 } 9032 synchronized (pae) { 9033 while (!pae.haveResult) { 9034 try { 9035 pae.wait(); 9036 } catch (InterruptedException e) { 9037 } 9038 } 9039 if (pae.result != null) { 9040 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9041 } 9042 } 9043 synchronized (this) { 9044 mPendingAssistExtras.remove(pae); 9045 mHandler.removeCallbacks(pae); 9046 } 9047 return extras; 9048 } 9049 9050 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9051 PendingAssistExtras pae = (PendingAssistExtras)token; 9052 synchronized (pae) { 9053 pae.result = extras; 9054 pae.haveResult = true; 9055 pae.notifyAll(); 9056 } 9057 } 9058 9059 public void registerProcessObserver(IProcessObserver observer) { 9060 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9061 "registerProcessObserver()"); 9062 synchronized (this) { 9063 mProcessObservers.register(observer); 9064 } 9065 } 9066 9067 @Override 9068 public void unregisterProcessObserver(IProcessObserver observer) { 9069 synchronized (this) { 9070 mProcessObservers.unregister(observer); 9071 } 9072 } 9073 9074 @Override 9075 public boolean convertFromTranslucent(IBinder token) { 9076 final long origId = Binder.clearCallingIdentity(); 9077 try { 9078 synchronized (this) { 9079 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9080 if (r == null) { 9081 return false; 9082 } 9083 if (r.changeWindowTranslucency(true)) { 9084 mWindowManager.setAppFullscreen(token, true); 9085 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9086 return true; 9087 } 9088 return false; 9089 } 9090 } finally { 9091 Binder.restoreCallingIdentity(origId); 9092 } 9093 } 9094 9095 @Override 9096 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9097 final long origId = Binder.clearCallingIdentity(); 9098 try { 9099 synchronized (this) { 9100 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9101 if (r == null) { 9102 return false; 9103 } 9104 if (r.changeWindowTranslucency(false)) { 9105 r.task.stack.convertToTranslucent(r, options); 9106 mWindowManager.setAppFullscreen(token, false); 9107 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9108 return true; 9109 } 9110 return false; 9111 } 9112 } finally { 9113 Binder.restoreCallingIdentity(origId); 9114 } 9115 } 9116 9117 @Override 9118 public ActivityOptions getActivityOptions(IBinder token) { 9119 final long origId = Binder.clearCallingIdentity(); 9120 try { 9121 synchronized (this) { 9122 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9123 if (r != null) { 9124 final ActivityOptions activityOptions = r.pendingOptions; 9125 r.pendingOptions = null; 9126 return activityOptions; 9127 } 9128 return null; 9129 } 9130 } finally { 9131 Binder.restoreCallingIdentity(origId); 9132 } 9133 } 9134 9135 @Override 9136 public void setImmersive(IBinder token, boolean immersive) { 9137 synchronized(this) { 9138 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9139 if (r == null) { 9140 throw new IllegalArgumentException(); 9141 } 9142 r.immersive = immersive; 9143 9144 // update associated state if we're frontmost 9145 if (r == mFocusedActivity) { 9146 if (DEBUG_IMMERSIVE) { 9147 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9148 } 9149 applyUpdateLockStateLocked(r); 9150 } 9151 } 9152 } 9153 9154 @Override 9155 public boolean isImmersive(IBinder token) { 9156 synchronized (this) { 9157 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9158 if (r == null) { 9159 throw new IllegalArgumentException(); 9160 } 9161 return r.immersive; 9162 } 9163 } 9164 9165 public boolean isTopActivityImmersive() { 9166 enforceNotIsolatedCaller("startActivity"); 9167 synchronized (this) { 9168 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9169 return (r != null) ? r.immersive : false; 9170 } 9171 } 9172 9173 public final void enterSafeMode() { 9174 synchronized(this) { 9175 // It only makes sense to do this before the system is ready 9176 // and started launching other packages. 9177 if (!mSystemReady) { 9178 try { 9179 AppGlobals.getPackageManager().enterSafeMode(); 9180 } catch (RemoteException e) { 9181 } 9182 } 9183 9184 mSafeMode = true; 9185 } 9186 } 9187 9188 public final void showSafeModeOverlay() { 9189 View v = LayoutInflater.from(mContext).inflate( 9190 com.android.internal.R.layout.safe_mode, null); 9191 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9192 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9193 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9194 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9195 lp.gravity = Gravity.BOTTOM | Gravity.START; 9196 lp.format = v.getBackground().getOpacity(); 9197 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9198 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9199 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9200 ((WindowManager)mContext.getSystemService( 9201 Context.WINDOW_SERVICE)).addView(v, lp); 9202 } 9203 9204 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9205 if (!(sender instanceof PendingIntentRecord)) { 9206 return; 9207 } 9208 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9209 synchronized (stats) { 9210 if (mBatteryStatsService.isOnBattery()) { 9211 mBatteryStatsService.enforceCallingPermission(); 9212 PendingIntentRecord rec = (PendingIntentRecord)sender; 9213 int MY_UID = Binder.getCallingUid(); 9214 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9215 BatteryStatsImpl.Uid.Pkg pkg = 9216 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9217 sourcePkg != null ? sourcePkg : rec.key.packageName); 9218 pkg.incWakeupsLocked(); 9219 } 9220 } 9221 } 9222 9223 public boolean killPids(int[] pids, String pReason, boolean secure) { 9224 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9225 throw new SecurityException("killPids only available to the system"); 9226 } 9227 String reason = (pReason == null) ? "Unknown" : pReason; 9228 // XXX Note: don't acquire main activity lock here, because the window 9229 // manager calls in with its locks held. 9230 9231 boolean killed = false; 9232 synchronized (mPidsSelfLocked) { 9233 int[] types = new int[pids.length]; 9234 int worstType = 0; 9235 for (int i=0; i<pids.length; i++) { 9236 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9237 if (proc != null) { 9238 int type = proc.setAdj; 9239 types[i] = type; 9240 if (type > worstType) { 9241 worstType = type; 9242 } 9243 } 9244 } 9245 9246 // If the worst oom_adj is somewhere in the cached proc LRU range, 9247 // then constrain it so we will kill all cached procs. 9248 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9249 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9250 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9251 } 9252 9253 // If this is not a secure call, don't let it kill processes that 9254 // are important. 9255 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9256 worstType = ProcessList.SERVICE_ADJ; 9257 } 9258 9259 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9260 for (int i=0; i<pids.length; i++) { 9261 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9262 if (proc == null) { 9263 continue; 9264 } 9265 int adj = proc.setAdj; 9266 if (adj >= worstType && !proc.killedByAm) { 9267 killUnneededProcessLocked(proc, reason); 9268 killed = true; 9269 } 9270 } 9271 } 9272 return killed; 9273 } 9274 9275 @Override 9276 public void killUid(int uid, String reason) { 9277 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9278 throw new SecurityException("killUid only available to the system"); 9279 } 9280 synchronized (this) { 9281 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9282 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9283 reason != null ? reason : "kill uid"); 9284 } 9285 } 9286 9287 @Override 9288 public boolean killProcessesBelowForeground(String reason) { 9289 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9290 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9291 } 9292 9293 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9294 } 9295 9296 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9297 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9298 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9299 } 9300 9301 boolean killed = false; 9302 synchronized (mPidsSelfLocked) { 9303 final int size = mPidsSelfLocked.size(); 9304 for (int i = 0; i < size; i++) { 9305 final int pid = mPidsSelfLocked.keyAt(i); 9306 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9307 if (proc == null) continue; 9308 9309 final int adj = proc.setAdj; 9310 if (adj > belowAdj && !proc.killedByAm) { 9311 killUnneededProcessLocked(proc, reason); 9312 killed = true; 9313 } 9314 } 9315 } 9316 return killed; 9317 } 9318 9319 @Override 9320 public void hang(final IBinder who, boolean allowRestart) { 9321 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9322 != PackageManager.PERMISSION_GRANTED) { 9323 throw new SecurityException("Requires permission " 9324 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9325 } 9326 9327 final IBinder.DeathRecipient death = new DeathRecipient() { 9328 @Override 9329 public void binderDied() { 9330 synchronized (this) { 9331 notifyAll(); 9332 } 9333 } 9334 }; 9335 9336 try { 9337 who.linkToDeath(death, 0); 9338 } catch (RemoteException e) { 9339 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9340 return; 9341 } 9342 9343 synchronized (this) { 9344 Watchdog.getInstance().setAllowRestart(allowRestart); 9345 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9346 synchronized (death) { 9347 while (who.isBinderAlive()) { 9348 try { 9349 death.wait(); 9350 } catch (InterruptedException e) { 9351 } 9352 } 9353 } 9354 Watchdog.getInstance().setAllowRestart(true); 9355 } 9356 } 9357 9358 @Override 9359 public void restart() { 9360 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9361 != PackageManager.PERMISSION_GRANTED) { 9362 throw new SecurityException("Requires permission " 9363 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9364 } 9365 9366 Log.i(TAG, "Sending shutdown broadcast..."); 9367 9368 BroadcastReceiver br = new BroadcastReceiver() { 9369 @Override public void onReceive(Context context, Intent intent) { 9370 // Now the broadcast is done, finish up the low-level shutdown. 9371 Log.i(TAG, "Shutting down activity manager..."); 9372 shutdown(10000); 9373 Log.i(TAG, "Shutdown complete, restarting!"); 9374 Process.killProcess(Process.myPid()); 9375 System.exit(10); 9376 } 9377 }; 9378 9379 // First send the high-level shut down broadcast. 9380 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9381 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9382 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9383 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9384 mContext.sendOrderedBroadcastAsUser(intent, 9385 UserHandle.ALL, null, br, mHandler, 0, null, null); 9386 */ 9387 br.onReceive(mContext, intent); 9388 } 9389 9390 private long getLowRamTimeSinceIdle(long now) { 9391 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9392 } 9393 9394 @Override 9395 public void performIdleMaintenance() { 9396 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9397 != PackageManager.PERMISSION_GRANTED) { 9398 throw new SecurityException("Requires permission " 9399 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9400 } 9401 9402 synchronized (this) { 9403 final long now = SystemClock.uptimeMillis(); 9404 final long timeSinceLastIdle = now - mLastIdleTime; 9405 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9406 mLastIdleTime = now; 9407 mLowRamTimeSinceLastIdle = 0; 9408 if (mLowRamStartTime != 0) { 9409 mLowRamStartTime = now; 9410 } 9411 9412 StringBuilder sb = new StringBuilder(128); 9413 sb.append("Idle maintenance over "); 9414 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9415 sb.append(" low RAM for "); 9416 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9417 Slog.i(TAG, sb.toString()); 9418 9419 // If at least 1/3 of our time since the last idle period has been spent 9420 // with RAM low, then we want to kill processes. 9421 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9422 9423 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9424 ProcessRecord proc = mLruProcesses.get(i); 9425 if (proc.notCachedSinceIdle) { 9426 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9427 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9428 if (doKilling && proc.initialIdlePss != 0 9429 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9430 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9431 + " from " + proc.initialIdlePss + ")"); 9432 } 9433 } 9434 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9435 proc.notCachedSinceIdle = true; 9436 proc.initialIdlePss = 0; 9437 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9438 isSleeping(), now); 9439 } 9440 } 9441 9442 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9443 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9444 } 9445 } 9446 9447 private void retrieveSettings() { 9448 final ContentResolver resolver = mContext.getContentResolver(); 9449 String debugApp = Settings.Global.getString( 9450 resolver, Settings.Global.DEBUG_APP); 9451 boolean waitForDebugger = Settings.Global.getInt( 9452 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9453 boolean alwaysFinishActivities = Settings.Global.getInt( 9454 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9455 boolean forceRtl = Settings.Global.getInt( 9456 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9457 // Transfer any global setting for forcing RTL layout, into a System Property 9458 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9459 9460 Configuration configuration = new Configuration(); 9461 Settings.System.getConfiguration(resolver, configuration); 9462 if (forceRtl) { 9463 // This will take care of setting the correct layout direction flags 9464 configuration.setLayoutDirection(configuration.locale); 9465 } 9466 9467 synchronized (this) { 9468 mDebugApp = mOrigDebugApp = debugApp; 9469 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9470 mAlwaysFinishActivities = alwaysFinishActivities; 9471 // This happens before any activities are started, so we can 9472 // change mConfiguration in-place. 9473 updateConfigurationLocked(configuration, null, false, true); 9474 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9475 } 9476 } 9477 9478 public boolean testIsSystemReady() { 9479 // no need to synchronize(this) just to read & return the value 9480 return mSystemReady; 9481 } 9482 9483 private static File getCalledPreBootReceiversFile() { 9484 File dataDir = Environment.getDataDirectory(); 9485 File systemDir = new File(dataDir, "system"); 9486 File fname = new File(systemDir, "called_pre_boots.dat"); 9487 return fname; 9488 } 9489 9490 static final int LAST_DONE_VERSION = 10000; 9491 9492 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9493 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9494 File file = getCalledPreBootReceiversFile(); 9495 FileInputStream fis = null; 9496 try { 9497 fis = new FileInputStream(file); 9498 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9499 int fvers = dis.readInt(); 9500 if (fvers == LAST_DONE_VERSION) { 9501 String vers = dis.readUTF(); 9502 String codename = dis.readUTF(); 9503 String build = dis.readUTF(); 9504 if (android.os.Build.VERSION.RELEASE.equals(vers) 9505 && android.os.Build.VERSION.CODENAME.equals(codename) 9506 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9507 int num = dis.readInt(); 9508 while (num > 0) { 9509 num--; 9510 String pkg = dis.readUTF(); 9511 String cls = dis.readUTF(); 9512 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9513 } 9514 } 9515 } 9516 } catch (FileNotFoundException e) { 9517 } catch (IOException e) { 9518 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9519 } finally { 9520 if (fis != null) { 9521 try { 9522 fis.close(); 9523 } catch (IOException e) { 9524 } 9525 } 9526 } 9527 return lastDoneReceivers; 9528 } 9529 9530 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9531 File file = getCalledPreBootReceiversFile(); 9532 FileOutputStream fos = null; 9533 DataOutputStream dos = null; 9534 try { 9535 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9536 fos = new FileOutputStream(file); 9537 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9538 dos.writeInt(LAST_DONE_VERSION); 9539 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9540 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9541 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9542 dos.writeInt(list.size()); 9543 for (int i=0; i<list.size(); i++) { 9544 dos.writeUTF(list.get(i).getPackageName()); 9545 dos.writeUTF(list.get(i).getClassName()); 9546 } 9547 } catch (IOException e) { 9548 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9549 file.delete(); 9550 } finally { 9551 FileUtils.sync(fos); 9552 if (dos != null) { 9553 try { 9554 dos.close(); 9555 } catch (IOException e) { 9556 // TODO Auto-generated catch block 9557 e.printStackTrace(); 9558 } 9559 } 9560 } 9561 } 9562 9563 public void systemReady(final Runnable goingCallback) { 9564 synchronized(this) { 9565 if (mSystemReady) { 9566 if (goingCallback != null) goingCallback.run(); 9567 return; 9568 } 9569 9570 // Check to see if there are any update receivers to run. 9571 if (!mDidUpdate) { 9572 if (mWaitingUpdate) { 9573 return; 9574 } 9575 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9576 List<ResolveInfo> ris = null; 9577 try { 9578 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9579 intent, null, 0, 0); 9580 } catch (RemoteException e) { 9581 } 9582 if (ris != null) { 9583 for (int i=ris.size()-1; i>=0; i--) { 9584 if ((ris.get(i).activityInfo.applicationInfo.flags 9585 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9586 ris.remove(i); 9587 } 9588 } 9589 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9590 9591 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9592 9593 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9594 for (int i=0; i<ris.size(); i++) { 9595 ActivityInfo ai = ris.get(i).activityInfo; 9596 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9597 if (lastDoneReceivers.contains(comp)) { 9598 // We already did the pre boot receiver for this app with the current 9599 // platform version, so don't do it again... 9600 ris.remove(i); 9601 i--; 9602 // ...however, do keep it as one that has been done, so we don't 9603 // forget about it when rewriting the file of last done receivers. 9604 doneReceivers.add(comp); 9605 } 9606 } 9607 9608 final int[] users = getUsersLocked(); 9609 for (int i=0; i<ris.size(); i++) { 9610 ActivityInfo ai = ris.get(i).activityInfo; 9611 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9612 doneReceivers.add(comp); 9613 intent.setComponent(comp); 9614 for (int j=0; j<users.length; j++) { 9615 IIntentReceiver finisher = null; 9616 if (i == ris.size()-1 && j == users.length-1) { 9617 finisher = new IIntentReceiver.Stub() { 9618 public void performReceive(Intent intent, int resultCode, 9619 String data, Bundle extras, boolean ordered, 9620 boolean sticky, int sendingUser) { 9621 // The raw IIntentReceiver interface is called 9622 // with the AM lock held, so redispatch to 9623 // execute our code without the lock. 9624 mHandler.post(new Runnable() { 9625 public void run() { 9626 synchronized (ActivityManagerService.this) { 9627 mDidUpdate = true; 9628 } 9629 writeLastDonePreBootReceivers(doneReceivers); 9630 showBootMessage(mContext.getText( 9631 R.string.android_upgrading_complete), 9632 false); 9633 systemReady(goingCallback); 9634 } 9635 }); 9636 } 9637 }; 9638 } 9639 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9640 + " for user " + users[j]); 9641 broadcastIntentLocked(null, null, intent, null, finisher, 9642 0, null, null, null, AppOpsManager.OP_NONE, 9643 true, false, MY_PID, Process.SYSTEM_UID, 9644 users[j]); 9645 if (finisher != null) { 9646 mWaitingUpdate = true; 9647 } 9648 } 9649 } 9650 } 9651 if (mWaitingUpdate) { 9652 return; 9653 } 9654 mDidUpdate = true; 9655 } 9656 9657 mAppOpsService.systemReady(); 9658 mUsageStatsService.systemReady(); 9659 mSystemReady = true; 9660 } 9661 9662 ArrayList<ProcessRecord> procsToKill = null; 9663 synchronized(mPidsSelfLocked) { 9664 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9665 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9666 if (!isAllowedWhileBooting(proc.info)){ 9667 if (procsToKill == null) { 9668 procsToKill = new ArrayList<ProcessRecord>(); 9669 } 9670 procsToKill.add(proc); 9671 } 9672 } 9673 } 9674 9675 synchronized(this) { 9676 if (procsToKill != null) { 9677 for (int i=procsToKill.size()-1; i>=0; i--) { 9678 ProcessRecord proc = procsToKill.get(i); 9679 Slog.i(TAG, "Removing system update proc: " + proc); 9680 removeProcessLocked(proc, true, false, "system update done"); 9681 } 9682 } 9683 9684 // Now that we have cleaned up any update processes, we 9685 // are ready to start launching real processes and know that 9686 // we won't trample on them any more. 9687 mProcessesReady = true; 9688 } 9689 9690 Slog.i(TAG, "System now ready"); 9691 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9692 SystemClock.uptimeMillis()); 9693 9694 synchronized(this) { 9695 // Make sure we have no pre-ready processes sitting around. 9696 9697 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9698 ResolveInfo ri = mContext.getPackageManager() 9699 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9700 STOCK_PM_FLAGS); 9701 CharSequence errorMsg = null; 9702 if (ri != null) { 9703 ActivityInfo ai = ri.activityInfo; 9704 ApplicationInfo app = ai.applicationInfo; 9705 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9706 mTopAction = Intent.ACTION_FACTORY_TEST; 9707 mTopData = null; 9708 mTopComponent = new ComponentName(app.packageName, 9709 ai.name); 9710 } else { 9711 errorMsg = mContext.getResources().getText( 9712 com.android.internal.R.string.factorytest_not_system); 9713 } 9714 } else { 9715 errorMsg = mContext.getResources().getText( 9716 com.android.internal.R.string.factorytest_no_action); 9717 } 9718 if (errorMsg != null) { 9719 mTopAction = null; 9720 mTopData = null; 9721 mTopComponent = null; 9722 Message msg = Message.obtain(); 9723 msg.what = SHOW_FACTORY_ERROR_MSG; 9724 msg.getData().putCharSequence("msg", errorMsg); 9725 mHandler.sendMessage(msg); 9726 } 9727 } 9728 } 9729 9730 retrieveSettings(); 9731 9732 synchronized (this) { 9733 readGrantedUriPermissionsLocked(); 9734 } 9735 9736 if (goingCallback != null) goingCallback.run(); 9737 9738 mSystemServiceManager.startUser(mCurrentUserId); 9739 9740 synchronized (this) { 9741 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9742 try { 9743 List apps = AppGlobals.getPackageManager(). 9744 getPersistentApplications(STOCK_PM_FLAGS); 9745 if (apps != null) { 9746 int N = apps.size(); 9747 int i; 9748 for (i=0; i<N; i++) { 9749 ApplicationInfo info 9750 = (ApplicationInfo)apps.get(i); 9751 if (info != null && 9752 !info.packageName.equals("android")) { 9753 addAppLocked(info, false); 9754 } 9755 } 9756 } 9757 } catch (RemoteException ex) { 9758 // pm is in same process, this will never happen. 9759 } 9760 } 9761 9762 // Start up initial activity. 9763 mBooting = true; 9764 9765 try { 9766 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9767 Message msg = Message.obtain(); 9768 msg.what = SHOW_UID_ERROR_MSG; 9769 mHandler.sendMessage(msg); 9770 } 9771 } catch (RemoteException e) { 9772 } 9773 9774 long ident = Binder.clearCallingIdentity(); 9775 try { 9776 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9777 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9778 | Intent.FLAG_RECEIVER_FOREGROUND); 9779 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9780 broadcastIntentLocked(null, null, intent, 9781 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9782 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9783 intent = new Intent(Intent.ACTION_USER_STARTING); 9784 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9785 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9786 broadcastIntentLocked(null, null, intent, 9787 null, new IIntentReceiver.Stub() { 9788 @Override 9789 public void performReceive(Intent intent, int resultCode, String data, 9790 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9791 throws RemoteException { 9792 } 9793 }, 0, null, null, 9794 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9795 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9796 } catch (Throwable t) { 9797 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9798 } finally { 9799 Binder.restoreCallingIdentity(ident); 9800 } 9801 mStackSupervisor.resumeTopActivitiesLocked(); 9802 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9803 } 9804 } 9805 9806 private boolean makeAppCrashingLocked(ProcessRecord app, 9807 String shortMsg, String longMsg, String stackTrace) { 9808 app.crashing = true; 9809 app.crashingReport = generateProcessError(app, 9810 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9811 startAppProblemLocked(app); 9812 app.stopFreezingAllLocked(); 9813 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9814 } 9815 9816 private void makeAppNotRespondingLocked(ProcessRecord app, 9817 String activity, String shortMsg, String longMsg) { 9818 app.notResponding = true; 9819 app.notRespondingReport = generateProcessError(app, 9820 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9821 activity, shortMsg, longMsg, null); 9822 startAppProblemLocked(app); 9823 app.stopFreezingAllLocked(); 9824 } 9825 9826 /** 9827 * Generate a process error record, suitable for attachment to a ProcessRecord. 9828 * 9829 * @param app The ProcessRecord in which the error occurred. 9830 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9831 * ActivityManager.AppErrorStateInfo 9832 * @param activity The activity associated with the crash, if known. 9833 * @param shortMsg Short message describing the crash. 9834 * @param longMsg Long message describing the crash. 9835 * @param stackTrace Full crash stack trace, may be null. 9836 * 9837 * @return Returns a fully-formed AppErrorStateInfo record. 9838 */ 9839 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9840 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9841 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9842 9843 report.condition = condition; 9844 report.processName = app.processName; 9845 report.pid = app.pid; 9846 report.uid = app.info.uid; 9847 report.tag = activity; 9848 report.shortMsg = shortMsg; 9849 report.longMsg = longMsg; 9850 report.stackTrace = stackTrace; 9851 9852 return report; 9853 } 9854 9855 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9856 synchronized (this) { 9857 app.crashing = false; 9858 app.crashingReport = null; 9859 app.notResponding = false; 9860 app.notRespondingReport = null; 9861 if (app.anrDialog == fromDialog) { 9862 app.anrDialog = null; 9863 } 9864 if (app.waitDialog == fromDialog) { 9865 app.waitDialog = null; 9866 } 9867 if (app.pid > 0 && app.pid != MY_PID) { 9868 handleAppCrashLocked(app, null, null, null); 9869 killUnneededProcessLocked(app, "user request after error"); 9870 } 9871 } 9872 } 9873 9874 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9875 String stackTrace) { 9876 long now = SystemClock.uptimeMillis(); 9877 9878 Long crashTime; 9879 if (!app.isolated) { 9880 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9881 } else { 9882 crashTime = null; 9883 } 9884 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9885 // This process loses! 9886 Slog.w(TAG, "Process " + app.info.processName 9887 + " has crashed too many times: killing!"); 9888 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9889 app.userId, app.info.processName, app.uid); 9890 mStackSupervisor.handleAppCrashLocked(app); 9891 if (!app.persistent) { 9892 // We don't want to start this process again until the user 9893 // explicitly does so... but for persistent process, we really 9894 // need to keep it running. If a persistent process is actually 9895 // repeatedly crashing, then badness for everyone. 9896 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9897 app.info.processName); 9898 if (!app.isolated) { 9899 // XXX We don't have a way to mark isolated processes 9900 // as bad, since they don't have a peristent identity. 9901 mBadProcesses.put(app.info.processName, app.uid, 9902 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9903 mProcessCrashTimes.remove(app.info.processName, app.uid); 9904 } 9905 app.bad = true; 9906 app.removed = true; 9907 // Don't let services in this process be restarted and potentially 9908 // annoy the user repeatedly. Unless it is persistent, since those 9909 // processes run critical code. 9910 removeProcessLocked(app, false, false, "crash"); 9911 mStackSupervisor.resumeTopActivitiesLocked(); 9912 return false; 9913 } 9914 mStackSupervisor.resumeTopActivitiesLocked(); 9915 } else { 9916 mStackSupervisor.finishTopRunningActivityLocked(app); 9917 } 9918 9919 // Bump up the crash count of any services currently running in the proc. 9920 for (int i=app.services.size()-1; i>=0; i--) { 9921 // Any services running in the application need to be placed 9922 // back in the pending list. 9923 ServiceRecord sr = app.services.valueAt(i); 9924 sr.crashCount++; 9925 } 9926 9927 // If the crashing process is what we consider to be the "home process" and it has been 9928 // replaced by a third-party app, clear the package preferred activities from packages 9929 // with a home activity running in the process to prevent a repeatedly crashing app 9930 // from blocking the user to manually clear the list. 9931 final ArrayList<ActivityRecord> activities = app.activities; 9932 if (app == mHomeProcess && activities.size() > 0 9933 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9934 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9935 final ActivityRecord r = activities.get(activityNdx); 9936 if (r.isHomeActivity()) { 9937 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9938 try { 9939 ActivityThread.getPackageManager() 9940 .clearPackagePreferredActivities(r.packageName); 9941 } catch (RemoteException c) { 9942 // pm is in same process, this will never happen. 9943 } 9944 } 9945 } 9946 } 9947 9948 if (!app.isolated) { 9949 // XXX Can't keep track of crash times for isolated processes, 9950 // because they don't have a perisistent identity. 9951 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9952 } 9953 9954 return true; 9955 } 9956 9957 void startAppProblemLocked(ProcessRecord app) { 9958 if (app.userId == mCurrentUserId) { 9959 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9960 mContext, app.info.packageName, app.info.flags); 9961 } else { 9962 // If this app is not running under the current user, then we 9963 // can't give it a report button because that would require 9964 // launching the report UI under a different user. 9965 app.errorReportReceiver = null; 9966 } 9967 skipCurrentReceiverLocked(app); 9968 } 9969 9970 void skipCurrentReceiverLocked(ProcessRecord app) { 9971 for (BroadcastQueue queue : mBroadcastQueues) { 9972 queue.skipCurrentReceiverLocked(app); 9973 } 9974 } 9975 9976 /** 9977 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9978 * The application process will exit immediately after this call returns. 9979 * @param app object of the crashing app, null for the system server 9980 * @param crashInfo describing the exception 9981 */ 9982 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9983 ProcessRecord r = findAppProcess(app, "Crash"); 9984 final String processName = app == null ? "system_server" 9985 : (r == null ? "unknown" : r.processName); 9986 9987 handleApplicationCrashInner("crash", r, processName, crashInfo); 9988 } 9989 9990 /* Native crash reporting uses this inner version because it needs to be somewhat 9991 * decoupled from the AM-managed cleanup lifecycle 9992 */ 9993 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9994 ApplicationErrorReport.CrashInfo crashInfo) { 9995 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9996 UserHandle.getUserId(Binder.getCallingUid()), processName, 9997 r == null ? -1 : r.info.flags, 9998 crashInfo.exceptionClassName, 9999 crashInfo.exceptionMessage, 10000 crashInfo.throwFileName, 10001 crashInfo.throwLineNumber); 10002 10003 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10004 10005 crashApplication(r, crashInfo); 10006 } 10007 10008 public void handleApplicationStrictModeViolation( 10009 IBinder app, 10010 int violationMask, 10011 StrictMode.ViolationInfo info) { 10012 ProcessRecord r = findAppProcess(app, "StrictMode"); 10013 if (r == null) { 10014 return; 10015 } 10016 10017 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10018 Integer stackFingerprint = info.hashCode(); 10019 boolean logIt = true; 10020 synchronized (mAlreadyLoggedViolatedStacks) { 10021 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10022 logIt = false; 10023 // TODO: sub-sample into EventLog for these, with 10024 // the info.durationMillis? Then we'd get 10025 // the relative pain numbers, without logging all 10026 // the stack traces repeatedly. We'd want to do 10027 // likewise in the client code, which also does 10028 // dup suppression, before the Binder call. 10029 } else { 10030 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10031 mAlreadyLoggedViolatedStacks.clear(); 10032 } 10033 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10034 } 10035 } 10036 if (logIt) { 10037 logStrictModeViolationToDropBox(r, info); 10038 } 10039 } 10040 10041 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10042 AppErrorResult result = new AppErrorResult(); 10043 synchronized (this) { 10044 final long origId = Binder.clearCallingIdentity(); 10045 10046 Message msg = Message.obtain(); 10047 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10048 HashMap<String, Object> data = new HashMap<String, Object>(); 10049 data.put("result", result); 10050 data.put("app", r); 10051 data.put("violationMask", violationMask); 10052 data.put("info", info); 10053 msg.obj = data; 10054 mHandler.sendMessage(msg); 10055 10056 Binder.restoreCallingIdentity(origId); 10057 } 10058 int res = result.get(); 10059 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10060 } 10061 } 10062 10063 // Depending on the policy in effect, there could be a bunch of 10064 // these in quick succession so we try to batch these together to 10065 // minimize disk writes, number of dropbox entries, and maximize 10066 // compression, by having more fewer, larger records. 10067 private void logStrictModeViolationToDropBox( 10068 ProcessRecord process, 10069 StrictMode.ViolationInfo info) { 10070 if (info == null) { 10071 return; 10072 } 10073 final boolean isSystemApp = process == null || 10074 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10075 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10076 final String processName = process == null ? "unknown" : process.processName; 10077 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10078 final DropBoxManager dbox = (DropBoxManager) 10079 mContext.getSystemService(Context.DROPBOX_SERVICE); 10080 10081 // Exit early if the dropbox isn't configured to accept this report type. 10082 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10083 10084 boolean bufferWasEmpty; 10085 boolean needsFlush; 10086 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10087 synchronized (sb) { 10088 bufferWasEmpty = sb.length() == 0; 10089 appendDropBoxProcessHeaders(process, processName, sb); 10090 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10091 sb.append("System-App: ").append(isSystemApp).append("\n"); 10092 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10093 if (info.violationNumThisLoop != 0) { 10094 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10095 } 10096 if (info.numAnimationsRunning != 0) { 10097 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10098 } 10099 if (info.broadcastIntentAction != null) { 10100 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10101 } 10102 if (info.durationMillis != -1) { 10103 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10104 } 10105 if (info.numInstances != -1) { 10106 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10107 } 10108 if (info.tags != null) { 10109 for (String tag : info.tags) { 10110 sb.append("Span-Tag: ").append(tag).append("\n"); 10111 } 10112 } 10113 sb.append("\n"); 10114 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10115 sb.append(info.crashInfo.stackTrace); 10116 } 10117 sb.append("\n"); 10118 10119 // Only buffer up to ~64k. Various logging bits truncate 10120 // things at 128k. 10121 needsFlush = (sb.length() > 64 * 1024); 10122 } 10123 10124 // Flush immediately if the buffer's grown too large, or this 10125 // is a non-system app. Non-system apps are isolated with a 10126 // different tag & policy and not batched. 10127 // 10128 // Batching is useful during internal testing with 10129 // StrictMode settings turned up high. Without batching, 10130 // thousands of separate files could be created on boot. 10131 if (!isSystemApp || needsFlush) { 10132 new Thread("Error dump: " + dropboxTag) { 10133 @Override 10134 public void run() { 10135 String report; 10136 synchronized (sb) { 10137 report = sb.toString(); 10138 sb.delete(0, sb.length()); 10139 sb.trimToSize(); 10140 } 10141 if (report.length() != 0) { 10142 dbox.addText(dropboxTag, report); 10143 } 10144 } 10145 }.start(); 10146 return; 10147 } 10148 10149 // System app batching: 10150 if (!bufferWasEmpty) { 10151 // An existing dropbox-writing thread is outstanding, so 10152 // we don't need to start it up. The existing thread will 10153 // catch the buffer appends we just did. 10154 return; 10155 } 10156 10157 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10158 // (After this point, we shouldn't access AMS internal data structures.) 10159 new Thread("Error dump: " + dropboxTag) { 10160 @Override 10161 public void run() { 10162 // 5 second sleep to let stacks arrive and be batched together 10163 try { 10164 Thread.sleep(5000); // 5 seconds 10165 } catch (InterruptedException e) {} 10166 10167 String errorReport; 10168 synchronized (mStrictModeBuffer) { 10169 errorReport = mStrictModeBuffer.toString(); 10170 if (errorReport.length() == 0) { 10171 return; 10172 } 10173 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10174 mStrictModeBuffer.trimToSize(); 10175 } 10176 dbox.addText(dropboxTag, errorReport); 10177 } 10178 }.start(); 10179 } 10180 10181 /** 10182 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10183 * @param app object of the crashing app, null for the system server 10184 * @param tag reported by the caller 10185 * @param crashInfo describing the context of the error 10186 * @return true if the process should exit immediately (WTF is fatal) 10187 */ 10188 public boolean handleApplicationWtf(IBinder app, String tag, 10189 ApplicationErrorReport.CrashInfo crashInfo) { 10190 ProcessRecord r = findAppProcess(app, "WTF"); 10191 final String processName = app == null ? "system_server" 10192 : (r == null ? "unknown" : r.processName); 10193 10194 EventLog.writeEvent(EventLogTags.AM_WTF, 10195 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10196 processName, 10197 r == null ? -1 : r.info.flags, 10198 tag, crashInfo.exceptionMessage); 10199 10200 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10201 10202 if (r != null && r.pid != Process.myPid() && 10203 Settings.Global.getInt(mContext.getContentResolver(), 10204 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10205 crashApplication(r, crashInfo); 10206 return true; 10207 } else { 10208 return false; 10209 } 10210 } 10211 10212 /** 10213 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10214 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10215 */ 10216 private ProcessRecord findAppProcess(IBinder app, String reason) { 10217 if (app == null) { 10218 return null; 10219 } 10220 10221 synchronized (this) { 10222 final int NP = mProcessNames.getMap().size(); 10223 for (int ip=0; ip<NP; ip++) { 10224 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10225 final int NA = apps.size(); 10226 for (int ia=0; ia<NA; ia++) { 10227 ProcessRecord p = apps.valueAt(ia); 10228 if (p.thread != null && p.thread.asBinder() == app) { 10229 return p; 10230 } 10231 } 10232 } 10233 10234 Slog.w(TAG, "Can't find mystery application for " + reason 10235 + " from pid=" + Binder.getCallingPid() 10236 + " uid=" + Binder.getCallingUid() + ": " + app); 10237 return null; 10238 } 10239 } 10240 10241 /** 10242 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10243 * to append various headers to the dropbox log text. 10244 */ 10245 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10246 StringBuilder sb) { 10247 // Watchdog thread ends up invoking this function (with 10248 // a null ProcessRecord) to add the stack file to dropbox. 10249 // Do not acquire a lock on this (am) in such cases, as it 10250 // could cause a potential deadlock, if and when watchdog 10251 // is invoked due to unavailability of lock on am and it 10252 // would prevent watchdog from killing system_server. 10253 if (process == null) { 10254 sb.append("Process: ").append(processName).append("\n"); 10255 return; 10256 } 10257 // Note: ProcessRecord 'process' is guarded by the service 10258 // instance. (notably process.pkgList, which could otherwise change 10259 // concurrently during execution of this method) 10260 synchronized (this) { 10261 sb.append("Process: ").append(processName).append("\n"); 10262 int flags = process.info.flags; 10263 IPackageManager pm = AppGlobals.getPackageManager(); 10264 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10265 for (int ip=0; ip<process.pkgList.size(); ip++) { 10266 String pkg = process.pkgList.keyAt(ip); 10267 sb.append("Package: ").append(pkg); 10268 try { 10269 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10270 if (pi != null) { 10271 sb.append(" v").append(pi.versionCode); 10272 if (pi.versionName != null) { 10273 sb.append(" (").append(pi.versionName).append(")"); 10274 } 10275 } 10276 } catch (RemoteException e) { 10277 Slog.e(TAG, "Error getting package info: " + pkg, e); 10278 } 10279 sb.append("\n"); 10280 } 10281 } 10282 } 10283 10284 private static String processClass(ProcessRecord process) { 10285 if (process == null || process.pid == MY_PID) { 10286 return "system_server"; 10287 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10288 return "system_app"; 10289 } else { 10290 return "data_app"; 10291 } 10292 } 10293 10294 /** 10295 * Write a description of an error (crash, WTF, ANR) to the drop box. 10296 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10297 * @param process which caused the error, null means the system server 10298 * @param activity which triggered the error, null if unknown 10299 * @param parent activity related to the error, null if unknown 10300 * @param subject line related to the error, null if absent 10301 * @param report in long form describing the error, null if absent 10302 * @param logFile to include in the report, null if none 10303 * @param crashInfo giving an application stack trace, null if absent 10304 */ 10305 public void addErrorToDropBox(String eventType, 10306 ProcessRecord process, String processName, ActivityRecord activity, 10307 ActivityRecord parent, String subject, 10308 final String report, final File logFile, 10309 final ApplicationErrorReport.CrashInfo crashInfo) { 10310 // NOTE -- this must never acquire the ActivityManagerService lock, 10311 // otherwise the watchdog may be prevented from resetting the system. 10312 10313 final String dropboxTag = processClass(process) + "_" + eventType; 10314 final DropBoxManager dbox = (DropBoxManager) 10315 mContext.getSystemService(Context.DROPBOX_SERVICE); 10316 10317 // Exit early if the dropbox isn't configured to accept this report type. 10318 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10319 10320 final StringBuilder sb = new StringBuilder(1024); 10321 appendDropBoxProcessHeaders(process, processName, sb); 10322 if (activity != null) { 10323 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10324 } 10325 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10326 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10327 } 10328 if (parent != null && parent != activity) { 10329 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10330 } 10331 if (subject != null) { 10332 sb.append("Subject: ").append(subject).append("\n"); 10333 } 10334 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10335 if (Debug.isDebuggerConnected()) { 10336 sb.append("Debugger: Connected\n"); 10337 } 10338 sb.append("\n"); 10339 10340 // Do the rest in a worker thread to avoid blocking the caller on I/O 10341 // (After this point, we shouldn't access AMS internal data structures.) 10342 Thread worker = new Thread("Error dump: " + dropboxTag) { 10343 @Override 10344 public void run() { 10345 if (report != null) { 10346 sb.append(report); 10347 } 10348 if (logFile != null) { 10349 try { 10350 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10351 "\n\n[[TRUNCATED]]")); 10352 } catch (IOException e) { 10353 Slog.e(TAG, "Error reading " + logFile, e); 10354 } 10355 } 10356 if (crashInfo != null && crashInfo.stackTrace != null) { 10357 sb.append(crashInfo.stackTrace); 10358 } 10359 10360 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10361 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10362 if (lines > 0) { 10363 sb.append("\n"); 10364 10365 // Merge several logcat streams, and take the last N lines 10366 InputStreamReader input = null; 10367 try { 10368 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10369 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10370 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10371 10372 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10373 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10374 input = new InputStreamReader(logcat.getInputStream()); 10375 10376 int num; 10377 char[] buf = new char[8192]; 10378 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10379 } catch (IOException e) { 10380 Slog.e(TAG, "Error running logcat", e); 10381 } finally { 10382 if (input != null) try { input.close(); } catch (IOException e) {} 10383 } 10384 } 10385 10386 dbox.addText(dropboxTag, sb.toString()); 10387 } 10388 }; 10389 10390 if (process == null) { 10391 // If process is null, we are being called from some internal code 10392 // and may be about to die -- run this synchronously. 10393 worker.run(); 10394 } else { 10395 worker.start(); 10396 } 10397 } 10398 10399 /** 10400 * Bring up the "unexpected error" dialog box for a crashing app. 10401 * Deal with edge cases (intercepts from instrumented applications, 10402 * ActivityController, error intent receivers, that sort of thing). 10403 * @param r the application crashing 10404 * @param crashInfo describing the failure 10405 */ 10406 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10407 long timeMillis = System.currentTimeMillis(); 10408 String shortMsg = crashInfo.exceptionClassName; 10409 String longMsg = crashInfo.exceptionMessage; 10410 String stackTrace = crashInfo.stackTrace; 10411 if (shortMsg != null && longMsg != null) { 10412 longMsg = shortMsg + ": " + longMsg; 10413 } else if (shortMsg != null) { 10414 longMsg = shortMsg; 10415 } 10416 10417 AppErrorResult result = new AppErrorResult(); 10418 synchronized (this) { 10419 if (mController != null) { 10420 try { 10421 String name = r != null ? r.processName : null; 10422 int pid = r != null ? r.pid : Binder.getCallingPid(); 10423 if (!mController.appCrashed(name, pid, 10424 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10425 Slog.w(TAG, "Force-killing crashed app " + name 10426 + " at watcher's request"); 10427 Process.killProcess(pid); 10428 return; 10429 } 10430 } catch (RemoteException e) { 10431 mController = null; 10432 Watchdog.getInstance().setActivityController(null); 10433 } 10434 } 10435 10436 final long origId = Binder.clearCallingIdentity(); 10437 10438 // If this process is running instrumentation, finish it. 10439 if (r != null && r.instrumentationClass != null) { 10440 Slog.w(TAG, "Error in app " + r.processName 10441 + " running instrumentation " + r.instrumentationClass + ":"); 10442 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10443 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10444 Bundle info = new Bundle(); 10445 info.putString("shortMsg", shortMsg); 10446 info.putString("longMsg", longMsg); 10447 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10448 Binder.restoreCallingIdentity(origId); 10449 return; 10450 } 10451 10452 // If we can't identify the process or it's already exceeded its crash quota, 10453 // quit right away without showing a crash dialog. 10454 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10455 Binder.restoreCallingIdentity(origId); 10456 return; 10457 } 10458 10459 Message msg = Message.obtain(); 10460 msg.what = SHOW_ERROR_MSG; 10461 HashMap data = new HashMap(); 10462 data.put("result", result); 10463 data.put("app", r); 10464 msg.obj = data; 10465 mHandler.sendMessage(msg); 10466 10467 Binder.restoreCallingIdentity(origId); 10468 } 10469 10470 int res = result.get(); 10471 10472 Intent appErrorIntent = null; 10473 synchronized (this) { 10474 if (r != null && !r.isolated) { 10475 // XXX Can't keep track of crash time for isolated processes, 10476 // since they don't have a persistent identity. 10477 mProcessCrashTimes.put(r.info.processName, r.uid, 10478 SystemClock.uptimeMillis()); 10479 } 10480 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10481 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10482 } 10483 } 10484 10485 if (appErrorIntent != null) { 10486 try { 10487 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10488 } catch (ActivityNotFoundException e) { 10489 Slog.w(TAG, "bug report receiver dissappeared", e); 10490 } 10491 } 10492 } 10493 10494 Intent createAppErrorIntentLocked(ProcessRecord r, 10495 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10496 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10497 if (report == null) { 10498 return null; 10499 } 10500 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10501 result.setComponent(r.errorReportReceiver); 10502 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10503 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10504 return result; 10505 } 10506 10507 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10508 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10509 if (r.errorReportReceiver == null) { 10510 return null; 10511 } 10512 10513 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10514 return null; 10515 } 10516 10517 ApplicationErrorReport report = new ApplicationErrorReport(); 10518 report.packageName = r.info.packageName; 10519 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10520 report.processName = r.processName; 10521 report.time = timeMillis; 10522 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10523 10524 if (r.crashing || r.forceCrashReport) { 10525 report.type = ApplicationErrorReport.TYPE_CRASH; 10526 report.crashInfo = crashInfo; 10527 } else if (r.notResponding) { 10528 report.type = ApplicationErrorReport.TYPE_ANR; 10529 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10530 10531 report.anrInfo.activity = r.notRespondingReport.tag; 10532 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10533 report.anrInfo.info = r.notRespondingReport.longMsg; 10534 } 10535 10536 return report; 10537 } 10538 10539 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10540 enforceNotIsolatedCaller("getProcessesInErrorState"); 10541 // assume our apps are happy - lazy create the list 10542 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10543 10544 final boolean allUsers = ActivityManager.checkUidPermission( 10545 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10546 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10547 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10548 10549 synchronized (this) { 10550 10551 // iterate across all processes 10552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10553 ProcessRecord app = mLruProcesses.get(i); 10554 if (!allUsers && app.userId != userId) { 10555 continue; 10556 } 10557 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10558 // This one's in trouble, so we'll generate a report for it 10559 // crashes are higher priority (in case there's a crash *and* an anr) 10560 ActivityManager.ProcessErrorStateInfo report = null; 10561 if (app.crashing) { 10562 report = app.crashingReport; 10563 } else if (app.notResponding) { 10564 report = app.notRespondingReport; 10565 } 10566 10567 if (report != null) { 10568 if (errList == null) { 10569 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10570 } 10571 errList.add(report); 10572 } else { 10573 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10574 " crashing = " + app.crashing + 10575 " notResponding = " + app.notResponding); 10576 } 10577 } 10578 } 10579 } 10580 10581 return errList; 10582 } 10583 10584 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10585 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10586 if (currApp != null) { 10587 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10588 } 10589 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10590 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10591 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10592 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10593 if (currApp != null) { 10594 currApp.lru = 0; 10595 } 10596 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10597 } else if (adj >= ProcessList.SERVICE_ADJ) { 10598 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10599 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10600 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10601 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10602 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10603 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10604 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10605 } else { 10606 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10607 } 10608 } 10609 10610 private void fillInProcMemInfo(ProcessRecord app, 10611 ActivityManager.RunningAppProcessInfo outInfo) { 10612 outInfo.pid = app.pid; 10613 outInfo.uid = app.info.uid; 10614 if (mHeavyWeightProcess == app) { 10615 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10616 } 10617 if (app.persistent) { 10618 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10619 } 10620 if (app.activities.size() > 0) { 10621 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10622 } 10623 outInfo.lastTrimLevel = app.trimMemoryLevel; 10624 int adj = app.curAdj; 10625 outInfo.importance = oomAdjToImportance(adj, outInfo); 10626 outInfo.importanceReasonCode = app.adjTypeCode; 10627 outInfo.processState = app.curProcState; 10628 } 10629 10630 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10631 enforceNotIsolatedCaller("getRunningAppProcesses"); 10632 // Lazy instantiation of list 10633 List<ActivityManager.RunningAppProcessInfo> runList = null; 10634 final boolean allUsers = ActivityManager.checkUidPermission( 10635 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10636 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10637 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10638 synchronized (this) { 10639 // Iterate across all processes 10640 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10641 ProcessRecord app = mLruProcesses.get(i); 10642 if (!allUsers && app.userId != userId) { 10643 continue; 10644 } 10645 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10646 // Generate process state info for running application 10647 ActivityManager.RunningAppProcessInfo currApp = 10648 new ActivityManager.RunningAppProcessInfo(app.processName, 10649 app.pid, app.getPackageList()); 10650 fillInProcMemInfo(app, currApp); 10651 if (app.adjSource instanceof ProcessRecord) { 10652 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10653 currApp.importanceReasonImportance = oomAdjToImportance( 10654 app.adjSourceOom, null); 10655 } else if (app.adjSource instanceof ActivityRecord) { 10656 ActivityRecord r = (ActivityRecord)app.adjSource; 10657 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10658 } 10659 if (app.adjTarget instanceof ComponentName) { 10660 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10661 } 10662 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10663 // + " lru=" + currApp.lru); 10664 if (runList == null) { 10665 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10666 } 10667 runList.add(currApp); 10668 } 10669 } 10670 } 10671 return runList; 10672 } 10673 10674 public List<ApplicationInfo> getRunningExternalApplications() { 10675 enforceNotIsolatedCaller("getRunningExternalApplications"); 10676 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10677 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10678 if (runningApps != null && runningApps.size() > 0) { 10679 Set<String> extList = new HashSet<String>(); 10680 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10681 if (app.pkgList != null) { 10682 for (String pkg : app.pkgList) { 10683 extList.add(pkg); 10684 } 10685 } 10686 } 10687 IPackageManager pm = AppGlobals.getPackageManager(); 10688 for (String pkg : extList) { 10689 try { 10690 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10691 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10692 retList.add(info); 10693 } 10694 } catch (RemoteException e) { 10695 } 10696 } 10697 } 10698 return retList; 10699 } 10700 10701 @Override 10702 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10703 enforceNotIsolatedCaller("getMyMemoryState"); 10704 synchronized (this) { 10705 ProcessRecord proc; 10706 synchronized (mPidsSelfLocked) { 10707 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10708 } 10709 fillInProcMemInfo(proc, outInfo); 10710 } 10711 } 10712 10713 @Override 10714 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10715 if (checkCallingPermission(android.Manifest.permission.DUMP) 10716 != PackageManager.PERMISSION_GRANTED) { 10717 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10718 + Binder.getCallingPid() 10719 + ", uid=" + Binder.getCallingUid() 10720 + " without permission " 10721 + android.Manifest.permission.DUMP); 10722 return; 10723 } 10724 10725 boolean dumpAll = false; 10726 boolean dumpClient = false; 10727 String dumpPackage = null; 10728 10729 int opti = 0; 10730 while (opti < args.length) { 10731 String opt = args[opti]; 10732 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10733 break; 10734 } 10735 opti++; 10736 if ("-a".equals(opt)) { 10737 dumpAll = true; 10738 } else if ("-c".equals(opt)) { 10739 dumpClient = true; 10740 } else if ("-h".equals(opt)) { 10741 pw.println("Activity manager dump options:"); 10742 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10743 pw.println(" cmd may be one of:"); 10744 pw.println(" a[ctivities]: activity stack state"); 10745 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10746 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10747 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10748 pw.println(" o[om]: out of memory management"); 10749 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10750 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10751 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10752 pw.println(" service [COMP_SPEC]: service client-side state"); 10753 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10754 pw.println(" all: dump all activities"); 10755 pw.println(" top: dump the top activity"); 10756 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10757 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10758 pw.println(" a partial substring in a component name, a"); 10759 pw.println(" hex object identifier."); 10760 pw.println(" -a: include all available server state."); 10761 pw.println(" -c: include client state."); 10762 return; 10763 } else { 10764 pw.println("Unknown argument: " + opt + "; use -h for help"); 10765 } 10766 } 10767 10768 long origId = Binder.clearCallingIdentity(); 10769 boolean more = false; 10770 // Is the caller requesting to dump a particular piece of data? 10771 if (opti < args.length) { 10772 String cmd = args[opti]; 10773 opti++; 10774 if ("activities".equals(cmd) || "a".equals(cmd)) { 10775 synchronized (this) { 10776 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10777 } 10778 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10779 String[] newArgs; 10780 String name; 10781 if (opti >= args.length) { 10782 name = null; 10783 newArgs = EMPTY_STRING_ARRAY; 10784 } else { 10785 name = args[opti]; 10786 opti++; 10787 newArgs = new String[args.length - opti]; 10788 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10789 args.length - opti); 10790 } 10791 synchronized (this) { 10792 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10793 } 10794 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10795 String[] newArgs; 10796 String name; 10797 if (opti >= args.length) { 10798 name = null; 10799 newArgs = EMPTY_STRING_ARRAY; 10800 } else { 10801 name = args[opti]; 10802 opti++; 10803 newArgs = new String[args.length - opti]; 10804 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10805 args.length - opti); 10806 } 10807 synchronized (this) { 10808 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10809 } 10810 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10811 String[] newArgs; 10812 String name; 10813 if (opti >= args.length) { 10814 name = null; 10815 newArgs = EMPTY_STRING_ARRAY; 10816 } else { 10817 name = args[opti]; 10818 opti++; 10819 newArgs = new String[args.length - opti]; 10820 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10821 args.length - opti); 10822 } 10823 synchronized (this) { 10824 dumpProcessesLocked(fd, pw, args, opti, true, name); 10825 } 10826 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10827 synchronized (this) { 10828 dumpOomLocked(fd, pw, args, opti, true); 10829 } 10830 } else if ("provider".equals(cmd)) { 10831 String[] newArgs; 10832 String name; 10833 if (opti >= args.length) { 10834 name = null; 10835 newArgs = EMPTY_STRING_ARRAY; 10836 } else { 10837 name = args[opti]; 10838 opti++; 10839 newArgs = new String[args.length - opti]; 10840 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10841 } 10842 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10843 pw.println("No providers match: " + name); 10844 pw.println("Use -h for help."); 10845 } 10846 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10847 synchronized (this) { 10848 dumpProvidersLocked(fd, pw, args, opti, true, null); 10849 } 10850 } else if ("service".equals(cmd)) { 10851 String[] newArgs; 10852 String name; 10853 if (opti >= args.length) { 10854 name = null; 10855 newArgs = EMPTY_STRING_ARRAY; 10856 } else { 10857 name = args[opti]; 10858 opti++; 10859 newArgs = new String[args.length - opti]; 10860 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10861 args.length - opti); 10862 } 10863 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10864 pw.println("No services match: " + name); 10865 pw.println("Use -h for help."); 10866 } 10867 } else if ("package".equals(cmd)) { 10868 String[] newArgs; 10869 if (opti >= args.length) { 10870 pw.println("package: no package name specified"); 10871 pw.println("Use -h for help."); 10872 } else { 10873 dumpPackage = args[opti]; 10874 opti++; 10875 newArgs = new String[args.length - opti]; 10876 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10877 args.length - opti); 10878 args = newArgs; 10879 opti = 0; 10880 more = true; 10881 } 10882 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10883 synchronized (this) { 10884 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10885 } 10886 } else { 10887 // Dumping a single activity? 10888 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10889 pw.println("Bad activity command, or no activities match: " + cmd); 10890 pw.println("Use -h for help."); 10891 } 10892 } 10893 if (!more) { 10894 Binder.restoreCallingIdentity(origId); 10895 return; 10896 } 10897 } 10898 10899 // No piece of data specified, dump everything. 10900 synchronized (this) { 10901 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10902 pw.println(); 10903 if (dumpAll) { 10904 pw.println("-------------------------------------------------------------------------------"); 10905 } 10906 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10907 pw.println(); 10908 if (dumpAll) { 10909 pw.println("-------------------------------------------------------------------------------"); 10910 } 10911 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10912 pw.println(); 10913 if (dumpAll) { 10914 pw.println("-------------------------------------------------------------------------------"); 10915 } 10916 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10917 pw.println(); 10918 if (dumpAll) { 10919 pw.println("-------------------------------------------------------------------------------"); 10920 } 10921 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10922 pw.println(); 10923 if (dumpAll) { 10924 pw.println("-------------------------------------------------------------------------------"); 10925 } 10926 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10927 } 10928 Binder.restoreCallingIdentity(origId); 10929 } 10930 10931 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10932 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10933 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10934 10935 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10936 dumpPackage); 10937 boolean needSep = printedAnything; 10938 10939 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10940 dumpPackage, needSep, " mFocusedActivity: "); 10941 if (printed) { 10942 printedAnything = true; 10943 needSep = false; 10944 } 10945 10946 if (dumpPackage == null) { 10947 if (needSep) { 10948 pw.println(); 10949 } 10950 needSep = true; 10951 printedAnything = true; 10952 mStackSupervisor.dump(pw, " "); 10953 } 10954 10955 if (mRecentTasks.size() > 0) { 10956 boolean printedHeader = false; 10957 10958 final int N = mRecentTasks.size(); 10959 for (int i=0; i<N; i++) { 10960 TaskRecord tr = mRecentTasks.get(i); 10961 if (dumpPackage != null) { 10962 if (tr.realActivity == null || 10963 !dumpPackage.equals(tr.realActivity)) { 10964 continue; 10965 } 10966 } 10967 if (!printedHeader) { 10968 if (needSep) { 10969 pw.println(); 10970 } 10971 pw.println(" Recent tasks:"); 10972 printedHeader = true; 10973 printedAnything = true; 10974 } 10975 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10976 pw.println(tr); 10977 if (dumpAll) { 10978 mRecentTasks.get(i).dump(pw, " "); 10979 } 10980 } 10981 } 10982 10983 if (!printedAnything) { 10984 pw.println(" (nothing)"); 10985 } 10986 } 10987 10988 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10989 int opti, boolean dumpAll, String dumpPackage) { 10990 boolean needSep = false; 10991 boolean printedAnything = false; 10992 int numPers = 0; 10993 10994 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10995 10996 if (dumpAll) { 10997 final int NP = mProcessNames.getMap().size(); 10998 for (int ip=0; ip<NP; ip++) { 10999 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11000 final int NA = procs.size(); 11001 for (int ia=0; ia<NA; ia++) { 11002 ProcessRecord r = procs.valueAt(ia); 11003 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11004 continue; 11005 } 11006 if (!needSep) { 11007 pw.println(" All known processes:"); 11008 needSep = true; 11009 printedAnything = true; 11010 } 11011 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11012 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11013 pw.print(" "); pw.println(r); 11014 r.dump(pw, " "); 11015 if (r.persistent) { 11016 numPers++; 11017 } 11018 } 11019 } 11020 } 11021 11022 if (mIsolatedProcesses.size() > 0) { 11023 boolean printed = false; 11024 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11025 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11026 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11027 continue; 11028 } 11029 if (!printed) { 11030 if (needSep) { 11031 pw.println(); 11032 } 11033 pw.println(" Isolated process list (sorted by uid):"); 11034 printedAnything = true; 11035 printed = true; 11036 needSep = true; 11037 } 11038 pw.println(String.format("%sIsolated #%2d: %s", 11039 " ", i, r.toString())); 11040 } 11041 } 11042 11043 if (mLruProcesses.size() > 0) { 11044 if (needSep) { 11045 pw.println(); 11046 } 11047 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11048 pw.print(" total, non-act at "); 11049 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11050 pw.print(", non-svc at "); 11051 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11052 pw.println("):"); 11053 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11054 needSep = true; 11055 printedAnything = true; 11056 } 11057 11058 if (dumpAll || dumpPackage != null) { 11059 synchronized (mPidsSelfLocked) { 11060 boolean printed = false; 11061 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11062 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11063 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11064 continue; 11065 } 11066 if (!printed) { 11067 if (needSep) pw.println(); 11068 needSep = true; 11069 pw.println(" PID mappings:"); 11070 printed = true; 11071 printedAnything = true; 11072 } 11073 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11074 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11075 } 11076 } 11077 } 11078 11079 if (mForegroundProcesses.size() > 0) { 11080 synchronized (mPidsSelfLocked) { 11081 boolean printed = false; 11082 for (int i=0; i<mForegroundProcesses.size(); i++) { 11083 ProcessRecord r = mPidsSelfLocked.get( 11084 mForegroundProcesses.valueAt(i).pid); 11085 if (dumpPackage != null && (r == null 11086 || !r.pkgList.containsKey(dumpPackage))) { 11087 continue; 11088 } 11089 if (!printed) { 11090 if (needSep) pw.println(); 11091 needSep = true; 11092 pw.println(" Foreground Processes:"); 11093 printed = true; 11094 printedAnything = true; 11095 } 11096 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11097 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11098 } 11099 } 11100 } 11101 11102 if (mPersistentStartingProcesses.size() > 0) { 11103 if (needSep) pw.println(); 11104 needSep = true; 11105 printedAnything = true; 11106 pw.println(" Persisent processes that are starting:"); 11107 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11108 "Starting Norm", "Restarting PERS", dumpPackage); 11109 } 11110 11111 if (mRemovedProcesses.size() > 0) { 11112 if (needSep) pw.println(); 11113 needSep = true; 11114 printedAnything = true; 11115 pw.println(" Processes that are being removed:"); 11116 dumpProcessList(pw, this, mRemovedProcesses, " ", 11117 "Removed Norm", "Removed PERS", dumpPackage); 11118 } 11119 11120 if (mProcessesOnHold.size() > 0) { 11121 if (needSep) pw.println(); 11122 needSep = true; 11123 printedAnything = true; 11124 pw.println(" Processes that are on old until the system is ready:"); 11125 dumpProcessList(pw, this, mProcessesOnHold, " ", 11126 "OnHold Norm", "OnHold PERS", dumpPackage); 11127 } 11128 11129 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11130 11131 if (mProcessCrashTimes.getMap().size() > 0) { 11132 boolean printed = false; 11133 long now = SystemClock.uptimeMillis(); 11134 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11135 final int NP = pmap.size(); 11136 for (int ip=0; ip<NP; ip++) { 11137 String pname = pmap.keyAt(ip); 11138 SparseArray<Long> uids = pmap.valueAt(ip); 11139 final int N = uids.size(); 11140 for (int i=0; i<N; i++) { 11141 int puid = uids.keyAt(i); 11142 ProcessRecord r = mProcessNames.get(pname, puid); 11143 if (dumpPackage != null && (r == null 11144 || !r.pkgList.containsKey(dumpPackage))) { 11145 continue; 11146 } 11147 if (!printed) { 11148 if (needSep) pw.println(); 11149 needSep = true; 11150 pw.println(" Time since processes crashed:"); 11151 printed = true; 11152 printedAnything = true; 11153 } 11154 pw.print(" Process "); pw.print(pname); 11155 pw.print(" uid "); pw.print(puid); 11156 pw.print(": last crashed "); 11157 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11158 pw.println(" ago"); 11159 } 11160 } 11161 } 11162 11163 if (mBadProcesses.getMap().size() > 0) { 11164 boolean printed = false; 11165 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11166 final int NP = pmap.size(); 11167 for (int ip=0; ip<NP; ip++) { 11168 String pname = pmap.keyAt(ip); 11169 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11170 final int N = uids.size(); 11171 for (int i=0; i<N; i++) { 11172 int puid = uids.keyAt(i); 11173 ProcessRecord r = mProcessNames.get(pname, puid); 11174 if (dumpPackage != null && (r == null 11175 || !r.pkgList.containsKey(dumpPackage))) { 11176 continue; 11177 } 11178 if (!printed) { 11179 if (needSep) pw.println(); 11180 needSep = true; 11181 pw.println(" Bad processes:"); 11182 printedAnything = true; 11183 } 11184 BadProcessInfo info = uids.valueAt(i); 11185 pw.print(" Bad process "); pw.print(pname); 11186 pw.print(" uid "); pw.print(puid); 11187 pw.print(": crashed at time "); pw.println(info.time); 11188 if (info.shortMsg != null) { 11189 pw.print(" Short msg: "); pw.println(info.shortMsg); 11190 } 11191 if (info.longMsg != null) { 11192 pw.print(" Long msg: "); pw.println(info.longMsg); 11193 } 11194 if (info.stack != null) { 11195 pw.println(" Stack:"); 11196 int lastPos = 0; 11197 for (int pos=0; pos<info.stack.length(); pos++) { 11198 if (info.stack.charAt(pos) == '\n') { 11199 pw.print(" "); 11200 pw.write(info.stack, lastPos, pos-lastPos); 11201 pw.println(); 11202 lastPos = pos+1; 11203 } 11204 } 11205 if (lastPos < info.stack.length()) { 11206 pw.print(" "); 11207 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11208 pw.println(); 11209 } 11210 } 11211 } 11212 } 11213 } 11214 11215 if (dumpPackage == null) { 11216 pw.println(); 11217 needSep = false; 11218 pw.println(" mStartedUsers:"); 11219 for (int i=0; i<mStartedUsers.size(); i++) { 11220 UserStartedState uss = mStartedUsers.valueAt(i); 11221 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11222 pw.print(": "); uss.dump("", pw); 11223 } 11224 pw.print(" mStartedUserArray: ["); 11225 for (int i=0; i<mStartedUserArray.length; i++) { 11226 if (i > 0) pw.print(", "); 11227 pw.print(mStartedUserArray[i]); 11228 } 11229 pw.println("]"); 11230 pw.print(" mUserLru: ["); 11231 for (int i=0; i<mUserLru.size(); i++) { 11232 if (i > 0) pw.print(", "); 11233 pw.print(mUserLru.get(i)); 11234 } 11235 pw.println("]"); 11236 if (dumpAll) { 11237 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11238 } 11239 } 11240 if (mHomeProcess != null && (dumpPackage == null 11241 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11242 if (needSep) { 11243 pw.println(); 11244 needSep = false; 11245 } 11246 pw.println(" mHomeProcess: " + mHomeProcess); 11247 } 11248 if (mPreviousProcess != null && (dumpPackage == null 11249 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11250 if (needSep) { 11251 pw.println(); 11252 needSep = false; 11253 } 11254 pw.println(" mPreviousProcess: " + mPreviousProcess); 11255 } 11256 if (dumpAll) { 11257 StringBuilder sb = new StringBuilder(128); 11258 sb.append(" mPreviousProcessVisibleTime: "); 11259 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11260 pw.println(sb); 11261 } 11262 if (mHeavyWeightProcess != null && (dumpPackage == null 11263 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11264 if (needSep) { 11265 pw.println(); 11266 needSep = false; 11267 } 11268 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11269 } 11270 if (dumpPackage == null) { 11271 pw.println(" mConfiguration: " + mConfiguration); 11272 } 11273 if (dumpAll) { 11274 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11275 if (mCompatModePackages.getPackages().size() > 0) { 11276 boolean printed = false; 11277 for (Map.Entry<String, Integer> entry 11278 : mCompatModePackages.getPackages().entrySet()) { 11279 String pkg = entry.getKey(); 11280 int mode = entry.getValue(); 11281 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11282 continue; 11283 } 11284 if (!printed) { 11285 pw.println(" mScreenCompatPackages:"); 11286 printed = true; 11287 } 11288 pw.print(" "); pw.print(pkg); pw.print(": "); 11289 pw.print(mode); pw.println(); 11290 } 11291 } 11292 } 11293 if (dumpPackage == null) { 11294 if (mSleeping || mWentToSleep || mLockScreenShown) { 11295 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11296 + " mLockScreenShown " + mLockScreenShown); 11297 } 11298 if (mShuttingDown || mRunningVoice) { 11299 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11300 } 11301 } 11302 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11303 || mOrigWaitForDebugger) { 11304 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11305 || dumpPackage.equals(mOrigDebugApp)) { 11306 if (needSep) { 11307 pw.println(); 11308 needSep = false; 11309 } 11310 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11311 + " mDebugTransient=" + mDebugTransient 11312 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11313 } 11314 } 11315 if (mOpenGlTraceApp != null) { 11316 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11317 if (needSep) { 11318 pw.println(); 11319 needSep = false; 11320 } 11321 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11322 } 11323 } 11324 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11325 || mProfileFd != null) { 11326 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11327 if (needSep) { 11328 pw.println(); 11329 needSep = false; 11330 } 11331 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11332 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11333 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11334 + mAutoStopProfiler); 11335 } 11336 } 11337 if (dumpPackage == null) { 11338 if (mAlwaysFinishActivities || mController != null) { 11339 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11340 + " mController=" + mController); 11341 } 11342 if (dumpAll) { 11343 pw.println(" Total persistent processes: " + numPers); 11344 pw.println(" mProcessesReady=" + mProcessesReady 11345 + " mSystemReady=" + mSystemReady); 11346 pw.println(" mBooting=" + mBooting 11347 + " mBooted=" + mBooted 11348 + " mFactoryTest=" + mFactoryTest); 11349 pw.print(" mLastPowerCheckRealtime="); 11350 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11351 pw.println(""); 11352 pw.print(" mLastPowerCheckUptime="); 11353 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11354 pw.println(""); 11355 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11356 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11357 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11358 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11359 + " (" + mLruProcesses.size() + " total)" 11360 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11361 + " mNumServiceProcs=" + mNumServiceProcs 11362 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11363 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11364 + " mLastMemoryLevel" + mLastMemoryLevel 11365 + " mLastNumProcesses" + mLastNumProcesses); 11366 long now = SystemClock.uptimeMillis(); 11367 pw.print(" mLastIdleTime="); 11368 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11369 pw.print(" mLowRamSinceLastIdle="); 11370 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11371 pw.println(); 11372 } 11373 } 11374 11375 if (!printedAnything) { 11376 pw.println(" (nothing)"); 11377 } 11378 } 11379 11380 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11381 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11382 if (mProcessesToGc.size() > 0) { 11383 boolean printed = false; 11384 long now = SystemClock.uptimeMillis(); 11385 for (int i=0; i<mProcessesToGc.size(); i++) { 11386 ProcessRecord proc = mProcessesToGc.get(i); 11387 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11388 continue; 11389 } 11390 if (!printed) { 11391 if (needSep) pw.println(); 11392 needSep = true; 11393 pw.println(" Processes that are waiting to GC:"); 11394 printed = true; 11395 } 11396 pw.print(" Process "); pw.println(proc); 11397 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11398 pw.print(", last gced="); 11399 pw.print(now-proc.lastRequestedGc); 11400 pw.print(" ms ago, last lowMem="); 11401 pw.print(now-proc.lastLowMemory); 11402 pw.println(" ms ago"); 11403 11404 } 11405 } 11406 return needSep; 11407 } 11408 11409 void printOomLevel(PrintWriter pw, String name, int adj) { 11410 pw.print(" "); 11411 if (adj >= 0) { 11412 pw.print(' '); 11413 if (adj < 10) pw.print(' '); 11414 } else { 11415 if (adj > -10) pw.print(' '); 11416 } 11417 pw.print(adj); 11418 pw.print(": "); 11419 pw.print(name); 11420 pw.print(" ("); 11421 pw.print(mProcessList.getMemLevel(adj)/1024); 11422 pw.println(" kB)"); 11423 } 11424 11425 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11426 int opti, boolean dumpAll) { 11427 boolean needSep = false; 11428 11429 if (mLruProcesses.size() > 0) { 11430 if (needSep) pw.println(); 11431 needSep = true; 11432 pw.println(" OOM levels:"); 11433 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11434 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11435 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11436 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11437 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11438 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11439 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11440 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11441 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11442 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11443 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11444 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11445 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11446 11447 if (needSep) pw.println(); 11448 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11449 pw.print(" total, non-act at "); 11450 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11451 pw.print(", non-svc at "); 11452 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11453 pw.println("):"); 11454 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11455 needSep = true; 11456 } 11457 11458 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11459 11460 pw.println(); 11461 pw.println(" mHomeProcess: " + mHomeProcess); 11462 pw.println(" mPreviousProcess: " + mPreviousProcess); 11463 if (mHeavyWeightProcess != null) { 11464 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11465 } 11466 11467 return true; 11468 } 11469 11470 /** 11471 * There are three ways to call this: 11472 * - no provider specified: dump all the providers 11473 * - a flattened component name that matched an existing provider was specified as the 11474 * first arg: dump that one provider 11475 * - the first arg isn't the flattened component name of an existing provider: 11476 * dump all providers whose component contains the first arg as a substring 11477 */ 11478 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11479 int opti, boolean dumpAll) { 11480 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11481 } 11482 11483 static class ItemMatcher { 11484 ArrayList<ComponentName> components; 11485 ArrayList<String> strings; 11486 ArrayList<Integer> objects; 11487 boolean all; 11488 11489 ItemMatcher() { 11490 all = true; 11491 } 11492 11493 void build(String name) { 11494 ComponentName componentName = ComponentName.unflattenFromString(name); 11495 if (componentName != null) { 11496 if (components == null) { 11497 components = new ArrayList<ComponentName>(); 11498 } 11499 components.add(componentName); 11500 all = false; 11501 } else { 11502 int objectId = 0; 11503 // Not a '/' separated full component name; maybe an object ID? 11504 try { 11505 objectId = Integer.parseInt(name, 16); 11506 if (objects == null) { 11507 objects = new ArrayList<Integer>(); 11508 } 11509 objects.add(objectId); 11510 all = false; 11511 } catch (RuntimeException e) { 11512 // Not an integer; just do string match. 11513 if (strings == null) { 11514 strings = new ArrayList<String>(); 11515 } 11516 strings.add(name); 11517 all = false; 11518 } 11519 } 11520 } 11521 11522 int build(String[] args, int opti) { 11523 for (; opti<args.length; opti++) { 11524 String name = args[opti]; 11525 if ("--".equals(name)) { 11526 return opti+1; 11527 } 11528 build(name); 11529 } 11530 return opti; 11531 } 11532 11533 boolean match(Object object, ComponentName comp) { 11534 if (all) { 11535 return true; 11536 } 11537 if (components != null) { 11538 for (int i=0; i<components.size(); i++) { 11539 if (components.get(i).equals(comp)) { 11540 return true; 11541 } 11542 } 11543 } 11544 if (objects != null) { 11545 for (int i=0; i<objects.size(); i++) { 11546 if (System.identityHashCode(object) == objects.get(i)) { 11547 return true; 11548 } 11549 } 11550 } 11551 if (strings != null) { 11552 String flat = comp.flattenToString(); 11553 for (int i=0; i<strings.size(); i++) { 11554 if (flat.contains(strings.get(i))) { 11555 return true; 11556 } 11557 } 11558 } 11559 return false; 11560 } 11561 } 11562 11563 /** 11564 * There are three things that cmd can be: 11565 * - a flattened component name that matches an existing activity 11566 * - the cmd arg isn't the flattened component name of an existing activity: 11567 * dump all activity whose component contains the cmd as a substring 11568 * - A hex number of the ActivityRecord object instance. 11569 */ 11570 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11571 int opti, boolean dumpAll) { 11572 ArrayList<ActivityRecord> activities; 11573 11574 synchronized (this) { 11575 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11576 } 11577 11578 if (activities.size() <= 0) { 11579 return false; 11580 } 11581 11582 String[] newArgs = new String[args.length - opti]; 11583 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11584 11585 TaskRecord lastTask = null; 11586 boolean needSep = false; 11587 for (int i=activities.size()-1; i>=0; i--) { 11588 ActivityRecord r = activities.get(i); 11589 if (needSep) { 11590 pw.println(); 11591 } 11592 needSep = true; 11593 synchronized (this) { 11594 if (lastTask != r.task) { 11595 lastTask = r.task; 11596 pw.print("TASK "); pw.print(lastTask.affinity); 11597 pw.print(" id="); pw.println(lastTask.taskId); 11598 if (dumpAll) { 11599 lastTask.dump(pw, " "); 11600 } 11601 } 11602 } 11603 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11604 } 11605 return true; 11606 } 11607 11608 /** 11609 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11610 * there is a thread associated with the activity. 11611 */ 11612 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11613 final ActivityRecord r, String[] args, boolean dumpAll) { 11614 String innerPrefix = prefix + " "; 11615 synchronized (this) { 11616 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11617 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11618 pw.print(" pid="); 11619 if (r.app != null) pw.println(r.app.pid); 11620 else pw.println("(not running)"); 11621 if (dumpAll) { 11622 r.dump(pw, innerPrefix); 11623 } 11624 } 11625 if (r.app != null && r.app.thread != null) { 11626 // flush anything that is already in the PrintWriter since the thread is going 11627 // to write to the file descriptor directly 11628 pw.flush(); 11629 try { 11630 TransferPipe tp = new TransferPipe(); 11631 try { 11632 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11633 r.appToken, innerPrefix, args); 11634 tp.go(fd); 11635 } finally { 11636 tp.kill(); 11637 } 11638 } catch (IOException e) { 11639 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11640 } catch (RemoteException e) { 11641 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11642 } 11643 } 11644 } 11645 11646 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11647 int opti, boolean dumpAll, String dumpPackage) { 11648 boolean needSep = false; 11649 boolean onlyHistory = false; 11650 boolean printedAnything = false; 11651 11652 if ("history".equals(dumpPackage)) { 11653 if (opti < args.length && "-s".equals(args[opti])) { 11654 dumpAll = false; 11655 } 11656 onlyHistory = true; 11657 dumpPackage = null; 11658 } 11659 11660 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11661 if (!onlyHistory && dumpAll) { 11662 if (mRegisteredReceivers.size() > 0) { 11663 boolean printed = false; 11664 Iterator it = mRegisteredReceivers.values().iterator(); 11665 while (it.hasNext()) { 11666 ReceiverList r = (ReceiverList)it.next(); 11667 if (dumpPackage != null && (r.app == null || 11668 !dumpPackage.equals(r.app.info.packageName))) { 11669 continue; 11670 } 11671 if (!printed) { 11672 pw.println(" Registered Receivers:"); 11673 needSep = true; 11674 printed = true; 11675 printedAnything = true; 11676 } 11677 pw.print(" * "); pw.println(r); 11678 r.dump(pw, " "); 11679 } 11680 } 11681 11682 if (mReceiverResolver.dump(pw, needSep ? 11683 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11684 " ", dumpPackage, false)) { 11685 needSep = true; 11686 printedAnything = true; 11687 } 11688 } 11689 11690 for (BroadcastQueue q : mBroadcastQueues) { 11691 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11692 printedAnything |= needSep; 11693 } 11694 11695 needSep = true; 11696 11697 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11698 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11699 if (needSep) { 11700 pw.println(); 11701 } 11702 needSep = true; 11703 printedAnything = true; 11704 pw.print(" Sticky broadcasts for user "); 11705 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11706 StringBuilder sb = new StringBuilder(128); 11707 for (Map.Entry<String, ArrayList<Intent>> ent 11708 : mStickyBroadcasts.valueAt(user).entrySet()) { 11709 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11710 if (dumpAll) { 11711 pw.println(":"); 11712 ArrayList<Intent> intents = ent.getValue(); 11713 final int N = intents.size(); 11714 for (int i=0; i<N; i++) { 11715 sb.setLength(0); 11716 sb.append(" Intent: "); 11717 intents.get(i).toShortString(sb, false, true, false, false); 11718 pw.println(sb.toString()); 11719 Bundle bundle = intents.get(i).getExtras(); 11720 if (bundle != null) { 11721 pw.print(" "); 11722 pw.println(bundle.toString()); 11723 } 11724 } 11725 } else { 11726 pw.println(""); 11727 } 11728 } 11729 } 11730 } 11731 11732 if (!onlyHistory && dumpAll) { 11733 pw.println(); 11734 for (BroadcastQueue queue : mBroadcastQueues) { 11735 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11736 + queue.mBroadcastsScheduled); 11737 } 11738 pw.println(" mHandler:"); 11739 mHandler.dump(new PrintWriterPrinter(pw), " "); 11740 needSep = true; 11741 printedAnything = true; 11742 } 11743 11744 if (!printedAnything) { 11745 pw.println(" (nothing)"); 11746 } 11747 } 11748 11749 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11750 int opti, boolean dumpAll, String dumpPackage) { 11751 boolean needSep; 11752 boolean printedAnything = false; 11753 11754 ItemMatcher matcher = new ItemMatcher(); 11755 matcher.build(args, opti); 11756 11757 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11758 11759 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11760 printedAnything |= needSep; 11761 11762 if (mLaunchingProviders.size() > 0) { 11763 boolean printed = false; 11764 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11765 ContentProviderRecord r = mLaunchingProviders.get(i); 11766 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11767 continue; 11768 } 11769 if (!printed) { 11770 if (needSep) pw.println(); 11771 needSep = true; 11772 pw.println(" Launching content providers:"); 11773 printed = true; 11774 printedAnything = true; 11775 } 11776 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11777 pw.println(r); 11778 } 11779 } 11780 11781 if (mGrantedUriPermissions.size() > 0) { 11782 boolean printed = false; 11783 int dumpUid = -2; 11784 if (dumpPackage != null) { 11785 try { 11786 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11787 } catch (NameNotFoundException e) { 11788 dumpUid = -1; 11789 } 11790 } 11791 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11792 int uid = mGrantedUriPermissions.keyAt(i); 11793 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11794 continue; 11795 } 11796 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11797 if (!printed) { 11798 if (needSep) pw.println(); 11799 needSep = true; 11800 pw.println(" Granted Uri Permissions:"); 11801 printed = true; 11802 printedAnything = true; 11803 } 11804 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11805 for (UriPermission perm : perms.values()) { 11806 pw.print(" "); pw.println(perm); 11807 if (dumpAll) { 11808 perm.dump(pw, " "); 11809 } 11810 } 11811 } 11812 } 11813 11814 if (!printedAnything) { 11815 pw.println(" (nothing)"); 11816 } 11817 } 11818 11819 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11820 int opti, boolean dumpAll, String dumpPackage) { 11821 boolean printed = false; 11822 11823 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11824 11825 if (mIntentSenderRecords.size() > 0) { 11826 Iterator<WeakReference<PendingIntentRecord>> it 11827 = mIntentSenderRecords.values().iterator(); 11828 while (it.hasNext()) { 11829 WeakReference<PendingIntentRecord> ref = it.next(); 11830 PendingIntentRecord rec = ref != null ? ref.get(): null; 11831 if (dumpPackage != null && (rec == null 11832 || !dumpPackage.equals(rec.key.packageName))) { 11833 continue; 11834 } 11835 printed = true; 11836 if (rec != null) { 11837 pw.print(" * "); pw.println(rec); 11838 if (dumpAll) { 11839 rec.dump(pw, " "); 11840 } 11841 } else { 11842 pw.print(" * "); pw.println(ref); 11843 } 11844 } 11845 } 11846 11847 if (!printed) { 11848 pw.println(" (nothing)"); 11849 } 11850 } 11851 11852 private static final int dumpProcessList(PrintWriter pw, 11853 ActivityManagerService service, List list, 11854 String prefix, String normalLabel, String persistentLabel, 11855 String dumpPackage) { 11856 int numPers = 0; 11857 final int N = list.size()-1; 11858 for (int i=N; i>=0; i--) { 11859 ProcessRecord r = (ProcessRecord)list.get(i); 11860 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11861 continue; 11862 } 11863 pw.println(String.format("%s%s #%2d: %s", 11864 prefix, (r.persistent ? persistentLabel : normalLabel), 11865 i, r.toString())); 11866 if (r.persistent) { 11867 numPers++; 11868 } 11869 } 11870 return numPers; 11871 } 11872 11873 private static final boolean dumpProcessOomList(PrintWriter pw, 11874 ActivityManagerService service, List<ProcessRecord> origList, 11875 String prefix, String normalLabel, String persistentLabel, 11876 boolean inclDetails, String dumpPackage) { 11877 11878 ArrayList<Pair<ProcessRecord, Integer>> list 11879 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11880 for (int i=0; i<origList.size(); i++) { 11881 ProcessRecord r = origList.get(i); 11882 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11883 continue; 11884 } 11885 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11886 } 11887 11888 if (list.size() <= 0) { 11889 return false; 11890 } 11891 11892 Comparator<Pair<ProcessRecord, Integer>> comparator 11893 = new Comparator<Pair<ProcessRecord, Integer>>() { 11894 @Override 11895 public int compare(Pair<ProcessRecord, Integer> object1, 11896 Pair<ProcessRecord, Integer> object2) { 11897 if (object1.first.setAdj != object2.first.setAdj) { 11898 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11899 } 11900 if (object1.second.intValue() != object2.second.intValue()) { 11901 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11902 } 11903 return 0; 11904 } 11905 }; 11906 11907 Collections.sort(list, comparator); 11908 11909 final long curRealtime = SystemClock.elapsedRealtime(); 11910 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11911 final long curUptime = SystemClock.uptimeMillis(); 11912 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11913 11914 for (int i=list.size()-1; i>=0; i--) { 11915 ProcessRecord r = list.get(i).first; 11916 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11917 char schedGroup; 11918 switch (r.setSchedGroup) { 11919 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11920 schedGroup = 'B'; 11921 break; 11922 case Process.THREAD_GROUP_DEFAULT: 11923 schedGroup = 'F'; 11924 break; 11925 default: 11926 schedGroup = '?'; 11927 break; 11928 } 11929 char foreground; 11930 if (r.foregroundActivities) { 11931 foreground = 'A'; 11932 } else if (r.foregroundServices) { 11933 foreground = 'S'; 11934 } else { 11935 foreground = ' '; 11936 } 11937 String procState = ProcessList.makeProcStateString(r.curProcState); 11938 pw.print(prefix); 11939 pw.print(r.persistent ? persistentLabel : normalLabel); 11940 pw.print(" #"); 11941 int num = (origList.size()-1)-list.get(i).second; 11942 if (num < 10) pw.print(' '); 11943 pw.print(num); 11944 pw.print(": "); 11945 pw.print(oomAdj); 11946 pw.print(' '); 11947 pw.print(schedGroup); 11948 pw.print('/'); 11949 pw.print(foreground); 11950 pw.print('/'); 11951 pw.print(procState); 11952 pw.print(" trm:"); 11953 if (r.trimMemoryLevel < 10) pw.print(' '); 11954 pw.print(r.trimMemoryLevel); 11955 pw.print(' '); 11956 pw.print(r.toShortString()); 11957 pw.print(" ("); 11958 pw.print(r.adjType); 11959 pw.println(')'); 11960 if (r.adjSource != null || r.adjTarget != null) { 11961 pw.print(prefix); 11962 pw.print(" "); 11963 if (r.adjTarget instanceof ComponentName) { 11964 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11965 } else if (r.adjTarget != null) { 11966 pw.print(r.adjTarget.toString()); 11967 } else { 11968 pw.print("{null}"); 11969 } 11970 pw.print("<="); 11971 if (r.adjSource instanceof ProcessRecord) { 11972 pw.print("Proc{"); 11973 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11974 pw.println("}"); 11975 } else if (r.adjSource != null) { 11976 pw.println(r.adjSource.toString()); 11977 } else { 11978 pw.println("{null}"); 11979 } 11980 } 11981 if (inclDetails) { 11982 pw.print(prefix); 11983 pw.print(" "); 11984 pw.print("oom: max="); pw.print(r.maxAdj); 11985 pw.print(" curRaw="); pw.print(r.curRawAdj); 11986 pw.print(" setRaw="); pw.print(r.setRawAdj); 11987 pw.print(" cur="); pw.print(r.curAdj); 11988 pw.print(" set="); pw.println(r.setAdj); 11989 pw.print(prefix); 11990 pw.print(" "); 11991 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11992 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11993 pw.print(" lastPss="); pw.print(r.lastPss); 11994 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11995 pw.print(prefix); 11996 pw.print(" "); 11997 pw.print("keeping="); pw.print(r.keeping); 11998 pw.print(" cached="); pw.print(r.cached); 11999 pw.print(" empty="); pw.print(r.empty); 12000 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12001 12002 if (!r.keeping) { 12003 if (r.lastWakeTime != 0) { 12004 long wtime; 12005 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12006 synchronized (stats) { 12007 wtime = stats.getProcessWakeTime(r.info.uid, 12008 r.pid, curRealtime); 12009 } 12010 long timeUsed = wtime - r.lastWakeTime; 12011 pw.print(prefix); 12012 pw.print(" "); 12013 pw.print("keep awake over "); 12014 TimeUtils.formatDuration(realtimeSince, pw); 12015 pw.print(" used "); 12016 TimeUtils.formatDuration(timeUsed, pw); 12017 pw.print(" ("); 12018 pw.print((timeUsed*100)/realtimeSince); 12019 pw.println("%)"); 12020 } 12021 if (r.lastCpuTime != 0) { 12022 long timeUsed = r.curCpuTime - r.lastCpuTime; 12023 pw.print(prefix); 12024 pw.print(" "); 12025 pw.print("run cpu over "); 12026 TimeUtils.formatDuration(uptimeSince, pw); 12027 pw.print(" used "); 12028 TimeUtils.formatDuration(timeUsed, pw); 12029 pw.print(" ("); 12030 pw.print((timeUsed*100)/uptimeSince); 12031 pw.println("%)"); 12032 } 12033 } 12034 } 12035 } 12036 return true; 12037 } 12038 12039 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12040 ArrayList<ProcessRecord> procs; 12041 synchronized (this) { 12042 if (args != null && args.length > start 12043 && args[start].charAt(0) != '-') { 12044 procs = new ArrayList<ProcessRecord>(); 12045 int pid = -1; 12046 try { 12047 pid = Integer.parseInt(args[start]); 12048 } catch (NumberFormatException e) { 12049 } 12050 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12051 ProcessRecord proc = mLruProcesses.get(i); 12052 if (proc.pid == pid) { 12053 procs.add(proc); 12054 } else if (proc.processName.equals(args[start])) { 12055 procs.add(proc); 12056 } 12057 } 12058 if (procs.size() <= 0) { 12059 return null; 12060 } 12061 } else { 12062 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12063 } 12064 } 12065 return procs; 12066 } 12067 12068 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12069 PrintWriter pw, String[] args) { 12070 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12071 if (procs == null) { 12072 pw.println("No process found for: " + args[0]); 12073 return; 12074 } 12075 12076 long uptime = SystemClock.uptimeMillis(); 12077 long realtime = SystemClock.elapsedRealtime(); 12078 pw.println("Applications Graphics Acceleration Info:"); 12079 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12080 12081 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12082 ProcessRecord r = procs.get(i); 12083 if (r.thread != null) { 12084 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12085 pw.flush(); 12086 try { 12087 TransferPipe tp = new TransferPipe(); 12088 try { 12089 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12090 tp.go(fd); 12091 } finally { 12092 tp.kill(); 12093 } 12094 } catch (IOException e) { 12095 pw.println("Failure while dumping the app: " + r); 12096 pw.flush(); 12097 } catch (RemoteException e) { 12098 pw.println("Got a RemoteException while dumping the app " + r); 12099 pw.flush(); 12100 } 12101 } 12102 } 12103 } 12104 12105 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12106 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12107 if (procs == null) { 12108 pw.println("No process found for: " + args[0]); 12109 return; 12110 } 12111 12112 pw.println("Applications Database Info:"); 12113 12114 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12115 ProcessRecord r = procs.get(i); 12116 if (r.thread != null) { 12117 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12118 pw.flush(); 12119 try { 12120 TransferPipe tp = new TransferPipe(); 12121 try { 12122 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12123 tp.go(fd); 12124 } finally { 12125 tp.kill(); 12126 } 12127 } catch (IOException e) { 12128 pw.println("Failure while dumping the app: " + r); 12129 pw.flush(); 12130 } catch (RemoteException e) { 12131 pw.println("Got a RemoteException while dumping the app " + r); 12132 pw.flush(); 12133 } 12134 } 12135 } 12136 } 12137 12138 final static class MemItem { 12139 final boolean isProc; 12140 final String label; 12141 final String shortLabel; 12142 final long pss; 12143 final int id; 12144 final boolean hasActivities; 12145 ArrayList<MemItem> subitems; 12146 12147 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12148 boolean _hasActivities) { 12149 isProc = true; 12150 label = _label; 12151 shortLabel = _shortLabel; 12152 pss = _pss; 12153 id = _id; 12154 hasActivities = _hasActivities; 12155 } 12156 12157 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12158 isProc = false; 12159 label = _label; 12160 shortLabel = _shortLabel; 12161 pss = _pss; 12162 id = _id; 12163 hasActivities = false; 12164 } 12165 } 12166 12167 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12168 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12169 if (sort && !isCompact) { 12170 Collections.sort(items, new Comparator<MemItem>() { 12171 @Override 12172 public int compare(MemItem lhs, MemItem rhs) { 12173 if (lhs.pss < rhs.pss) { 12174 return 1; 12175 } else if (lhs.pss > rhs.pss) { 12176 return -1; 12177 } 12178 return 0; 12179 } 12180 }); 12181 } 12182 12183 for (int i=0; i<items.size(); i++) { 12184 MemItem mi = items.get(i); 12185 if (!isCompact) { 12186 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12187 } else if (mi.isProc) { 12188 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12189 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12190 pw.println(mi.hasActivities ? ",a" : ",e"); 12191 } else { 12192 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12193 pw.println(mi.pss); 12194 } 12195 if (mi.subitems != null) { 12196 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12197 true, isCompact); 12198 } 12199 } 12200 } 12201 12202 // These are in KB. 12203 static final long[] DUMP_MEM_BUCKETS = new long[] { 12204 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12205 120*1024, 160*1024, 200*1024, 12206 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12207 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12208 }; 12209 12210 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12211 boolean stackLike) { 12212 int start = label.lastIndexOf('.'); 12213 if (start >= 0) start++; 12214 else start = 0; 12215 int end = label.length(); 12216 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12217 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12218 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12219 out.append(bucket); 12220 out.append(stackLike ? "MB." : "MB "); 12221 out.append(label, start, end); 12222 return; 12223 } 12224 } 12225 out.append(memKB/1024); 12226 out.append(stackLike ? "MB." : "MB "); 12227 out.append(label, start, end); 12228 } 12229 12230 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12231 ProcessList.NATIVE_ADJ, 12232 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12233 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12234 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12235 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12236 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12237 }; 12238 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12239 "Native", 12240 "System", "Persistent", "Foreground", 12241 "Visible", "Perceptible", 12242 "Heavy Weight", "Backup", 12243 "A Services", "Home", 12244 "Previous", "B Services", "Cached" 12245 }; 12246 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12247 "native", 12248 "sys", "pers", "fore", 12249 "vis", "percept", 12250 "heavy", "backup", 12251 "servicea", "home", 12252 "prev", "serviceb", "cached" 12253 }; 12254 12255 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12256 long realtime, boolean isCheckinRequest, boolean isCompact) { 12257 if (isCheckinRequest || isCompact) { 12258 // short checkin version 12259 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12260 } else { 12261 pw.println("Applications Memory Usage (kB):"); 12262 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12263 } 12264 } 12265 12266 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12267 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12268 boolean dumpDetails = false; 12269 boolean dumpFullDetails = false; 12270 boolean dumpDalvik = false; 12271 boolean oomOnly = false; 12272 boolean isCompact = false; 12273 boolean localOnly = false; 12274 12275 int opti = 0; 12276 while (opti < args.length) { 12277 String opt = args[opti]; 12278 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12279 break; 12280 } 12281 opti++; 12282 if ("-a".equals(opt)) { 12283 dumpDetails = true; 12284 dumpFullDetails = true; 12285 dumpDalvik = true; 12286 } else if ("-d".equals(opt)) { 12287 dumpDalvik = true; 12288 } else if ("-c".equals(opt)) { 12289 isCompact = true; 12290 } else if ("--oom".equals(opt)) { 12291 oomOnly = true; 12292 } else if ("--local".equals(opt)) { 12293 localOnly = true; 12294 } else if ("-h".equals(opt)) { 12295 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12296 pw.println(" -a: include all available information for each process."); 12297 pw.println(" -d: include dalvik details when dumping process details."); 12298 pw.println(" -c: dump in a compact machine-parseable representation."); 12299 pw.println(" --oom: only show processes organized by oom adj."); 12300 pw.println(" --local: only collect details locally, don't call process."); 12301 pw.println("If [process] is specified it can be the name or "); 12302 pw.println("pid of a specific process to dump."); 12303 return; 12304 } else { 12305 pw.println("Unknown argument: " + opt + "; use -h for help"); 12306 } 12307 } 12308 12309 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12310 long uptime = SystemClock.uptimeMillis(); 12311 long realtime = SystemClock.elapsedRealtime(); 12312 final long[] tmpLong = new long[1]; 12313 12314 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12315 if (procs == null) { 12316 // No Java processes. Maybe they want to print a native process. 12317 if (args != null && args.length > opti 12318 && args[opti].charAt(0) != '-') { 12319 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12320 = new ArrayList<ProcessCpuTracker.Stats>(); 12321 updateCpuStatsNow(); 12322 int findPid = -1; 12323 try { 12324 findPid = Integer.parseInt(args[opti]); 12325 } catch (NumberFormatException e) { 12326 } 12327 synchronized (mProcessCpuThread) { 12328 final int N = mProcessCpuTracker.countStats(); 12329 for (int i=0; i<N; i++) { 12330 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12331 if (st.pid == findPid || (st.baseName != null 12332 && st.baseName.equals(args[opti]))) { 12333 nativeProcs.add(st); 12334 } 12335 } 12336 } 12337 if (nativeProcs.size() > 0) { 12338 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12339 isCompact); 12340 Debug.MemoryInfo mi = null; 12341 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12342 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12343 final int pid = r.pid; 12344 if (!isCheckinRequest && dumpDetails) { 12345 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12346 } 12347 if (mi == null) { 12348 mi = new Debug.MemoryInfo(); 12349 } 12350 if (dumpDetails || (!brief && !oomOnly)) { 12351 Debug.getMemoryInfo(pid, mi); 12352 } else { 12353 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12354 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12355 } 12356 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12357 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12358 if (isCheckinRequest) { 12359 pw.println(); 12360 } 12361 } 12362 return; 12363 } 12364 } 12365 pw.println("No process found for: " + args[opti]); 12366 return; 12367 } 12368 12369 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12370 dumpDetails = true; 12371 } 12372 12373 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12374 12375 String[] innerArgs = new String[args.length-opti]; 12376 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12377 12378 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12379 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12380 long nativePss=0, dalvikPss=0, otherPss=0; 12381 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12382 12383 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12384 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12385 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12386 12387 long totalPss = 0; 12388 long cachedPss = 0; 12389 12390 Debug.MemoryInfo mi = null; 12391 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12392 final ProcessRecord r = procs.get(i); 12393 final IApplicationThread thread; 12394 final int pid; 12395 final int oomAdj; 12396 final boolean hasActivities; 12397 synchronized (this) { 12398 thread = r.thread; 12399 pid = r.pid; 12400 oomAdj = r.getSetAdjWithServices(); 12401 hasActivities = r.activities.size() > 0; 12402 } 12403 if (thread != null) { 12404 if (!isCheckinRequest && dumpDetails) { 12405 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12406 } 12407 if (mi == null) { 12408 mi = new Debug.MemoryInfo(); 12409 } 12410 if (dumpDetails || (!brief && !oomOnly)) { 12411 Debug.getMemoryInfo(pid, mi); 12412 } else { 12413 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12414 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12415 } 12416 if (dumpDetails) { 12417 if (localOnly) { 12418 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12419 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12420 if (isCheckinRequest) { 12421 pw.println(); 12422 } 12423 } else { 12424 try { 12425 pw.flush(); 12426 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12427 dumpDalvik, innerArgs); 12428 } catch (RemoteException e) { 12429 if (!isCheckinRequest) { 12430 pw.println("Got RemoteException!"); 12431 pw.flush(); 12432 } 12433 } 12434 } 12435 } 12436 12437 final long myTotalPss = mi.getTotalPss(); 12438 final long myTotalUss = mi.getTotalUss(); 12439 12440 synchronized (this) { 12441 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12442 // Record this for posterity if the process has been stable. 12443 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12444 } 12445 } 12446 12447 if (!isCheckinRequest && mi != null) { 12448 totalPss += myTotalPss; 12449 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12450 (hasActivities ? " / activities)" : ")"), 12451 r.processName, myTotalPss, pid, hasActivities); 12452 procMems.add(pssItem); 12453 procMemsMap.put(pid, pssItem); 12454 12455 nativePss += mi.nativePss; 12456 dalvikPss += mi.dalvikPss; 12457 otherPss += mi.otherPss; 12458 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12459 long mem = mi.getOtherPss(j); 12460 miscPss[j] += mem; 12461 otherPss -= mem; 12462 } 12463 12464 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12465 cachedPss += myTotalPss; 12466 } 12467 12468 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12469 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12470 || oomIndex == (oomPss.length-1)) { 12471 oomPss[oomIndex] += myTotalPss; 12472 if (oomProcs[oomIndex] == null) { 12473 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12474 } 12475 oomProcs[oomIndex].add(pssItem); 12476 break; 12477 } 12478 } 12479 } 12480 } 12481 } 12482 12483 if (!isCheckinRequest && procs.size() > 1) { 12484 // If we are showing aggregations, also look for native processes to 12485 // include so that our aggregations are more accurate. 12486 updateCpuStatsNow(); 12487 synchronized (mProcessCpuThread) { 12488 final int N = mProcessCpuTracker.countStats(); 12489 for (int i=0; i<N; i++) { 12490 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12491 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12492 if (mi == null) { 12493 mi = new Debug.MemoryInfo(); 12494 } 12495 if (!brief && !oomOnly) { 12496 Debug.getMemoryInfo(st.pid, mi); 12497 } else { 12498 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12499 mi.nativePrivateDirty = (int)tmpLong[0]; 12500 } 12501 12502 final long myTotalPss = mi.getTotalPss(); 12503 totalPss += myTotalPss; 12504 12505 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12506 st.name, myTotalPss, st.pid, false); 12507 procMems.add(pssItem); 12508 12509 nativePss += mi.nativePss; 12510 dalvikPss += mi.dalvikPss; 12511 otherPss += mi.otherPss; 12512 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12513 long mem = mi.getOtherPss(j); 12514 miscPss[j] += mem; 12515 otherPss -= mem; 12516 } 12517 oomPss[0] += myTotalPss; 12518 if (oomProcs[0] == null) { 12519 oomProcs[0] = new ArrayList<MemItem>(); 12520 } 12521 oomProcs[0].add(pssItem); 12522 } 12523 } 12524 } 12525 12526 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12527 12528 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12529 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12530 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12531 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12532 String label = Debug.MemoryInfo.getOtherLabel(j); 12533 catMems.add(new MemItem(label, label, miscPss[j], j)); 12534 } 12535 12536 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12537 for (int j=0; j<oomPss.length; j++) { 12538 if (oomPss[j] != 0) { 12539 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12540 : DUMP_MEM_OOM_LABEL[j]; 12541 MemItem item = new MemItem(label, label, oomPss[j], 12542 DUMP_MEM_OOM_ADJ[j]); 12543 item.subitems = oomProcs[j]; 12544 oomMems.add(item); 12545 } 12546 } 12547 12548 if (!brief && !oomOnly && !isCompact) { 12549 pw.println(); 12550 pw.println("Total PSS by process:"); 12551 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12552 pw.println(); 12553 } 12554 if (!isCompact) { 12555 pw.println("Total PSS by OOM adjustment:"); 12556 } 12557 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12558 if (!brief && !oomOnly) { 12559 PrintWriter out = categoryPw != null ? categoryPw : pw; 12560 if (!isCompact) { 12561 out.println(); 12562 out.println("Total PSS by category:"); 12563 } 12564 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12565 } 12566 if (!isCompact) { 12567 pw.println(); 12568 } 12569 MemInfoReader memInfo = new MemInfoReader(); 12570 memInfo.readMemInfo(); 12571 if (!brief) { 12572 if (!isCompact) { 12573 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12574 pw.print(" kB (status "); 12575 switch (mLastMemoryLevel) { 12576 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12577 pw.println("normal)"); 12578 break; 12579 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12580 pw.println("moderate)"); 12581 break; 12582 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12583 pw.println("low)"); 12584 break; 12585 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12586 pw.println("critical)"); 12587 break; 12588 default: 12589 pw.print(mLastMemoryLevel); 12590 pw.println(")"); 12591 break; 12592 } 12593 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12594 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12595 pw.print(cachedPss); pw.print(" cached pss + "); 12596 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12597 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12598 } else { 12599 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12600 pw.print(cachedPss + memInfo.getCachedSizeKb() 12601 + memInfo.getFreeSizeKb()); pw.print(","); 12602 pw.println(totalPss - cachedPss); 12603 } 12604 } 12605 if (!isCompact) { 12606 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12607 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12608 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12609 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12610 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12611 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12612 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12613 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12614 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12615 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12616 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12617 } 12618 if (!brief) { 12619 if (memInfo.getZramTotalSizeKb() != 0) { 12620 if (!isCompact) { 12621 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12622 pw.print(" kB physical used for "); 12623 pw.print(memInfo.getSwapTotalSizeKb() 12624 - memInfo.getSwapFreeSizeKb()); 12625 pw.print(" kB in swap ("); 12626 pw.print(memInfo.getSwapTotalSizeKb()); 12627 pw.println(" kB total swap)"); 12628 } else { 12629 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12630 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12631 pw.println(memInfo.getSwapFreeSizeKb()); 12632 } 12633 } 12634 final int[] SINGLE_LONG_FORMAT = new int[] { 12635 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12636 }; 12637 long[] longOut = new long[1]; 12638 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12639 SINGLE_LONG_FORMAT, null, longOut, null); 12640 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12641 longOut[0] = 0; 12642 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12643 SINGLE_LONG_FORMAT, null, longOut, null); 12644 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12645 longOut[0] = 0; 12646 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12647 SINGLE_LONG_FORMAT, null, longOut, null); 12648 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12649 longOut[0] = 0; 12650 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12651 SINGLE_LONG_FORMAT, null, longOut, null); 12652 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12653 if (!isCompact) { 12654 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12655 pw.print(" KSM: "); pw.print(sharing); 12656 pw.print(" kB saved from shared "); 12657 pw.print(shared); pw.println(" kB"); 12658 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12659 pw.print(voltile); pw.println(" kB volatile"); 12660 } 12661 pw.print(" Tuning: "); 12662 pw.print(ActivityManager.staticGetMemoryClass()); 12663 pw.print(" (large "); 12664 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12665 pw.print("), oom "); 12666 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12667 pw.print(" kB"); 12668 pw.print(", restore limit "); 12669 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12670 pw.print(" kB"); 12671 if (ActivityManager.isLowRamDeviceStatic()) { 12672 pw.print(" (low-ram)"); 12673 } 12674 if (ActivityManager.isHighEndGfx()) { 12675 pw.print(" (high-end-gfx)"); 12676 } 12677 pw.println(); 12678 } else { 12679 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12680 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12681 pw.println(voltile); 12682 pw.print("tuning,"); 12683 pw.print(ActivityManager.staticGetMemoryClass()); 12684 pw.print(','); 12685 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12686 pw.print(','); 12687 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12688 if (ActivityManager.isLowRamDeviceStatic()) { 12689 pw.print(",low-ram"); 12690 } 12691 if (ActivityManager.isHighEndGfx()) { 12692 pw.print(",high-end-gfx"); 12693 } 12694 pw.println(); 12695 } 12696 } 12697 } 12698 } 12699 12700 /** 12701 * Searches array of arguments for the specified string 12702 * @param args array of argument strings 12703 * @param value value to search for 12704 * @return true if the value is contained in the array 12705 */ 12706 private static boolean scanArgs(String[] args, String value) { 12707 if (args != null) { 12708 for (String arg : args) { 12709 if (value.equals(arg)) { 12710 return true; 12711 } 12712 } 12713 } 12714 return false; 12715 } 12716 12717 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12718 ContentProviderRecord cpr, boolean always) { 12719 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12720 12721 if (!inLaunching || always) { 12722 synchronized (cpr) { 12723 cpr.launchingApp = null; 12724 cpr.notifyAll(); 12725 } 12726 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12727 String names[] = cpr.info.authority.split(";"); 12728 for (int j = 0; j < names.length; j++) { 12729 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12730 } 12731 } 12732 12733 for (int i=0; i<cpr.connections.size(); i++) { 12734 ContentProviderConnection conn = cpr.connections.get(i); 12735 if (conn.waiting) { 12736 // If this connection is waiting for the provider, then we don't 12737 // need to mess with its process unless we are always removing 12738 // or for some reason the provider is not currently launching. 12739 if (inLaunching && !always) { 12740 continue; 12741 } 12742 } 12743 ProcessRecord capp = conn.client; 12744 conn.dead = true; 12745 if (conn.stableCount > 0) { 12746 if (!capp.persistent && capp.thread != null 12747 && capp.pid != 0 12748 && capp.pid != MY_PID) { 12749 killUnneededProcessLocked(capp, "depends on provider " 12750 + cpr.name.flattenToShortString() 12751 + " in dying proc " + (proc != null ? proc.processName : "??")); 12752 } 12753 } else if (capp.thread != null && conn.provider.provider != null) { 12754 try { 12755 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12756 } catch (RemoteException e) { 12757 } 12758 // In the protocol here, we don't expect the client to correctly 12759 // clean up this connection, we'll just remove it. 12760 cpr.connections.remove(i); 12761 conn.client.conProviders.remove(conn); 12762 } 12763 } 12764 12765 if (inLaunching && always) { 12766 mLaunchingProviders.remove(cpr); 12767 } 12768 return inLaunching; 12769 } 12770 12771 /** 12772 * Main code for cleaning up a process when it has gone away. This is 12773 * called both as a result of the process dying, or directly when stopping 12774 * a process when running in single process mode. 12775 */ 12776 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12777 boolean restarting, boolean allowRestart, int index) { 12778 if (index >= 0) { 12779 removeLruProcessLocked(app); 12780 ProcessList.remove(app.pid); 12781 } 12782 12783 mProcessesToGc.remove(app); 12784 mPendingPssProcesses.remove(app); 12785 12786 // Dismiss any open dialogs. 12787 if (app.crashDialog != null && !app.forceCrashReport) { 12788 app.crashDialog.dismiss(); 12789 app.crashDialog = null; 12790 } 12791 if (app.anrDialog != null) { 12792 app.anrDialog.dismiss(); 12793 app.anrDialog = null; 12794 } 12795 if (app.waitDialog != null) { 12796 app.waitDialog.dismiss(); 12797 app.waitDialog = null; 12798 } 12799 12800 app.crashing = false; 12801 app.notResponding = false; 12802 12803 app.resetPackageList(mProcessStats); 12804 app.unlinkDeathRecipient(); 12805 app.makeInactive(mProcessStats); 12806 app.forcingToForeground = null; 12807 updateProcessForegroundLocked(app, false, false); 12808 app.foregroundActivities = false; 12809 app.hasShownUi = false; 12810 app.treatLikeActivity = false; 12811 app.hasAboveClient = false; 12812 app.hasClientActivities = false; 12813 12814 mServices.killServicesLocked(app, allowRestart); 12815 12816 boolean restart = false; 12817 12818 // Remove published content providers. 12819 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12820 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12821 final boolean always = app.bad || !allowRestart; 12822 if (removeDyingProviderLocked(app, cpr, always) || always) { 12823 // We left the provider in the launching list, need to 12824 // restart it. 12825 restart = true; 12826 } 12827 12828 cpr.provider = null; 12829 cpr.proc = null; 12830 } 12831 app.pubProviders.clear(); 12832 12833 // Take care of any launching providers waiting for this process. 12834 if (checkAppInLaunchingProvidersLocked(app, false)) { 12835 restart = true; 12836 } 12837 12838 // Unregister from connected content providers. 12839 if (!app.conProviders.isEmpty()) { 12840 for (int i=0; i<app.conProviders.size(); i++) { 12841 ContentProviderConnection conn = app.conProviders.get(i); 12842 conn.provider.connections.remove(conn); 12843 } 12844 app.conProviders.clear(); 12845 } 12846 12847 // At this point there may be remaining entries in mLaunchingProviders 12848 // where we were the only one waiting, so they are no longer of use. 12849 // Look for these and clean up if found. 12850 // XXX Commented out for now. Trying to figure out a way to reproduce 12851 // the actual situation to identify what is actually going on. 12852 if (false) { 12853 for (int i=0; i<mLaunchingProviders.size(); i++) { 12854 ContentProviderRecord cpr = (ContentProviderRecord) 12855 mLaunchingProviders.get(i); 12856 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12857 synchronized (cpr) { 12858 cpr.launchingApp = null; 12859 cpr.notifyAll(); 12860 } 12861 } 12862 } 12863 } 12864 12865 skipCurrentReceiverLocked(app); 12866 12867 // Unregister any receivers. 12868 for (int i=app.receivers.size()-1; i>=0; i--) { 12869 removeReceiverLocked(app.receivers.valueAt(i)); 12870 } 12871 app.receivers.clear(); 12872 12873 // If the app is undergoing backup, tell the backup manager about it 12874 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12875 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12876 + mBackupTarget.appInfo + " died during backup"); 12877 try { 12878 IBackupManager bm = IBackupManager.Stub.asInterface( 12879 ServiceManager.getService(Context.BACKUP_SERVICE)); 12880 bm.agentDisconnected(app.info.packageName); 12881 } catch (RemoteException e) { 12882 // can't happen; backup manager is local 12883 } 12884 } 12885 12886 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12887 ProcessChangeItem item = mPendingProcessChanges.get(i); 12888 if (item.pid == app.pid) { 12889 mPendingProcessChanges.remove(i); 12890 mAvailProcessChanges.add(item); 12891 } 12892 } 12893 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12894 12895 // If the caller is restarting this app, then leave it in its 12896 // current lists and let the caller take care of it. 12897 if (restarting) { 12898 return; 12899 } 12900 12901 if (!app.persistent || app.isolated) { 12902 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12903 "Removing non-persistent process during cleanup: " + app); 12904 mProcessNames.remove(app.processName, app.uid); 12905 mIsolatedProcesses.remove(app.uid); 12906 if (mHeavyWeightProcess == app) { 12907 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12908 mHeavyWeightProcess.userId, 0)); 12909 mHeavyWeightProcess = null; 12910 } 12911 } else if (!app.removed) { 12912 // This app is persistent, so we need to keep its record around. 12913 // If it is not already on the pending app list, add it there 12914 // and start a new process for it. 12915 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12916 mPersistentStartingProcesses.add(app); 12917 restart = true; 12918 } 12919 } 12920 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12921 "Clean-up removing on hold: " + app); 12922 mProcessesOnHold.remove(app); 12923 12924 if (app == mHomeProcess) { 12925 mHomeProcess = null; 12926 } 12927 if (app == mPreviousProcess) { 12928 mPreviousProcess = null; 12929 } 12930 12931 if (restart && !app.isolated) { 12932 // We have components that still need to be running in the 12933 // process, so re-launch it. 12934 mProcessNames.put(app.processName, app.uid, app); 12935 startProcessLocked(app, "restart", app.processName); 12936 } else if (app.pid > 0 && app.pid != MY_PID) { 12937 // Goodbye! 12938 boolean removed; 12939 synchronized (mPidsSelfLocked) { 12940 mPidsSelfLocked.remove(app.pid); 12941 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12942 } 12943 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12944 app.processName, app.info.uid); 12945 if (app.isolated) { 12946 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12947 } 12948 app.setPid(0); 12949 } 12950 } 12951 12952 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12953 // Look through the content providers we are waiting to have launched, 12954 // and if any run in this process then either schedule a restart of 12955 // the process or kill the client waiting for it if this process has 12956 // gone bad. 12957 int NL = mLaunchingProviders.size(); 12958 boolean restart = false; 12959 for (int i=0; i<NL; i++) { 12960 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12961 if (cpr.launchingApp == app) { 12962 if (!alwaysBad && !app.bad) { 12963 restart = true; 12964 } else { 12965 removeDyingProviderLocked(app, cpr, true); 12966 // cpr should have been removed from mLaunchingProviders 12967 NL = mLaunchingProviders.size(); 12968 i--; 12969 } 12970 } 12971 } 12972 return restart; 12973 } 12974 12975 // ========================================================= 12976 // SERVICES 12977 // ========================================================= 12978 12979 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12980 int flags) { 12981 enforceNotIsolatedCaller("getServices"); 12982 synchronized (this) { 12983 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12984 } 12985 } 12986 12987 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12988 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12989 synchronized (this) { 12990 return mServices.getRunningServiceControlPanelLocked(name); 12991 } 12992 } 12993 12994 public ComponentName startService(IApplicationThread caller, Intent service, 12995 String resolvedType, int userId) { 12996 enforceNotIsolatedCaller("startService"); 12997 // Refuse possible leaked file descriptors 12998 if (service != null && service.hasFileDescriptors() == true) { 12999 throw new IllegalArgumentException("File descriptors passed in Intent"); 13000 } 13001 13002 if (DEBUG_SERVICE) 13003 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13004 synchronized(this) { 13005 final int callingPid = Binder.getCallingPid(); 13006 final int callingUid = Binder.getCallingUid(); 13007 final long origId = Binder.clearCallingIdentity(); 13008 ComponentName res = mServices.startServiceLocked(caller, service, 13009 resolvedType, callingPid, callingUid, userId); 13010 Binder.restoreCallingIdentity(origId); 13011 return res; 13012 } 13013 } 13014 13015 ComponentName startServiceInPackage(int uid, 13016 Intent service, String resolvedType, int userId) { 13017 synchronized(this) { 13018 if (DEBUG_SERVICE) 13019 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13020 final long origId = Binder.clearCallingIdentity(); 13021 ComponentName res = mServices.startServiceLocked(null, service, 13022 resolvedType, -1, uid, userId); 13023 Binder.restoreCallingIdentity(origId); 13024 return res; 13025 } 13026 } 13027 13028 public int stopService(IApplicationThread caller, Intent service, 13029 String resolvedType, int userId) { 13030 enforceNotIsolatedCaller("stopService"); 13031 // Refuse possible leaked file descriptors 13032 if (service != null && service.hasFileDescriptors() == true) { 13033 throw new IllegalArgumentException("File descriptors passed in Intent"); 13034 } 13035 13036 synchronized(this) { 13037 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13038 } 13039 } 13040 13041 public IBinder peekService(Intent service, String resolvedType) { 13042 enforceNotIsolatedCaller("peekService"); 13043 // Refuse possible leaked file descriptors 13044 if (service != null && service.hasFileDescriptors() == true) { 13045 throw new IllegalArgumentException("File descriptors passed in Intent"); 13046 } 13047 synchronized(this) { 13048 return mServices.peekServiceLocked(service, resolvedType); 13049 } 13050 } 13051 13052 public boolean stopServiceToken(ComponentName className, IBinder token, 13053 int startId) { 13054 synchronized(this) { 13055 return mServices.stopServiceTokenLocked(className, token, startId); 13056 } 13057 } 13058 13059 public void setServiceForeground(ComponentName className, IBinder token, 13060 int id, Notification notification, boolean removeNotification) { 13061 synchronized(this) { 13062 mServices.setServiceForegroundLocked(className, token, id, notification, 13063 removeNotification); 13064 } 13065 } 13066 13067 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13068 boolean requireFull, String name, String callerPackage) { 13069 final int callingUserId = UserHandle.getUserId(callingUid); 13070 if (callingUserId != userId) { 13071 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13072 if ((requireFull || checkComponentPermission( 13073 android.Manifest.permission.INTERACT_ACROSS_USERS, 13074 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13075 && checkComponentPermission( 13076 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13077 callingPid, callingUid, -1, true) 13078 != PackageManager.PERMISSION_GRANTED) { 13079 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13080 // In this case, they would like to just execute as their 13081 // owner user instead of failing. 13082 userId = callingUserId; 13083 } else { 13084 StringBuilder builder = new StringBuilder(128); 13085 builder.append("Permission Denial: "); 13086 builder.append(name); 13087 if (callerPackage != null) { 13088 builder.append(" from "); 13089 builder.append(callerPackage); 13090 } 13091 builder.append(" asks to run as user "); 13092 builder.append(userId); 13093 builder.append(" but is calling from user "); 13094 builder.append(UserHandle.getUserId(callingUid)); 13095 builder.append("; this requires "); 13096 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13097 if (!requireFull) { 13098 builder.append(" or "); 13099 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13100 } 13101 String msg = builder.toString(); 13102 Slog.w(TAG, msg); 13103 throw new SecurityException(msg); 13104 } 13105 } 13106 } 13107 if (userId == UserHandle.USER_CURRENT 13108 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13109 // Note that we may be accessing this outside of a lock... 13110 // shouldn't be a big deal, if this is being called outside 13111 // of a locked context there is intrinsically a race with 13112 // the value the caller will receive and someone else changing it. 13113 userId = mCurrentUserId; 13114 } 13115 if (!allowAll && userId < 0) { 13116 throw new IllegalArgumentException( 13117 "Call does not support special user #" + userId); 13118 } 13119 } 13120 return userId; 13121 } 13122 13123 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13124 String className, int flags) { 13125 boolean result = false; 13126 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13127 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13128 if (ActivityManager.checkUidPermission( 13129 android.Manifest.permission.INTERACT_ACROSS_USERS, 13130 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13131 ComponentName comp = new ComponentName(aInfo.packageName, className); 13132 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13133 + " requests FLAG_SINGLE_USER, but app does not hold " 13134 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13135 Slog.w(TAG, msg); 13136 throw new SecurityException(msg); 13137 } 13138 result = true; 13139 } 13140 } else if (componentProcessName == aInfo.packageName) { 13141 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13142 } else if ("system".equals(componentProcessName)) { 13143 result = true; 13144 } 13145 if (DEBUG_MU) { 13146 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13147 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13148 } 13149 return result; 13150 } 13151 13152 public int bindService(IApplicationThread caller, IBinder token, 13153 Intent service, String resolvedType, 13154 IServiceConnection connection, int flags, int userId) { 13155 enforceNotIsolatedCaller("bindService"); 13156 // Refuse possible leaked file descriptors 13157 if (service != null && service.hasFileDescriptors() == true) { 13158 throw new IllegalArgumentException("File descriptors passed in Intent"); 13159 } 13160 13161 synchronized(this) { 13162 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13163 connection, flags, userId); 13164 } 13165 } 13166 13167 public boolean unbindService(IServiceConnection connection) { 13168 synchronized (this) { 13169 return mServices.unbindServiceLocked(connection); 13170 } 13171 } 13172 13173 public void publishService(IBinder token, Intent intent, IBinder service) { 13174 // Refuse possible leaked file descriptors 13175 if (intent != null && intent.hasFileDescriptors() == true) { 13176 throw new IllegalArgumentException("File descriptors passed in Intent"); 13177 } 13178 13179 synchronized(this) { 13180 if (!(token instanceof ServiceRecord)) { 13181 throw new IllegalArgumentException("Invalid service token"); 13182 } 13183 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13184 } 13185 } 13186 13187 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13188 // Refuse possible leaked file descriptors 13189 if (intent != null && intent.hasFileDescriptors() == true) { 13190 throw new IllegalArgumentException("File descriptors passed in Intent"); 13191 } 13192 13193 synchronized(this) { 13194 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13195 } 13196 } 13197 13198 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13199 synchronized(this) { 13200 if (!(token instanceof ServiceRecord)) { 13201 throw new IllegalArgumentException("Invalid service token"); 13202 } 13203 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13204 } 13205 } 13206 13207 // ========================================================= 13208 // BACKUP AND RESTORE 13209 // ========================================================= 13210 13211 // Cause the target app to be launched if necessary and its backup agent 13212 // instantiated. The backup agent will invoke backupAgentCreated() on the 13213 // activity manager to announce its creation. 13214 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13215 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13216 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13217 13218 synchronized(this) { 13219 // !!! TODO: currently no check here that we're already bound 13220 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13221 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13222 synchronized (stats) { 13223 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13224 } 13225 13226 // Backup agent is now in use, its package can't be stopped. 13227 try { 13228 AppGlobals.getPackageManager().setPackageStoppedState( 13229 app.packageName, false, UserHandle.getUserId(app.uid)); 13230 } catch (RemoteException e) { 13231 } catch (IllegalArgumentException e) { 13232 Slog.w(TAG, "Failed trying to unstop package " 13233 + app.packageName + ": " + e); 13234 } 13235 13236 BackupRecord r = new BackupRecord(ss, app, backupMode); 13237 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13238 ? new ComponentName(app.packageName, app.backupAgentName) 13239 : new ComponentName("android", "FullBackupAgent"); 13240 // startProcessLocked() returns existing proc's record if it's already running 13241 ProcessRecord proc = startProcessLocked(app.processName, app, 13242 false, 0, "backup", hostingName, false, false, false); 13243 if (proc == null) { 13244 Slog.e(TAG, "Unable to start backup agent process " + r); 13245 return false; 13246 } 13247 13248 r.app = proc; 13249 mBackupTarget = r; 13250 mBackupAppName = app.packageName; 13251 13252 // Try not to kill the process during backup 13253 updateOomAdjLocked(proc); 13254 13255 // If the process is already attached, schedule the creation of the backup agent now. 13256 // If it is not yet live, this will be done when it attaches to the framework. 13257 if (proc.thread != null) { 13258 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13259 try { 13260 proc.thread.scheduleCreateBackupAgent(app, 13261 compatibilityInfoForPackageLocked(app), backupMode); 13262 } catch (RemoteException e) { 13263 // Will time out on the backup manager side 13264 } 13265 } else { 13266 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13267 } 13268 // Invariants: at this point, the target app process exists and the application 13269 // is either already running or in the process of coming up. mBackupTarget and 13270 // mBackupAppName describe the app, so that when it binds back to the AM we 13271 // know that it's scheduled for a backup-agent operation. 13272 } 13273 13274 return true; 13275 } 13276 13277 @Override 13278 public void clearPendingBackup() { 13279 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13280 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13281 13282 synchronized (this) { 13283 mBackupTarget = null; 13284 mBackupAppName = null; 13285 } 13286 } 13287 13288 // A backup agent has just come up 13289 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13290 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13291 + " = " + agent); 13292 13293 synchronized(this) { 13294 if (!agentPackageName.equals(mBackupAppName)) { 13295 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13296 return; 13297 } 13298 } 13299 13300 long oldIdent = Binder.clearCallingIdentity(); 13301 try { 13302 IBackupManager bm = IBackupManager.Stub.asInterface( 13303 ServiceManager.getService(Context.BACKUP_SERVICE)); 13304 bm.agentConnected(agentPackageName, agent); 13305 } catch (RemoteException e) { 13306 // can't happen; the backup manager service is local 13307 } catch (Exception e) { 13308 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13309 e.printStackTrace(); 13310 } finally { 13311 Binder.restoreCallingIdentity(oldIdent); 13312 } 13313 } 13314 13315 // done with this agent 13316 public void unbindBackupAgent(ApplicationInfo appInfo) { 13317 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13318 if (appInfo == null) { 13319 Slog.w(TAG, "unbind backup agent for null app"); 13320 return; 13321 } 13322 13323 synchronized(this) { 13324 try { 13325 if (mBackupAppName == null) { 13326 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13327 return; 13328 } 13329 13330 if (!mBackupAppName.equals(appInfo.packageName)) { 13331 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13332 return; 13333 } 13334 13335 // Not backing this app up any more; reset its OOM adjustment 13336 final ProcessRecord proc = mBackupTarget.app; 13337 updateOomAdjLocked(proc); 13338 13339 // If the app crashed during backup, 'thread' will be null here 13340 if (proc.thread != null) { 13341 try { 13342 proc.thread.scheduleDestroyBackupAgent(appInfo, 13343 compatibilityInfoForPackageLocked(appInfo)); 13344 } catch (Exception e) { 13345 Slog.e(TAG, "Exception when unbinding backup agent:"); 13346 e.printStackTrace(); 13347 } 13348 } 13349 } finally { 13350 mBackupTarget = null; 13351 mBackupAppName = null; 13352 } 13353 } 13354 } 13355 // ========================================================= 13356 // BROADCASTS 13357 // ========================================================= 13358 13359 private final List getStickiesLocked(String action, IntentFilter filter, 13360 List cur, int userId) { 13361 final ContentResolver resolver = mContext.getContentResolver(); 13362 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13363 if (stickies == null) { 13364 return cur; 13365 } 13366 final ArrayList<Intent> list = stickies.get(action); 13367 if (list == null) { 13368 return cur; 13369 } 13370 int N = list.size(); 13371 for (int i=0; i<N; i++) { 13372 Intent intent = list.get(i); 13373 if (filter.match(resolver, intent, true, TAG) >= 0) { 13374 if (cur == null) { 13375 cur = new ArrayList<Intent>(); 13376 } 13377 cur.add(intent); 13378 } 13379 } 13380 return cur; 13381 } 13382 13383 boolean isPendingBroadcastProcessLocked(int pid) { 13384 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13385 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13386 } 13387 13388 void skipPendingBroadcastLocked(int pid) { 13389 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13390 for (BroadcastQueue queue : mBroadcastQueues) { 13391 queue.skipPendingBroadcastLocked(pid); 13392 } 13393 } 13394 13395 // The app just attached; send any pending broadcasts that it should receive 13396 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13397 boolean didSomething = false; 13398 for (BroadcastQueue queue : mBroadcastQueues) { 13399 didSomething |= queue.sendPendingBroadcastsLocked(app); 13400 } 13401 return didSomething; 13402 } 13403 13404 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13405 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13406 enforceNotIsolatedCaller("registerReceiver"); 13407 int callingUid; 13408 int callingPid; 13409 synchronized(this) { 13410 ProcessRecord callerApp = null; 13411 if (caller != null) { 13412 callerApp = getRecordForAppLocked(caller); 13413 if (callerApp == null) { 13414 throw new SecurityException( 13415 "Unable to find app for caller " + caller 13416 + " (pid=" + Binder.getCallingPid() 13417 + ") when registering receiver " + receiver); 13418 } 13419 if (callerApp.info.uid != Process.SYSTEM_UID && 13420 !callerApp.pkgList.containsKey(callerPackage) && 13421 !"android".equals(callerPackage)) { 13422 throw new SecurityException("Given caller package " + callerPackage 13423 + " is not running in process " + callerApp); 13424 } 13425 callingUid = callerApp.info.uid; 13426 callingPid = callerApp.pid; 13427 } else { 13428 callerPackage = null; 13429 callingUid = Binder.getCallingUid(); 13430 callingPid = Binder.getCallingPid(); 13431 } 13432 13433 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13434 true, true, "registerReceiver", callerPackage); 13435 13436 List allSticky = null; 13437 13438 // Look for any matching sticky broadcasts... 13439 Iterator actions = filter.actionsIterator(); 13440 if (actions != null) { 13441 while (actions.hasNext()) { 13442 String action = (String)actions.next(); 13443 allSticky = getStickiesLocked(action, filter, allSticky, 13444 UserHandle.USER_ALL); 13445 allSticky = getStickiesLocked(action, filter, allSticky, 13446 UserHandle.getUserId(callingUid)); 13447 } 13448 } else { 13449 allSticky = getStickiesLocked(null, filter, allSticky, 13450 UserHandle.USER_ALL); 13451 allSticky = getStickiesLocked(null, filter, allSticky, 13452 UserHandle.getUserId(callingUid)); 13453 } 13454 13455 // The first sticky in the list is returned directly back to 13456 // the client. 13457 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13458 13459 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13460 + ": " + sticky); 13461 13462 if (receiver == null) { 13463 return sticky; 13464 } 13465 13466 ReceiverList rl 13467 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13468 if (rl == null) { 13469 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13470 userId, receiver); 13471 if (rl.app != null) { 13472 rl.app.receivers.add(rl); 13473 } else { 13474 try { 13475 receiver.asBinder().linkToDeath(rl, 0); 13476 } catch (RemoteException e) { 13477 return sticky; 13478 } 13479 rl.linkedToDeath = true; 13480 } 13481 mRegisteredReceivers.put(receiver.asBinder(), rl); 13482 } else if (rl.uid != callingUid) { 13483 throw new IllegalArgumentException( 13484 "Receiver requested to register for uid " + callingUid 13485 + " was previously registered for uid " + rl.uid); 13486 } else if (rl.pid != callingPid) { 13487 throw new IllegalArgumentException( 13488 "Receiver requested to register for pid " + callingPid 13489 + " was previously registered for pid " + rl.pid); 13490 } else if (rl.userId != userId) { 13491 throw new IllegalArgumentException( 13492 "Receiver requested to register for user " + userId 13493 + " was previously registered for user " + rl.userId); 13494 } 13495 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13496 permission, callingUid, userId); 13497 rl.add(bf); 13498 if (!bf.debugCheck()) { 13499 Slog.w(TAG, "==> For Dynamic broadast"); 13500 } 13501 mReceiverResolver.addFilter(bf); 13502 13503 // Enqueue broadcasts for all existing stickies that match 13504 // this filter. 13505 if (allSticky != null) { 13506 ArrayList receivers = new ArrayList(); 13507 receivers.add(bf); 13508 13509 int N = allSticky.size(); 13510 for (int i=0; i<N; i++) { 13511 Intent intent = (Intent)allSticky.get(i); 13512 BroadcastQueue queue = broadcastQueueForIntent(intent); 13513 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13514 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13515 null, null, false, true, true, -1); 13516 queue.enqueueParallelBroadcastLocked(r); 13517 queue.scheduleBroadcastsLocked(); 13518 } 13519 } 13520 13521 return sticky; 13522 } 13523 } 13524 13525 public void unregisterReceiver(IIntentReceiver receiver) { 13526 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13527 13528 final long origId = Binder.clearCallingIdentity(); 13529 try { 13530 boolean doTrim = false; 13531 13532 synchronized(this) { 13533 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13534 if (rl != null) { 13535 if (rl.curBroadcast != null) { 13536 BroadcastRecord r = rl.curBroadcast; 13537 final boolean doNext = finishReceiverLocked( 13538 receiver.asBinder(), r.resultCode, r.resultData, 13539 r.resultExtras, r.resultAbort); 13540 if (doNext) { 13541 doTrim = true; 13542 r.queue.processNextBroadcast(false); 13543 } 13544 } 13545 13546 if (rl.app != null) { 13547 rl.app.receivers.remove(rl); 13548 } 13549 removeReceiverLocked(rl); 13550 if (rl.linkedToDeath) { 13551 rl.linkedToDeath = false; 13552 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13553 } 13554 } 13555 } 13556 13557 // If we actually concluded any broadcasts, we might now be able 13558 // to trim the recipients' apps from our working set 13559 if (doTrim) { 13560 trimApplications(); 13561 return; 13562 } 13563 13564 } finally { 13565 Binder.restoreCallingIdentity(origId); 13566 } 13567 } 13568 13569 void removeReceiverLocked(ReceiverList rl) { 13570 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13571 int N = rl.size(); 13572 for (int i=0; i<N; i++) { 13573 mReceiverResolver.removeFilter(rl.get(i)); 13574 } 13575 } 13576 13577 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13578 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13579 ProcessRecord r = mLruProcesses.get(i); 13580 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13581 try { 13582 r.thread.dispatchPackageBroadcast(cmd, packages); 13583 } catch (RemoteException ex) { 13584 } 13585 } 13586 } 13587 } 13588 13589 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13590 int[] users) { 13591 List<ResolveInfo> receivers = null; 13592 try { 13593 HashSet<ComponentName> singleUserReceivers = null; 13594 boolean scannedFirstReceivers = false; 13595 for (int user : users) { 13596 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13597 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13598 if (user != 0 && newReceivers != null) { 13599 // If this is not the primary user, we need to check for 13600 // any receivers that should be filtered out. 13601 for (int i=0; i<newReceivers.size(); i++) { 13602 ResolveInfo ri = newReceivers.get(i); 13603 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13604 newReceivers.remove(i); 13605 i--; 13606 } 13607 } 13608 } 13609 if (newReceivers != null && newReceivers.size() == 0) { 13610 newReceivers = null; 13611 } 13612 if (receivers == null) { 13613 receivers = newReceivers; 13614 } else if (newReceivers != null) { 13615 // We need to concatenate the additional receivers 13616 // found with what we have do far. This would be easy, 13617 // but we also need to de-dup any receivers that are 13618 // singleUser. 13619 if (!scannedFirstReceivers) { 13620 // Collect any single user receivers we had already retrieved. 13621 scannedFirstReceivers = true; 13622 for (int i=0; i<receivers.size(); i++) { 13623 ResolveInfo ri = receivers.get(i); 13624 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13625 ComponentName cn = new ComponentName( 13626 ri.activityInfo.packageName, ri.activityInfo.name); 13627 if (singleUserReceivers == null) { 13628 singleUserReceivers = new HashSet<ComponentName>(); 13629 } 13630 singleUserReceivers.add(cn); 13631 } 13632 } 13633 } 13634 // Add the new results to the existing results, tracking 13635 // and de-dupping single user receivers. 13636 for (int i=0; i<newReceivers.size(); i++) { 13637 ResolveInfo ri = newReceivers.get(i); 13638 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13639 ComponentName cn = new ComponentName( 13640 ri.activityInfo.packageName, ri.activityInfo.name); 13641 if (singleUserReceivers == null) { 13642 singleUserReceivers = new HashSet<ComponentName>(); 13643 } 13644 if (!singleUserReceivers.contains(cn)) { 13645 singleUserReceivers.add(cn); 13646 receivers.add(ri); 13647 } 13648 } else { 13649 receivers.add(ri); 13650 } 13651 } 13652 } 13653 } 13654 } catch (RemoteException ex) { 13655 // pm is in same process, this will never happen. 13656 } 13657 return receivers; 13658 } 13659 13660 private final int broadcastIntentLocked(ProcessRecord callerApp, 13661 String callerPackage, Intent intent, String resolvedType, 13662 IIntentReceiver resultTo, int resultCode, String resultData, 13663 Bundle map, String requiredPermission, int appOp, 13664 boolean ordered, boolean sticky, int callingPid, int callingUid, 13665 int userId) { 13666 intent = new Intent(intent); 13667 13668 // By default broadcasts do not go to stopped apps. 13669 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13670 13671 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13672 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13673 + " ordered=" + ordered + " userid=" + userId); 13674 if ((resultTo != null) && !ordered) { 13675 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13676 } 13677 13678 userId = handleIncomingUser(callingPid, callingUid, userId, 13679 true, false, "broadcast", callerPackage); 13680 13681 // Make sure that the user who is receiving this broadcast is started. 13682 // If not, we will just skip it. 13683 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13684 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13685 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13686 Slog.w(TAG, "Skipping broadcast of " + intent 13687 + ": user " + userId + " is stopped"); 13688 return ActivityManager.BROADCAST_SUCCESS; 13689 } 13690 } 13691 13692 /* 13693 * Prevent non-system code (defined here to be non-persistent 13694 * processes) from sending protected broadcasts. 13695 */ 13696 int callingAppId = UserHandle.getAppId(callingUid); 13697 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13698 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13699 callingUid == 0) { 13700 // Always okay. 13701 } else if (callerApp == null || !callerApp.persistent) { 13702 try { 13703 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13704 intent.getAction())) { 13705 String msg = "Permission Denial: not allowed to send broadcast " 13706 + intent.getAction() + " from pid=" 13707 + callingPid + ", uid=" + callingUid; 13708 Slog.w(TAG, msg); 13709 throw new SecurityException(msg); 13710 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13711 // Special case for compatibility: we don't want apps to send this, 13712 // but historically it has not been protected and apps may be using it 13713 // to poke their own app widget. So, instead of making it protected, 13714 // just limit it to the caller. 13715 if (callerApp == null) { 13716 String msg = "Permission Denial: not allowed to send broadcast " 13717 + intent.getAction() + " from unknown caller."; 13718 Slog.w(TAG, msg); 13719 throw new SecurityException(msg); 13720 } else if (intent.getComponent() != null) { 13721 // They are good enough to send to an explicit component... verify 13722 // it is being sent to the calling app. 13723 if (!intent.getComponent().getPackageName().equals( 13724 callerApp.info.packageName)) { 13725 String msg = "Permission Denial: not allowed to send broadcast " 13726 + intent.getAction() + " to " 13727 + intent.getComponent().getPackageName() + " from " 13728 + callerApp.info.packageName; 13729 Slog.w(TAG, msg); 13730 throw new SecurityException(msg); 13731 } 13732 } else { 13733 // Limit broadcast to their own package. 13734 intent.setPackage(callerApp.info.packageName); 13735 } 13736 } 13737 } catch (RemoteException e) { 13738 Slog.w(TAG, "Remote exception", e); 13739 return ActivityManager.BROADCAST_SUCCESS; 13740 } 13741 } 13742 13743 // Handle special intents: if this broadcast is from the package 13744 // manager about a package being removed, we need to remove all of 13745 // its activities from the history stack. 13746 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13747 intent.getAction()); 13748 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13749 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13750 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13751 || uidRemoved) { 13752 if (checkComponentPermission( 13753 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13754 callingPid, callingUid, -1, true) 13755 == PackageManager.PERMISSION_GRANTED) { 13756 if (uidRemoved) { 13757 final Bundle intentExtras = intent.getExtras(); 13758 final int uid = intentExtras != null 13759 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13760 if (uid >= 0) { 13761 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13762 synchronized (bs) { 13763 bs.removeUidStatsLocked(uid); 13764 } 13765 mAppOpsService.uidRemoved(uid); 13766 } 13767 } else { 13768 // If resources are unavailable just force stop all 13769 // those packages and flush the attribute cache as well. 13770 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13771 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13772 if (list != null && (list.length > 0)) { 13773 for (String pkg : list) { 13774 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13775 "storage unmount"); 13776 } 13777 sendPackageBroadcastLocked( 13778 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13779 } 13780 } else { 13781 Uri data = intent.getData(); 13782 String ssp; 13783 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13784 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13785 intent.getAction()); 13786 boolean fullUninstall = removed && 13787 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13788 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13789 forceStopPackageLocked(ssp, UserHandle.getAppId( 13790 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13791 false, fullUninstall, userId, 13792 removed ? "pkg removed" : "pkg changed"); 13793 } 13794 if (removed) { 13795 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13796 new String[] {ssp}, userId); 13797 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13798 mAppOpsService.packageRemoved( 13799 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13800 13801 // Remove all permissions granted from/to this package 13802 removeUriPermissionsForPackageLocked(ssp, userId, true); 13803 } 13804 } 13805 } 13806 } 13807 } 13808 } else { 13809 String msg = "Permission Denial: " + intent.getAction() 13810 + " broadcast from " + callerPackage + " (pid=" + callingPid 13811 + ", uid=" + callingUid + ")" 13812 + " requires " 13813 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13814 Slog.w(TAG, msg); 13815 throw new SecurityException(msg); 13816 } 13817 13818 // Special case for adding a package: by default turn on compatibility 13819 // mode. 13820 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13821 Uri data = intent.getData(); 13822 String ssp; 13823 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13824 mCompatModePackages.handlePackageAddedLocked(ssp, 13825 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13826 } 13827 } 13828 13829 /* 13830 * If this is the time zone changed action, queue up a message that will reset the timezone 13831 * of all currently running processes. This message will get queued up before the broadcast 13832 * happens. 13833 */ 13834 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13835 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13836 } 13837 13838 /* 13839 * If the user set the time, let all running processes know. 13840 */ 13841 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13842 final int is24Hour = intent.getBooleanExtra( 13843 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13844 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13845 } 13846 13847 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13848 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13849 } 13850 13851 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13852 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13853 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13854 } 13855 13856 // Add to the sticky list if requested. 13857 if (sticky) { 13858 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13859 callingPid, callingUid) 13860 != PackageManager.PERMISSION_GRANTED) { 13861 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13862 + callingPid + ", uid=" + callingUid 13863 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13864 Slog.w(TAG, msg); 13865 throw new SecurityException(msg); 13866 } 13867 if (requiredPermission != null) { 13868 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13869 + " and enforce permission " + requiredPermission); 13870 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13871 } 13872 if (intent.getComponent() != null) { 13873 throw new SecurityException( 13874 "Sticky broadcasts can't target a specific component"); 13875 } 13876 // We use userId directly here, since the "all" target is maintained 13877 // as a separate set of sticky broadcasts. 13878 if (userId != UserHandle.USER_ALL) { 13879 // But first, if this is not a broadcast to all users, then 13880 // make sure it doesn't conflict with an existing broadcast to 13881 // all users. 13882 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13883 UserHandle.USER_ALL); 13884 if (stickies != null) { 13885 ArrayList<Intent> list = stickies.get(intent.getAction()); 13886 if (list != null) { 13887 int N = list.size(); 13888 int i; 13889 for (i=0; i<N; i++) { 13890 if (intent.filterEquals(list.get(i))) { 13891 throw new IllegalArgumentException( 13892 "Sticky broadcast " + intent + " for user " 13893 + userId + " conflicts with existing global broadcast"); 13894 } 13895 } 13896 } 13897 } 13898 } 13899 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13900 if (stickies == null) { 13901 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13902 mStickyBroadcasts.put(userId, stickies); 13903 } 13904 ArrayList<Intent> list = stickies.get(intent.getAction()); 13905 if (list == null) { 13906 list = new ArrayList<Intent>(); 13907 stickies.put(intent.getAction(), list); 13908 } 13909 int N = list.size(); 13910 int i; 13911 for (i=0; i<N; i++) { 13912 if (intent.filterEquals(list.get(i))) { 13913 // This sticky already exists, replace it. 13914 list.set(i, new Intent(intent)); 13915 break; 13916 } 13917 } 13918 if (i >= N) { 13919 list.add(new Intent(intent)); 13920 } 13921 } 13922 13923 int[] users; 13924 if (userId == UserHandle.USER_ALL) { 13925 // Caller wants broadcast to go to all started users. 13926 users = mStartedUserArray; 13927 } else { 13928 // Caller wants broadcast to go to one specific user. 13929 users = new int[] {userId}; 13930 } 13931 13932 // Figure out who all will receive this broadcast. 13933 List receivers = null; 13934 List<BroadcastFilter> registeredReceivers = null; 13935 // Need to resolve the intent to interested receivers... 13936 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13937 == 0) { 13938 receivers = collectReceiverComponents(intent, resolvedType, users); 13939 } 13940 if (intent.getComponent() == null) { 13941 registeredReceivers = mReceiverResolver.queryIntent(intent, 13942 resolvedType, false, userId); 13943 } 13944 13945 final boolean replacePending = 13946 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13947 13948 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13949 + " replacePending=" + replacePending); 13950 13951 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13952 if (!ordered && NR > 0) { 13953 // If we are not serializing this broadcast, then send the 13954 // registered receivers separately so they don't wait for the 13955 // components to be launched. 13956 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13957 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13958 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13959 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13960 ordered, sticky, false, userId); 13961 if (DEBUG_BROADCAST) Slog.v( 13962 TAG, "Enqueueing parallel broadcast " + r); 13963 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13964 if (!replaced) { 13965 queue.enqueueParallelBroadcastLocked(r); 13966 queue.scheduleBroadcastsLocked(); 13967 } 13968 registeredReceivers = null; 13969 NR = 0; 13970 } 13971 13972 // Merge into one list. 13973 int ir = 0; 13974 if (receivers != null) { 13975 // A special case for PACKAGE_ADDED: do not allow the package 13976 // being added to see this broadcast. This prevents them from 13977 // using this as a back door to get run as soon as they are 13978 // installed. Maybe in the future we want to have a special install 13979 // broadcast or such for apps, but we'd like to deliberately make 13980 // this decision. 13981 String skipPackages[] = null; 13982 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13983 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13984 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13985 Uri data = intent.getData(); 13986 if (data != null) { 13987 String pkgName = data.getSchemeSpecificPart(); 13988 if (pkgName != null) { 13989 skipPackages = new String[] { pkgName }; 13990 } 13991 } 13992 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13993 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13994 } 13995 if (skipPackages != null && (skipPackages.length > 0)) { 13996 for (String skipPackage : skipPackages) { 13997 if (skipPackage != null) { 13998 int NT = receivers.size(); 13999 for (int it=0; it<NT; it++) { 14000 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14001 if (curt.activityInfo.packageName.equals(skipPackage)) { 14002 receivers.remove(it); 14003 it--; 14004 NT--; 14005 } 14006 } 14007 } 14008 } 14009 } 14010 14011 int NT = receivers != null ? receivers.size() : 0; 14012 int it = 0; 14013 ResolveInfo curt = null; 14014 BroadcastFilter curr = null; 14015 while (it < NT && ir < NR) { 14016 if (curt == null) { 14017 curt = (ResolveInfo)receivers.get(it); 14018 } 14019 if (curr == null) { 14020 curr = registeredReceivers.get(ir); 14021 } 14022 if (curr.getPriority() >= curt.priority) { 14023 // Insert this broadcast record into the final list. 14024 receivers.add(it, curr); 14025 ir++; 14026 curr = null; 14027 it++; 14028 NT++; 14029 } else { 14030 // Skip to the next ResolveInfo in the final list. 14031 it++; 14032 curt = null; 14033 } 14034 } 14035 } 14036 while (ir < NR) { 14037 if (receivers == null) { 14038 receivers = new ArrayList(); 14039 } 14040 receivers.add(registeredReceivers.get(ir)); 14041 ir++; 14042 } 14043 14044 if ((receivers != null && receivers.size() > 0) 14045 || resultTo != null) { 14046 BroadcastQueue queue = broadcastQueueForIntent(intent); 14047 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14048 callerPackage, callingPid, callingUid, resolvedType, 14049 requiredPermission, appOp, receivers, resultTo, resultCode, 14050 resultData, map, ordered, sticky, false, userId); 14051 if (DEBUG_BROADCAST) Slog.v( 14052 TAG, "Enqueueing ordered broadcast " + r 14053 + ": prev had " + queue.mOrderedBroadcasts.size()); 14054 if (DEBUG_BROADCAST) { 14055 int seq = r.intent.getIntExtra("seq", -1); 14056 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14057 } 14058 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14059 if (!replaced) { 14060 queue.enqueueOrderedBroadcastLocked(r); 14061 queue.scheduleBroadcastsLocked(); 14062 } 14063 } 14064 14065 return ActivityManager.BROADCAST_SUCCESS; 14066 } 14067 14068 final Intent verifyBroadcastLocked(Intent intent) { 14069 // Refuse possible leaked file descriptors 14070 if (intent != null && intent.hasFileDescriptors() == true) { 14071 throw new IllegalArgumentException("File descriptors passed in Intent"); 14072 } 14073 14074 int flags = intent.getFlags(); 14075 14076 if (!mProcessesReady) { 14077 // if the caller really truly claims to know what they're doing, go 14078 // ahead and allow the broadcast without launching any receivers 14079 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14080 intent = new Intent(intent); 14081 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14082 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14083 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14084 + " before boot completion"); 14085 throw new IllegalStateException("Cannot broadcast before boot completed"); 14086 } 14087 } 14088 14089 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14090 throw new IllegalArgumentException( 14091 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14092 } 14093 14094 return intent; 14095 } 14096 14097 public final int broadcastIntent(IApplicationThread caller, 14098 Intent intent, String resolvedType, IIntentReceiver resultTo, 14099 int resultCode, String resultData, Bundle map, 14100 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14101 enforceNotIsolatedCaller("broadcastIntent"); 14102 synchronized(this) { 14103 intent = verifyBroadcastLocked(intent); 14104 14105 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14106 final int callingPid = Binder.getCallingPid(); 14107 final int callingUid = Binder.getCallingUid(); 14108 final long origId = Binder.clearCallingIdentity(); 14109 int res = broadcastIntentLocked(callerApp, 14110 callerApp != null ? callerApp.info.packageName : null, 14111 intent, resolvedType, resultTo, 14112 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14113 callingPid, callingUid, userId); 14114 Binder.restoreCallingIdentity(origId); 14115 return res; 14116 } 14117 } 14118 14119 int broadcastIntentInPackage(String packageName, int uid, 14120 Intent intent, String resolvedType, IIntentReceiver resultTo, 14121 int resultCode, String resultData, Bundle map, 14122 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14123 synchronized(this) { 14124 intent = verifyBroadcastLocked(intent); 14125 14126 final long origId = Binder.clearCallingIdentity(); 14127 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14128 resultTo, resultCode, resultData, map, requiredPermission, 14129 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14130 Binder.restoreCallingIdentity(origId); 14131 return res; 14132 } 14133 } 14134 14135 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14136 // Refuse possible leaked file descriptors 14137 if (intent != null && intent.hasFileDescriptors() == true) { 14138 throw new IllegalArgumentException("File descriptors passed in Intent"); 14139 } 14140 14141 userId = handleIncomingUser(Binder.getCallingPid(), 14142 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14143 14144 synchronized(this) { 14145 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14146 != PackageManager.PERMISSION_GRANTED) { 14147 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14148 + Binder.getCallingPid() 14149 + ", uid=" + Binder.getCallingUid() 14150 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14151 Slog.w(TAG, msg); 14152 throw new SecurityException(msg); 14153 } 14154 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14155 if (stickies != null) { 14156 ArrayList<Intent> list = stickies.get(intent.getAction()); 14157 if (list != null) { 14158 int N = list.size(); 14159 int i; 14160 for (i=0; i<N; i++) { 14161 if (intent.filterEquals(list.get(i))) { 14162 list.remove(i); 14163 break; 14164 } 14165 } 14166 if (list.size() <= 0) { 14167 stickies.remove(intent.getAction()); 14168 } 14169 } 14170 if (stickies.size() <= 0) { 14171 mStickyBroadcasts.remove(userId); 14172 } 14173 } 14174 } 14175 } 14176 14177 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14178 String resultData, Bundle resultExtras, boolean resultAbort) { 14179 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14180 if (r == null) { 14181 Slog.w(TAG, "finishReceiver called but not found on queue"); 14182 return false; 14183 } 14184 14185 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14186 } 14187 14188 void backgroundServicesFinishedLocked(int userId) { 14189 for (BroadcastQueue queue : mBroadcastQueues) { 14190 queue.backgroundServicesFinishedLocked(userId); 14191 } 14192 } 14193 14194 public void finishReceiver(IBinder who, int resultCode, String resultData, 14195 Bundle resultExtras, boolean resultAbort) { 14196 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14197 14198 // Refuse possible leaked file descriptors 14199 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14200 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14201 } 14202 14203 final long origId = Binder.clearCallingIdentity(); 14204 try { 14205 boolean doNext = false; 14206 BroadcastRecord r; 14207 14208 synchronized(this) { 14209 r = broadcastRecordForReceiverLocked(who); 14210 if (r != null) { 14211 doNext = r.queue.finishReceiverLocked(r, resultCode, 14212 resultData, resultExtras, resultAbort, true); 14213 } 14214 } 14215 14216 if (doNext) { 14217 r.queue.processNextBroadcast(false); 14218 } 14219 trimApplications(); 14220 } finally { 14221 Binder.restoreCallingIdentity(origId); 14222 } 14223 } 14224 14225 // ========================================================= 14226 // INSTRUMENTATION 14227 // ========================================================= 14228 14229 public boolean startInstrumentation(ComponentName className, 14230 String profileFile, int flags, Bundle arguments, 14231 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14232 int userId) { 14233 enforceNotIsolatedCaller("startInstrumentation"); 14234 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14235 userId, false, true, "startInstrumentation", null); 14236 // Refuse possible leaked file descriptors 14237 if (arguments != null && arguments.hasFileDescriptors()) { 14238 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14239 } 14240 14241 synchronized(this) { 14242 InstrumentationInfo ii = null; 14243 ApplicationInfo ai = null; 14244 try { 14245 ii = mContext.getPackageManager().getInstrumentationInfo( 14246 className, STOCK_PM_FLAGS); 14247 ai = AppGlobals.getPackageManager().getApplicationInfo( 14248 ii.targetPackage, STOCK_PM_FLAGS, userId); 14249 } catch (PackageManager.NameNotFoundException e) { 14250 } catch (RemoteException e) { 14251 } 14252 if (ii == null) { 14253 reportStartInstrumentationFailure(watcher, className, 14254 "Unable to find instrumentation info for: " + className); 14255 return false; 14256 } 14257 if (ai == null) { 14258 reportStartInstrumentationFailure(watcher, className, 14259 "Unable to find instrumentation target package: " + ii.targetPackage); 14260 return false; 14261 } 14262 14263 int match = mContext.getPackageManager().checkSignatures( 14264 ii.targetPackage, ii.packageName); 14265 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14266 String msg = "Permission Denial: starting instrumentation " 14267 + className + " from pid=" 14268 + Binder.getCallingPid() 14269 + ", uid=" + Binder.getCallingPid() 14270 + " not allowed because package " + ii.packageName 14271 + " does not have a signature matching the target " 14272 + ii.targetPackage; 14273 reportStartInstrumentationFailure(watcher, className, msg); 14274 throw new SecurityException(msg); 14275 } 14276 14277 final long origId = Binder.clearCallingIdentity(); 14278 // Instrumentation can kill and relaunch even persistent processes 14279 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14280 "start instr"); 14281 ProcessRecord app = addAppLocked(ai, false); 14282 app.instrumentationClass = className; 14283 app.instrumentationInfo = ai; 14284 app.instrumentationProfileFile = profileFile; 14285 app.instrumentationArguments = arguments; 14286 app.instrumentationWatcher = watcher; 14287 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14288 app.instrumentationResultClass = className; 14289 Binder.restoreCallingIdentity(origId); 14290 } 14291 14292 return true; 14293 } 14294 14295 /** 14296 * Report errors that occur while attempting to start Instrumentation. Always writes the 14297 * error to the logs, but if somebody is watching, send the report there too. This enables 14298 * the "am" command to report errors with more information. 14299 * 14300 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14301 * @param cn The component name of the instrumentation. 14302 * @param report The error report. 14303 */ 14304 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14305 ComponentName cn, String report) { 14306 Slog.w(TAG, report); 14307 try { 14308 if (watcher != null) { 14309 Bundle results = new Bundle(); 14310 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14311 results.putString("Error", report); 14312 watcher.instrumentationStatus(cn, -1, results); 14313 } 14314 } catch (RemoteException e) { 14315 Slog.w(TAG, e); 14316 } 14317 } 14318 14319 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14320 if (app.instrumentationWatcher != null) { 14321 try { 14322 // NOTE: IInstrumentationWatcher *must* be oneway here 14323 app.instrumentationWatcher.instrumentationFinished( 14324 app.instrumentationClass, 14325 resultCode, 14326 results); 14327 } catch (RemoteException e) { 14328 } 14329 } 14330 if (app.instrumentationUiAutomationConnection != null) { 14331 try { 14332 app.instrumentationUiAutomationConnection.shutdown(); 14333 } catch (RemoteException re) { 14334 /* ignore */ 14335 } 14336 // Only a UiAutomation can set this flag and now that 14337 // it is finished we make sure it is reset to its default. 14338 mUserIsMonkey = false; 14339 } 14340 app.instrumentationWatcher = null; 14341 app.instrumentationUiAutomationConnection = null; 14342 app.instrumentationClass = null; 14343 app.instrumentationInfo = null; 14344 app.instrumentationProfileFile = null; 14345 app.instrumentationArguments = null; 14346 14347 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14348 "finished inst"); 14349 } 14350 14351 public void finishInstrumentation(IApplicationThread target, 14352 int resultCode, Bundle results) { 14353 int userId = UserHandle.getCallingUserId(); 14354 // Refuse possible leaked file descriptors 14355 if (results != null && results.hasFileDescriptors()) { 14356 throw new IllegalArgumentException("File descriptors passed in Intent"); 14357 } 14358 14359 synchronized(this) { 14360 ProcessRecord app = getRecordForAppLocked(target); 14361 if (app == null) { 14362 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14363 return; 14364 } 14365 final long origId = Binder.clearCallingIdentity(); 14366 finishInstrumentationLocked(app, resultCode, results); 14367 Binder.restoreCallingIdentity(origId); 14368 } 14369 } 14370 14371 // ========================================================= 14372 // CONFIGURATION 14373 // ========================================================= 14374 14375 public ConfigurationInfo getDeviceConfigurationInfo() { 14376 ConfigurationInfo config = new ConfigurationInfo(); 14377 synchronized (this) { 14378 config.reqTouchScreen = mConfiguration.touchscreen; 14379 config.reqKeyboardType = mConfiguration.keyboard; 14380 config.reqNavigation = mConfiguration.navigation; 14381 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14382 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14383 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14384 } 14385 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14386 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14387 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14388 } 14389 config.reqGlEsVersion = GL_ES_VERSION; 14390 } 14391 return config; 14392 } 14393 14394 ActivityStack getFocusedStack() { 14395 return mStackSupervisor.getFocusedStack(); 14396 } 14397 14398 public Configuration getConfiguration() { 14399 Configuration ci; 14400 synchronized(this) { 14401 ci = new Configuration(mConfiguration); 14402 } 14403 return ci; 14404 } 14405 14406 public void updatePersistentConfiguration(Configuration values) { 14407 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14408 "updateConfiguration()"); 14409 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14410 "updateConfiguration()"); 14411 if (values == null) { 14412 throw new NullPointerException("Configuration must not be null"); 14413 } 14414 14415 synchronized(this) { 14416 final long origId = Binder.clearCallingIdentity(); 14417 updateConfigurationLocked(values, null, true, false); 14418 Binder.restoreCallingIdentity(origId); 14419 } 14420 } 14421 14422 public void updateConfiguration(Configuration values) { 14423 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14424 "updateConfiguration()"); 14425 14426 synchronized(this) { 14427 if (values == null && mWindowManager != null) { 14428 // sentinel: fetch the current configuration from the window manager 14429 values = mWindowManager.computeNewConfiguration(); 14430 } 14431 14432 if (mWindowManager != null) { 14433 mProcessList.applyDisplaySize(mWindowManager); 14434 } 14435 14436 final long origId = Binder.clearCallingIdentity(); 14437 if (values != null) { 14438 Settings.System.clearConfiguration(values); 14439 } 14440 updateConfigurationLocked(values, null, false, false); 14441 Binder.restoreCallingIdentity(origId); 14442 } 14443 } 14444 14445 /** 14446 * Do either or both things: (1) change the current configuration, and (2) 14447 * make sure the given activity is running with the (now) current 14448 * configuration. Returns true if the activity has been left running, or 14449 * false if <var>starting</var> is being destroyed to match the new 14450 * configuration. 14451 * @param persistent TODO 14452 */ 14453 boolean updateConfigurationLocked(Configuration values, 14454 ActivityRecord starting, boolean persistent, boolean initLocale) { 14455 int changes = 0; 14456 14457 if (values != null) { 14458 Configuration newConfig = new Configuration(mConfiguration); 14459 changes = newConfig.updateFrom(values); 14460 if (changes != 0) { 14461 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14462 Slog.i(TAG, "Updating configuration to: " + values); 14463 } 14464 14465 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14466 14467 if (values.locale != null && !initLocale) { 14468 saveLocaleLocked(values.locale, 14469 !values.locale.equals(mConfiguration.locale), 14470 values.userSetLocale); 14471 } 14472 14473 mConfigurationSeq++; 14474 if (mConfigurationSeq <= 0) { 14475 mConfigurationSeq = 1; 14476 } 14477 newConfig.seq = mConfigurationSeq; 14478 mConfiguration = newConfig; 14479 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14480 mUsageStatsService.noteStartConfig(newConfig); 14481 14482 final Configuration configCopy = new Configuration(mConfiguration); 14483 14484 // TODO: If our config changes, should we auto dismiss any currently 14485 // showing dialogs? 14486 mShowDialogs = shouldShowDialogs(newConfig); 14487 14488 AttributeCache ac = AttributeCache.instance(); 14489 if (ac != null) { 14490 ac.updateConfiguration(configCopy); 14491 } 14492 14493 // Make sure all resources in our process are updated 14494 // right now, so that anyone who is going to retrieve 14495 // resource values after we return will be sure to get 14496 // the new ones. This is especially important during 14497 // boot, where the first config change needs to guarantee 14498 // all resources have that config before following boot 14499 // code is executed. 14500 mSystemThread.applyConfigurationToResources(configCopy); 14501 14502 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14503 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14504 msg.obj = new Configuration(configCopy); 14505 mHandler.sendMessage(msg); 14506 } 14507 14508 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14509 ProcessRecord app = mLruProcesses.get(i); 14510 try { 14511 if (app.thread != null) { 14512 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14513 + app.processName + " new config " + mConfiguration); 14514 app.thread.scheduleConfigurationChanged(configCopy); 14515 } 14516 } catch (Exception e) { 14517 } 14518 } 14519 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14520 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14521 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14522 | Intent.FLAG_RECEIVER_FOREGROUND); 14523 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14524 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14525 Process.SYSTEM_UID, UserHandle.USER_ALL); 14526 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14527 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14528 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14529 broadcastIntentLocked(null, null, intent, 14530 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14531 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14532 } 14533 } 14534 } 14535 14536 boolean kept = true; 14537 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14538 // mainStack is null during startup. 14539 if (mainStack != null) { 14540 if (changes != 0 && starting == null) { 14541 // If the configuration changed, and the caller is not already 14542 // in the process of starting an activity, then find the top 14543 // activity to check if its configuration needs to change. 14544 starting = mainStack.topRunningActivityLocked(null); 14545 } 14546 14547 if (starting != null) { 14548 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14549 // And we need to make sure at this point that all other activities 14550 // are made visible with the correct configuration. 14551 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14552 } 14553 } 14554 14555 if (values != null && mWindowManager != null) { 14556 mWindowManager.setNewConfiguration(mConfiguration); 14557 } 14558 14559 return kept; 14560 } 14561 14562 /** 14563 * Decide based on the configuration whether we should shouw the ANR, 14564 * crash, etc dialogs. The idea is that if there is no affordnace to 14565 * press the on-screen buttons, we shouldn't show the dialog. 14566 * 14567 * A thought: SystemUI might also want to get told about this, the Power 14568 * dialog / global actions also might want different behaviors. 14569 */ 14570 private static final boolean shouldShowDialogs(Configuration config) { 14571 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14572 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14573 } 14574 14575 /** 14576 * Save the locale. You must be inside a synchronized (this) block. 14577 */ 14578 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14579 if(isDiff) { 14580 SystemProperties.set("user.language", l.getLanguage()); 14581 SystemProperties.set("user.region", l.getCountry()); 14582 } 14583 14584 if(isPersist) { 14585 SystemProperties.set("persist.sys.language", l.getLanguage()); 14586 SystemProperties.set("persist.sys.country", l.getCountry()); 14587 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14588 } 14589 } 14590 14591 @Override 14592 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14593 ActivityRecord srec = ActivityRecord.forToken(token); 14594 return srec != null && srec.task.affinity != null && 14595 srec.task.affinity.equals(destAffinity); 14596 } 14597 14598 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14599 Intent resultData) { 14600 14601 synchronized (this) { 14602 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14603 if (stack != null) { 14604 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14605 } 14606 return false; 14607 } 14608 } 14609 14610 public int getLaunchedFromUid(IBinder activityToken) { 14611 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14612 if (srec == null) { 14613 return -1; 14614 } 14615 return srec.launchedFromUid; 14616 } 14617 14618 public String getLaunchedFromPackage(IBinder activityToken) { 14619 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14620 if (srec == null) { 14621 return null; 14622 } 14623 return srec.launchedFromPackage; 14624 } 14625 14626 // ========================================================= 14627 // LIFETIME MANAGEMENT 14628 // ========================================================= 14629 14630 // Returns which broadcast queue the app is the current [or imminent] receiver 14631 // on, or 'null' if the app is not an active broadcast recipient. 14632 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14633 BroadcastRecord r = app.curReceiver; 14634 if (r != null) { 14635 return r.queue; 14636 } 14637 14638 // It's not the current receiver, but it might be starting up to become one 14639 synchronized (this) { 14640 for (BroadcastQueue queue : mBroadcastQueues) { 14641 r = queue.mPendingBroadcast; 14642 if (r != null && r.curApp == app) { 14643 // found it; report which queue it's in 14644 return queue; 14645 } 14646 } 14647 } 14648 14649 return null; 14650 } 14651 14652 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14653 boolean doingAll, long now) { 14654 if (mAdjSeq == app.adjSeq) { 14655 // This adjustment has already been computed. 14656 return app.curRawAdj; 14657 } 14658 14659 if (app.thread == null) { 14660 app.adjSeq = mAdjSeq; 14661 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14662 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14663 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14664 } 14665 14666 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14667 app.adjSource = null; 14668 app.adjTarget = null; 14669 app.empty = false; 14670 app.cached = false; 14671 14672 final int activitiesSize = app.activities.size(); 14673 14674 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14675 // The max adjustment doesn't allow this app to be anything 14676 // below foreground, so it is not worth doing work for it. 14677 app.adjType = "fixed"; 14678 app.adjSeq = mAdjSeq; 14679 app.curRawAdj = app.maxAdj; 14680 app.foregroundActivities = false; 14681 app.keeping = true; 14682 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14683 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14684 // System processes can do UI, and when they do we want to have 14685 // them trim their memory after the user leaves the UI. To 14686 // facilitate this, here we need to determine whether or not it 14687 // is currently showing UI. 14688 app.systemNoUi = true; 14689 if (app == TOP_APP) { 14690 app.systemNoUi = false; 14691 } else if (activitiesSize > 0) { 14692 for (int j = 0; j < activitiesSize; j++) { 14693 final ActivityRecord r = app.activities.get(j); 14694 if (r.visible) { 14695 app.systemNoUi = false; 14696 } 14697 } 14698 } 14699 if (!app.systemNoUi) { 14700 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14701 } 14702 return (app.curAdj=app.maxAdj); 14703 } 14704 14705 app.keeping = false; 14706 app.systemNoUi = false; 14707 14708 // Determine the importance of the process, starting with most 14709 // important to least, and assign an appropriate OOM adjustment. 14710 int adj; 14711 int schedGroup; 14712 int procState; 14713 boolean foregroundActivities = false; 14714 boolean interesting = false; 14715 BroadcastQueue queue; 14716 if (app == TOP_APP) { 14717 // The last app on the list is the foreground app. 14718 adj = ProcessList.FOREGROUND_APP_ADJ; 14719 schedGroup = Process.THREAD_GROUP_DEFAULT; 14720 app.adjType = "top-activity"; 14721 foregroundActivities = true; 14722 interesting = true; 14723 procState = ActivityManager.PROCESS_STATE_TOP; 14724 } else if (app.instrumentationClass != null) { 14725 // Don't want to kill running instrumentation. 14726 adj = ProcessList.FOREGROUND_APP_ADJ; 14727 schedGroup = Process.THREAD_GROUP_DEFAULT; 14728 app.adjType = "instrumentation"; 14729 interesting = true; 14730 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14731 } else if ((queue = isReceivingBroadcast(app)) != null) { 14732 // An app that is currently receiving a broadcast also 14733 // counts as being in the foreground for OOM killer purposes. 14734 // It's placed in a sched group based on the nature of the 14735 // broadcast as reflected by which queue it's active in. 14736 adj = ProcessList.FOREGROUND_APP_ADJ; 14737 schedGroup = (queue == mFgBroadcastQueue) 14738 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14739 app.adjType = "broadcast"; 14740 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14741 } else if (app.executingServices.size() > 0) { 14742 // An app that is currently executing a service callback also 14743 // counts as being in the foreground. 14744 adj = ProcessList.FOREGROUND_APP_ADJ; 14745 schedGroup = app.execServicesFg ? 14746 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14747 app.adjType = "exec-service"; 14748 procState = ActivityManager.PROCESS_STATE_SERVICE; 14749 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14750 } else { 14751 // As far as we know the process is empty. We may change our mind later. 14752 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14753 // At this point we don't actually know the adjustment. Use the cached adj 14754 // value that the caller wants us to. 14755 adj = cachedAdj; 14756 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14757 app.cached = true; 14758 app.empty = true; 14759 app.adjType = "cch-empty"; 14760 } 14761 14762 // Examine all activities if not already foreground. 14763 if (!foregroundActivities && activitiesSize > 0) { 14764 for (int j = 0; j < activitiesSize; j++) { 14765 final ActivityRecord r = app.activities.get(j); 14766 if (r.app != app) { 14767 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14768 + app + "?!?"); 14769 continue; 14770 } 14771 if (r.visible) { 14772 // App has a visible activity; only upgrade adjustment. 14773 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14774 adj = ProcessList.VISIBLE_APP_ADJ; 14775 app.adjType = "visible"; 14776 } 14777 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14778 procState = ActivityManager.PROCESS_STATE_TOP; 14779 } 14780 schedGroup = Process.THREAD_GROUP_DEFAULT; 14781 app.cached = false; 14782 app.empty = false; 14783 foregroundActivities = true; 14784 break; 14785 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14786 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14787 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14788 app.adjType = "pausing"; 14789 } 14790 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14791 procState = ActivityManager.PROCESS_STATE_TOP; 14792 } 14793 schedGroup = Process.THREAD_GROUP_DEFAULT; 14794 app.cached = false; 14795 app.empty = false; 14796 foregroundActivities = true; 14797 } else if (r.state == ActivityState.STOPPING) { 14798 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14799 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14800 app.adjType = "stopping"; 14801 } 14802 // For the process state, we will at this point consider the 14803 // process to be cached. It will be cached either as an activity 14804 // or empty depending on whether the activity is finishing. We do 14805 // this so that we can treat the process as cached for purposes of 14806 // memory trimming (determing current memory level, trim command to 14807 // send to process) since there can be an arbitrary number of stopping 14808 // processes and they should soon all go into the cached state. 14809 if (!r.finishing) { 14810 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14811 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14812 } 14813 } 14814 app.cached = false; 14815 app.empty = false; 14816 foregroundActivities = true; 14817 } else { 14818 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14819 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14820 app.adjType = "cch-act"; 14821 } 14822 } 14823 } 14824 } 14825 14826 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14827 if (app.foregroundServices) { 14828 // The user is aware of this app, so make it visible. 14829 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14830 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14831 app.cached = false; 14832 app.adjType = "fg-service"; 14833 schedGroup = Process.THREAD_GROUP_DEFAULT; 14834 } else if (app.forcingToForeground != null) { 14835 // The user is aware of this app, so make it visible. 14836 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14837 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14838 app.cached = false; 14839 app.adjType = "force-fg"; 14840 app.adjSource = app.forcingToForeground; 14841 schedGroup = Process.THREAD_GROUP_DEFAULT; 14842 } 14843 } 14844 14845 if (app.foregroundServices) { 14846 interesting = true; 14847 } 14848 14849 if (app == mHeavyWeightProcess) { 14850 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14851 // We don't want to kill the current heavy-weight process. 14852 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14853 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14854 app.cached = false; 14855 app.adjType = "heavy"; 14856 } 14857 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14858 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14859 } 14860 } 14861 14862 if (app == mHomeProcess) { 14863 if (adj > ProcessList.HOME_APP_ADJ) { 14864 // This process is hosting what we currently consider to be the 14865 // home app, so we don't want to let it go into the background. 14866 adj = ProcessList.HOME_APP_ADJ; 14867 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14868 app.cached = false; 14869 app.adjType = "home"; 14870 } 14871 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14872 procState = ActivityManager.PROCESS_STATE_HOME; 14873 } 14874 } 14875 14876 if (app == mPreviousProcess && app.activities.size() > 0) { 14877 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14878 // This was the previous process that showed UI to the user. 14879 // We want to try to keep it around more aggressively, to give 14880 // a good experience around switching between two apps. 14881 adj = ProcessList.PREVIOUS_APP_ADJ; 14882 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14883 app.cached = false; 14884 app.adjType = "previous"; 14885 } 14886 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14887 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14888 } 14889 } 14890 14891 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14892 + " reason=" + app.adjType); 14893 14894 // By default, we use the computed adjustment. It may be changed if 14895 // there are applications dependent on our services or providers, but 14896 // this gives us a baseline and makes sure we don't get into an 14897 // infinite recursion. 14898 app.adjSeq = mAdjSeq; 14899 app.curRawAdj = adj; 14900 app.hasStartedServices = false; 14901 14902 if (mBackupTarget != null && app == mBackupTarget.app) { 14903 // If possible we want to avoid killing apps while they're being backed up 14904 if (adj > ProcessList.BACKUP_APP_ADJ) { 14905 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14906 adj = ProcessList.BACKUP_APP_ADJ; 14907 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14908 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14909 } 14910 app.adjType = "backup"; 14911 app.cached = false; 14912 } 14913 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14914 procState = ActivityManager.PROCESS_STATE_BACKUP; 14915 } 14916 } 14917 14918 boolean mayBeTop = false; 14919 14920 for (int is = app.services.size()-1; 14921 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14922 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14923 || procState > ActivityManager.PROCESS_STATE_TOP); 14924 is--) { 14925 ServiceRecord s = app.services.valueAt(is); 14926 if (s.startRequested) { 14927 app.hasStartedServices = true; 14928 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14929 procState = ActivityManager.PROCESS_STATE_SERVICE; 14930 } 14931 if (app.hasShownUi && app != mHomeProcess) { 14932 // If this process has shown some UI, let it immediately 14933 // go to the LRU list because it may be pretty heavy with 14934 // UI stuff. We'll tag it with a label just to help 14935 // debug and understand what is going on. 14936 if (adj > ProcessList.SERVICE_ADJ) { 14937 app.adjType = "cch-started-ui-services"; 14938 } 14939 } else { 14940 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14941 // This service has seen some activity within 14942 // recent memory, so we will keep its process ahead 14943 // of the background processes. 14944 if (adj > ProcessList.SERVICE_ADJ) { 14945 adj = ProcessList.SERVICE_ADJ; 14946 app.adjType = "started-services"; 14947 app.cached = false; 14948 } 14949 } 14950 // If we have let the service slide into the background 14951 // state, still have some text describing what it is doing 14952 // even though the service no longer has an impact. 14953 if (adj > ProcessList.SERVICE_ADJ) { 14954 app.adjType = "cch-started-services"; 14955 } 14956 } 14957 // Don't kill this process because it is doing work; it 14958 // has said it is doing work. 14959 app.keeping = true; 14960 } 14961 for (int conni = s.connections.size()-1; 14962 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14963 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14964 || procState > ActivityManager.PROCESS_STATE_TOP); 14965 conni--) { 14966 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14967 for (int i = 0; 14968 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14969 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14970 || procState > ActivityManager.PROCESS_STATE_TOP); 14971 i++) { 14972 // XXX should compute this based on the max of 14973 // all connected clients. 14974 ConnectionRecord cr = clist.get(i); 14975 if (cr.binding.client == app) { 14976 // Binding to ourself is not interesting. 14977 continue; 14978 } 14979 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14980 ProcessRecord client = cr.binding.client; 14981 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14982 TOP_APP, doingAll, now); 14983 int clientProcState = client.curProcState; 14984 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14985 // If the other app is cached for any reason, for purposes here 14986 // we are going to consider it empty. The specific cached state 14987 // doesn't propagate except under certain conditions. 14988 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14989 } 14990 String adjType = null; 14991 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14992 // Not doing bind OOM management, so treat 14993 // this guy more like a started service. 14994 if (app.hasShownUi && app != mHomeProcess) { 14995 // If this process has shown some UI, let it immediately 14996 // go to the LRU list because it may be pretty heavy with 14997 // UI stuff. We'll tag it with a label just to help 14998 // debug and understand what is going on. 14999 if (adj > clientAdj) { 15000 adjType = "cch-bound-ui-services"; 15001 } 15002 app.cached = false; 15003 clientAdj = adj; 15004 clientProcState = procState; 15005 } else { 15006 if (now >= (s.lastActivity 15007 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15008 // This service has not seen activity within 15009 // recent memory, so allow it to drop to the 15010 // LRU list if there is no other reason to keep 15011 // it around. We'll also tag it with a label just 15012 // to help debug and undertand what is going on. 15013 if (adj > clientAdj) { 15014 adjType = "cch-bound-services"; 15015 } 15016 clientAdj = adj; 15017 } 15018 } 15019 } 15020 if (adj > clientAdj) { 15021 // If this process has recently shown UI, and 15022 // the process that is binding to it is less 15023 // important than being visible, then we don't 15024 // care about the binding as much as we care 15025 // about letting this process get into the LRU 15026 // list to be killed and restarted if needed for 15027 // memory. 15028 if (app.hasShownUi && app != mHomeProcess 15029 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15030 adjType = "cch-bound-ui-services"; 15031 } else { 15032 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15033 |Context.BIND_IMPORTANT)) != 0) { 15034 adj = clientAdj; 15035 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15036 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15037 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15038 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15039 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15040 adj = clientAdj; 15041 } else { 15042 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15043 adj = ProcessList.VISIBLE_APP_ADJ; 15044 } 15045 } 15046 if (!client.cached) { 15047 app.cached = false; 15048 } 15049 if (client.keeping) { 15050 app.keeping = true; 15051 } 15052 adjType = "service"; 15053 } 15054 } 15055 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15056 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15057 schedGroup = Process.THREAD_GROUP_DEFAULT; 15058 } 15059 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15060 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15061 // Special handling of clients who are in the top state. 15062 // We *may* want to consider this process to be in the 15063 // top state as well, but only if there is not another 15064 // reason for it to be running. Being on the top is a 15065 // special state, meaning you are specifically running 15066 // for the current top app. If the process is already 15067 // running in the background for some other reason, it 15068 // is more important to continue considering it to be 15069 // in the background state. 15070 mayBeTop = true; 15071 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15072 } else { 15073 // Special handling for above-top states (persistent 15074 // processes). These should not bring the current process 15075 // into the top state, since they are not on top. Instead 15076 // give them the best state after that. 15077 clientProcState = 15078 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15079 } 15080 } 15081 } else { 15082 if (clientProcState < 15083 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15084 clientProcState = 15085 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15086 } 15087 } 15088 if (procState > clientProcState) { 15089 procState = clientProcState; 15090 } 15091 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15092 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15093 app.pendingUiClean = true; 15094 } 15095 if (adjType != null) { 15096 app.adjType = adjType; 15097 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15098 .REASON_SERVICE_IN_USE; 15099 app.adjSource = cr.binding.client; 15100 app.adjSourceOom = clientAdj; 15101 app.adjTarget = s.name; 15102 } 15103 } 15104 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15105 app.treatLikeActivity = true; 15106 } 15107 final ActivityRecord a = cr.activity; 15108 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15109 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15110 (a.visible || a.state == ActivityState.RESUMED 15111 || a.state == ActivityState.PAUSING)) { 15112 adj = ProcessList.FOREGROUND_APP_ADJ; 15113 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15114 schedGroup = Process.THREAD_GROUP_DEFAULT; 15115 } 15116 app.cached = false; 15117 app.adjType = "service"; 15118 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15119 .REASON_SERVICE_IN_USE; 15120 app.adjSource = a; 15121 app.adjSourceOom = adj; 15122 app.adjTarget = s.name; 15123 } 15124 } 15125 } 15126 } 15127 } 15128 15129 for (int provi = app.pubProviders.size()-1; 15130 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15131 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15132 || procState > ActivityManager.PROCESS_STATE_TOP); 15133 provi--) { 15134 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15135 for (int i = cpr.connections.size()-1; 15136 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15137 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15138 || procState > ActivityManager.PROCESS_STATE_TOP); 15139 i--) { 15140 ContentProviderConnection conn = cpr.connections.get(i); 15141 ProcessRecord client = conn.client; 15142 if (client == app) { 15143 // Being our own client is not interesting. 15144 continue; 15145 } 15146 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15147 int clientProcState = client.curProcState; 15148 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15149 // If the other app is cached for any reason, for purposes here 15150 // we are going to consider it empty. 15151 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15152 } 15153 if (adj > clientAdj) { 15154 if (app.hasShownUi && app != mHomeProcess 15155 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15156 app.adjType = "cch-ui-provider"; 15157 } else { 15158 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15159 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15160 app.adjType = "provider"; 15161 } 15162 app.cached &= client.cached; 15163 app.keeping |= client.keeping; 15164 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15165 .REASON_PROVIDER_IN_USE; 15166 app.adjSource = client; 15167 app.adjSourceOom = clientAdj; 15168 app.adjTarget = cpr.name; 15169 } 15170 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15171 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15172 // Special handling of clients who are in the top state. 15173 // We *may* want to consider this process to be in the 15174 // top state as well, but only if there is not another 15175 // reason for it to be running. Being on the top is a 15176 // special state, meaning you are specifically running 15177 // for the current top app. If the process is already 15178 // running in the background for some other reason, it 15179 // is more important to continue considering it to be 15180 // in the background state. 15181 mayBeTop = true; 15182 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15183 } else { 15184 // Special handling for above-top states (persistent 15185 // processes). These should not bring the current process 15186 // into the top state, since they are not on top. Instead 15187 // give them the best state after that. 15188 clientProcState = 15189 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15190 } 15191 } 15192 if (procState > clientProcState) { 15193 procState = clientProcState; 15194 } 15195 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15196 schedGroup = Process.THREAD_GROUP_DEFAULT; 15197 } 15198 } 15199 // If the provider has external (non-framework) process 15200 // dependencies, ensure that its adjustment is at least 15201 // FOREGROUND_APP_ADJ. 15202 if (cpr.hasExternalProcessHandles()) { 15203 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15204 adj = ProcessList.FOREGROUND_APP_ADJ; 15205 schedGroup = Process.THREAD_GROUP_DEFAULT; 15206 app.cached = false; 15207 app.keeping = true; 15208 app.adjType = "provider"; 15209 app.adjTarget = cpr.name; 15210 } 15211 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15212 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15213 } 15214 } 15215 } 15216 15217 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15218 // A client of one of our services or providers is in the top state. We 15219 // *may* want to be in the top state, but not if we are already running in 15220 // the background for some other reason. For the decision here, we are going 15221 // to pick out a few specific states that we want to remain in when a client 15222 // is top (states that tend to be longer-term) and otherwise allow it to go 15223 // to the top state. 15224 switch (procState) { 15225 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15226 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15227 case ActivityManager.PROCESS_STATE_SERVICE: 15228 // These all are longer-term states, so pull them up to the top 15229 // of the background states, but not all the way to the top state. 15230 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15231 break; 15232 default: 15233 // Otherwise, top is a better choice, so take it. 15234 procState = ActivityManager.PROCESS_STATE_TOP; 15235 break; 15236 } 15237 } 15238 15239 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15240 if (app.hasClientActivities) { 15241 // This is a cached process, but with client activities. Mark it so. 15242 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15243 app.adjType = "cch-client-act"; 15244 } else if (app.treatLikeActivity) { 15245 // This is a cached process, but somebody wants us to treat it like it has 15246 // an activity, okay! 15247 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15248 app.adjType = "cch-as-act"; 15249 } 15250 } 15251 15252 if (adj == ProcessList.SERVICE_ADJ) { 15253 if (doingAll) { 15254 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15255 mNewNumServiceProcs++; 15256 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15257 if (!app.serviceb) { 15258 // This service isn't far enough down on the LRU list to 15259 // normally be a B service, but if we are low on RAM and it 15260 // is large we want to force it down since we would prefer to 15261 // keep launcher over it. 15262 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15263 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15264 app.serviceHighRam = true; 15265 app.serviceb = true; 15266 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15267 } else { 15268 mNewNumAServiceProcs++; 15269 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15270 } 15271 } else { 15272 app.serviceHighRam = false; 15273 } 15274 } 15275 if (app.serviceb) { 15276 adj = ProcessList.SERVICE_B_ADJ; 15277 } 15278 } 15279 15280 app.curRawAdj = adj; 15281 15282 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15283 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15284 if (adj > app.maxAdj) { 15285 adj = app.maxAdj; 15286 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15287 schedGroup = Process.THREAD_GROUP_DEFAULT; 15288 } 15289 } 15290 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15291 app.keeping = true; 15292 } 15293 15294 // Do final modification to adj. Everything we do between here and applying 15295 // the final setAdj must be done in this function, because we will also use 15296 // it when computing the final cached adj later. Note that we don't need to 15297 // worry about this for max adj above, since max adj will always be used to 15298 // keep it out of the cached vaues. 15299 app.curAdj = app.modifyRawOomAdj(adj); 15300 app.curSchedGroup = schedGroup; 15301 app.curProcState = procState; 15302 app.foregroundActivities = foregroundActivities; 15303 15304 return app.curRawAdj; 15305 } 15306 15307 /** 15308 * Schedule PSS collection of a process. 15309 */ 15310 void requestPssLocked(ProcessRecord proc, int procState) { 15311 if (mPendingPssProcesses.contains(proc)) { 15312 return; 15313 } 15314 if (mPendingPssProcesses.size() == 0) { 15315 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15316 } 15317 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15318 proc.pssProcState = procState; 15319 mPendingPssProcesses.add(proc); 15320 } 15321 15322 /** 15323 * Schedule PSS collection of all processes. 15324 */ 15325 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15326 if (!always) { 15327 if (now < (mLastFullPssTime + 15328 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15329 return; 15330 } 15331 } 15332 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15333 mLastFullPssTime = now; 15334 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15335 mPendingPssProcesses.clear(); 15336 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15337 ProcessRecord app = mLruProcesses.get(i); 15338 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15339 app.pssProcState = app.setProcState; 15340 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15341 isSleeping(), now); 15342 mPendingPssProcesses.add(app); 15343 } 15344 } 15345 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15346 } 15347 15348 /** 15349 * Ask a given process to GC right now. 15350 */ 15351 final void performAppGcLocked(ProcessRecord app) { 15352 try { 15353 app.lastRequestedGc = SystemClock.uptimeMillis(); 15354 if (app.thread != null) { 15355 if (app.reportLowMemory) { 15356 app.reportLowMemory = false; 15357 app.thread.scheduleLowMemory(); 15358 } else { 15359 app.thread.processInBackground(); 15360 } 15361 } 15362 } catch (Exception e) { 15363 // whatever. 15364 } 15365 } 15366 15367 /** 15368 * Returns true if things are idle enough to perform GCs. 15369 */ 15370 private final boolean canGcNowLocked() { 15371 boolean processingBroadcasts = false; 15372 for (BroadcastQueue q : mBroadcastQueues) { 15373 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15374 processingBroadcasts = true; 15375 } 15376 } 15377 return !processingBroadcasts 15378 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15379 } 15380 15381 /** 15382 * Perform GCs on all processes that are waiting for it, but only 15383 * if things are idle. 15384 */ 15385 final void performAppGcsLocked() { 15386 final int N = mProcessesToGc.size(); 15387 if (N <= 0) { 15388 return; 15389 } 15390 if (canGcNowLocked()) { 15391 while (mProcessesToGc.size() > 0) { 15392 ProcessRecord proc = mProcessesToGc.remove(0); 15393 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15394 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15395 <= SystemClock.uptimeMillis()) { 15396 // To avoid spamming the system, we will GC processes one 15397 // at a time, waiting a few seconds between each. 15398 performAppGcLocked(proc); 15399 scheduleAppGcsLocked(); 15400 return; 15401 } else { 15402 // It hasn't been long enough since we last GCed this 15403 // process... put it in the list to wait for its time. 15404 addProcessToGcListLocked(proc); 15405 break; 15406 } 15407 } 15408 } 15409 15410 scheduleAppGcsLocked(); 15411 } 15412 } 15413 15414 /** 15415 * If all looks good, perform GCs on all processes waiting for them. 15416 */ 15417 final void performAppGcsIfAppropriateLocked() { 15418 if (canGcNowLocked()) { 15419 performAppGcsLocked(); 15420 return; 15421 } 15422 // Still not idle, wait some more. 15423 scheduleAppGcsLocked(); 15424 } 15425 15426 /** 15427 * Schedule the execution of all pending app GCs. 15428 */ 15429 final void scheduleAppGcsLocked() { 15430 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15431 15432 if (mProcessesToGc.size() > 0) { 15433 // Schedule a GC for the time to the next process. 15434 ProcessRecord proc = mProcessesToGc.get(0); 15435 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15436 15437 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15438 long now = SystemClock.uptimeMillis(); 15439 if (when < (now+GC_TIMEOUT)) { 15440 when = now + GC_TIMEOUT; 15441 } 15442 mHandler.sendMessageAtTime(msg, when); 15443 } 15444 } 15445 15446 /** 15447 * Add a process to the array of processes waiting to be GCed. Keeps the 15448 * list in sorted order by the last GC time. The process can't already be 15449 * on the list. 15450 */ 15451 final void addProcessToGcListLocked(ProcessRecord proc) { 15452 boolean added = false; 15453 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15454 if (mProcessesToGc.get(i).lastRequestedGc < 15455 proc.lastRequestedGc) { 15456 added = true; 15457 mProcessesToGc.add(i+1, proc); 15458 break; 15459 } 15460 } 15461 if (!added) { 15462 mProcessesToGc.add(0, proc); 15463 } 15464 } 15465 15466 /** 15467 * Set up to ask a process to GC itself. This will either do it 15468 * immediately, or put it on the list of processes to gc the next 15469 * time things are idle. 15470 */ 15471 final void scheduleAppGcLocked(ProcessRecord app) { 15472 long now = SystemClock.uptimeMillis(); 15473 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15474 return; 15475 } 15476 if (!mProcessesToGc.contains(app)) { 15477 addProcessToGcListLocked(app); 15478 scheduleAppGcsLocked(); 15479 } 15480 } 15481 15482 final void checkExcessivePowerUsageLocked(boolean doKills) { 15483 updateCpuStatsNow(); 15484 15485 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15486 boolean doWakeKills = doKills; 15487 boolean doCpuKills = doKills; 15488 if (mLastPowerCheckRealtime == 0) { 15489 doWakeKills = false; 15490 } 15491 if (mLastPowerCheckUptime == 0) { 15492 doCpuKills = false; 15493 } 15494 if (stats.isScreenOn()) { 15495 doWakeKills = false; 15496 } 15497 final long curRealtime = SystemClock.elapsedRealtime(); 15498 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15499 final long curUptime = SystemClock.uptimeMillis(); 15500 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15501 mLastPowerCheckRealtime = curRealtime; 15502 mLastPowerCheckUptime = curUptime; 15503 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15504 doWakeKills = false; 15505 } 15506 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15507 doCpuKills = false; 15508 } 15509 int i = mLruProcesses.size(); 15510 while (i > 0) { 15511 i--; 15512 ProcessRecord app = mLruProcesses.get(i); 15513 if (!app.keeping) { 15514 long wtime; 15515 synchronized (stats) { 15516 wtime = stats.getProcessWakeTime(app.info.uid, 15517 app.pid, curRealtime); 15518 } 15519 long wtimeUsed = wtime - app.lastWakeTime; 15520 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15521 if (DEBUG_POWER) { 15522 StringBuilder sb = new StringBuilder(128); 15523 sb.append("Wake for "); 15524 app.toShortString(sb); 15525 sb.append(": over "); 15526 TimeUtils.formatDuration(realtimeSince, sb); 15527 sb.append(" used "); 15528 TimeUtils.formatDuration(wtimeUsed, sb); 15529 sb.append(" ("); 15530 sb.append((wtimeUsed*100)/realtimeSince); 15531 sb.append("%)"); 15532 Slog.i(TAG, sb.toString()); 15533 sb.setLength(0); 15534 sb.append("CPU for "); 15535 app.toShortString(sb); 15536 sb.append(": over "); 15537 TimeUtils.formatDuration(uptimeSince, sb); 15538 sb.append(" used "); 15539 TimeUtils.formatDuration(cputimeUsed, sb); 15540 sb.append(" ("); 15541 sb.append((cputimeUsed*100)/uptimeSince); 15542 sb.append("%)"); 15543 Slog.i(TAG, sb.toString()); 15544 } 15545 // If a process has held a wake lock for more 15546 // than 50% of the time during this period, 15547 // that sounds bad. Kill! 15548 if (doWakeKills && realtimeSince > 0 15549 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15550 synchronized (stats) { 15551 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15552 realtimeSince, wtimeUsed); 15553 } 15554 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15555 + " during " + realtimeSince); 15556 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15557 } else if (doCpuKills && uptimeSince > 0 15558 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15559 synchronized (stats) { 15560 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15561 uptimeSince, cputimeUsed); 15562 } 15563 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15564 + " during " + uptimeSince); 15565 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15566 } else { 15567 app.lastWakeTime = wtime; 15568 app.lastCpuTime = app.curCpuTime; 15569 } 15570 } 15571 } 15572 } 15573 15574 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15575 ProcessRecord TOP_APP, boolean doingAll, long now) { 15576 boolean success = true; 15577 15578 if (app.curRawAdj != app.setRawAdj) { 15579 if (wasKeeping && !app.keeping) { 15580 // This app is no longer something we want to keep. Note 15581 // its current wake lock time to later know to kill it if 15582 // it is not behaving well. 15583 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15584 synchronized (stats) { 15585 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15586 app.pid, SystemClock.elapsedRealtime()); 15587 } 15588 app.lastCpuTime = app.curCpuTime; 15589 } 15590 15591 app.setRawAdj = app.curRawAdj; 15592 } 15593 15594 int changes = 0; 15595 15596 if (app.curAdj != app.setAdj) { 15597 ProcessList.setOomAdj(app.pid, app.curAdj); 15598 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15599 TAG, "Set " + app.pid + " " + app.processName + 15600 " adj " + app.curAdj + ": " + app.adjType); 15601 app.setAdj = app.curAdj; 15602 } 15603 15604 if (app.setSchedGroup != app.curSchedGroup) { 15605 app.setSchedGroup = app.curSchedGroup; 15606 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15607 "Setting process group of " + app.processName 15608 + " to " + app.curSchedGroup); 15609 if (app.waitingToKill != null && 15610 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15611 killUnneededProcessLocked(app, app.waitingToKill); 15612 success = false; 15613 } else { 15614 if (true) { 15615 long oldId = Binder.clearCallingIdentity(); 15616 try { 15617 Process.setProcessGroup(app.pid, app.curSchedGroup); 15618 } catch (Exception e) { 15619 Slog.w(TAG, "Failed setting process group of " + app.pid 15620 + " to " + app.curSchedGroup); 15621 e.printStackTrace(); 15622 } finally { 15623 Binder.restoreCallingIdentity(oldId); 15624 } 15625 } else { 15626 if (app.thread != null) { 15627 try { 15628 app.thread.setSchedulingGroup(app.curSchedGroup); 15629 } catch (RemoteException e) { 15630 } 15631 } 15632 } 15633 Process.setSwappiness(app.pid, 15634 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15635 } 15636 } 15637 if (app.repForegroundActivities != app.foregroundActivities) { 15638 app.repForegroundActivities = app.foregroundActivities; 15639 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15640 } 15641 if (app.repProcState != app.curProcState) { 15642 app.repProcState = app.curProcState; 15643 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15644 if (app.thread != null) { 15645 try { 15646 if (false) { 15647 //RuntimeException h = new RuntimeException("here"); 15648 Slog.i(TAG, "Sending new process state " + app.repProcState 15649 + " to " + app /*, h*/); 15650 } 15651 app.thread.setProcessState(app.repProcState); 15652 } catch (RemoteException e) { 15653 } 15654 } 15655 } 15656 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15657 app.setProcState)) { 15658 app.lastStateTime = now; 15659 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15660 isSleeping(), now); 15661 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15662 + ProcessList.makeProcStateString(app.setProcState) + " to " 15663 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15664 + (app.nextPssTime-now) + ": " + app); 15665 } else { 15666 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15667 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15668 requestPssLocked(app, app.setProcState); 15669 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15670 isSleeping(), now); 15671 } else if (false && DEBUG_PSS) { 15672 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15673 } 15674 } 15675 if (app.setProcState != app.curProcState) { 15676 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15677 "Proc state change of " + app.processName 15678 + " to " + app.curProcState); 15679 app.setProcState = app.curProcState; 15680 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15681 app.notCachedSinceIdle = false; 15682 } 15683 if (!doingAll) { 15684 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15685 } else { 15686 app.procStateChanged = true; 15687 } 15688 } 15689 15690 if (changes != 0) { 15691 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15692 int i = mPendingProcessChanges.size()-1; 15693 ProcessChangeItem item = null; 15694 while (i >= 0) { 15695 item = mPendingProcessChanges.get(i); 15696 if (item.pid == app.pid) { 15697 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15698 break; 15699 } 15700 i--; 15701 } 15702 if (i < 0) { 15703 // No existing item in pending changes; need a new one. 15704 final int NA = mAvailProcessChanges.size(); 15705 if (NA > 0) { 15706 item = mAvailProcessChanges.remove(NA-1); 15707 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15708 } else { 15709 item = new ProcessChangeItem(); 15710 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15711 } 15712 item.changes = 0; 15713 item.pid = app.pid; 15714 item.uid = app.info.uid; 15715 if (mPendingProcessChanges.size() == 0) { 15716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15717 "*** Enqueueing dispatch processes changed!"); 15718 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15719 } 15720 mPendingProcessChanges.add(item); 15721 } 15722 item.changes |= changes; 15723 item.processState = app.repProcState; 15724 item.foregroundActivities = app.repForegroundActivities; 15725 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15726 + Integer.toHexString(System.identityHashCode(item)) 15727 + " " + app.toShortString() + ": changes=" + item.changes 15728 + " procState=" + item.processState 15729 + " foreground=" + item.foregroundActivities 15730 + " type=" + app.adjType + " source=" + app.adjSource 15731 + " target=" + app.adjTarget); 15732 } 15733 15734 return success; 15735 } 15736 15737 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15738 if (proc.thread != null && proc.baseProcessTracker != null) { 15739 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15740 } 15741 } 15742 15743 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15744 ProcessRecord TOP_APP, boolean doingAll, long now) { 15745 if (app.thread == null) { 15746 return false; 15747 } 15748 15749 final boolean wasKeeping = app.keeping; 15750 15751 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15752 15753 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15754 } 15755 15756 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15757 boolean oomAdj) { 15758 if (isForeground != proc.foregroundServices) { 15759 proc.foregroundServices = isForeground; 15760 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15761 proc.info.uid); 15762 if (isForeground) { 15763 if (curProcs == null) { 15764 curProcs = new ArrayList<ProcessRecord>(); 15765 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15766 } 15767 if (!curProcs.contains(proc)) { 15768 curProcs.add(proc); 15769 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15770 proc.info.packageName, proc.info.uid); 15771 } 15772 } else { 15773 if (curProcs != null) { 15774 if (curProcs.remove(proc)) { 15775 mBatteryStatsService.noteEvent( 15776 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15777 proc.info.packageName, proc.info.uid); 15778 if (curProcs.size() <= 0) { 15779 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15780 } 15781 } 15782 } 15783 } 15784 if (oomAdj) { 15785 updateOomAdjLocked(); 15786 } 15787 } 15788 } 15789 15790 private final ActivityRecord resumedAppLocked() { 15791 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15792 String pkg; 15793 int uid; 15794 if (act != null && !act.sleeping) { 15795 pkg = act.packageName; 15796 uid = act.info.applicationInfo.uid; 15797 } else { 15798 pkg = null; 15799 uid = -1; 15800 } 15801 // Has the UID or resumed package name changed? 15802 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15803 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15804 if (mCurResumedPackage != null) { 15805 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15806 mCurResumedPackage, mCurResumedUid); 15807 } 15808 mCurResumedPackage = pkg; 15809 mCurResumedUid = uid; 15810 if (mCurResumedPackage != null) { 15811 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15812 mCurResumedPackage, mCurResumedUid); 15813 } 15814 } 15815 return act; 15816 } 15817 15818 final boolean updateOomAdjLocked(ProcessRecord app) { 15819 final ActivityRecord TOP_ACT = resumedAppLocked(); 15820 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15821 final boolean wasCached = app.cached; 15822 15823 mAdjSeq++; 15824 15825 // This is the desired cached adjusment we want to tell it to use. 15826 // If our app is currently cached, we know it, and that is it. Otherwise, 15827 // we don't know it yet, and it needs to now be cached we will then 15828 // need to do a complete oom adj. 15829 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15830 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15831 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15832 SystemClock.uptimeMillis()); 15833 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15834 // Changed to/from cached state, so apps after it in the LRU 15835 // list may also be changed. 15836 updateOomAdjLocked(); 15837 } 15838 return success; 15839 } 15840 15841 final void updateOomAdjLocked() { 15842 final ActivityRecord TOP_ACT = resumedAppLocked(); 15843 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15844 final long now = SystemClock.uptimeMillis(); 15845 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15846 final int N = mLruProcesses.size(); 15847 15848 if (false) { 15849 RuntimeException e = new RuntimeException(); 15850 e.fillInStackTrace(); 15851 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15852 } 15853 15854 mAdjSeq++; 15855 mNewNumServiceProcs = 0; 15856 mNewNumAServiceProcs = 0; 15857 15858 final int emptyProcessLimit; 15859 final int cachedProcessLimit; 15860 if (mProcessLimit <= 0) { 15861 emptyProcessLimit = cachedProcessLimit = 0; 15862 } else if (mProcessLimit == 1) { 15863 emptyProcessLimit = 1; 15864 cachedProcessLimit = 0; 15865 } else { 15866 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15867 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15868 } 15869 15870 // Let's determine how many processes we have running vs. 15871 // how many slots we have for background processes; we may want 15872 // to put multiple processes in a slot of there are enough of 15873 // them. 15874 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15875 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15876 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15877 if (numEmptyProcs > cachedProcessLimit) { 15878 // If there are more empty processes than our limit on cached 15879 // processes, then use the cached process limit for the factor. 15880 // This ensures that the really old empty processes get pushed 15881 // down to the bottom, so if we are running low on memory we will 15882 // have a better chance at keeping around more cached processes 15883 // instead of a gazillion empty processes. 15884 numEmptyProcs = cachedProcessLimit; 15885 } 15886 int emptyFactor = numEmptyProcs/numSlots; 15887 if (emptyFactor < 1) emptyFactor = 1; 15888 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15889 if (cachedFactor < 1) cachedFactor = 1; 15890 int stepCached = 0; 15891 int stepEmpty = 0; 15892 int numCached = 0; 15893 int numEmpty = 0; 15894 int numTrimming = 0; 15895 15896 mNumNonCachedProcs = 0; 15897 mNumCachedHiddenProcs = 0; 15898 15899 // First update the OOM adjustment for each of the 15900 // application processes based on their current state. 15901 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15902 int nextCachedAdj = curCachedAdj+1; 15903 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15904 int nextEmptyAdj = curEmptyAdj+2; 15905 for (int i=N-1; i>=0; i--) { 15906 ProcessRecord app = mLruProcesses.get(i); 15907 if (!app.killedByAm && app.thread != null) { 15908 app.procStateChanged = false; 15909 final boolean wasKeeping = app.keeping; 15910 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15911 15912 // If we haven't yet assigned the final cached adj 15913 // to the process, do that now. 15914 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15915 switch (app.curProcState) { 15916 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15917 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15918 // This process is a cached process holding activities... 15919 // assign it the next cached value for that type, and then 15920 // step that cached level. 15921 app.curRawAdj = curCachedAdj; 15922 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15923 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15924 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15925 + ")"); 15926 if (curCachedAdj != nextCachedAdj) { 15927 stepCached++; 15928 if (stepCached >= cachedFactor) { 15929 stepCached = 0; 15930 curCachedAdj = nextCachedAdj; 15931 nextCachedAdj += 2; 15932 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15933 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15934 } 15935 } 15936 } 15937 break; 15938 default: 15939 // For everything else, assign next empty cached process 15940 // level and bump that up. Note that this means that 15941 // long-running services that have dropped down to the 15942 // cached level will be treated as empty (since their process 15943 // state is still as a service), which is what we want. 15944 app.curRawAdj = curEmptyAdj; 15945 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15946 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15947 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15948 + ")"); 15949 if (curEmptyAdj != nextEmptyAdj) { 15950 stepEmpty++; 15951 if (stepEmpty >= emptyFactor) { 15952 stepEmpty = 0; 15953 curEmptyAdj = nextEmptyAdj; 15954 nextEmptyAdj += 2; 15955 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15956 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15957 } 15958 } 15959 } 15960 break; 15961 } 15962 } 15963 15964 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15965 15966 // Count the number of process types. 15967 switch (app.curProcState) { 15968 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15969 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15970 mNumCachedHiddenProcs++; 15971 numCached++; 15972 if (numCached > cachedProcessLimit) { 15973 killUnneededProcessLocked(app, "cached #" + numCached); 15974 } 15975 break; 15976 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15977 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15978 && app.lastActivityTime < oldTime) { 15979 killUnneededProcessLocked(app, "empty for " 15980 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15981 / 1000) + "s"); 15982 } else { 15983 numEmpty++; 15984 if (numEmpty > emptyProcessLimit) { 15985 killUnneededProcessLocked(app, "empty #" + numEmpty); 15986 } 15987 } 15988 break; 15989 default: 15990 mNumNonCachedProcs++; 15991 break; 15992 } 15993 15994 if (app.isolated && app.services.size() <= 0) { 15995 // If this is an isolated process, and there are no 15996 // services running in it, then the process is no longer 15997 // needed. We agressively kill these because we can by 15998 // definition not re-use the same process again, and it is 15999 // good to avoid having whatever code was running in them 16000 // left sitting around after no longer needed. 16001 killUnneededProcessLocked(app, "isolated not needed"); 16002 } 16003 16004 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16005 && !app.killedByAm) { 16006 numTrimming++; 16007 } 16008 } 16009 } 16010 16011 mNumServiceProcs = mNewNumServiceProcs; 16012 16013 // Now determine the memory trimming level of background processes. 16014 // Unfortunately we need to start at the back of the list to do this 16015 // properly. We only do this if the number of background apps we 16016 // are managing to keep around is less than half the maximum we desire; 16017 // if we are keeping a good number around, we'll let them use whatever 16018 // memory they want. 16019 final int numCachedAndEmpty = numCached + numEmpty; 16020 int memFactor; 16021 if (numCached <= ProcessList.TRIM_CACHED_APPS 16022 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16023 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16024 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16025 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16026 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16027 } else { 16028 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16029 } 16030 } else { 16031 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16032 } 16033 // We always allow the memory level to go up (better). We only allow it to go 16034 // down if we are in a state where that is allowed, *and* the total number of processes 16035 // has gone down since last time. 16036 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16037 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16038 + " last=" + mLastNumProcesses); 16039 if (memFactor > mLastMemoryLevel) { 16040 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16041 memFactor = mLastMemoryLevel; 16042 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16043 } 16044 } 16045 mLastMemoryLevel = memFactor; 16046 mLastNumProcesses = mLruProcesses.size(); 16047 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16048 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16049 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16050 if (mLowRamStartTime == 0) { 16051 mLowRamStartTime = now; 16052 } 16053 int step = 0; 16054 int fgTrimLevel; 16055 switch (memFactor) { 16056 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16057 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16058 break; 16059 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16060 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16061 break; 16062 default: 16063 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16064 break; 16065 } 16066 int factor = numTrimming/3; 16067 int minFactor = 2; 16068 if (mHomeProcess != null) minFactor++; 16069 if (mPreviousProcess != null) minFactor++; 16070 if (factor < minFactor) factor = minFactor; 16071 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16072 for (int i=N-1; i>=0; i--) { 16073 ProcessRecord app = mLruProcesses.get(i); 16074 if (allChanged || app.procStateChanged) { 16075 setProcessTrackerState(app, trackerMemFactor, now); 16076 app.procStateChanged = false; 16077 } 16078 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16079 && !app.killedByAm) { 16080 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16081 try { 16082 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16083 "Trimming memory of " + app.processName 16084 + " to " + curLevel); 16085 app.thread.scheduleTrimMemory(curLevel); 16086 } catch (RemoteException e) { 16087 } 16088 if (false) { 16089 // For now we won't do this; our memory trimming seems 16090 // to be good enough at this point that destroying 16091 // activities causes more harm than good. 16092 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16093 && app != mHomeProcess && app != mPreviousProcess) { 16094 // Need to do this on its own message because the stack may not 16095 // be in a consistent state at this point. 16096 // For these apps we will also finish their activities 16097 // to help them free memory. 16098 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16099 } 16100 } 16101 } 16102 app.trimMemoryLevel = curLevel; 16103 step++; 16104 if (step >= factor) { 16105 step = 0; 16106 switch (curLevel) { 16107 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16108 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16109 break; 16110 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16111 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16112 break; 16113 } 16114 } 16115 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16116 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16117 && app.thread != null) { 16118 try { 16119 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16120 "Trimming memory of heavy-weight " + app.processName 16121 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16122 app.thread.scheduleTrimMemory( 16123 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16124 } catch (RemoteException e) { 16125 } 16126 } 16127 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16128 } else { 16129 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16130 || app.systemNoUi) && app.pendingUiClean) { 16131 // If this application is now in the background and it 16132 // had done UI, then give it the special trim level to 16133 // have it free UI resources. 16134 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16135 if (app.trimMemoryLevel < level && app.thread != null) { 16136 try { 16137 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16138 "Trimming memory of bg-ui " + app.processName 16139 + " to " + level); 16140 app.thread.scheduleTrimMemory(level); 16141 } catch (RemoteException e) { 16142 } 16143 } 16144 app.pendingUiClean = false; 16145 } 16146 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16147 try { 16148 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16149 "Trimming memory of fg " + app.processName 16150 + " to " + fgTrimLevel); 16151 app.thread.scheduleTrimMemory(fgTrimLevel); 16152 } catch (RemoteException e) { 16153 } 16154 } 16155 app.trimMemoryLevel = fgTrimLevel; 16156 } 16157 } 16158 } else { 16159 if (mLowRamStartTime != 0) { 16160 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16161 mLowRamStartTime = 0; 16162 } 16163 for (int i=N-1; i>=0; i--) { 16164 ProcessRecord app = mLruProcesses.get(i); 16165 if (allChanged || app.procStateChanged) { 16166 setProcessTrackerState(app, trackerMemFactor, now); 16167 app.procStateChanged = false; 16168 } 16169 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16170 || app.systemNoUi) && app.pendingUiClean) { 16171 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16172 && app.thread != null) { 16173 try { 16174 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16175 "Trimming memory of ui hidden " + app.processName 16176 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16177 app.thread.scheduleTrimMemory( 16178 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16179 } catch (RemoteException e) { 16180 } 16181 } 16182 app.pendingUiClean = false; 16183 } 16184 app.trimMemoryLevel = 0; 16185 } 16186 } 16187 16188 if (mAlwaysFinishActivities) { 16189 // Need to do this on its own message because the stack may not 16190 // be in a consistent state at this point. 16191 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16192 } 16193 16194 if (allChanged) { 16195 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16196 } 16197 16198 if (mProcessStats.shouldWriteNowLocked(now)) { 16199 mHandler.post(new Runnable() { 16200 @Override public void run() { 16201 synchronized (ActivityManagerService.this) { 16202 mProcessStats.writeStateAsyncLocked(); 16203 } 16204 } 16205 }); 16206 } 16207 16208 if (DEBUG_OOM_ADJ) { 16209 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16210 } 16211 } 16212 16213 final void trimApplications() { 16214 synchronized (this) { 16215 int i; 16216 16217 // First remove any unused application processes whose package 16218 // has been removed. 16219 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16220 final ProcessRecord app = mRemovedProcesses.get(i); 16221 if (app.activities.size() == 0 16222 && app.curReceiver == null && app.services.size() == 0) { 16223 Slog.i( 16224 TAG, "Exiting empty application process " 16225 + app.processName + " (" 16226 + (app.thread != null ? app.thread.asBinder() : null) 16227 + ")\n"); 16228 if (app.pid > 0 && app.pid != MY_PID) { 16229 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16230 app.processName, app.setAdj, "empty"); 16231 app.killedByAm = true; 16232 Process.killProcessQuiet(app.pid); 16233 } else { 16234 try { 16235 app.thread.scheduleExit(); 16236 } catch (Exception e) { 16237 // Ignore exceptions. 16238 } 16239 } 16240 cleanUpApplicationRecordLocked(app, false, true, -1); 16241 mRemovedProcesses.remove(i); 16242 16243 if (app.persistent) { 16244 if (app.persistent) { 16245 addAppLocked(app.info, false); 16246 } 16247 } 16248 } 16249 } 16250 16251 // Now update the oom adj for all processes. 16252 updateOomAdjLocked(); 16253 } 16254 } 16255 16256 /** This method sends the specified signal to each of the persistent apps */ 16257 public void signalPersistentProcesses(int sig) throws RemoteException { 16258 if (sig != Process.SIGNAL_USR1) { 16259 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16260 } 16261 16262 synchronized (this) { 16263 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16264 != PackageManager.PERMISSION_GRANTED) { 16265 throw new SecurityException("Requires permission " 16266 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16267 } 16268 16269 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16270 ProcessRecord r = mLruProcesses.get(i); 16271 if (r.thread != null && r.persistent) { 16272 Process.sendSignal(r.pid, sig); 16273 } 16274 } 16275 } 16276 } 16277 16278 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16279 if (proc == null || proc == mProfileProc) { 16280 proc = mProfileProc; 16281 path = mProfileFile; 16282 profileType = mProfileType; 16283 clearProfilerLocked(); 16284 } 16285 if (proc == null) { 16286 return; 16287 } 16288 try { 16289 proc.thread.profilerControl(false, path, null, profileType); 16290 } catch (RemoteException e) { 16291 throw new IllegalStateException("Process disappeared"); 16292 } 16293 } 16294 16295 private void clearProfilerLocked() { 16296 if (mProfileFd != null) { 16297 try { 16298 mProfileFd.close(); 16299 } catch (IOException e) { 16300 } 16301 } 16302 mProfileApp = null; 16303 mProfileProc = null; 16304 mProfileFile = null; 16305 mProfileType = 0; 16306 mAutoStopProfiler = false; 16307 } 16308 16309 public boolean profileControl(String process, int userId, boolean start, 16310 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16311 16312 try { 16313 synchronized (this) { 16314 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16315 // its own permission. 16316 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16317 != PackageManager.PERMISSION_GRANTED) { 16318 throw new SecurityException("Requires permission " 16319 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16320 } 16321 16322 if (start && fd == null) { 16323 throw new IllegalArgumentException("null fd"); 16324 } 16325 16326 ProcessRecord proc = null; 16327 if (process != null) { 16328 proc = findProcessLocked(process, userId, "profileControl"); 16329 } 16330 16331 if (start && (proc == null || proc.thread == null)) { 16332 throw new IllegalArgumentException("Unknown process: " + process); 16333 } 16334 16335 if (start) { 16336 stopProfilerLocked(null, null, 0); 16337 setProfileApp(proc.info, proc.processName, path, fd, false); 16338 mProfileProc = proc; 16339 mProfileType = profileType; 16340 try { 16341 fd = fd.dup(); 16342 } catch (IOException e) { 16343 fd = null; 16344 } 16345 proc.thread.profilerControl(start, path, fd, profileType); 16346 fd = null; 16347 mProfileFd = null; 16348 } else { 16349 stopProfilerLocked(proc, path, profileType); 16350 if (fd != null) { 16351 try { 16352 fd.close(); 16353 } catch (IOException e) { 16354 } 16355 } 16356 } 16357 16358 return true; 16359 } 16360 } catch (RemoteException e) { 16361 throw new IllegalStateException("Process disappeared"); 16362 } finally { 16363 if (fd != null) { 16364 try { 16365 fd.close(); 16366 } catch (IOException e) { 16367 } 16368 } 16369 } 16370 } 16371 16372 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16373 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16374 userId, true, true, callName, null); 16375 ProcessRecord proc = null; 16376 try { 16377 int pid = Integer.parseInt(process); 16378 synchronized (mPidsSelfLocked) { 16379 proc = mPidsSelfLocked.get(pid); 16380 } 16381 } catch (NumberFormatException e) { 16382 } 16383 16384 if (proc == null) { 16385 ArrayMap<String, SparseArray<ProcessRecord>> all 16386 = mProcessNames.getMap(); 16387 SparseArray<ProcessRecord> procs = all.get(process); 16388 if (procs != null && procs.size() > 0) { 16389 proc = procs.valueAt(0); 16390 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16391 for (int i=1; i<procs.size(); i++) { 16392 ProcessRecord thisProc = procs.valueAt(i); 16393 if (thisProc.userId == userId) { 16394 proc = thisProc; 16395 break; 16396 } 16397 } 16398 } 16399 } 16400 } 16401 16402 return proc; 16403 } 16404 16405 public boolean dumpHeap(String process, int userId, boolean managed, 16406 String path, ParcelFileDescriptor fd) throws RemoteException { 16407 16408 try { 16409 synchronized (this) { 16410 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16411 // its own permission (same as profileControl). 16412 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16413 != PackageManager.PERMISSION_GRANTED) { 16414 throw new SecurityException("Requires permission " 16415 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16416 } 16417 16418 if (fd == null) { 16419 throw new IllegalArgumentException("null fd"); 16420 } 16421 16422 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16423 if (proc == null || proc.thread == null) { 16424 throw new IllegalArgumentException("Unknown process: " + process); 16425 } 16426 16427 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16428 if (!isDebuggable) { 16429 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16430 throw new SecurityException("Process not debuggable: " + proc); 16431 } 16432 } 16433 16434 proc.thread.dumpHeap(managed, path, fd); 16435 fd = null; 16436 return true; 16437 } 16438 } catch (RemoteException e) { 16439 throw new IllegalStateException("Process disappeared"); 16440 } finally { 16441 if (fd != null) { 16442 try { 16443 fd.close(); 16444 } catch (IOException e) { 16445 } 16446 } 16447 } 16448 } 16449 16450 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16451 public void monitor() { 16452 synchronized (this) { } 16453 } 16454 16455 void onCoreSettingsChange(Bundle settings) { 16456 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16457 ProcessRecord processRecord = mLruProcesses.get(i); 16458 try { 16459 if (processRecord.thread != null) { 16460 processRecord.thread.setCoreSettings(settings); 16461 } 16462 } catch (RemoteException re) { 16463 /* ignore */ 16464 } 16465 } 16466 } 16467 16468 // Multi-user methods 16469 16470 /** 16471 * Start user, if its not already running, but don't bring it to foreground. 16472 */ 16473 @Override 16474 public boolean startUserInBackground(final int userId) { 16475 return startUser(userId, /* foreground */ false); 16476 } 16477 16478 /** 16479 * Refreshes the list of users related to the current user when either a 16480 * user switch happens or when a new related user is started in the 16481 * background. 16482 */ 16483 private void updateCurrentProfileIdsLocked() { 16484 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16485 mCurrentUserId, false /* enabledOnly */); 16486 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16487 for (int i = 0; i < currentProfileIds.length; i++) { 16488 currentProfileIds[i] = profiles.get(i).id; 16489 } 16490 mCurrentProfileIds = currentProfileIds; 16491 } 16492 16493 private Set getProfileIdsLocked(int userId) { 16494 Set userIds = new HashSet<Integer>(); 16495 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16496 userId, false /* enabledOnly */); 16497 for (UserInfo user : profiles) { 16498 userIds.add(Integer.valueOf(user.id)); 16499 } 16500 return userIds; 16501 } 16502 16503 @Override 16504 public boolean switchUser(final int userId) { 16505 return startUser(userId, /* foregound */ true); 16506 } 16507 16508 private boolean startUser(final int userId, boolean foreground) { 16509 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16510 != PackageManager.PERMISSION_GRANTED) { 16511 String msg = "Permission Denial: switchUser() from pid=" 16512 + Binder.getCallingPid() 16513 + ", uid=" + Binder.getCallingUid() 16514 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16515 Slog.w(TAG, msg); 16516 throw new SecurityException(msg); 16517 } 16518 16519 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16520 16521 final long ident = Binder.clearCallingIdentity(); 16522 try { 16523 synchronized (this) { 16524 final int oldUserId = mCurrentUserId; 16525 if (oldUserId == userId) { 16526 return true; 16527 } 16528 16529 mStackSupervisor.setLockTaskModeLocked(null); 16530 16531 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16532 if (userInfo == null) { 16533 Slog.w(TAG, "No user info for user #" + userId); 16534 return false; 16535 } 16536 16537 if (foreground) { 16538 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16539 R.anim.screen_user_enter); 16540 } 16541 16542 boolean needStart = false; 16543 16544 // If the user we are switching to is not currently started, then 16545 // we need to start it now. 16546 if (mStartedUsers.get(userId) == null) { 16547 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16548 updateStartedUserArrayLocked(); 16549 needStart = true; 16550 } 16551 16552 final Integer userIdInt = Integer.valueOf(userId); 16553 mUserLru.remove(userIdInt); 16554 mUserLru.add(userIdInt); 16555 16556 if (foreground) { 16557 mCurrentUserId = userId; 16558 updateCurrentProfileIdsLocked(); 16559 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16560 // Once the internal notion of the active user has switched, we lock the device 16561 // with the option to show the user switcher on the keyguard. 16562 mWindowManager.lockNow(null); 16563 } else { 16564 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16565 updateCurrentProfileIdsLocked(); 16566 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16567 mUserLru.remove(currentUserIdInt); 16568 mUserLru.add(currentUserIdInt); 16569 } 16570 16571 final UserStartedState uss = mStartedUsers.get(userId); 16572 16573 // Make sure user is in the started state. If it is currently 16574 // stopping, we need to knock that off. 16575 if (uss.mState == UserStartedState.STATE_STOPPING) { 16576 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16577 // so we can just fairly silently bring the user back from 16578 // the almost-dead. 16579 uss.mState = UserStartedState.STATE_RUNNING; 16580 updateStartedUserArrayLocked(); 16581 needStart = true; 16582 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16583 // This means ACTION_SHUTDOWN has been sent, so we will 16584 // need to treat this as a new boot of the user. 16585 uss.mState = UserStartedState.STATE_BOOTING; 16586 updateStartedUserArrayLocked(); 16587 needStart = true; 16588 } 16589 16590 if (uss.mState == UserStartedState.STATE_BOOTING) { 16591 // Booting up a new user, need to tell system services about it. 16592 // Note that this is on the same handler as scheduling of broadcasts, 16593 // which is important because it needs to go first. 16594 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16595 } 16596 16597 if (foreground) { 16598 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16599 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16600 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16601 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16602 oldUserId, userId, uss)); 16603 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16604 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16605 } 16606 16607 if (needStart) { 16608 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16609 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16610 | Intent.FLAG_RECEIVER_FOREGROUND); 16611 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16612 broadcastIntentLocked(null, null, intent, 16613 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16614 false, false, MY_PID, Process.SYSTEM_UID, userId); 16615 } 16616 16617 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16618 if (userId != UserHandle.USER_OWNER) { 16619 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16620 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16621 broadcastIntentLocked(null, null, intent, null, 16622 new IIntentReceiver.Stub() { 16623 public void performReceive(Intent intent, int resultCode, 16624 String data, Bundle extras, boolean ordered, 16625 boolean sticky, int sendingUser) { 16626 userInitialized(uss, userId); 16627 } 16628 }, 0, null, null, null, AppOpsManager.OP_NONE, 16629 true, false, MY_PID, Process.SYSTEM_UID, 16630 userId); 16631 uss.initializing = true; 16632 } else { 16633 getUserManagerLocked().makeInitialized(userInfo.id); 16634 } 16635 } 16636 16637 if (foreground) { 16638 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16639 if (homeInFront) { 16640 startHomeActivityLocked(userId); 16641 } else { 16642 mStackSupervisor.resumeTopActivitiesLocked(); 16643 } 16644 EventLogTags.writeAmSwitchUser(userId); 16645 getUserManagerLocked().userForeground(userId); 16646 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16647 } else { 16648 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16649 } 16650 16651 if (needStart) { 16652 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16653 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16654 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16655 broadcastIntentLocked(null, null, intent, 16656 null, new IIntentReceiver.Stub() { 16657 @Override 16658 public void performReceive(Intent intent, int resultCode, String data, 16659 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16660 throws RemoteException { 16661 } 16662 }, 0, null, null, 16663 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16664 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16665 } 16666 } 16667 } finally { 16668 Binder.restoreCallingIdentity(ident); 16669 } 16670 16671 return true; 16672 } 16673 16674 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16675 long ident = Binder.clearCallingIdentity(); 16676 try { 16677 Intent intent; 16678 if (oldUserId >= 0) { 16679 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16680 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16681 | Intent.FLAG_RECEIVER_FOREGROUND); 16682 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16683 broadcastIntentLocked(null, null, intent, 16684 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16685 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16686 } 16687 if (newUserId >= 0) { 16688 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16689 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16690 | Intent.FLAG_RECEIVER_FOREGROUND); 16691 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16692 broadcastIntentLocked(null, null, intent, 16693 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16694 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16695 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16697 | Intent.FLAG_RECEIVER_FOREGROUND); 16698 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16699 broadcastIntentLocked(null, null, intent, 16700 null, null, 0, null, null, 16701 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16702 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16703 } 16704 } finally { 16705 Binder.restoreCallingIdentity(ident); 16706 } 16707 } 16708 16709 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16710 final int newUserId) { 16711 final int N = mUserSwitchObservers.beginBroadcast(); 16712 if (N > 0) { 16713 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16714 int mCount = 0; 16715 @Override 16716 public void sendResult(Bundle data) throws RemoteException { 16717 synchronized (ActivityManagerService.this) { 16718 if (mCurUserSwitchCallback == this) { 16719 mCount++; 16720 if (mCount == N) { 16721 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16722 } 16723 } 16724 } 16725 } 16726 }; 16727 synchronized (this) { 16728 uss.switching = true; 16729 mCurUserSwitchCallback = callback; 16730 } 16731 for (int i=0; i<N; i++) { 16732 try { 16733 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16734 newUserId, callback); 16735 } catch (RemoteException e) { 16736 } 16737 } 16738 } else { 16739 synchronized (this) { 16740 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16741 } 16742 } 16743 mUserSwitchObservers.finishBroadcast(); 16744 } 16745 16746 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16747 synchronized (this) { 16748 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16749 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16750 } 16751 } 16752 16753 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16754 mCurUserSwitchCallback = null; 16755 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16756 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16757 oldUserId, newUserId, uss)); 16758 } 16759 16760 void userInitialized(UserStartedState uss, int newUserId) { 16761 completeSwitchAndInitalize(uss, newUserId, true, false); 16762 } 16763 16764 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16765 completeSwitchAndInitalize(uss, newUserId, false, true); 16766 } 16767 16768 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16769 boolean clearInitializing, boolean clearSwitching) { 16770 boolean unfrozen = false; 16771 synchronized (this) { 16772 if (clearInitializing) { 16773 uss.initializing = false; 16774 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16775 } 16776 if (clearSwitching) { 16777 uss.switching = false; 16778 } 16779 if (!uss.switching && !uss.initializing) { 16780 mWindowManager.stopFreezingScreen(); 16781 unfrozen = true; 16782 } 16783 } 16784 if (unfrozen) { 16785 final int N = mUserSwitchObservers.beginBroadcast(); 16786 for (int i=0; i<N; i++) { 16787 try { 16788 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16789 } catch (RemoteException e) { 16790 } 16791 } 16792 mUserSwitchObservers.finishBroadcast(); 16793 } 16794 } 16795 16796 void scheduleStartProfilesLocked() { 16797 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16798 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16799 DateUtils.SECOND_IN_MILLIS); 16800 } 16801 } 16802 16803 void startProfilesLocked() { 16804 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16805 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16806 mCurrentUserId, false /* enabledOnly */); 16807 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16808 for (UserInfo user : profiles) { 16809 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16810 && user.id != mCurrentUserId) { 16811 toStart.add(user); 16812 } 16813 } 16814 final int n = toStart.size(); 16815 int i = 0; 16816 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16817 startUserInBackground(toStart.get(i).id); 16818 } 16819 if (i < n) { 16820 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16821 } 16822 } 16823 16824 void finishUserBoot(UserStartedState uss) { 16825 synchronized (this) { 16826 if (uss.mState == UserStartedState.STATE_BOOTING 16827 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16828 uss.mState = UserStartedState.STATE_RUNNING; 16829 final int userId = uss.mHandle.getIdentifier(); 16830 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16831 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16832 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16833 broadcastIntentLocked(null, null, intent, 16834 null, null, 0, null, null, 16835 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16836 true, false, MY_PID, Process.SYSTEM_UID, userId); 16837 } 16838 } 16839 } 16840 16841 void finishUserSwitch(UserStartedState uss) { 16842 synchronized (this) { 16843 finishUserBoot(uss); 16844 16845 startProfilesLocked(); 16846 16847 int num = mUserLru.size(); 16848 int i = 0; 16849 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16850 Integer oldUserId = mUserLru.get(i); 16851 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16852 if (oldUss == null) { 16853 // Shouldn't happen, but be sane if it does. 16854 mUserLru.remove(i); 16855 num--; 16856 continue; 16857 } 16858 if (oldUss.mState == UserStartedState.STATE_STOPPING 16859 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16860 // This user is already stopping, doesn't count. 16861 num--; 16862 i++; 16863 continue; 16864 } 16865 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16866 // Owner and current can't be stopped, but count as running. 16867 i++; 16868 continue; 16869 } 16870 // This is a user to be stopped. 16871 stopUserLocked(oldUserId, null); 16872 num--; 16873 i++; 16874 } 16875 } 16876 } 16877 16878 @Override 16879 public int stopUser(final int userId, final IStopUserCallback callback) { 16880 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16881 != PackageManager.PERMISSION_GRANTED) { 16882 String msg = "Permission Denial: switchUser() from pid=" 16883 + Binder.getCallingPid() 16884 + ", uid=" + Binder.getCallingUid() 16885 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16886 Slog.w(TAG, msg); 16887 throw new SecurityException(msg); 16888 } 16889 if (userId <= 0) { 16890 throw new IllegalArgumentException("Can't stop primary user " + userId); 16891 } 16892 synchronized (this) { 16893 return stopUserLocked(userId, callback); 16894 } 16895 } 16896 16897 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16898 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16899 if (mCurrentUserId == userId) { 16900 return ActivityManager.USER_OP_IS_CURRENT; 16901 } 16902 16903 final UserStartedState uss = mStartedUsers.get(userId); 16904 if (uss == null) { 16905 // User is not started, nothing to do... but we do need to 16906 // callback if requested. 16907 if (callback != null) { 16908 mHandler.post(new Runnable() { 16909 @Override 16910 public void run() { 16911 try { 16912 callback.userStopped(userId); 16913 } catch (RemoteException e) { 16914 } 16915 } 16916 }); 16917 } 16918 return ActivityManager.USER_OP_SUCCESS; 16919 } 16920 16921 if (callback != null) { 16922 uss.mStopCallbacks.add(callback); 16923 } 16924 16925 if (uss.mState != UserStartedState.STATE_STOPPING 16926 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16927 uss.mState = UserStartedState.STATE_STOPPING; 16928 updateStartedUserArrayLocked(); 16929 16930 long ident = Binder.clearCallingIdentity(); 16931 try { 16932 // We are going to broadcast ACTION_USER_STOPPING and then 16933 // once that is done send a final ACTION_SHUTDOWN and then 16934 // stop the user. 16935 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16936 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16937 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16938 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16939 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16940 // This is the result receiver for the final shutdown broadcast. 16941 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16942 @Override 16943 public void performReceive(Intent intent, int resultCode, String data, 16944 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16945 finishUserStop(uss); 16946 } 16947 }; 16948 // This is the result receiver for the initial stopping broadcast. 16949 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16950 @Override 16951 public void performReceive(Intent intent, int resultCode, String data, 16952 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16953 // On to the next. 16954 synchronized (ActivityManagerService.this) { 16955 if (uss.mState != UserStartedState.STATE_STOPPING) { 16956 // Whoops, we are being started back up. Abort, abort! 16957 return; 16958 } 16959 uss.mState = UserStartedState.STATE_SHUTDOWN; 16960 } 16961 mSystemServiceManager.stopUser(userId); 16962 broadcastIntentLocked(null, null, shutdownIntent, 16963 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16964 true, false, MY_PID, Process.SYSTEM_UID, userId); 16965 } 16966 }; 16967 // Kick things off. 16968 broadcastIntentLocked(null, null, stoppingIntent, 16969 null, stoppingReceiver, 0, null, null, 16970 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16971 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16972 } finally { 16973 Binder.restoreCallingIdentity(ident); 16974 } 16975 } 16976 16977 return ActivityManager.USER_OP_SUCCESS; 16978 } 16979 16980 void finishUserStop(UserStartedState uss) { 16981 final int userId = uss.mHandle.getIdentifier(); 16982 boolean stopped; 16983 ArrayList<IStopUserCallback> callbacks; 16984 synchronized (this) { 16985 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16986 if (mStartedUsers.get(userId) != uss) { 16987 stopped = false; 16988 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16989 stopped = false; 16990 } else { 16991 stopped = true; 16992 // User can no longer run. 16993 mStartedUsers.remove(userId); 16994 mUserLru.remove(Integer.valueOf(userId)); 16995 updateStartedUserArrayLocked(); 16996 16997 // Clean up all state and processes associated with the user. 16998 // Kill all the processes for the user. 16999 forceStopUserLocked(userId, "finish user"); 17000 } 17001 } 17002 17003 for (int i=0; i<callbacks.size(); i++) { 17004 try { 17005 if (stopped) callbacks.get(i).userStopped(userId); 17006 else callbacks.get(i).userStopAborted(userId); 17007 } catch (RemoteException e) { 17008 } 17009 } 17010 17011 if (stopped) { 17012 mSystemServiceManager.cleanupUser(userId); 17013 synchronized (this) { 17014 mStackSupervisor.removeUserLocked(userId); 17015 } 17016 } 17017 } 17018 17019 @Override 17020 public UserInfo getCurrentUser() { 17021 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17022 != PackageManager.PERMISSION_GRANTED) && ( 17023 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17024 != PackageManager.PERMISSION_GRANTED)) { 17025 String msg = "Permission Denial: getCurrentUser() from pid=" 17026 + Binder.getCallingPid() 17027 + ", uid=" + Binder.getCallingUid() 17028 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17029 Slog.w(TAG, msg); 17030 throw new SecurityException(msg); 17031 } 17032 synchronized (this) { 17033 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17034 } 17035 } 17036 17037 int getCurrentUserIdLocked() { 17038 return mCurrentUserId; 17039 } 17040 17041 @Override 17042 public boolean isUserRunning(int userId, boolean orStopped) { 17043 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17044 != PackageManager.PERMISSION_GRANTED) { 17045 String msg = "Permission Denial: isUserRunning() from pid=" 17046 + Binder.getCallingPid() 17047 + ", uid=" + Binder.getCallingUid() 17048 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17049 Slog.w(TAG, msg); 17050 throw new SecurityException(msg); 17051 } 17052 synchronized (this) { 17053 return isUserRunningLocked(userId, orStopped); 17054 } 17055 } 17056 17057 boolean isUserRunningLocked(int userId, boolean orStopped) { 17058 UserStartedState state = mStartedUsers.get(userId); 17059 if (state == null) { 17060 return false; 17061 } 17062 if (orStopped) { 17063 return true; 17064 } 17065 return state.mState != UserStartedState.STATE_STOPPING 17066 && state.mState != UserStartedState.STATE_SHUTDOWN; 17067 } 17068 17069 @Override 17070 public int[] getRunningUserIds() { 17071 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17072 != PackageManager.PERMISSION_GRANTED) { 17073 String msg = "Permission Denial: isUserRunning() from pid=" 17074 + Binder.getCallingPid() 17075 + ", uid=" + Binder.getCallingUid() 17076 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17077 Slog.w(TAG, msg); 17078 throw new SecurityException(msg); 17079 } 17080 synchronized (this) { 17081 return mStartedUserArray; 17082 } 17083 } 17084 17085 private void updateStartedUserArrayLocked() { 17086 int num = 0; 17087 for (int i=0; i<mStartedUsers.size(); i++) { 17088 UserStartedState uss = mStartedUsers.valueAt(i); 17089 // This list does not include stopping users. 17090 if (uss.mState != UserStartedState.STATE_STOPPING 17091 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17092 num++; 17093 } 17094 } 17095 mStartedUserArray = new int[num]; 17096 num = 0; 17097 for (int i=0; i<mStartedUsers.size(); i++) { 17098 UserStartedState uss = mStartedUsers.valueAt(i); 17099 if (uss.mState != UserStartedState.STATE_STOPPING 17100 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17101 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17102 num++; 17103 } 17104 } 17105 } 17106 17107 @Override 17108 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17109 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17110 != PackageManager.PERMISSION_GRANTED) { 17111 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17112 + Binder.getCallingPid() 17113 + ", uid=" + Binder.getCallingUid() 17114 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17115 Slog.w(TAG, msg); 17116 throw new SecurityException(msg); 17117 } 17118 17119 mUserSwitchObservers.register(observer); 17120 } 17121 17122 @Override 17123 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17124 mUserSwitchObservers.unregister(observer); 17125 } 17126 17127 private boolean userExists(int userId) { 17128 if (userId == 0) { 17129 return true; 17130 } 17131 UserManagerService ums = getUserManagerLocked(); 17132 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17133 } 17134 17135 int[] getUsersLocked() { 17136 UserManagerService ums = getUserManagerLocked(); 17137 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17138 } 17139 17140 UserManagerService getUserManagerLocked() { 17141 if (mUserManager == null) { 17142 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17143 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17144 } 17145 return mUserManager; 17146 } 17147 17148 private int applyUserId(int uid, int userId) { 17149 return UserHandle.getUid(userId, uid); 17150 } 17151 17152 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17153 if (info == null) return null; 17154 ApplicationInfo newInfo = new ApplicationInfo(info); 17155 newInfo.uid = applyUserId(info.uid, userId); 17156 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17157 + info.packageName; 17158 return newInfo; 17159 } 17160 17161 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17162 if (aInfo == null 17163 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17164 return aInfo; 17165 } 17166 17167 ActivityInfo info = new ActivityInfo(aInfo); 17168 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17169 return info; 17170 } 17171 17172 private final class LocalService extends ActivityManagerInternal { 17173 @Override 17174 public void goingToSleep() { 17175 ActivityManagerService.this.goingToSleep(); 17176 } 17177 17178 @Override 17179 public void wakingUp() { 17180 ActivityManagerService.this.wakingUp(); 17181 } 17182 } 17183 17184 /** 17185 * An implementation of IAppTask, that allows an app to manage its own tasks via 17186 * {@link android.app.ActivityManager#AppTask}. We keep track of the callingUid to ensure that 17187 * only the process that calls getAppTasks() can call the AppTask methods. 17188 */ 17189 class AppTaskImpl extends IAppTask.Stub { 17190 private int mTaskId; 17191 private int mCallingUid; 17192 17193 public AppTaskImpl(int taskId, int callingUid) { 17194 mTaskId = taskId; 17195 mCallingUid = callingUid; 17196 } 17197 17198 @Override 17199 public void finishAndRemoveTask() { 17200 // Ensure that we are called from the same process that created this AppTask 17201 if (mCallingUid != Binder.getCallingUid()) { 17202 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17203 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17204 return; 17205 } 17206 17207 synchronized (ActivityManagerService.this) { 17208 long origId = Binder.clearCallingIdentity(); 17209 try { 17210 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17211 if (tr != null) { 17212 // Only kill the process if we are not a new document 17213 int flags = tr.getBaseIntent().getFlags(); 17214 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17215 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17216 removeTaskByIdLocked(mTaskId, 17217 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17218 } 17219 } finally { 17220 Binder.restoreCallingIdentity(origId); 17221 } 17222 } 17223 } 17224 17225 @Override 17226 public ActivityManager.RecentTaskInfo getTaskInfo() { 17227 // Ensure that we are called from the same process that created this AppTask 17228 if (mCallingUid != Binder.getCallingUid()) { 17229 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17230 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17231 return null; 17232 } 17233 17234 synchronized (ActivityManagerService.this) { 17235 long origId = Binder.clearCallingIdentity(); 17236 try { 17237 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17238 if (tr != null) { 17239 return createRecentTaskInfoFromTaskRecord(tr); 17240 } 17241 } finally { 17242 Binder.restoreCallingIdentity(origId); 17243 } 17244 return null; 17245 } 17246 } 17247 } 17248} 17249