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