ActivityManagerService.java revision c6cf95c0f5f7250c65e40c441fe58d8cbfd114c9
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 = 1200*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 ArrayList<TaskRecord> mRecentTasks; 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 * Save recent tasks information across reboots. 826 */ 827 final TaskPersister mTaskPersister; 828 829 /** 830 * Current configuration information. HistoryRecord objects are given 831 * a reference to this object to indicate which configuration they are 832 * currently running in, so this object must be kept immutable. 833 */ 834 Configuration mConfiguration = new Configuration(); 835 836 /** 837 * Current sequencing integer of the configuration, for skipping old 838 * configurations. 839 */ 840 int mConfigurationSeq = 0; 841 842 /** 843 * Hardware-reported OpenGLES version. 844 */ 845 final int GL_ES_VERSION; 846 847 /** 848 * List of initialization arguments to pass to all processes when binding applications to them. 849 * For example, references to the commonly used services. 850 */ 851 HashMap<String, IBinder> mAppBindArgs; 852 853 /** 854 * Temporary to avoid allocations. Protected by main lock. 855 */ 856 final StringBuilder mStringBuilder = new StringBuilder(256); 857 858 /** 859 * Used to control how we initialize the service. 860 */ 861 ComponentName mTopComponent; 862 String mTopAction = Intent.ACTION_MAIN; 863 String mTopData; 864 boolean mProcessesReady = false; 865 boolean mSystemReady = false; 866 boolean mBooting = false; 867 boolean mWaitingUpdate = false; 868 boolean mDidUpdate = false; 869 boolean mOnBattery = false; 870 boolean mLaunchWarningShown = false; 871 872 Context mContext; 873 874 int mFactoryTest; 875 876 boolean mCheckedForSetup; 877 878 /** 879 * The time at which we will allow normal application switches again, 880 * after a call to {@link #stopAppSwitches()}. 881 */ 882 long mAppSwitchesAllowedTime; 883 884 /** 885 * This is set to true after the first switch after mAppSwitchesAllowedTime 886 * is set; any switches after that will clear the time. 887 */ 888 boolean mDidAppSwitch; 889 890 /** 891 * Last time (in realtime) at which we checked for power usage. 892 */ 893 long mLastPowerCheckRealtime; 894 895 /** 896 * Last time (in uptime) at which we checked for power usage. 897 */ 898 long mLastPowerCheckUptime; 899 900 /** 901 * Set while we are wanting to sleep, to prevent any 902 * activities from being started/resumed. 903 */ 904 private boolean mSleeping = false; 905 906 /** 907 * Set while we are running a voice interaction. This overrides 908 * sleeping while it is active. 909 */ 910 private boolean mRunningVoice = false; 911 912 /** 913 * State of external calls telling us if the device is asleep. 914 */ 915 private boolean mWentToSleep = false; 916 917 /** 918 * State of external call telling us if the lock screen is shown. 919 */ 920 private boolean mLockScreenShown = false; 921 922 /** 923 * Set if we are shutting down the system, similar to sleeping. 924 */ 925 boolean mShuttingDown = false; 926 927 /** 928 * Current sequence id for oom_adj computation traversal. 929 */ 930 int mAdjSeq = 0; 931 932 /** 933 * Current sequence id for process LRU updating. 934 */ 935 int mLruSeq = 0; 936 937 /** 938 * Keep track of the non-cached/empty process we last found, to help 939 * determine how to distribute cached/empty processes next time. 940 */ 941 int mNumNonCachedProcs = 0; 942 943 /** 944 * Keep track of the number of cached hidden procs, to balance oom adj 945 * distribution between those and empty procs. 946 */ 947 int mNumCachedHiddenProcs = 0; 948 949 /** 950 * Keep track of the number of service processes we last found, to 951 * determine on the next iteration which should be B services. 952 */ 953 int mNumServiceProcs = 0; 954 int mNewNumAServiceProcs = 0; 955 int mNewNumServiceProcs = 0; 956 957 /** 958 * Allow the current computed overall memory level of the system to go down? 959 * This is set to false when we are killing processes for reasons other than 960 * memory management, so that the now smaller process list will not be taken as 961 * an indication that memory is tighter. 962 */ 963 boolean mAllowLowerMemLevel = false; 964 965 /** 966 * The last computed memory level, for holding when we are in a state that 967 * processes are going away for other reasons. 968 */ 969 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 970 971 /** 972 * The last total number of process we have, to determine if changes actually look 973 * like a shrinking number of process due to lower RAM. 974 */ 975 int mLastNumProcesses; 976 977 /** 978 * The uptime of the last time we performed idle maintenance. 979 */ 980 long mLastIdleTime = SystemClock.uptimeMillis(); 981 982 /** 983 * Total time spent with RAM that has been added in the past since the last idle time. 984 */ 985 long mLowRamTimeSinceLastIdle = 0; 986 987 /** 988 * If RAM is currently low, when that horrible situation started. 989 */ 990 long mLowRamStartTime = 0; 991 992 /** 993 * For reporting to battery stats the current top application. 994 */ 995 private String mCurResumedPackage = null; 996 private int mCurResumedUid = -1; 997 998 /** 999 * For reporting to battery stats the apps currently running foreground 1000 * service. The ProcessMap is package/uid tuples; each of these contain 1001 * an array of the currently foreground processes. 1002 */ 1003 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1004 = new ProcessMap<ArrayList<ProcessRecord>>(); 1005 1006 /** 1007 * This is set if we had to do a delayed dexopt of an app before launching 1008 * it, to increase the ANR timeouts in that case. 1009 */ 1010 boolean mDidDexOpt; 1011 1012 /** 1013 * Set if the systemServer made a call to enterSafeMode. 1014 */ 1015 boolean mSafeMode; 1016 1017 String mDebugApp = null; 1018 boolean mWaitForDebugger = false; 1019 boolean mDebugTransient = false; 1020 String mOrigDebugApp = null; 1021 boolean mOrigWaitForDebugger = false; 1022 boolean mAlwaysFinishActivities = false; 1023 IActivityController mController = null; 1024 String mProfileApp = null; 1025 ProcessRecord mProfileProc = null; 1026 String mProfileFile; 1027 ParcelFileDescriptor mProfileFd; 1028 int mProfileType = 0; 1029 boolean mAutoStopProfiler = false; 1030 String mOpenGlTraceApp = null; 1031 1032 static class ProcessChangeItem { 1033 static final int CHANGE_ACTIVITIES = 1<<0; 1034 static final int CHANGE_PROCESS_STATE = 1<<1; 1035 int changes; 1036 int uid; 1037 int pid; 1038 int processState; 1039 boolean foregroundActivities; 1040 } 1041 1042 final RemoteCallbackList<IProcessObserver> mProcessObservers 1043 = new RemoteCallbackList<IProcessObserver>(); 1044 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1045 1046 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1047 = new ArrayList<ProcessChangeItem>(); 1048 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1049 = new ArrayList<ProcessChangeItem>(); 1050 1051 /** 1052 * Runtime CPU use collection thread. This object's lock is used to 1053 * protect all related state. 1054 */ 1055 final Thread mProcessCpuThread; 1056 1057 /** 1058 * Used to collect process stats when showing not responding dialog. 1059 * Protected by mProcessCpuThread. 1060 */ 1061 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1062 MONITOR_THREAD_CPU_USAGE); 1063 final AtomicLong mLastCpuTime = new AtomicLong(0); 1064 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1065 1066 long mLastWriteTime = 0; 1067 1068 /** 1069 * Used to retain an update lock when the foreground activity is in 1070 * immersive mode. 1071 */ 1072 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1073 1074 /** 1075 * Set to true after the system has finished booting. 1076 */ 1077 boolean mBooted = false; 1078 1079 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1080 int mProcessLimitOverride = -1; 1081 1082 WindowManagerService mWindowManager; 1083 1084 final ActivityThread mSystemThread; 1085 1086 int mCurrentUserId = 0; 1087 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1088 private UserManagerService mUserManager; 1089 1090 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1091 final ProcessRecord mApp; 1092 final int mPid; 1093 final IApplicationThread mAppThread; 1094 1095 AppDeathRecipient(ProcessRecord app, int pid, 1096 IApplicationThread thread) { 1097 if (localLOGV) Slog.v( 1098 TAG, "New death recipient " + this 1099 + " for thread " + thread.asBinder()); 1100 mApp = app; 1101 mPid = pid; 1102 mAppThread = thread; 1103 } 1104 1105 @Override 1106 public void binderDied() { 1107 if (localLOGV) Slog.v( 1108 TAG, "Death received in " + this 1109 + " for thread " + mAppThread.asBinder()); 1110 synchronized(ActivityManagerService.this) { 1111 appDiedLocked(mApp, mPid, mAppThread); 1112 } 1113 } 1114 } 1115 1116 static final int SHOW_ERROR_MSG = 1; 1117 static final int SHOW_NOT_RESPONDING_MSG = 2; 1118 static final int SHOW_FACTORY_ERROR_MSG = 3; 1119 static final int UPDATE_CONFIGURATION_MSG = 4; 1120 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1121 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1122 static final int SERVICE_TIMEOUT_MSG = 12; 1123 static final int UPDATE_TIME_ZONE = 13; 1124 static final int SHOW_UID_ERROR_MSG = 14; 1125 static final int IM_FEELING_LUCKY_MSG = 15; 1126 static final int PROC_START_TIMEOUT_MSG = 20; 1127 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1128 static final int KILL_APPLICATION_MSG = 22; 1129 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1130 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1131 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1132 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1133 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1134 static final int CLEAR_DNS_CACHE_MSG = 28; 1135 static final int UPDATE_HTTP_PROXY_MSG = 29; 1136 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1137 static final int DISPATCH_PROCESSES_CHANGED = 31; 1138 static final int DISPATCH_PROCESS_DIED = 32; 1139 static final int REPORT_MEM_USAGE_MSG = 33; 1140 static final int REPORT_USER_SWITCH_MSG = 34; 1141 static final int CONTINUE_USER_SWITCH_MSG = 35; 1142 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1143 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1144 static final int PERSIST_URI_GRANTS_MSG = 38; 1145 static final int REQUEST_ALL_PSS_MSG = 39; 1146 static final int START_PROFILES_MSG = 40; 1147 static final int UPDATE_TIME = 41; 1148 static final int SYSTEM_USER_START_MSG = 42; 1149 static final int SYSTEM_USER_CURRENT_MSG = 43; 1150 1151 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1152 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1153 static final int FIRST_COMPAT_MODE_MSG = 300; 1154 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1155 1156 AlertDialog mUidAlert; 1157 CompatModeDialog mCompatModeDialog; 1158 long mLastMemUsageReportTime = 0; 1159 1160 /** 1161 * Flag whether the current user is a "monkey", i.e. whether 1162 * the UI is driven by a UI automation tool. 1163 */ 1164 private boolean mUserIsMonkey; 1165 1166 final ServiceThread mHandlerThread; 1167 final MainHandler mHandler; 1168 1169 final class MainHandler extends Handler { 1170 public MainHandler(Looper looper) { 1171 super(looper, null, true); 1172 } 1173 1174 @Override 1175 public void handleMessage(Message msg) { 1176 switch (msg.what) { 1177 case SHOW_ERROR_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1180 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1181 synchronized (ActivityManagerService.this) { 1182 ProcessRecord proc = (ProcessRecord)data.get("app"); 1183 AppErrorResult res = (AppErrorResult) data.get("result"); 1184 if (proc != null && proc.crashDialog != null) { 1185 Slog.e(TAG, "App already has crash dialog: " + proc); 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 return; 1190 } 1191 if (!showBackground && UserHandle.getAppId(proc.uid) 1192 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1193 && proc.pid != MY_PID) { 1194 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1195 if (res != null) { 1196 res.set(0); 1197 } 1198 return; 1199 } 1200 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1201 Dialog d = new AppErrorDialog(mContext, 1202 ActivityManagerService.this, res, proc); 1203 d.show(); 1204 proc.crashDialog = d; 1205 } else { 1206 // The device is asleep, so just pretend that the user 1207 // saw a crash dialog and hit "force quit". 1208 if (res != null) { 1209 res.set(0); 1210 } 1211 } 1212 } 1213 1214 ensureBootCompleted(); 1215 } break; 1216 case SHOW_NOT_RESPONDING_MSG: { 1217 synchronized (ActivityManagerService.this) { 1218 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1219 ProcessRecord proc = (ProcessRecord)data.get("app"); 1220 if (proc != null && proc.anrDialog != null) { 1221 Slog.e(TAG, "App already has anr dialog: " + proc); 1222 return; 1223 } 1224 1225 Intent intent = new Intent("android.intent.action.ANR"); 1226 if (!mProcessesReady) { 1227 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1228 | Intent.FLAG_RECEIVER_FOREGROUND); 1229 } 1230 broadcastIntentLocked(null, null, intent, 1231 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1232 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1233 1234 if (mShowDialogs) { 1235 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1236 mContext, proc, (ActivityRecord)data.get("activity"), 1237 msg.arg1 != 0); 1238 d.show(); 1239 proc.anrDialog = d; 1240 } else { 1241 // Just kill the app if there is no dialog to be shown. 1242 killAppAtUsersRequest(proc, null); 1243 } 1244 } 1245 1246 ensureBootCompleted(); 1247 } break; 1248 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1249 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord) data.get("app"); 1252 if (proc == null) { 1253 Slog.e(TAG, "App not found when showing strict mode dialog."); 1254 break; 1255 } 1256 if (proc.crashDialog != null) { 1257 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1258 return; 1259 } 1260 AppErrorResult res = (AppErrorResult) data.get("result"); 1261 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1262 Dialog d = new StrictModeViolationDialog(mContext, 1263 ActivityManagerService.this, res, proc); 1264 d.show(); 1265 proc.crashDialog = d; 1266 } else { 1267 // The device is asleep, so just pretend that the user 1268 // saw a crash dialog and hit "force quit". 1269 res.set(0); 1270 } 1271 } 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_FACTORY_ERROR_MSG: { 1275 Dialog d = new FactoryErrorDialog( 1276 mContext, msg.getData().getCharSequence("msg")); 1277 d.show(); 1278 ensureBootCompleted(); 1279 } break; 1280 case UPDATE_CONFIGURATION_MSG: { 1281 final ContentResolver resolver = mContext.getContentResolver(); 1282 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1283 } break; 1284 case GC_BACKGROUND_PROCESSES_MSG: { 1285 synchronized (ActivityManagerService.this) { 1286 performAppGcsIfAppropriateLocked(); 1287 } 1288 } break; 1289 case WAIT_FOR_DEBUGGER_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 ProcessRecord app = (ProcessRecord)msg.obj; 1292 if (msg.arg1 != 0) { 1293 if (!app.waitedForDebugger) { 1294 Dialog d = new AppWaitingForDebuggerDialog( 1295 ActivityManagerService.this, 1296 mContext, app); 1297 app.waitDialog = d; 1298 app.waitedForDebugger = true; 1299 d.show(); 1300 } 1301 } else { 1302 if (app.waitDialog != null) { 1303 app.waitDialog.dismiss(); 1304 app.waitDialog = null; 1305 } 1306 } 1307 } 1308 } break; 1309 case SERVICE_TIMEOUT_MSG: { 1310 if (mDidDexOpt) { 1311 mDidDexOpt = false; 1312 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1313 nmsg.obj = msg.obj; 1314 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1315 return; 1316 } 1317 mServices.serviceTimeout((ProcessRecord)msg.obj); 1318 } break; 1319 case UPDATE_TIME_ZONE: { 1320 synchronized (ActivityManagerService.this) { 1321 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1322 ProcessRecord r = mLruProcesses.get(i); 1323 if (r.thread != null) { 1324 try { 1325 r.thread.updateTimeZone(); 1326 } catch (RemoteException ex) { 1327 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1328 } 1329 } 1330 } 1331 } 1332 } break; 1333 case CLEAR_DNS_CACHE_MSG: { 1334 synchronized (ActivityManagerService.this) { 1335 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1336 ProcessRecord r = mLruProcesses.get(i); 1337 if (r.thread != null) { 1338 try { 1339 r.thread.clearDnsCache(); 1340 } catch (RemoteException ex) { 1341 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1342 } 1343 } 1344 } 1345 } 1346 } break; 1347 case UPDATE_HTTP_PROXY_MSG: { 1348 ProxyInfo proxy = (ProxyInfo)msg.obj; 1349 String host = ""; 1350 String port = ""; 1351 String exclList = ""; 1352 Uri pacFileUrl = Uri.EMPTY; 1353 if (proxy != null) { 1354 host = proxy.getHost(); 1355 port = Integer.toString(proxy.getPort()); 1356 exclList = proxy.getExclusionListAsString(); 1357 pacFileUrl = proxy.getPacFileUrl(); 1358 } 1359 synchronized (ActivityManagerService.this) { 1360 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1361 ProcessRecord r = mLruProcesses.get(i); 1362 if (r.thread != null) { 1363 try { 1364 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1365 } catch (RemoteException ex) { 1366 Slog.w(TAG, "Failed to update http proxy for: " + 1367 r.info.processName); 1368 } 1369 } 1370 } 1371 } 1372 } break; 1373 case SHOW_UID_ERROR_MSG: { 1374 String title = "System UIDs Inconsistent"; 1375 String text = "UIDs on the system are inconsistent, you need to wipe your" 1376 + " data partition or your device will be unstable."; 1377 Log.e(TAG, title + ": " + text); 1378 if (mShowDialogs) { 1379 // XXX This is a temporary dialog, no need to localize. 1380 AlertDialog d = new BaseErrorDialog(mContext); 1381 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1382 d.setCancelable(false); 1383 d.setTitle(title); 1384 d.setMessage(text); 1385 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1386 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1387 mUidAlert = d; 1388 d.show(); 1389 } 1390 } break; 1391 case IM_FEELING_LUCKY_MSG: { 1392 if (mUidAlert != null) { 1393 mUidAlert.dismiss(); 1394 mUidAlert = null; 1395 } 1396 } break; 1397 case PROC_START_TIMEOUT_MSG: { 1398 if (mDidDexOpt) { 1399 mDidDexOpt = false; 1400 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1401 nmsg.obj = msg.obj; 1402 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1403 return; 1404 } 1405 ProcessRecord app = (ProcessRecord)msg.obj; 1406 synchronized (ActivityManagerService.this) { 1407 processStartTimedOutLocked(app); 1408 } 1409 } break; 1410 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 doPendingActivityLaunchesLocked(true); 1413 } 1414 } break; 1415 case KILL_APPLICATION_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 int appid = msg.arg1; 1418 boolean restart = (msg.arg2 == 1); 1419 Bundle bundle = (Bundle)msg.obj; 1420 String pkg = bundle.getString("pkg"); 1421 String reason = bundle.getString("reason"); 1422 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1423 false, UserHandle.USER_ALL, reason); 1424 } 1425 } break; 1426 case FINALIZE_PENDING_INTENT_MSG: { 1427 ((PendingIntentRecord)msg.obj).completeFinalize(); 1428 } break; 1429 case POST_HEAVY_NOTIFICATION_MSG: { 1430 INotificationManager inm = NotificationManager.getService(); 1431 if (inm == null) { 1432 return; 1433 } 1434 1435 ActivityRecord root = (ActivityRecord)msg.obj; 1436 ProcessRecord process = root.app; 1437 if (process == null) { 1438 return; 1439 } 1440 1441 try { 1442 Context context = mContext.createPackageContext(process.info.packageName, 0); 1443 String text = mContext.getString(R.string.heavy_weight_notification, 1444 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1445 Notification notification = new Notification(); 1446 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1447 notification.when = 0; 1448 notification.flags = Notification.FLAG_ONGOING_EVENT; 1449 notification.tickerText = text; 1450 notification.defaults = 0; // please be quiet 1451 notification.sound = null; 1452 notification.vibrate = null; 1453 notification.setLatestEventInfo(context, text, 1454 mContext.getText(R.string.heavy_weight_notification_detail), 1455 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1456 PendingIntent.FLAG_CANCEL_CURRENT, null, 1457 new UserHandle(root.userId))); 1458 1459 try { 1460 int[] outId = new int[1]; 1461 inm.enqueueNotificationWithTag("android", "android", null, 1462 R.string.heavy_weight_notification, 1463 notification, outId, root.userId); 1464 } catch (RuntimeException e) { 1465 Slog.w(ActivityManagerService.TAG, 1466 "Error showing notification for heavy-weight app", e); 1467 } catch (RemoteException e) { 1468 } 1469 } catch (NameNotFoundException e) { 1470 Slog.w(TAG, "Unable to create context for heavy notification", e); 1471 } 1472 } break; 1473 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1474 INotificationManager inm = NotificationManager.getService(); 1475 if (inm == null) { 1476 return; 1477 } 1478 try { 1479 inm.cancelNotificationWithTag("android", null, 1480 R.string.heavy_weight_notification, msg.arg1); 1481 } catch (RuntimeException e) { 1482 Slog.w(ActivityManagerService.TAG, 1483 "Error canceling notification for service", e); 1484 } catch (RemoteException e) { 1485 } 1486 } break; 1487 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1488 synchronized (ActivityManagerService.this) { 1489 checkExcessivePowerUsageLocked(true); 1490 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1491 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1492 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1493 } 1494 } break; 1495 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1496 synchronized (ActivityManagerService.this) { 1497 ActivityRecord ar = (ActivityRecord)msg.obj; 1498 if (mCompatModeDialog != null) { 1499 if (mCompatModeDialog.mAppInfo.packageName.equals( 1500 ar.info.applicationInfo.packageName)) { 1501 return; 1502 } 1503 mCompatModeDialog.dismiss(); 1504 mCompatModeDialog = null; 1505 } 1506 if (ar != null && false) { 1507 if (mCompatModePackages.getPackageAskCompatModeLocked( 1508 ar.packageName)) { 1509 int mode = mCompatModePackages.computeCompatModeLocked( 1510 ar.info.applicationInfo); 1511 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1512 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1513 mCompatModeDialog = new CompatModeDialog( 1514 ActivityManagerService.this, mContext, 1515 ar.info.applicationInfo); 1516 mCompatModeDialog.show(); 1517 } 1518 } 1519 } 1520 } 1521 break; 1522 } 1523 case DISPATCH_PROCESSES_CHANGED: { 1524 dispatchProcessesChanged(); 1525 break; 1526 } 1527 case DISPATCH_PROCESS_DIED: { 1528 final int pid = msg.arg1; 1529 final int uid = msg.arg2; 1530 dispatchProcessDied(pid, uid); 1531 break; 1532 } 1533 case REPORT_MEM_USAGE_MSG: { 1534 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1535 Thread thread = new Thread() { 1536 @Override public void run() { 1537 final SparseArray<ProcessMemInfo> infoMap 1538 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1539 for (int i=0, N=memInfos.size(); i<N; i++) { 1540 ProcessMemInfo mi = memInfos.get(i); 1541 infoMap.put(mi.pid, mi); 1542 } 1543 updateCpuStatsNow(); 1544 synchronized (mProcessCpuThread) { 1545 final int N = mProcessCpuTracker.countStats(); 1546 for (int i=0; i<N; i++) { 1547 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1548 if (st.vsize > 0) { 1549 long pss = Debug.getPss(st.pid, null); 1550 if (pss > 0) { 1551 if (infoMap.indexOfKey(st.pid) < 0) { 1552 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1553 ProcessList.NATIVE_ADJ, -1, "native", null); 1554 mi.pss = pss; 1555 memInfos.add(mi); 1556 } 1557 } 1558 } 1559 } 1560 } 1561 1562 long totalPss = 0; 1563 for (int i=0, N=memInfos.size(); i<N; i++) { 1564 ProcessMemInfo mi = memInfos.get(i); 1565 if (mi.pss == 0) { 1566 mi.pss = Debug.getPss(mi.pid, null); 1567 } 1568 totalPss += mi.pss; 1569 } 1570 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1571 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1572 if (lhs.oomAdj != rhs.oomAdj) { 1573 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1574 } 1575 if (lhs.pss != rhs.pss) { 1576 return lhs.pss < rhs.pss ? 1 : -1; 1577 } 1578 return 0; 1579 } 1580 }); 1581 1582 StringBuilder tag = new StringBuilder(128); 1583 StringBuilder stack = new StringBuilder(128); 1584 tag.append("Low on memory -- "); 1585 appendMemBucket(tag, totalPss, "total", false); 1586 appendMemBucket(stack, totalPss, "total", true); 1587 1588 StringBuilder logBuilder = new StringBuilder(1024); 1589 logBuilder.append("Low on memory:\n"); 1590 1591 boolean firstLine = true; 1592 int lastOomAdj = Integer.MIN_VALUE; 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 1596 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1597 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1598 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1599 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1600 if (lastOomAdj != mi.oomAdj) { 1601 lastOomAdj = mi.oomAdj; 1602 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1603 tag.append(" / "); 1604 } 1605 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1606 if (firstLine) { 1607 stack.append(":"); 1608 firstLine = false; 1609 } 1610 stack.append("\n\t at "); 1611 } else { 1612 stack.append("$"); 1613 } 1614 } else { 1615 tag.append(" "); 1616 stack.append("$"); 1617 } 1618 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1619 appendMemBucket(tag, mi.pss, mi.name, false); 1620 } 1621 appendMemBucket(stack, mi.pss, mi.name, true); 1622 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1623 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1624 stack.append("("); 1625 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1626 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1627 stack.append(DUMP_MEM_OOM_LABEL[k]); 1628 stack.append(":"); 1629 stack.append(DUMP_MEM_OOM_ADJ[k]); 1630 } 1631 } 1632 stack.append(")"); 1633 } 1634 } 1635 1636 logBuilder.append(" "); 1637 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1638 logBuilder.append(' '); 1639 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1640 logBuilder.append(' '); 1641 ProcessList.appendRamKb(logBuilder, mi.pss); 1642 logBuilder.append(" kB: "); 1643 logBuilder.append(mi.name); 1644 logBuilder.append(" ("); 1645 logBuilder.append(mi.pid); 1646 logBuilder.append(") "); 1647 logBuilder.append(mi.adjType); 1648 logBuilder.append('\n'); 1649 if (mi.adjReason != null) { 1650 logBuilder.append(" "); 1651 logBuilder.append(mi.adjReason); 1652 logBuilder.append('\n'); 1653 } 1654 } 1655 1656 logBuilder.append(" "); 1657 ProcessList.appendRamKb(logBuilder, totalPss); 1658 logBuilder.append(" kB: TOTAL\n"); 1659 1660 long[] infos = new long[Debug.MEMINFO_COUNT]; 1661 Debug.getMemInfo(infos); 1662 logBuilder.append(" MemInfo: "); 1663 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1664 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1665 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1666 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1667 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1668 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1669 logBuilder.append(" ZRAM: "); 1670 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1671 logBuilder.append(" kB RAM, "); 1672 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1673 logBuilder.append(" kB swap total, "); 1674 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1675 logBuilder.append(" kB swap free\n"); 1676 } 1677 Slog.i(TAG, logBuilder.toString()); 1678 1679 StringBuilder dropBuilder = new StringBuilder(1024); 1680 /* 1681 StringWriter oomSw = new StringWriter(); 1682 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1683 StringWriter catSw = new StringWriter(); 1684 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1685 String[] emptyArgs = new String[] { }; 1686 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1687 oomPw.flush(); 1688 String oomString = oomSw.toString(); 1689 */ 1690 dropBuilder.append(stack); 1691 dropBuilder.append('\n'); 1692 dropBuilder.append('\n'); 1693 dropBuilder.append(logBuilder); 1694 dropBuilder.append('\n'); 1695 /* 1696 dropBuilder.append(oomString); 1697 dropBuilder.append('\n'); 1698 */ 1699 StringWriter catSw = new StringWriter(); 1700 synchronized (ActivityManagerService.this) { 1701 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1702 String[] emptyArgs = new String[] { }; 1703 catPw.println(); 1704 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1705 catPw.println(); 1706 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1707 false, false, null); 1708 catPw.println(); 1709 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1710 catPw.flush(); 1711 } 1712 dropBuilder.append(catSw.toString()); 1713 addErrorToDropBox("lowmem", null, "system_server", null, 1714 null, tag.toString(), dropBuilder.toString(), null, null); 1715 //Slog.i(TAG, "Sent to dropbox:"); 1716 //Slog.i(TAG, dropBuilder.toString()); 1717 synchronized (ActivityManagerService.this) { 1718 long now = SystemClock.uptimeMillis(); 1719 if (mLastMemUsageReportTime < now) { 1720 mLastMemUsageReportTime = now; 1721 } 1722 } 1723 } 1724 }; 1725 thread.start(); 1726 break; 1727 } 1728 case REPORT_USER_SWITCH_MSG: { 1729 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1730 break; 1731 } 1732 case CONTINUE_USER_SWITCH_MSG: { 1733 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1734 break; 1735 } 1736 case USER_SWITCH_TIMEOUT_MSG: { 1737 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1738 break; 1739 } 1740 case IMMERSIVE_MODE_LOCK_MSG: { 1741 final boolean nextState = (msg.arg1 != 0); 1742 if (mUpdateLock.isHeld() != nextState) { 1743 if (DEBUG_IMMERSIVE) { 1744 final ActivityRecord r = (ActivityRecord) msg.obj; 1745 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1746 } 1747 if (nextState) { 1748 mUpdateLock.acquire(); 1749 } else { 1750 mUpdateLock.release(); 1751 } 1752 } 1753 break; 1754 } 1755 case PERSIST_URI_GRANTS_MSG: { 1756 writeGrantedUriPermissions(); 1757 break; 1758 } 1759 case REQUEST_ALL_PSS_MSG: { 1760 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1761 break; 1762 } 1763 case START_PROFILES_MSG: { 1764 synchronized (ActivityManagerService.this) { 1765 startProfilesLocked(); 1766 } 1767 break; 1768 } 1769 case UPDATE_TIME: { 1770 synchronized (ActivityManagerService.this) { 1771 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1772 ProcessRecord r = mLruProcesses.get(i); 1773 if (r.thread != null) { 1774 try { 1775 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1776 } catch (RemoteException ex) { 1777 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1778 } 1779 } 1780 } 1781 } 1782 break; 1783 } 1784 case SYSTEM_USER_START_MSG: { 1785 mSystemServiceManager.startUser(msg.arg1); 1786 break; 1787 } 1788 case SYSTEM_USER_CURRENT_MSG: { 1789 mSystemServiceManager.switchUser(msg.arg1); 1790 break; 1791 } 1792 } 1793 } 1794 }; 1795 1796 static final int COLLECT_PSS_BG_MSG = 1; 1797 1798 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1799 @Override 1800 public void handleMessage(Message msg) { 1801 switch (msg.what) { 1802 case COLLECT_PSS_BG_MSG: { 1803 int i=0, num=0; 1804 long start = SystemClock.uptimeMillis(); 1805 long[] tmp = new long[1]; 1806 do { 1807 ProcessRecord proc; 1808 int procState; 1809 int pid; 1810 synchronized (ActivityManagerService.this) { 1811 if (i >= mPendingPssProcesses.size()) { 1812 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1813 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1814 mPendingPssProcesses.clear(); 1815 return; 1816 } 1817 proc = mPendingPssProcesses.get(i); 1818 procState = proc.pssProcState; 1819 if (proc.thread != null && procState == proc.setProcState) { 1820 pid = proc.pid; 1821 } else { 1822 proc = null; 1823 pid = 0; 1824 } 1825 i++; 1826 } 1827 if (proc != null) { 1828 long pss = Debug.getPss(pid, tmp); 1829 synchronized (ActivityManagerService.this) { 1830 if (proc.thread != null && proc.setProcState == procState 1831 && proc.pid == pid) { 1832 num++; 1833 proc.lastPssTime = SystemClock.uptimeMillis(); 1834 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1835 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1836 + ": " + pss + " lastPss=" + proc.lastPss 1837 + " state=" + ProcessList.makeProcStateString(procState)); 1838 if (proc.initialIdlePss == 0) { 1839 proc.initialIdlePss = pss; 1840 } 1841 proc.lastPss = pss; 1842 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1843 proc.lastCachedPss = pss; 1844 } 1845 } 1846 } 1847 } 1848 } while (true); 1849 } 1850 } 1851 } 1852 }; 1853 1854 /** 1855 * Monitor for package changes and update our internal state. 1856 */ 1857 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1858 @Override 1859 public void onPackageRemoved(String packageName, int uid) { 1860 // Remove all tasks with activities in the specified package from the list of recent tasks 1861 synchronized (ActivityManagerService.this) { 1862 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1863 TaskRecord tr = mRecentTasks.get(i); 1864 ComponentName cn = tr.intent.getComponent(); 1865 if (cn != null && cn.getPackageName().equals(packageName)) { 1866 // If the package name matches, remove the task and kill the process 1867 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1868 } 1869 } 1870 } 1871 } 1872 1873 @Override 1874 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1875 onPackageModified(packageName); 1876 return true; 1877 } 1878 1879 @Override 1880 public void onPackageModified(String packageName) { 1881 final PackageManager pm = mContext.getPackageManager(); 1882 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1883 new ArrayList<Pair<Intent, Integer>>(); 1884 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1885 // Copy the list of recent tasks so that we don't hold onto the lock on 1886 // ActivityManagerService for long periods while checking if components exist. 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1889 TaskRecord tr = mRecentTasks.get(i); 1890 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1891 } 1892 } 1893 // Check the recent tasks and filter out all tasks with components that no longer exist. 1894 Intent tmpI = new Intent(); 1895 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1896 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1897 ComponentName cn = p.first.getComponent(); 1898 if (cn != null && cn.getPackageName().equals(packageName)) { 1899 try { 1900 // Add the task to the list to remove if the component no longer exists 1901 tmpI.setComponent(cn); 1902 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1903 tasksToRemove.add(p.second); 1904 } 1905 } catch (Exception e) {} 1906 } 1907 } 1908 // Prune all the tasks with removed components from the list of recent tasks 1909 synchronized (ActivityManagerService.this) { 1910 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1911 // Remove the task but don't kill the process (since other components in that 1912 // package may still be running and in the background) 1913 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1914 } 1915 } 1916 } 1917 1918 @Override 1919 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1920 // Force stop the specified packages 1921 if (packages != null) { 1922 for (String pkg : packages) { 1923 synchronized (ActivityManagerService.this) { 1924 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1925 "finished booting")) { 1926 return true; 1927 } 1928 } 1929 } 1930 } 1931 return false; 1932 } 1933 }; 1934 1935 public void setSystemProcess() { 1936 try { 1937 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1938 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1939 ServiceManager.addService("meminfo", new MemBinder(this)); 1940 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1941 ServiceManager.addService("dbinfo", new DbBinder(this)); 1942 if (MONITOR_CPU_USAGE) { 1943 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1944 } 1945 ServiceManager.addService("permission", new PermissionController(this)); 1946 1947 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1948 "android", STOCK_PM_FLAGS); 1949 mSystemThread.installSystemApplicationInfo(info); 1950 1951 synchronized (this) { 1952 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1953 app.persistent = true; 1954 app.pid = MY_PID; 1955 app.maxAdj = ProcessList.SYSTEM_ADJ; 1956 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1957 mProcessNames.put(app.processName, app.uid, app); 1958 synchronized (mPidsSelfLocked) { 1959 mPidsSelfLocked.put(app.pid, app); 1960 } 1961 updateLruProcessLocked(app, false, null); 1962 updateOomAdjLocked(); 1963 } 1964 } catch (PackageManager.NameNotFoundException e) { 1965 throw new RuntimeException( 1966 "Unable to find android system package", e); 1967 } 1968 } 1969 1970 public void setWindowManager(WindowManagerService wm) { 1971 mWindowManager = wm; 1972 mStackSupervisor.setWindowManager(wm); 1973 } 1974 1975 public void startObservingNativeCrashes() { 1976 final NativeCrashListener ncl = new NativeCrashListener(this); 1977 ncl.start(); 1978 } 1979 1980 public IAppOpsService getAppOpsService() { 1981 return mAppOpsService; 1982 } 1983 1984 static class MemBinder extends Binder { 1985 ActivityManagerService mActivityManagerService; 1986 MemBinder(ActivityManagerService activityManagerService) { 1987 mActivityManagerService = activityManagerService; 1988 } 1989 1990 @Override 1991 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1992 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1993 != PackageManager.PERMISSION_GRANTED) { 1994 pw.println("Permission Denial: can't dump meminfo from from pid=" 1995 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1996 + " without permission " + android.Manifest.permission.DUMP); 1997 return; 1998 } 1999 2000 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2001 } 2002 } 2003 2004 static class GraphicsBinder extends Binder { 2005 ActivityManagerService mActivityManagerService; 2006 GraphicsBinder(ActivityManagerService activityManagerService) { 2007 mActivityManagerService = activityManagerService; 2008 } 2009 2010 @Override 2011 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2012 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2013 != PackageManager.PERMISSION_GRANTED) { 2014 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2015 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2016 + " without permission " + android.Manifest.permission.DUMP); 2017 return; 2018 } 2019 2020 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2021 } 2022 } 2023 2024 static class DbBinder extends Binder { 2025 ActivityManagerService mActivityManagerService; 2026 DbBinder(ActivityManagerService activityManagerService) { 2027 mActivityManagerService = activityManagerService; 2028 } 2029 2030 @Override 2031 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2032 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2033 != PackageManager.PERMISSION_GRANTED) { 2034 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2035 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2036 + " without permission " + android.Manifest.permission.DUMP); 2037 return; 2038 } 2039 2040 mActivityManagerService.dumpDbInfo(fd, pw, args); 2041 } 2042 } 2043 2044 static class CpuBinder extends Binder { 2045 ActivityManagerService mActivityManagerService; 2046 CpuBinder(ActivityManagerService activityManagerService) { 2047 mActivityManagerService = activityManagerService; 2048 } 2049 2050 @Override 2051 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2052 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2053 != PackageManager.PERMISSION_GRANTED) { 2054 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2055 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2056 + " without permission " + android.Manifest.permission.DUMP); 2057 return; 2058 } 2059 2060 synchronized (mActivityManagerService.mProcessCpuThread) { 2061 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2063 SystemClock.uptimeMillis())); 2064 } 2065 } 2066 } 2067 2068 public static final class Lifecycle extends SystemService { 2069 private final ActivityManagerService mService; 2070 2071 public Lifecycle(Context context) { 2072 super(context); 2073 mService = new ActivityManagerService(context); 2074 } 2075 2076 @Override 2077 public void onStart() { 2078 mService.start(); 2079 } 2080 2081 public ActivityManagerService getService() { 2082 return mService; 2083 } 2084 } 2085 2086 // Note: This method is invoked on the main thread but may need to attach various 2087 // handlers to other threads. So take care to be explicit about the looper. 2088 public ActivityManagerService(Context systemContext) { 2089 mContext = systemContext; 2090 mFactoryTest = FactoryTest.getMode(); 2091 mSystemThread = ActivityThread.currentActivityThread(); 2092 2093 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2094 2095 mHandlerThread = new ServiceThread(TAG, 2096 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2097 mHandlerThread.start(); 2098 mHandler = new MainHandler(mHandlerThread.getLooper()); 2099 2100 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2101 "foreground", BROADCAST_FG_TIMEOUT, false); 2102 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2103 "background", BROADCAST_BG_TIMEOUT, true); 2104 mBroadcastQueues[0] = mFgBroadcastQueue; 2105 mBroadcastQueues[1] = mBgBroadcastQueue; 2106 2107 mServices = new ActiveServices(this); 2108 mProviderMap = new ProviderMap(this); 2109 2110 // TODO: Move creation of battery stats service outside of activity manager service. 2111 File dataDir = Environment.getDataDirectory(); 2112 File systemDir = new File(dataDir, "system"); 2113 systemDir.mkdirs(); 2114 mBatteryStatsService = new BatteryStatsService(new File( 2115 systemDir, "batterystats.bin").toString(), mHandler); 2116 mBatteryStatsService.getActiveStatistics().readLocked(); 2117 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2118 mOnBattery = DEBUG_POWER ? true 2119 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2120 mBatteryStatsService.getActiveStatistics().setCallback(this); 2121 2122 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2123 2124 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2125 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2126 2127 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2128 2129 // User 0 is the first and only user that runs at boot. 2130 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2131 mUserLru.add(Integer.valueOf(0)); 2132 updateStartedUserArrayLocked(); 2133 2134 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2135 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2136 2137 mConfiguration.setToDefaults(); 2138 mConfiguration.setLocale(Locale.getDefault()); 2139 2140 mConfigurationSeq = mConfiguration.seq = 1; 2141 mProcessCpuTracker.init(); 2142 2143 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2144 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2145 mStackSupervisor = new ActivityStackSupervisor(this); 2146 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2147 2148 mProcessCpuThread = new Thread("CpuTracker") { 2149 @Override 2150 public void run() { 2151 while (true) { 2152 try { 2153 try { 2154 synchronized(this) { 2155 final long now = SystemClock.uptimeMillis(); 2156 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2157 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2158 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2159 // + ", write delay=" + nextWriteDelay); 2160 if (nextWriteDelay < nextCpuDelay) { 2161 nextCpuDelay = nextWriteDelay; 2162 } 2163 if (nextCpuDelay > 0) { 2164 mProcessCpuMutexFree.set(true); 2165 this.wait(nextCpuDelay); 2166 } 2167 } 2168 } catch (InterruptedException e) { 2169 } 2170 updateCpuStatsNow(); 2171 } catch (Exception e) { 2172 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2173 } 2174 } 2175 } 2176 }; 2177 2178 Watchdog.getInstance().addMonitor(this); 2179 Watchdog.getInstance().addThread(mHandler); 2180 } 2181 2182 public void setSystemServiceManager(SystemServiceManager mgr) { 2183 mSystemServiceManager = mgr; 2184 } 2185 2186 private void start() { 2187 mProcessCpuThread.start(); 2188 2189 mBatteryStatsService.publish(mContext); 2190 mUsageStatsService.publish(mContext); 2191 mAppOpsService.publish(mContext); 2192 2193 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2194 } 2195 2196 @Override 2197 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2198 throws RemoteException { 2199 if (code == SYSPROPS_TRANSACTION) { 2200 // We need to tell all apps about the system property change. 2201 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2202 synchronized(this) { 2203 final int NP = mProcessNames.getMap().size(); 2204 for (int ip=0; ip<NP; ip++) { 2205 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2206 final int NA = apps.size(); 2207 for (int ia=0; ia<NA; ia++) { 2208 ProcessRecord app = apps.valueAt(ia); 2209 if (app.thread != null) { 2210 procs.add(app.thread.asBinder()); 2211 } 2212 } 2213 } 2214 } 2215 2216 int N = procs.size(); 2217 for (int i=0; i<N; i++) { 2218 Parcel data2 = Parcel.obtain(); 2219 try { 2220 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2221 } catch (RemoteException e) { 2222 } 2223 data2.recycle(); 2224 } 2225 } 2226 try { 2227 return super.onTransact(code, data, reply, flags); 2228 } catch (RuntimeException e) { 2229 // The activity manager only throws security exceptions, so let's 2230 // log all others. 2231 if (!(e instanceof SecurityException)) { 2232 Slog.wtf(TAG, "Activity Manager Crash", e); 2233 } 2234 throw e; 2235 } 2236 } 2237 2238 void updateCpuStats() { 2239 final long now = SystemClock.uptimeMillis(); 2240 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2241 return; 2242 } 2243 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2244 synchronized (mProcessCpuThread) { 2245 mProcessCpuThread.notify(); 2246 } 2247 } 2248 } 2249 2250 void updateCpuStatsNow() { 2251 synchronized (mProcessCpuThread) { 2252 mProcessCpuMutexFree.set(false); 2253 final long now = SystemClock.uptimeMillis(); 2254 boolean haveNewCpuStats = false; 2255 2256 if (MONITOR_CPU_USAGE && 2257 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2258 mLastCpuTime.set(now); 2259 haveNewCpuStats = true; 2260 mProcessCpuTracker.update(); 2261 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2262 //Slog.i(TAG, "Total CPU usage: " 2263 // + mProcessCpu.getTotalCpuPercent() + "%"); 2264 2265 // Slog the cpu usage if the property is set. 2266 if ("true".equals(SystemProperties.get("events.cpu"))) { 2267 int user = mProcessCpuTracker.getLastUserTime(); 2268 int system = mProcessCpuTracker.getLastSystemTime(); 2269 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2270 int irq = mProcessCpuTracker.getLastIrqTime(); 2271 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2272 int idle = mProcessCpuTracker.getLastIdleTime(); 2273 2274 int total = user + system + iowait + irq + softIrq + idle; 2275 if (total == 0) total = 1; 2276 2277 EventLog.writeEvent(EventLogTags.CPU, 2278 ((user+system+iowait+irq+softIrq) * 100) / total, 2279 (user * 100) / total, 2280 (system * 100) / total, 2281 (iowait * 100) / total, 2282 (irq * 100) / total, 2283 (softIrq * 100) / total); 2284 } 2285 } 2286 2287 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2288 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2289 synchronized(bstats) { 2290 synchronized(mPidsSelfLocked) { 2291 if (haveNewCpuStats) { 2292 if (mOnBattery) { 2293 int perc = bstats.startAddingCpuLocked(); 2294 int totalUTime = 0; 2295 int totalSTime = 0; 2296 final int N = mProcessCpuTracker.countStats(); 2297 for (int i=0; i<N; i++) { 2298 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2299 if (!st.working) { 2300 continue; 2301 } 2302 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2303 int otherUTime = (st.rel_utime*perc)/100; 2304 int otherSTime = (st.rel_stime*perc)/100; 2305 totalUTime += otherUTime; 2306 totalSTime += otherSTime; 2307 if (pr != null) { 2308 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2309 if (ps == null || !ps.isActive()) { 2310 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2311 pr.info.uid, pr.processName); 2312 } 2313 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2314 st.rel_stime-otherSTime); 2315 ps.addSpeedStepTimes(cpuSpeedTimes); 2316 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2317 } else { 2318 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2319 if (ps == null || !ps.isActive()) { 2320 st.batteryStats = ps = bstats.getProcessStatsLocked( 2321 bstats.mapUid(st.uid), st.name); 2322 } 2323 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2324 st.rel_stime-otherSTime); 2325 ps.addSpeedStepTimes(cpuSpeedTimes); 2326 } 2327 } 2328 bstats.finishAddingCpuLocked(perc, totalUTime, 2329 totalSTime, cpuSpeedTimes); 2330 } 2331 } 2332 } 2333 2334 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2335 mLastWriteTime = now; 2336 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2337 } 2338 } 2339 } 2340 } 2341 2342 @Override 2343 public void batteryNeedsCpuUpdate() { 2344 updateCpuStatsNow(); 2345 } 2346 2347 @Override 2348 public void batteryPowerChanged(boolean onBattery) { 2349 // When plugging in, update the CPU stats first before changing 2350 // the plug state. 2351 updateCpuStatsNow(); 2352 synchronized (this) { 2353 synchronized(mPidsSelfLocked) { 2354 mOnBattery = DEBUG_POWER ? true : onBattery; 2355 } 2356 } 2357 } 2358 2359 /** 2360 * Initialize the application bind args. These are passed to each 2361 * process when the bindApplication() IPC is sent to the process. They're 2362 * lazily setup to make sure the services are running when they're asked for. 2363 */ 2364 private HashMap<String, IBinder> getCommonServicesLocked() { 2365 if (mAppBindArgs == null) { 2366 mAppBindArgs = new HashMap<String, IBinder>(); 2367 2368 // Setup the application init args 2369 mAppBindArgs.put("package", ServiceManager.getService("package")); 2370 mAppBindArgs.put("window", ServiceManager.getService("window")); 2371 mAppBindArgs.put(Context.ALARM_SERVICE, 2372 ServiceManager.getService(Context.ALARM_SERVICE)); 2373 } 2374 return mAppBindArgs; 2375 } 2376 2377 final void setFocusedActivityLocked(ActivityRecord r) { 2378 if (mFocusedActivity != r) { 2379 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2380 mFocusedActivity = r; 2381 if (r.task != null && r.task.voiceInteractor != null) { 2382 startRunningVoiceLocked(); 2383 } else { 2384 finishRunningVoiceLocked(); 2385 } 2386 mStackSupervisor.setFocusedStack(r); 2387 if (r != null) { 2388 mWindowManager.setFocusedApp(r.appToken, true); 2389 } 2390 applyUpdateLockStateLocked(r); 2391 } 2392 } 2393 2394 final void clearFocusedActivity(ActivityRecord r) { 2395 if (mFocusedActivity == r) { 2396 mFocusedActivity = null; 2397 } 2398 } 2399 2400 @Override 2401 public void setFocusedStack(int stackId) { 2402 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2403 synchronized (ActivityManagerService.this) { 2404 ActivityStack stack = mStackSupervisor.getStack(stackId); 2405 if (stack != null) { 2406 ActivityRecord r = stack.topRunningActivityLocked(null); 2407 if (r != null) { 2408 setFocusedActivityLocked(r); 2409 } 2410 } 2411 } 2412 } 2413 2414 @Override 2415 public void notifyActivityDrawn(IBinder token) { 2416 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2417 synchronized (this) { 2418 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2419 if (r != null) { 2420 r.task.stack.notifyActivityDrawnLocked(r); 2421 } 2422 } 2423 } 2424 2425 final void applyUpdateLockStateLocked(ActivityRecord r) { 2426 // Modifications to the UpdateLock state are done on our handler, outside 2427 // the activity manager's locks. The new state is determined based on the 2428 // state *now* of the relevant activity record. The object is passed to 2429 // the handler solely for logging detail, not to be consulted/modified. 2430 final boolean nextState = r != null && r.immersive; 2431 mHandler.sendMessage( 2432 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2433 } 2434 2435 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2436 Message msg = Message.obtain(); 2437 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2438 msg.obj = r.task.askedCompatMode ? null : r; 2439 mHandler.sendMessage(msg); 2440 } 2441 2442 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2443 String what, Object obj, ProcessRecord srcApp) { 2444 app.lastActivityTime = now; 2445 2446 if (app.activities.size() > 0) { 2447 // Don't want to touch dependent processes that are hosting activities. 2448 return index; 2449 } 2450 2451 int lrui = mLruProcesses.lastIndexOf(app); 2452 if (lrui < 0) { 2453 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2454 + what + " " + obj + " from " + srcApp); 2455 return index; 2456 } 2457 2458 if (lrui >= index) { 2459 // Don't want to cause this to move dependent processes *back* in the 2460 // list as if they were less frequently used. 2461 return index; 2462 } 2463 2464 if (lrui >= mLruProcessActivityStart) { 2465 // Don't want to touch dependent processes that are hosting activities. 2466 return index; 2467 } 2468 2469 mLruProcesses.remove(lrui); 2470 if (index > 0) { 2471 index--; 2472 } 2473 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2474 + " in LRU list: " + app); 2475 mLruProcesses.add(index, app); 2476 return index; 2477 } 2478 2479 final void removeLruProcessLocked(ProcessRecord app) { 2480 int lrui = mLruProcesses.lastIndexOf(app); 2481 if (lrui >= 0) { 2482 if (lrui <= mLruProcessActivityStart) { 2483 mLruProcessActivityStart--; 2484 } 2485 if (lrui <= mLruProcessServiceStart) { 2486 mLruProcessServiceStart--; 2487 } 2488 mLruProcesses.remove(lrui); 2489 } 2490 } 2491 2492 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2493 ProcessRecord client) { 2494 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2495 || app.treatLikeActivity; 2496 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2497 if (!activityChange && hasActivity) { 2498 // The process has activities, so we are only allowing activity-based adjustments 2499 // to move it. It should be kept in the front of the list with other 2500 // processes that have activities, and we don't want those to change their 2501 // order except due to activity operations. 2502 return; 2503 } 2504 2505 mLruSeq++; 2506 final long now = SystemClock.uptimeMillis(); 2507 app.lastActivityTime = now; 2508 2509 // First a quick reject: if the app is already at the position we will 2510 // put it, then there is nothing to do. 2511 if (hasActivity) { 2512 final int N = mLruProcesses.size(); 2513 if (N > 0 && mLruProcesses.get(N-1) == app) { 2514 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2515 return; 2516 } 2517 } else { 2518 if (mLruProcessServiceStart > 0 2519 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2520 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2521 return; 2522 } 2523 } 2524 2525 int lrui = mLruProcesses.lastIndexOf(app); 2526 2527 if (app.persistent && lrui >= 0) { 2528 // We don't care about the position of persistent processes, as long as 2529 // they are in the list. 2530 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2531 return; 2532 } 2533 2534 /* In progress: compute new position first, so we can avoid doing work 2535 if the process is not actually going to move. Not yet working. 2536 int addIndex; 2537 int nextIndex; 2538 boolean inActivity = false, inService = false; 2539 if (hasActivity) { 2540 // Process has activities, put it at the very tipsy-top. 2541 addIndex = mLruProcesses.size(); 2542 nextIndex = mLruProcessServiceStart; 2543 inActivity = true; 2544 } else if (hasService) { 2545 // Process has services, put it at the top of the service list. 2546 addIndex = mLruProcessActivityStart; 2547 nextIndex = mLruProcessServiceStart; 2548 inActivity = true; 2549 inService = true; 2550 } else { 2551 // Process not otherwise of interest, it goes to the top of the non-service area. 2552 addIndex = mLruProcessServiceStart; 2553 if (client != null) { 2554 int clientIndex = mLruProcesses.lastIndexOf(client); 2555 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2556 + app); 2557 if (clientIndex >= 0 && addIndex > clientIndex) { 2558 addIndex = clientIndex; 2559 } 2560 } 2561 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2562 } 2563 2564 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2565 + mLruProcessActivityStart + "): " + app); 2566 */ 2567 2568 if (lrui >= 0) { 2569 if (lrui < mLruProcessActivityStart) { 2570 mLruProcessActivityStart--; 2571 } 2572 if (lrui < mLruProcessServiceStart) { 2573 mLruProcessServiceStart--; 2574 } 2575 /* 2576 if (addIndex > lrui) { 2577 addIndex--; 2578 } 2579 if (nextIndex > lrui) { 2580 nextIndex--; 2581 } 2582 */ 2583 mLruProcesses.remove(lrui); 2584 } 2585 2586 /* 2587 mLruProcesses.add(addIndex, app); 2588 if (inActivity) { 2589 mLruProcessActivityStart++; 2590 } 2591 if (inService) { 2592 mLruProcessActivityStart++; 2593 } 2594 */ 2595 2596 int nextIndex; 2597 if (hasActivity) { 2598 final int N = mLruProcesses.size(); 2599 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2600 // Process doesn't have activities, but has clients with 2601 // activities... move it up, but one below the top (the top 2602 // should always have a real activity). 2603 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2604 mLruProcesses.add(N-1, app); 2605 // To keep it from spamming the LRU list (by making a bunch of clients), 2606 // we will push down any other entries owned by the app. 2607 final int uid = app.info.uid; 2608 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2609 ProcessRecord subProc = mLruProcesses.get(i); 2610 if (subProc.info.uid == uid) { 2611 // We want to push this one down the list. If the process after 2612 // it is for the same uid, however, don't do so, because we don't 2613 // want them internally to be re-ordered. 2614 if (mLruProcesses.get(i-1).info.uid != uid) { 2615 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2616 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2617 ProcessRecord tmp = mLruProcesses.get(i); 2618 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2619 mLruProcesses.set(i-1, tmp); 2620 i--; 2621 } 2622 } else { 2623 // A gap, we can stop here. 2624 break; 2625 } 2626 } 2627 } else { 2628 // Process has activities, put it at the very tipsy-top. 2629 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2630 mLruProcesses.add(app); 2631 } 2632 nextIndex = mLruProcessServiceStart; 2633 } else if (hasService) { 2634 // Process has services, put it at the top of the service list. 2635 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2636 mLruProcesses.add(mLruProcessActivityStart, app); 2637 nextIndex = mLruProcessServiceStart; 2638 mLruProcessActivityStart++; 2639 } else { 2640 // Process not otherwise of interest, it goes to the top of the non-service area. 2641 int index = mLruProcessServiceStart; 2642 if (client != null) { 2643 // If there is a client, don't allow the process to be moved up higher 2644 // in the list than that client. 2645 int clientIndex = mLruProcesses.lastIndexOf(client); 2646 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2647 + " when updating " + app); 2648 if (clientIndex <= lrui) { 2649 // Don't allow the client index restriction to push it down farther in the 2650 // list than it already is. 2651 clientIndex = lrui; 2652 } 2653 if (clientIndex >= 0 && index > clientIndex) { 2654 index = clientIndex; 2655 } 2656 } 2657 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2658 mLruProcesses.add(index, app); 2659 nextIndex = index-1; 2660 mLruProcessActivityStart++; 2661 mLruProcessServiceStart++; 2662 } 2663 2664 // If the app is currently using a content provider or service, 2665 // bump those processes as well. 2666 for (int j=app.connections.size()-1; j>=0; j--) { 2667 ConnectionRecord cr = app.connections.valueAt(j); 2668 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2669 && cr.binding.service.app != null 2670 && cr.binding.service.app.lruSeq != mLruSeq 2671 && !cr.binding.service.app.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2673 "service connection", cr, app); 2674 } 2675 } 2676 for (int j=app.conProviders.size()-1; j>=0; j--) { 2677 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2678 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2679 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2680 "provider reference", cpr, app); 2681 } 2682 } 2683 } 2684 2685 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2686 if (uid == Process.SYSTEM_UID) { 2687 // The system gets to run in any process. If there are multiple 2688 // processes with the same uid, just pick the first (this 2689 // should never happen). 2690 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2691 if (procs == null) return null; 2692 final int N = procs.size(); 2693 for (int i = 0; i < N; i++) { 2694 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2695 } 2696 } 2697 ProcessRecord proc = mProcessNames.get(processName, uid); 2698 if (false && proc != null && !keepIfLarge 2699 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2700 && proc.lastCachedPss >= 4000) { 2701 // Turn this condition on to cause killing to happen regularly, for testing. 2702 if (proc.baseProcessTracker != null) { 2703 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2704 } 2705 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2706 + "k from cached"); 2707 } else if (proc != null && !keepIfLarge 2708 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2710 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2711 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2712 if (proc.baseProcessTracker != null) { 2713 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2714 } 2715 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2716 + "k from cached"); 2717 } 2718 } 2719 return proc; 2720 } 2721 2722 void ensurePackageDexOpt(String packageName) { 2723 IPackageManager pm = AppGlobals.getPackageManager(); 2724 try { 2725 if (pm.performDexOpt(packageName)) { 2726 mDidDexOpt = true; 2727 } 2728 } catch (RemoteException e) { 2729 } 2730 } 2731 2732 boolean isNextTransitionForward() { 2733 int transit = mWindowManager.getPendingAppTransition(); 2734 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2737 } 2738 2739 final ProcessRecord startProcessLocked(String processName, 2740 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2741 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2742 boolean isolated, boolean keepIfLarge) { 2743 ProcessRecord app; 2744 if (!isolated) { 2745 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, mProcessStats); 2767 return app; 2768 } 2769 2770 // An application record is attached to a previous process, 2771 // clean it up now. 2772 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2773 handleAppDiedLocked(app, true, true); 2774 } 2775 2776 String hostingNameStr = hostingName != null 2777 ? hostingName.flattenToShortString() : null; 2778 2779 if (!isolated) { 2780 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2781 // If we are in the background, then check to see if this process 2782 // is bad. If so, we will just silently fail. 2783 if (mBadProcesses.get(info.processName, info.uid) != null) { 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2785 + "/" + info.processName); 2786 return null; 2787 } 2788 } else { 2789 // When the user is explicitly starting a process, then clear its 2790 // crash count so that we won't make it bad until they see at 2791 // least one crash dialog again, and make the process good again 2792 // if it had been bad. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2794 + "/" + info.processName); 2795 mProcessCrashTimes.remove(info.processName, info.uid); 2796 if (mBadProcesses.get(info.processName, info.uid) != null) { 2797 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2798 UserHandle.getUserId(info.uid), info.uid, 2799 info.processName); 2800 mBadProcesses.remove(info.processName, info.uid); 2801 if (app != null) { 2802 app.bad = false; 2803 } 2804 } 2805 } 2806 } 2807 2808 if (app == null) { 2809 app = newProcessRecordLocked(info, processName, isolated); 2810 if (app == null) { 2811 Slog.w(TAG, "Failed making new process record for " 2812 + processName + "/" + info.uid + " isolated=" + isolated); 2813 return null; 2814 } 2815 mProcessNames.put(processName, app.uid, app); 2816 if (isolated) { 2817 mIsolatedProcesses.put(app.uid, app); 2818 } 2819 } else { 2820 // If this is a new package in the process, add the package to the list 2821 app.addPackage(info.packageName, mProcessStats); 2822 } 2823 2824 // If the system is not ready yet, then hold off on starting this 2825 // process until it is. 2826 if (!mProcessesReady 2827 && !isAllowedWhileBooting(info) 2828 && !allowWhileBooting) { 2829 if (!mProcessesOnHold.contains(app)) { 2830 mProcessesOnHold.add(app); 2831 } 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2833 return app; 2834 } 2835 2836 startProcessLocked(app, hostingType, hostingNameStr); 2837 return (app.pid != 0) ? app : null; 2838 } 2839 2840 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2841 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2842 } 2843 2844 private final void startProcessLocked(ProcessRecord app, 2845 String hostingType, String hostingNameStr) { 2846 if (app.pid > 0 && app.pid != MY_PID) { 2847 synchronized (mPidsSelfLocked) { 2848 mPidsSelfLocked.remove(app.pid); 2849 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2850 } 2851 app.setPid(0); 2852 } 2853 2854 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2855 "startProcessLocked removing on hold: " + app); 2856 mProcessesOnHold.remove(app); 2857 2858 updateCpuStats(); 2859 2860 try { 2861 int uid = app.uid; 2862 2863 int[] gids = null; 2864 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2865 if (!app.isolated) { 2866 int[] permGids = null; 2867 try { 2868 final PackageManager pm = mContext.getPackageManager(); 2869 permGids = pm.getPackageGids(app.info.packageName); 2870 2871 if (Environment.isExternalStorageEmulated()) { 2872 if (pm.checkPermission( 2873 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2874 app.info.packageName) == PERMISSION_GRANTED) { 2875 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2876 } else { 2877 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2878 } 2879 } 2880 } catch (PackageManager.NameNotFoundException e) { 2881 Slog.w(TAG, "Unable to retrieve gids", e); 2882 } 2883 2884 /* 2885 * Add shared application GID so applications can share some 2886 * resources like shared libraries 2887 */ 2888 if (permGids == null) { 2889 gids = new int[1]; 2890 } else { 2891 gids = new int[permGids.length + 1]; 2892 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2893 } 2894 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2895 } 2896 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2897 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2898 && mTopComponent != null 2899 && app.processName.equals(mTopComponent.getPackageName())) { 2900 uid = 0; 2901 } 2902 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2903 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2904 uid = 0; 2905 } 2906 } 2907 int debugFlags = 0; 2908 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2909 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2910 // Also turn on CheckJNI for debuggable apps. It's quite 2911 // awkward to turn on otherwise. 2912 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2913 } 2914 // Run the app in safe mode if its manifest requests so or the 2915 // system is booted in safe mode. 2916 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2917 mSafeMode == true) { 2918 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2919 } 2920 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2921 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2922 } 2923 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2924 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2925 } 2926 if ("1".equals(SystemProperties.get("debug.assert"))) { 2927 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2928 } 2929 2930 String requiredAbi = app.info.cpuAbi; 2931 if (requiredAbi == null) { 2932 requiredAbi = Build.SUPPORTED_ABIS[0]; 2933 } 2934 2935 // Start the process. It will either succeed and return a result containing 2936 // the PID of the new process, or else throw a RuntimeException. 2937 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2938 app.processName, uid, uid, gids, debugFlags, mountExternal, 2939 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2940 2941 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2942 synchronized (bs) { 2943 if (bs.isOnBattery()) { 2944 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2945 } 2946 } 2947 2948 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2949 UserHandle.getUserId(uid), startResult.pid, uid, 2950 app.processName, hostingType, 2951 hostingNameStr != null ? hostingNameStr : ""); 2952 2953 if (app.persistent) { 2954 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2955 } 2956 2957 StringBuilder buf = mStringBuilder; 2958 buf.setLength(0); 2959 buf.append("Start proc "); 2960 buf.append(app.processName); 2961 buf.append(" for "); 2962 buf.append(hostingType); 2963 if (hostingNameStr != null) { 2964 buf.append(" "); 2965 buf.append(hostingNameStr); 2966 } 2967 buf.append(": pid="); 2968 buf.append(startResult.pid); 2969 buf.append(" uid="); 2970 buf.append(uid); 2971 buf.append(" gids={"); 2972 if (gids != null) { 2973 for (int gi=0; gi<gids.length; gi++) { 2974 if (gi != 0) buf.append(", "); 2975 buf.append(gids[gi]); 2976 2977 } 2978 } 2979 buf.append("}"); 2980 Slog.i(TAG, buf.toString()); 2981 app.setPid(startResult.pid); 2982 app.usingWrapper = startResult.usingWrapper; 2983 app.removed = false; 2984 synchronized (mPidsSelfLocked) { 2985 this.mPidsSelfLocked.put(startResult.pid, app); 2986 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2987 msg.obj = app; 2988 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2989 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2990 } 2991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2992 app.processName, app.info.uid); 2993 if (app.isolated) { 2994 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2995 } 2996 } catch (RuntimeException e) { 2997 // XXX do better error recovery. 2998 app.setPid(0); 2999 Slog.e(TAG, "Failure starting process " + app.processName, e); 3000 } 3001 } 3002 3003 void updateUsageStats(ActivityRecord component, boolean resumed) { 3004 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3005 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3006 if (resumed) { 3007 mUsageStatsService.noteResumeComponent(component.realActivity); 3008 synchronized (stats) { 3009 stats.noteActivityResumedLocked(component.app.uid); 3010 } 3011 } else { 3012 mUsageStatsService.notePauseComponent(component.realActivity); 3013 synchronized (stats) { 3014 stats.noteActivityPausedLocked(component.app.uid); 3015 } 3016 } 3017 } 3018 3019 Intent getHomeIntent() { 3020 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3021 intent.setComponent(mTopComponent); 3022 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3023 intent.addCategory(Intent.CATEGORY_HOME); 3024 } 3025 return intent; 3026 } 3027 3028 boolean startHomeActivityLocked(int userId) { 3029 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3030 && mTopAction == null) { 3031 // We are running in factory test mode, but unable to find 3032 // the factory test app, so just sit around displaying the 3033 // error message and don't try to start anything. 3034 return false; 3035 } 3036 Intent intent = getHomeIntent(); 3037 ActivityInfo aInfo = 3038 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3039 if (aInfo != null) { 3040 intent.setComponent(new ComponentName( 3041 aInfo.applicationInfo.packageName, aInfo.name)); 3042 // Don't do this if the home app is currently being 3043 // instrumented. 3044 aInfo = new ActivityInfo(aInfo); 3045 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3046 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3047 aInfo.applicationInfo.uid, true); 3048 if (app == null || app.instrumentationClass == null) { 3049 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3050 mStackSupervisor.startHomeActivity(intent, aInfo); 3051 } 3052 } 3053 3054 return true; 3055 } 3056 3057 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3058 ActivityInfo ai = null; 3059 ComponentName comp = intent.getComponent(); 3060 try { 3061 if (comp != null) { 3062 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3063 } else { 3064 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3065 intent, 3066 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3067 flags, userId); 3068 3069 if (info != null) { 3070 ai = info.activityInfo; 3071 } 3072 } 3073 } catch (RemoteException e) { 3074 // ignore 3075 } 3076 3077 return ai; 3078 } 3079 3080 /** 3081 * Starts the "new version setup screen" if appropriate. 3082 */ 3083 void startSetupActivityLocked() { 3084 // Only do this once per boot. 3085 if (mCheckedForSetup) { 3086 return; 3087 } 3088 3089 // We will show this screen if the current one is a different 3090 // version than the last one shown, and we are not running in 3091 // low-level factory test mode. 3092 final ContentResolver resolver = mContext.getContentResolver(); 3093 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3094 Settings.Global.getInt(resolver, 3095 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3096 mCheckedForSetup = true; 3097 3098 // See if we should be showing the platform update setup UI. 3099 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3100 List<ResolveInfo> ris = mContext.getPackageManager() 3101 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3102 3103 // We don't allow third party apps to replace this. 3104 ResolveInfo ri = null; 3105 for (int i=0; ris != null && i<ris.size(); i++) { 3106 if ((ris.get(i).activityInfo.applicationInfo.flags 3107 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3108 ri = ris.get(i); 3109 break; 3110 } 3111 } 3112 3113 if (ri != null) { 3114 String vers = ri.activityInfo.metaData != null 3115 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3116 : null; 3117 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3118 vers = ri.activityInfo.applicationInfo.metaData.getString( 3119 Intent.METADATA_SETUP_VERSION); 3120 } 3121 String lastVers = Settings.Secure.getString( 3122 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3123 if (vers != null && !vers.equals(lastVers)) { 3124 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3125 intent.setComponent(new ComponentName( 3126 ri.activityInfo.packageName, ri.activityInfo.name)); 3127 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3128 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3129 } 3130 } 3131 } 3132 } 3133 3134 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3135 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3136 } 3137 3138 void enforceNotIsolatedCaller(String caller) { 3139 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3140 throw new SecurityException("Isolated process not allowed to call " + caller); 3141 } 3142 } 3143 3144 @Override 3145 public int getFrontActivityScreenCompatMode() { 3146 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3147 synchronized (this) { 3148 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3149 } 3150 } 3151 3152 @Override 3153 public void setFrontActivityScreenCompatMode(int mode) { 3154 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3155 "setFrontActivityScreenCompatMode"); 3156 synchronized (this) { 3157 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3158 } 3159 } 3160 3161 @Override 3162 public int getPackageScreenCompatMode(String packageName) { 3163 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3164 synchronized (this) { 3165 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3166 } 3167 } 3168 3169 @Override 3170 public void setPackageScreenCompatMode(String packageName, int mode) { 3171 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3172 "setPackageScreenCompatMode"); 3173 synchronized (this) { 3174 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3175 } 3176 } 3177 3178 @Override 3179 public boolean getPackageAskScreenCompat(String packageName) { 3180 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3181 synchronized (this) { 3182 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3183 } 3184 } 3185 3186 @Override 3187 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3188 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3189 "setPackageAskScreenCompat"); 3190 synchronized (this) { 3191 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3192 } 3193 } 3194 3195 private void dispatchProcessesChanged() { 3196 int N; 3197 synchronized (this) { 3198 N = mPendingProcessChanges.size(); 3199 if (mActiveProcessChanges.length < N) { 3200 mActiveProcessChanges = new ProcessChangeItem[N]; 3201 } 3202 mPendingProcessChanges.toArray(mActiveProcessChanges); 3203 mAvailProcessChanges.addAll(mPendingProcessChanges); 3204 mPendingProcessChanges.clear(); 3205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3206 } 3207 3208 int i = mProcessObservers.beginBroadcast(); 3209 while (i > 0) { 3210 i--; 3211 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3212 if (observer != null) { 3213 try { 3214 for (int j=0; j<N; j++) { 3215 ProcessChangeItem item = mActiveProcessChanges[j]; 3216 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3218 + item.pid + " uid=" + item.uid + ": " 3219 + item.foregroundActivities); 3220 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3221 item.foregroundActivities); 3222 } 3223 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3224 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3225 + item.pid + " uid=" + item.uid + ": " + item.processState); 3226 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3227 } 3228 } 3229 } catch (RemoteException e) { 3230 } 3231 } 3232 } 3233 mProcessObservers.finishBroadcast(); 3234 } 3235 3236 private void dispatchProcessDied(int pid, int uid) { 3237 int i = mProcessObservers.beginBroadcast(); 3238 while (i > 0) { 3239 i--; 3240 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3241 if (observer != null) { 3242 try { 3243 observer.onProcessDied(pid, uid); 3244 } catch (RemoteException e) { 3245 } 3246 } 3247 } 3248 mProcessObservers.finishBroadcast(); 3249 } 3250 3251 final void doPendingActivityLaunchesLocked(boolean doResume) { 3252 final int N = mPendingActivityLaunches.size(); 3253 if (N <= 0) { 3254 return; 3255 } 3256 for (int i=0; i<N; i++) { 3257 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3258 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3259 doResume && i == (N-1), null); 3260 } 3261 mPendingActivityLaunches.clear(); 3262 } 3263 3264 @Override 3265 public final int startActivity(IApplicationThread caller, String callingPackage, 3266 Intent intent, String resolvedType, IBinder resultTo, 3267 String resultWho, int requestCode, int startFlags, 3268 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3269 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3270 resultWho, requestCode, 3271 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3272 } 3273 3274 @Override 3275 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, 3278 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3279 enforceNotIsolatedCaller("startActivity"); 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivity", null); 3282 // TODO: Switch to user app stacks here. 3283 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3284 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3285 null, null, options, userId, null); 3286 } 3287 3288 @Override 3289 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3290 Intent intent, String resolvedType, IBinder resultTo, 3291 String resultWho, int requestCode, int startFlags, String profileFile, 3292 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3293 enforceNotIsolatedCaller("startActivityAndWait"); 3294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3295 false, true, "startActivityAndWait", null); 3296 WaitResult res = new WaitResult(); 3297 // TODO: Switch to user app stacks here. 3298 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3299 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3300 res, null, options, UserHandle.getCallingUserId(), null); 3301 return res; 3302 } 3303 3304 @Override 3305 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3306 Intent intent, String resolvedType, IBinder resultTo, 3307 String resultWho, int requestCode, int startFlags, Configuration config, 3308 Bundle options, int userId) { 3309 enforceNotIsolatedCaller("startActivityWithConfig"); 3310 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3311 false, true, "startActivityWithConfig", null); 3312 // TODO: Switch to user app stacks here. 3313 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3314 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3315 null, null, null, config, options, userId, null); 3316 return ret; 3317 } 3318 3319 @Override 3320 public int startActivityIntentSender(IApplicationThread caller, 3321 IntentSender intent, Intent fillInIntent, String resolvedType, 3322 IBinder resultTo, String resultWho, int requestCode, 3323 int flagsMask, int flagsValues, Bundle options) { 3324 enforceNotIsolatedCaller("startActivityIntentSender"); 3325 // Refuse possible leaked file descriptors 3326 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3327 throw new IllegalArgumentException("File descriptors passed in Intent"); 3328 } 3329 3330 IIntentSender sender = intent.getTarget(); 3331 if (!(sender instanceof PendingIntentRecord)) { 3332 throw new IllegalArgumentException("Bad PendingIntent object"); 3333 } 3334 3335 PendingIntentRecord pir = (PendingIntentRecord)sender; 3336 3337 synchronized (this) { 3338 // If this is coming from the currently resumed activity, it is 3339 // effectively saying that app switches are allowed at this point. 3340 final ActivityStack stack = getFocusedStack(); 3341 if (stack.mResumedActivity != null && 3342 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3343 mAppSwitchesAllowedTime = 0; 3344 } 3345 } 3346 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3347 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3348 return ret; 3349 } 3350 3351 @Override 3352 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3353 Intent intent, String resolvedType, IVoiceInteractionSession session, 3354 IVoiceInteractor interactor, int startFlags, String profileFile, 3355 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3356 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3357 != PackageManager.PERMISSION_GRANTED) { 3358 String msg = "Permission Denial: startVoiceActivity() from pid=" 3359 + Binder.getCallingPid() 3360 + ", uid=" + Binder.getCallingUid() 3361 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3362 Slog.w(TAG, msg); 3363 throw new SecurityException(msg); 3364 } 3365 if (session == null || interactor == null) { 3366 throw new NullPointerException("null session or interactor"); 3367 } 3368 userId = handleIncomingUser(callingPid, callingUid, userId, 3369 false, true, "startVoiceActivity", null); 3370 // TODO: Switch to user app stacks here. 3371 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3372 resolvedType, session, interactor, null, null, 0, startFlags, 3373 profileFile, profileFd, null, null, options, userId, null); 3374 } 3375 3376 @Override 3377 public boolean startNextMatchingActivity(IBinder callingActivity, 3378 Intent intent, Bundle options) { 3379 // Refuse possible leaked file descriptors 3380 if (intent != null && intent.hasFileDescriptors() == true) { 3381 throw new IllegalArgumentException("File descriptors passed in Intent"); 3382 } 3383 3384 synchronized (this) { 3385 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3386 if (r == null) { 3387 ActivityOptions.abort(options); 3388 return false; 3389 } 3390 if (r.app == null || r.app.thread == null) { 3391 // The caller is not running... d'oh! 3392 ActivityOptions.abort(options); 3393 return false; 3394 } 3395 intent = new Intent(intent); 3396 // The caller is not allowed to change the data. 3397 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3398 // And we are resetting to find the next component... 3399 intent.setComponent(null); 3400 3401 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3402 3403 ActivityInfo aInfo = null; 3404 try { 3405 List<ResolveInfo> resolves = 3406 AppGlobals.getPackageManager().queryIntentActivities( 3407 intent, r.resolvedType, 3408 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3409 UserHandle.getCallingUserId()); 3410 3411 // Look for the original activity in the list... 3412 final int N = resolves != null ? resolves.size() : 0; 3413 for (int i=0; i<N; i++) { 3414 ResolveInfo rInfo = resolves.get(i); 3415 if (rInfo.activityInfo.packageName.equals(r.packageName) 3416 && rInfo.activityInfo.name.equals(r.info.name)) { 3417 // We found the current one... the next matching is 3418 // after it. 3419 i++; 3420 if (i<N) { 3421 aInfo = resolves.get(i).activityInfo; 3422 } 3423 if (debug) { 3424 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3425 + "/" + r.info.name); 3426 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3427 + "/" + aInfo.name); 3428 } 3429 break; 3430 } 3431 } 3432 } catch (RemoteException e) { 3433 } 3434 3435 if (aInfo == null) { 3436 // Nobody who is next! 3437 ActivityOptions.abort(options); 3438 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3439 return false; 3440 } 3441 3442 intent.setComponent(new ComponentName( 3443 aInfo.applicationInfo.packageName, aInfo.name)); 3444 intent.setFlags(intent.getFlags()&~( 3445 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3446 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3447 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3448 Intent.FLAG_ACTIVITY_NEW_TASK)); 3449 3450 // Okay now we need to start the new activity, replacing the 3451 // currently running activity. This is a little tricky because 3452 // we want to start the new one as if the current one is finished, 3453 // but not finish the current one first so that there is no flicker. 3454 // And thus... 3455 final boolean wasFinishing = r.finishing; 3456 r.finishing = true; 3457 3458 // Propagate reply information over to the new activity. 3459 final ActivityRecord resultTo = r.resultTo; 3460 final String resultWho = r.resultWho; 3461 final int requestCode = r.requestCode; 3462 r.resultTo = null; 3463 if (resultTo != null) { 3464 resultTo.removeResultsLocked(r, resultWho, requestCode); 3465 } 3466 3467 final long origId = Binder.clearCallingIdentity(); 3468 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3469 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3470 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3471 options, false, null, null); 3472 Binder.restoreCallingIdentity(origId); 3473 3474 r.finishing = wasFinishing; 3475 if (res != ActivityManager.START_SUCCESS) { 3476 return false; 3477 } 3478 return true; 3479 } 3480 } 3481 3482 final int startActivityInPackage(int uid, String callingPackage, 3483 Intent intent, String resolvedType, IBinder resultTo, 3484 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3485 IActivityContainer container) { 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3488 false, true, "startActivityInPackage", null); 3489 3490 // TODO: Switch to user app stacks here. 3491 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3492 null, null, resultTo, resultWho, requestCode, startFlags, 3493 null, null, null, null, options, userId, container); 3494 return ret; 3495 } 3496 3497 @Override 3498 public final int startActivities(IApplicationThread caller, String callingPackage, 3499 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3500 int userId) { 3501 enforceNotIsolatedCaller("startActivities"); 3502 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3503 false, true, "startActivity", null); 3504 // TODO: Switch to user app stacks here. 3505 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3506 resolvedTypes, resultTo, options, userId); 3507 return ret; 3508 } 3509 3510 final int startActivitiesInPackage(int uid, String callingPackage, 3511 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3512 Bundle options, int userId) { 3513 3514 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3515 false, true, "startActivityInPackage", null); 3516 // TODO: Switch to user app stacks here. 3517 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3518 resultTo, options, userId); 3519 return ret; 3520 } 3521 3522 final void addRecentTaskLocked(TaskRecord task) { 3523 int N = mRecentTasks.size(); 3524 // Quick case: check if the top-most recent task is the same. 3525 if (N > 0 && mRecentTasks.get(0) == task) { 3526 return; 3527 } 3528 // Another quick case: never add voice sessions. 3529 if (task.voiceSession != null) { 3530 return; 3531 } 3532 // Remove any existing entries that are the same kind of task. 3533 final Intent intent = task.intent; 3534 final boolean document = intent != null && intent.isDocument(); 3535 for (int i=0; i<N; i++) { 3536 TaskRecord tr = mRecentTasks.get(i); 3537 if (task != tr) { 3538 if (task.userId != tr.userId) { 3539 continue; 3540 } 3541 final Intent trIntent = tr.intent; 3542 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3543 (intent == null || !intent.filterEquals(trIntent))) { 3544 continue; 3545 } 3546 if (document || trIntent != null && trIntent.isDocument()) { 3547 // Document tasks do not match other tasks. 3548 continue; 3549 } 3550 } 3551 3552 // Either task and tr are the same or, their affinities match or their intents match 3553 // and neither of them is a document. 3554 tr.disposeThumbnail(); 3555 mRecentTasks.remove(i); 3556 i--; 3557 N--; 3558 if (task.intent == null) { 3559 // If the new recent task we are adding is not fully 3560 // specified, then replace it with the existing recent task. 3561 task = tr; 3562 } 3563 } 3564 if (N >= MAX_RECENT_TASKS) { 3565 mRecentTasks.remove(N-1).disposeThumbnail(); 3566 } 3567 mRecentTasks.add(0, task); 3568 } 3569 3570 @Override 3571 public void reportActivityFullyDrawn(IBinder token) { 3572 synchronized (this) { 3573 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3574 if (r == null) { 3575 return; 3576 } 3577 r.reportFullyDrawnLocked(); 3578 } 3579 } 3580 3581 @Override 3582 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3583 synchronized (this) { 3584 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3585 if (r == null) { 3586 return; 3587 } 3588 final long origId = Binder.clearCallingIdentity(); 3589 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3590 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3591 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3592 if (config != null) { 3593 r.frozenBeforeDestroy = true; 3594 if (!updateConfigurationLocked(config, r, false, false)) { 3595 mStackSupervisor.resumeTopActivitiesLocked(); 3596 } 3597 } 3598 Binder.restoreCallingIdentity(origId); 3599 } 3600 } 3601 3602 @Override 3603 public int getRequestedOrientation(IBinder token) { 3604 synchronized (this) { 3605 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3606 if (r == null) { 3607 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3608 } 3609 return mWindowManager.getAppOrientation(r.appToken); 3610 } 3611 } 3612 3613 /** 3614 * This is the internal entry point for handling Activity.finish(). 3615 * 3616 * @param token The Binder token referencing the Activity we want to finish. 3617 * @param resultCode Result code, if any, from this Activity. 3618 * @param resultData Result data (Intent), if any, from this Activity. 3619 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3620 * the root Activity in the task. 3621 * 3622 * @return Returns true if the activity successfully finished, or false if it is still running. 3623 */ 3624 @Override 3625 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3626 boolean finishTask) { 3627 // Refuse possible leaked file descriptors 3628 if (resultData != null && resultData.hasFileDescriptors() == true) { 3629 throw new IllegalArgumentException("File descriptors passed in Intent"); 3630 } 3631 3632 synchronized(this) { 3633 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3634 if (r == null) { 3635 return true; 3636 } 3637 // Keep track of the root activity of the task before we finish it 3638 TaskRecord tr = r.task; 3639 ActivityRecord rootR = tr.getRootActivity(); 3640 if (mController != null) { 3641 // Find the first activity that is not finishing. 3642 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3643 if (next != null) { 3644 // ask watcher if this is allowed 3645 boolean resumeOK = true; 3646 try { 3647 resumeOK = mController.activityResuming(next.packageName); 3648 } catch (RemoteException e) { 3649 mController = null; 3650 Watchdog.getInstance().setActivityController(null); 3651 } 3652 3653 if (!resumeOK) { 3654 return false; 3655 } 3656 } 3657 } 3658 final long origId = Binder.clearCallingIdentity(); 3659 try { 3660 boolean res; 3661 if (finishTask && r == rootR) { 3662 // If requested, remove the task that is associated to this activity only if it 3663 // was the root activity in the task. The result code and data is ignored because 3664 // we don't support returning them across task boundaries. 3665 res = removeTaskByIdLocked(tr.taskId, 0); 3666 } else { 3667 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3668 resultData, "app-request", true); 3669 } 3670 return res; 3671 } finally { 3672 Binder.restoreCallingIdentity(origId); 3673 } 3674 } 3675 } 3676 3677 @Override 3678 public final void finishHeavyWeightApp() { 3679 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3680 != PackageManager.PERMISSION_GRANTED) { 3681 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3682 + Binder.getCallingPid() 3683 + ", uid=" + Binder.getCallingUid() 3684 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3685 Slog.w(TAG, msg); 3686 throw new SecurityException(msg); 3687 } 3688 3689 synchronized(this) { 3690 if (mHeavyWeightProcess == null) { 3691 return; 3692 } 3693 3694 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3695 mHeavyWeightProcess.activities); 3696 for (int i=0; i<activities.size(); i++) { 3697 ActivityRecord r = activities.get(i); 3698 if (!r.finishing) { 3699 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3700 null, "finish-heavy", true); 3701 } 3702 } 3703 3704 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3705 mHeavyWeightProcess.userId, 0)); 3706 mHeavyWeightProcess = null; 3707 } 3708 } 3709 3710 @Override 3711 public void crashApplication(int uid, int initialPid, String packageName, 3712 String message) { 3713 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3714 != PackageManager.PERMISSION_GRANTED) { 3715 String msg = "Permission Denial: crashApplication() from pid=" 3716 + Binder.getCallingPid() 3717 + ", uid=" + Binder.getCallingUid() 3718 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3719 Slog.w(TAG, msg); 3720 throw new SecurityException(msg); 3721 } 3722 3723 synchronized(this) { 3724 ProcessRecord proc = null; 3725 3726 // Figure out which process to kill. We don't trust that initialPid 3727 // still has any relation to current pids, so must scan through the 3728 // list. 3729 synchronized (mPidsSelfLocked) { 3730 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3731 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3732 if (p.uid != uid) { 3733 continue; 3734 } 3735 if (p.pid == initialPid) { 3736 proc = p; 3737 break; 3738 } 3739 if (p.pkgList.containsKey(packageName)) { 3740 proc = p; 3741 } 3742 } 3743 } 3744 3745 if (proc == null) { 3746 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3747 + " initialPid=" + initialPid 3748 + " packageName=" + packageName); 3749 return; 3750 } 3751 3752 if (proc.thread != null) { 3753 if (proc.pid == Process.myPid()) { 3754 Log.w(TAG, "crashApplication: trying to crash self!"); 3755 return; 3756 } 3757 long ident = Binder.clearCallingIdentity(); 3758 try { 3759 proc.thread.scheduleCrash(message); 3760 } catch (RemoteException e) { 3761 } 3762 Binder.restoreCallingIdentity(ident); 3763 } 3764 } 3765 } 3766 3767 @Override 3768 public final void finishSubActivity(IBinder token, String resultWho, 3769 int requestCode) { 3770 synchronized(this) { 3771 final long origId = Binder.clearCallingIdentity(); 3772 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3773 if (r != null) { 3774 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3775 } 3776 Binder.restoreCallingIdentity(origId); 3777 } 3778 } 3779 3780 @Override 3781 public boolean finishActivityAffinity(IBinder token) { 3782 synchronized(this) { 3783 final long origId = Binder.clearCallingIdentity(); 3784 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3785 boolean res = false; 3786 if (r != null) { 3787 res = r.task.stack.finishActivityAffinityLocked(r); 3788 } 3789 Binder.restoreCallingIdentity(origId); 3790 return res; 3791 } 3792 } 3793 3794 @Override 3795 public boolean willActivityBeVisible(IBinder token) { 3796 synchronized(this) { 3797 ActivityStack stack = ActivityRecord.getStackLocked(token); 3798 if (stack != null) { 3799 return stack.willActivityBeVisibleLocked(token); 3800 } 3801 return false; 3802 } 3803 } 3804 3805 @Override 3806 public void overridePendingTransition(IBinder token, String packageName, 3807 int enterAnim, int exitAnim) { 3808 synchronized(this) { 3809 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3810 if (self == null) { 3811 return; 3812 } 3813 3814 final long origId = Binder.clearCallingIdentity(); 3815 3816 if (self.state == ActivityState.RESUMED 3817 || self.state == ActivityState.PAUSING) { 3818 mWindowManager.overridePendingAppTransition(packageName, 3819 enterAnim, exitAnim, null); 3820 } 3821 3822 Binder.restoreCallingIdentity(origId); 3823 } 3824 } 3825 3826 /** 3827 * Main function for removing an existing process from the activity manager 3828 * as a result of that process going away. Clears out all connections 3829 * to the process. 3830 */ 3831 private final void handleAppDiedLocked(ProcessRecord app, 3832 boolean restarting, boolean allowRestart) { 3833 int pid = app.pid; 3834 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3835 if (!restarting) { 3836 removeLruProcessLocked(app); 3837 if (pid > 0) { 3838 ProcessList.remove(pid); 3839 } 3840 } 3841 3842 if (mProfileProc == app) { 3843 clearProfilerLocked(); 3844 } 3845 3846 // Remove this application's activities from active lists. 3847 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3848 3849 app.activities.clear(); 3850 3851 if (app.instrumentationClass != null) { 3852 Slog.w(TAG, "Crash of app " + app.processName 3853 + " running instrumentation " + app.instrumentationClass); 3854 Bundle info = new Bundle(); 3855 info.putString("shortMsg", "Process crashed."); 3856 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3857 } 3858 3859 if (!restarting) { 3860 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3861 // If there was nothing to resume, and we are not already 3862 // restarting this process, but there is a visible activity that 3863 // is hosted by the process... then make sure all visible 3864 // activities are running, taking care of restarting this 3865 // process. 3866 if (hasVisibleActivities) { 3867 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3868 } 3869 } 3870 } 3871 } 3872 3873 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3874 IBinder threadBinder = thread.asBinder(); 3875 // Find the application record. 3876 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3877 ProcessRecord rec = mLruProcesses.get(i); 3878 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3879 return i; 3880 } 3881 } 3882 return -1; 3883 } 3884 3885 final ProcessRecord getRecordForAppLocked( 3886 IApplicationThread thread) { 3887 if (thread == null) { 3888 return null; 3889 } 3890 3891 int appIndex = getLRURecordIndexForAppLocked(thread); 3892 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3893 } 3894 3895 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3896 // If there are no longer any background processes running, 3897 // and the app that died was not running instrumentation, 3898 // then tell everyone we are now low on memory. 3899 boolean haveBg = false; 3900 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3901 ProcessRecord rec = mLruProcesses.get(i); 3902 if (rec.thread != null 3903 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3904 haveBg = true; 3905 break; 3906 } 3907 } 3908 3909 if (!haveBg) { 3910 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3911 if (doReport) { 3912 long now = SystemClock.uptimeMillis(); 3913 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3914 doReport = false; 3915 } else { 3916 mLastMemUsageReportTime = now; 3917 } 3918 } 3919 final ArrayList<ProcessMemInfo> memInfos 3920 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3921 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3922 long now = SystemClock.uptimeMillis(); 3923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3924 ProcessRecord rec = mLruProcesses.get(i); 3925 if (rec == dyingProc || rec.thread == null) { 3926 continue; 3927 } 3928 if (doReport) { 3929 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3930 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3931 } 3932 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3933 // The low memory report is overriding any current 3934 // state for a GC request. Make sure to do 3935 // heavy/important/visible/foreground processes first. 3936 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3937 rec.lastRequestedGc = 0; 3938 } else { 3939 rec.lastRequestedGc = rec.lastLowMemory; 3940 } 3941 rec.reportLowMemory = true; 3942 rec.lastLowMemory = now; 3943 mProcessesToGc.remove(rec); 3944 addProcessToGcListLocked(rec); 3945 } 3946 } 3947 if (doReport) { 3948 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3949 mHandler.sendMessage(msg); 3950 } 3951 scheduleAppGcsLocked(); 3952 } 3953 } 3954 3955 final void appDiedLocked(ProcessRecord app, int pid, 3956 IApplicationThread thread) { 3957 3958 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3959 synchronized (stats) { 3960 stats.noteProcessDiedLocked(app.info.uid, pid); 3961 } 3962 3963 // Clean up already done if the process has been re-started. 3964 if (app.pid == pid && app.thread != null && 3965 app.thread.asBinder() == thread.asBinder()) { 3966 boolean doLowMem = app.instrumentationClass == null; 3967 boolean doOomAdj = doLowMem; 3968 if (!app.killedByAm) { 3969 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3970 + ") has died."); 3971 mAllowLowerMemLevel = true; 3972 } else { 3973 // Note that we always want to do oom adj to update our state with the 3974 // new number of procs. 3975 mAllowLowerMemLevel = false; 3976 doLowMem = false; 3977 } 3978 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3979 if (DEBUG_CLEANUP) Slog.v( 3980 TAG, "Dying app: " + app + ", pid: " + pid 3981 + ", thread: " + thread.asBinder()); 3982 handleAppDiedLocked(app, false, true); 3983 3984 if (doOomAdj) { 3985 updateOomAdjLocked(); 3986 } 3987 if (doLowMem) { 3988 doLowMemReportIfNeededLocked(app); 3989 } 3990 } else if (app.pid != pid) { 3991 // A new process has already been started. 3992 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3993 + ") has died and restarted (pid " + app.pid + ")."); 3994 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3995 } else if (DEBUG_PROCESSES) { 3996 Slog.d(TAG, "Received spurious death notification for thread " 3997 + thread.asBinder()); 3998 } 3999 } 4000 4001 /** 4002 * If a stack trace dump file is configured, dump process stack traces. 4003 * @param clearTraces causes the dump file to be erased prior to the new 4004 * traces being written, if true; when false, the new traces will be 4005 * appended to any existing file content. 4006 * @param firstPids of dalvik VM processes to dump stack traces for first 4007 * @param lastPids of dalvik VM processes to dump stack traces for last 4008 * @param nativeProcs optional list of native process names to dump stack crawls 4009 * @return file containing stack traces, or null if no dump file is configured 4010 */ 4011 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4012 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4013 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4014 if (tracesPath == null || tracesPath.length() == 0) { 4015 return null; 4016 } 4017 4018 File tracesFile = new File(tracesPath); 4019 try { 4020 File tracesDir = tracesFile.getParentFile(); 4021 if (!tracesDir.exists()) { 4022 tracesFile.mkdirs(); 4023 if (!SELinux.restorecon(tracesDir)) { 4024 return null; 4025 } 4026 } 4027 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4028 4029 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4030 tracesFile.createNewFile(); 4031 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4032 } catch (IOException e) { 4033 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4034 return null; 4035 } 4036 4037 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4038 return tracesFile; 4039 } 4040 4041 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4042 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4043 // Use a FileObserver to detect when traces finish writing. 4044 // The order of traces is considered important to maintain for legibility. 4045 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4046 @Override 4047 public synchronized void onEvent(int event, String path) { notify(); } 4048 }; 4049 4050 try { 4051 observer.startWatching(); 4052 4053 // First collect all of the stacks of the most important pids. 4054 if (firstPids != null) { 4055 try { 4056 int num = firstPids.size(); 4057 for (int i = 0; i < num; i++) { 4058 synchronized (observer) { 4059 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4060 observer.wait(200); // Wait for write-close, give up after 200msec 4061 } 4062 } 4063 } catch (InterruptedException e) { 4064 Log.wtf(TAG, e); 4065 } 4066 } 4067 4068 // Next collect the stacks of the native pids 4069 if (nativeProcs != null) { 4070 int[] pids = Process.getPidsForCommands(nativeProcs); 4071 if (pids != null) { 4072 for (int pid : pids) { 4073 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4074 } 4075 } 4076 } 4077 4078 // Lastly, measure CPU usage. 4079 if (processCpuTracker != null) { 4080 processCpuTracker.init(); 4081 System.gc(); 4082 processCpuTracker.update(); 4083 try { 4084 synchronized (processCpuTracker) { 4085 processCpuTracker.wait(500); // measure over 1/2 second. 4086 } 4087 } catch (InterruptedException e) { 4088 } 4089 processCpuTracker.update(); 4090 4091 // We'll take the stack crawls of just the top apps using CPU. 4092 final int N = processCpuTracker.countWorkingStats(); 4093 int numProcs = 0; 4094 for (int i=0; i<N && numProcs<5; i++) { 4095 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4096 if (lastPids.indexOfKey(stats.pid) >= 0) { 4097 numProcs++; 4098 try { 4099 synchronized (observer) { 4100 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4101 observer.wait(200); // Wait for write-close, give up after 200msec 4102 } 4103 } catch (InterruptedException e) { 4104 Log.wtf(TAG, e); 4105 } 4106 4107 } 4108 } 4109 } 4110 } finally { 4111 observer.stopWatching(); 4112 } 4113 } 4114 4115 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4116 if (true || IS_USER_BUILD) { 4117 return; 4118 } 4119 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4120 if (tracesPath == null || tracesPath.length() == 0) { 4121 return; 4122 } 4123 4124 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4125 StrictMode.allowThreadDiskWrites(); 4126 try { 4127 final File tracesFile = new File(tracesPath); 4128 final File tracesDir = tracesFile.getParentFile(); 4129 final File tracesTmp = new File(tracesDir, "__tmp__"); 4130 try { 4131 if (!tracesDir.exists()) { 4132 tracesFile.mkdirs(); 4133 if (!SELinux.restorecon(tracesDir.getPath())) { 4134 return; 4135 } 4136 } 4137 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4138 4139 if (tracesFile.exists()) { 4140 tracesTmp.delete(); 4141 tracesFile.renameTo(tracesTmp); 4142 } 4143 StringBuilder sb = new StringBuilder(); 4144 Time tobj = new Time(); 4145 tobj.set(System.currentTimeMillis()); 4146 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4147 sb.append(": "); 4148 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4149 sb.append(" since "); 4150 sb.append(msg); 4151 FileOutputStream fos = new FileOutputStream(tracesFile); 4152 fos.write(sb.toString().getBytes()); 4153 if (app == null) { 4154 fos.write("\n*** No application process!".getBytes()); 4155 } 4156 fos.close(); 4157 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4158 } catch (IOException e) { 4159 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4160 return; 4161 } 4162 4163 if (app != null) { 4164 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4165 firstPids.add(app.pid); 4166 dumpStackTraces(tracesPath, firstPids, null, null, null); 4167 } 4168 4169 File lastTracesFile = null; 4170 File curTracesFile = null; 4171 for (int i=9; i>=0; i--) { 4172 String name = String.format(Locale.US, "slow%02d.txt", i); 4173 curTracesFile = new File(tracesDir, name); 4174 if (curTracesFile.exists()) { 4175 if (lastTracesFile != null) { 4176 curTracesFile.renameTo(lastTracesFile); 4177 } else { 4178 curTracesFile.delete(); 4179 } 4180 } 4181 lastTracesFile = curTracesFile; 4182 } 4183 tracesFile.renameTo(curTracesFile); 4184 if (tracesTmp.exists()) { 4185 tracesTmp.renameTo(tracesFile); 4186 } 4187 } finally { 4188 StrictMode.setThreadPolicy(oldPolicy); 4189 } 4190 } 4191 4192 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4193 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4194 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4195 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4196 4197 if (mController != null) { 4198 try { 4199 // 0 == continue, -1 = kill process immediately 4200 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4201 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4202 } catch (RemoteException e) { 4203 mController = null; 4204 Watchdog.getInstance().setActivityController(null); 4205 } 4206 } 4207 4208 long anrTime = SystemClock.uptimeMillis(); 4209 if (MONITOR_CPU_USAGE) { 4210 updateCpuStatsNow(); 4211 } 4212 4213 synchronized (this) { 4214 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4215 if (mShuttingDown) { 4216 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4217 return; 4218 } else if (app.notResponding) { 4219 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4220 return; 4221 } else if (app.crashing) { 4222 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4223 return; 4224 } 4225 4226 // In case we come through here for the same app before completing 4227 // this one, mark as anring now so we will bail out. 4228 app.notResponding = true; 4229 4230 // Log the ANR to the event log. 4231 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4232 app.processName, app.info.flags, annotation); 4233 4234 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4235 firstPids.add(app.pid); 4236 4237 int parentPid = app.pid; 4238 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4239 if (parentPid != app.pid) firstPids.add(parentPid); 4240 4241 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4242 4243 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4244 ProcessRecord r = mLruProcesses.get(i); 4245 if (r != null && r.thread != null) { 4246 int pid = r.pid; 4247 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4248 if (r.persistent) { 4249 firstPids.add(pid); 4250 } else { 4251 lastPids.put(pid, Boolean.TRUE); 4252 } 4253 } 4254 } 4255 } 4256 } 4257 4258 // Log the ANR to the main log. 4259 StringBuilder info = new StringBuilder(); 4260 info.setLength(0); 4261 info.append("ANR in ").append(app.processName); 4262 if (activity != null && activity.shortComponentName != null) { 4263 info.append(" (").append(activity.shortComponentName).append(")"); 4264 } 4265 info.append("\n"); 4266 info.append("PID: ").append(app.pid).append("\n"); 4267 if (annotation != null) { 4268 info.append("Reason: ").append(annotation).append("\n"); 4269 } 4270 if (parent != null && parent != activity) { 4271 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4272 } 4273 4274 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4275 4276 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4277 NATIVE_STACKS_OF_INTEREST); 4278 4279 String cpuInfo = null; 4280 if (MONITOR_CPU_USAGE) { 4281 updateCpuStatsNow(); 4282 synchronized (mProcessCpuThread) { 4283 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4284 } 4285 info.append(processCpuTracker.printCurrentLoad()); 4286 info.append(cpuInfo); 4287 } 4288 4289 info.append(processCpuTracker.printCurrentState(anrTime)); 4290 4291 Slog.e(TAG, info.toString()); 4292 if (tracesFile == null) { 4293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4295 } 4296 4297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4298 cpuInfo, tracesFile, null); 4299 4300 if (mController != null) { 4301 try { 4302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4304 if (res != 0) { 4305 if (res < 0 && app.pid != MY_PID) { 4306 Process.killProcess(app.pid); 4307 } else { 4308 synchronized (this) { 4309 mServices.scheduleServiceTimeoutLocked(app); 4310 } 4311 } 4312 return; 4313 } 4314 } catch (RemoteException e) { 4315 mController = null; 4316 Watchdog.getInstance().setActivityController(null); 4317 } 4318 } 4319 4320 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4321 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4322 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4323 4324 synchronized (this) { 4325 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4326 killUnneededProcessLocked(app, "background ANR"); 4327 return; 4328 } 4329 4330 // Set the app's notResponding state, and look up the errorReportReceiver 4331 makeAppNotRespondingLocked(app, 4332 activity != null ? activity.shortComponentName : null, 4333 annotation != null ? "ANR " + annotation : "ANR", 4334 info.toString()); 4335 4336 // Bring up the infamous App Not Responding dialog 4337 Message msg = Message.obtain(); 4338 HashMap<String, Object> map = new HashMap<String, Object>(); 4339 msg.what = SHOW_NOT_RESPONDING_MSG; 4340 msg.obj = map; 4341 msg.arg1 = aboveSystem ? 1 : 0; 4342 map.put("app", app); 4343 if (activity != null) { 4344 map.put("activity", activity); 4345 } 4346 4347 mHandler.sendMessage(msg); 4348 } 4349 } 4350 4351 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4352 if (!mLaunchWarningShown) { 4353 mLaunchWarningShown = true; 4354 mHandler.post(new Runnable() { 4355 @Override 4356 public void run() { 4357 synchronized (ActivityManagerService.this) { 4358 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4359 d.show(); 4360 mHandler.postDelayed(new Runnable() { 4361 @Override 4362 public void run() { 4363 synchronized (ActivityManagerService.this) { 4364 d.dismiss(); 4365 mLaunchWarningShown = false; 4366 } 4367 } 4368 }, 4000); 4369 } 4370 } 4371 }); 4372 } 4373 } 4374 4375 @Override 4376 public boolean clearApplicationUserData(final String packageName, 4377 final IPackageDataObserver observer, int userId) { 4378 enforceNotIsolatedCaller("clearApplicationUserData"); 4379 int uid = Binder.getCallingUid(); 4380 int pid = Binder.getCallingPid(); 4381 userId = handleIncomingUser(pid, uid, 4382 userId, false, true, "clearApplicationUserData", null); 4383 long callingId = Binder.clearCallingIdentity(); 4384 try { 4385 IPackageManager pm = AppGlobals.getPackageManager(); 4386 int pkgUid = -1; 4387 synchronized(this) { 4388 try { 4389 pkgUid = pm.getPackageUid(packageName, userId); 4390 } catch (RemoteException e) { 4391 } 4392 if (pkgUid == -1) { 4393 Slog.w(TAG, "Invalid packageName: " + packageName); 4394 if (observer != null) { 4395 try { 4396 observer.onRemoveCompleted(packageName, false); 4397 } catch (RemoteException e) { 4398 Slog.i(TAG, "Observer no longer exists."); 4399 } 4400 } 4401 return false; 4402 } 4403 if (uid == pkgUid || checkComponentPermission( 4404 android.Manifest.permission.CLEAR_APP_USER_DATA, 4405 pid, uid, -1, true) 4406 == PackageManager.PERMISSION_GRANTED) { 4407 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4408 } else { 4409 throw new SecurityException("PID " + pid + " does not have permission " 4410 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4411 + " of package " + packageName); 4412 } 4413 } 4414 4415 try { 4416 // Clear application user data 4417 pm.clearApplicationUserData(packageName, observer, userId); 4418 4419 // Remove all permissions granted from/to this package 4420 removeUriPermissionsForPackageLocked(packageName, userId, true); 4421 4422 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4423 Uri.fromParts("package", packageName, null)); 4424 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4425 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4426 null, null, 0, null, null, null, false, false, userId); 4427 } catch (RemoteException e) { 4428 } 4429 } finally { 4430 Binder.restoreCallingIdentity(callingId); 4431 } 4432 return true; 4433 } 4434 4435 @Override 4436 public void killBackgroundProcesses(final String packageName, int userId) { 4437 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4438 != PackageManager.PERMISSION_GRANTED && 4439 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4440 != PackageManager.PERMISSION_GRANTED) { 4441 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4442 + Binder.getCallingPid() 4443 + ", uid=" + Binder.getCallingUid() 4444 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4445 Slog.w(TAG, msg); 4446 throw new SecurityException(msg); 4447 } 4448 4449 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4450 userId, true, true, "killBackgroundProcesses", null); 4451 long callingId = Binder.clearCallingIdentity(); 4452 try { 4453 IPackageManager pm = AppGlobals.getPackageManager(); 4454 synchronized(this) { 4455 int appId = -1; 4456 try { 4457 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4458 } catch (RemoteException e) { 4459 } 4460 if (appId == -1) { 4461 Slog.w(TAG, "Invalid packageName: " + packageName); 4462 return; 4463 } 4464 killPackageProcessesLocked(packageName, appId, userId, 4465 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4466 } 4467 } finally { 4468 Binder.restoreCallingIdentity(callingId); 4469 } 4470 } 4471 4472 @Override 4473 public void killAllBackgroundProcesses() { 4474 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4475 != PackageManager.PERMISSION_GRANTED) { 4476 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4477 + Binder.getCallingPid() 4478 + ", uid=" + Binder.getCallingUid() 4479 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4480 Slog.w(TAG, msg); 4481 throw new SecurityException(msg); 4482 } 4483 4484 long callingId = Binder.clearCallingIdentity(); 4485 try { 4486 synchronized(this) { 4487 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4488 final int NP = mProcessNames.getMap().size(); 4489 for (int ip=0; ip<NP; ip++) { 4490 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4491 final int NA = apps.size(); 4492 for (int ia=0; ia<NA; ia++) { 4493 ProcessRecord app = apps.valueAt(ia); 4494 if (app.persistent) { 4495 // we don't kill persistent processes 4496 continue; 4497 } 4498 if (app.removed) { 4499 procs.add(app); 4500 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4501 app.removed = true; 4502 procs.add(app); 4503 } 4504 } 4505 } 4506 4507 int N = procs.size(); 4508 for (int i=0; i<N; i++) { 4509 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4510 } 4511 mAllowLowerMemLevel = true; 4512 updateOomAdjLocked(); 4513 doLowMemReportIfNeededLocked(null); 4514 } 4515 } finally { 4516 Binder.restoreCallingIdentity(callingId); 4517 } 4518 } 4519 4520 @Override 4521 public void forceStopPackage(final String packageName, int userId) { 4522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4523 != PackageManager.PERMISSION_GRANTED) { 4524 String msg = "Permission Denial: forceStopPackage() from pid=" 4525 + Binder.getCallingPid() 4526 + ", uid=" + Binder.getCallingUid() 4527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4528 Slog.w(TAG, msg); 4529 throw new SecurityException(msg); 4530 } 4531 final int callingPid = Binder.getCallingPid(); 4532 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4533 userId, true, true, "forceStopPackage", null); 4534 long callingId = Binder.clearCallingIdentity(); 4535 try { 4536 IPackageManager pm = AppGlobals.getPackageManager(); 4537 synchronized(this) { 4538 int[] users = userId == UserHandle.USER_ALL 4539 ? getUsersLocked() : new int[] { userId }; 4540 for (int user : users) { 4541 int pkgUid = -1; 4542 try { 4543 pkgUid = pm.getPackageUid(packageName, user); 4544 } catch (RemoteException e) { 4545 } 4546 if (pkgUid == -1) { 4547 Slog.w(TAG, "Invalid packageName: " + packageName); 4548 continue; 4549 } 4550 try { 4551 pm.setPackageStoppedState(packageName, true, user); 4552 } catch (RemoteException e) { 4553 } catch (IllegalArgumentException e) { 4554 Slog.w(TAG, "Failed trying to unstop package " 4555 + packageName + ": " + e); 4556 } 4557 if (isUserRunningLocked(user, false)) { 4558 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4559 } 4560 } 4561 } 4562 } finally { 4563 Binder.restoreCallingIdentity(callingId); 4564 } 4565 } 4566 4567 /* 4568 * The pkg name and app id have to be specified. 4569 */ 4570 @Override 4571 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4572 if (pkg == null) { 4573 return; 4574 } 4575 // Make sure the uid is valid. 4576 if (appid < 0) { 4577 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4578 return; 4579 } 4580 int callerUid = Binder.getCallingUid(); 4581 // Only the system server can kill an application 4582 if (callerUid == Process.SYSTEM_UID) { 4583 // Post an aysnc message to kill the application 4584 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4585 msg.arg1 = appid; 4586 msg.arg2 = 0; 4587 Bundle bundle = new Bundle(); 4588 bundle.putString("pkg", pkg); 4589 bundle.putString("reason", reason); 4590 msg.obj = bundle; 4591 mHandler.sendMessage(msg); 4592 } else { 4593 throw new SecurityException(callerUid + " cannot kill pkg: " + 4594 pkg); 4595 } 4596 } 4597 4598 @Override 4599 public void closeSystemDialogs(String reason) { 4600 enforceNotIsolatedCaller("closeSystemDialogs"); 4601 4602 final int pid = Binder.getCallingPid(); 4603 final int uid = Binder.getCallingUid(); 4604 final long origId = Binder.clearCallingIdentity(); 4605 try { 4606 synchronized (this) { 4607 // Only allow this from foreground processes, so that background 4608 // applications can't abuse it to prevent system UI from being shown. 4609 if (uid >= Process.FIRST_APPLICATION_UID) { 4610 ProcessRecord proc; 4611 synchronized (mPidsSelfLocked) { 4612 proc = mPidsSelfLocked.get(pid); 4613 } 4614 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4615 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4616 + " from background process " + proc); 4617 return; 4618 } 4619 } 4620 closeSystemDialogsLocked(reason); 4621 } 4622 } finally { 4623 Binder.restoreCallingIdentity(origId); 4624 } 4625 } 4626 4627 void closeSystemDialogsLocked(String reason) { 4628 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4630 | Intent.FLAG_RECEIVER_FOREGROUND); 4631 if (reason != null) { 4632 intent.putExtra("reason", reason); 4633 } 4634 mWindowManager.closeSystemDialogs(reason); 4635 4636 mStackSupervisor.closeSystemDialogsLocked(); 4637 4638 broadcastIntentLocked(null, null, intent, null, 4639 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4640 Process.SYSTEM_UID, UserHandle.USER_ALL); 4641 } 4642 4643 @Override 4644 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4645 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4646 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4647 for (int i=pids.length-1; i>=0; i--) { 4648 ProcessRecord proc; 4649 int oomAdj; 4650 synchronized (this) { 4651 synchronized (mPidsSelfLocked) { 4652 proc = mPidsSelfLocked.get(pids[i]); 4653 oomAdj = proc != null ? proc.setAdj : 0; 4654 } 4655 } 4656 infos[i] = new Debug.MemoryInfo(); 4657 Debug.getMemoryInfo(pids[i], infos[i]); 4658 if (proc != null) { 4659 synchronized (this) { 4660 if (proc.thread != null && proc.setAdj == oomAdj) { 4661 // Record this for posterity if the process has been stable. 4662 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4663 infos[i].getTotalUss(), false, proc.pkgList); 4664 } 4665 } 4666 } 4667 } 4668 return infos; 4669 } 4670 4671 @Override 4672 public long[] getProcessPss(int[] pids) { 4673 enforceNotIsolatedCaller("getProcessPss"); 4674 long[] pss = new long[pids.length]; 4675 for (int i=pids.length-1; i>=0; i--) { 4676 ProcessRecord proc; 4677 int oomAdj; 4678 synchronized (this) { 4679 synchronized (mPidsSelfLocked) { 4680 proc = mPidsSelfLocked.get(pids[i]); 4681 oomAdj = proc != null ? proc.setAdj : 0; 4682 } 4683 } 4684 long[] tmpUss = new long[1]; 4685 pss[i] = Debug.getPss(pids[i], tmpUss); 4686 if (proc != null) { 4687 synchronized (this) { 4688 if (proc.thread != null && proc.setAdj == oomAdj) { 4689 // Record this for posterity if the process has been stable. 4690 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4691 } 4692 } 4693 } 4694 } 4695 return pss; 4696 } 4697 4698 @Override 4699 public void killApplicationProcess(String processName, int uid) { 4700 if (processName == null) { 4701 return; 4702 } 4703 4704 int callerUid = Binder.getCallingUid(); 4705 // Only the system server can kill an application 4706 if (callerUid == Process.SYSTEM_UID) { 4707 synchronized (this) { 4708 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4709 if (app != null && app.thread != null) { 4710 try { 4711 app.thread.scheduleSuicide(); 4712 } catch (RemoteException e) { 4713 // If the other end already died, then our work here is done. 4714 } 4715 } else { 4716 Slog.w(TAG, "Process/uid not found attempting kill of " 4717 + processName + " / " + uid); 4718 } 4719 } 4720 } else { 4721 throw new SecurityException(callerUid + " cannot kill app process: " + 4722 processName); 4723 } 4724 } 4725 4726 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4727 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4728 false, true, false, false, UserHandle.getUserId(uid), reason); 4729 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4730 Uri.fromParts("package", packageName, null)); 4731 if (!mProcessesReady) { 4732 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4733 | Intent.FLAG_RECEIVER_FOREGROUND); 4734 } 4735 intent.putExtra(Intent.EXTRA_UID, uid); 4736 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4737 broadcastIntentLocked(null, null, intent, 4738 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4739 false, false, 4740 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4741 } 4742 4743 private void forceStopUserLocked(int userId, String reason) { 4744 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4745 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4747 | Intent.FLAG_RECEIVER_FOREGROUND); 4748 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4749 broadcastIntentLocked(null, null, intent, 4750 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4751 false, false, 4752 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4753 } 4754 4755 private final boolean killPackageProcessesLocked(String packageName, int appId, 4756 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4757 boolean doit, boolean evenPersistent, String reason) { 4758 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4759 4760 // Remove all processes this package may have touched: all with the 4761 // same UID (except for the system or root user), and all whose name 4762 // matches the package name. 4763 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4764 final int NP = mProcessNames.getMap().size(); 4765 for (int ip=0; ip<NP; ip++) { 4766 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4767 final int NA = apps.size(); 4768 for (int ia=0; ia<NA; ia++) { 4769 ProcessRecord app = apps.valueAt(ia); 4770 if (app.persistent && !evenPersistent) { 4771 // we don't kill persistent processes 4772 continue; 4773 } 4774 if (app.removed) { 4775 if (doit) { 4776 procs.add(app); 4777 } 4778 continue; 4779 } 4780 4781 // Skip process if it doesn't meet our oom adj requirement. 4782 if (app.setAdj < minOomAdj) { 4783 continue; 4784 } 4785 4786 // If no package is specified, we call all processes under the 4787 // give user id. 4788 if (packageName == null) { 4789 if (app.userId != userId) { 4790 continue; 4791 } 4792 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4793 continue; 4794 } 4795 // Package has been specified, we want to hit all processes 4796 // that match it. We need to qualify this by the processes 4797 // that are running under the specified app and user ID. 4798 } else { 4799 if (UserHandle.getAppId(app.uid) != appId) { 4800 continue; 4801 } 4802 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4803 continue; 4804 } 4805 if (!app.pkgList.containsKey(packageName)) { 4806 continue; 4807 } 4808 } 4809 4810 // Process has passed all conditions, kill it! 4811 if (!doit) { 4812 return true; 4813 } 4814 app.removed = true; 4815 procs.add(app); 4816 } 4817 } 4818 4819 int N = procs.size(); 4820 for (int i=0; i<N; i++) { 4821 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4822 } 4823 updateOomAdjLocked(); 4824 return N > 0; 4825 } 4826 4827 private final boolean forceStopPackageLocked(String name, int appId, 4828 boolean callerWillRestart, boolean purgeCache, boolean doit, 4829 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4830 int i; 4831 int N; 4832 4833 if (userId == UserHandle.USER_ALL && name == null) { 4834 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4835 } 4836 4837 if (appId < 0 && name != null) { 4838 try { 4839 appId = UserHandle.getAppId( 4840 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4841 } catch (RemoteException e) { 4842 } 4843 } 4844 4845 if (doit) { 4846 if (name != null) { 4847 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4848 + " user=" + userId + ": " + reason); 4849 } else { 4850 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4851 } 4852 4853 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4854 for (int ip=pmap.size()-1; ip>=0; ip--) { 4855 SparseArray<Long> ba = pmap.valueAt(ip); 4856 for (i=ba.size()-1; i>=0; i--) { 4857 boolean remove = false; 4858 final int entUid = ba.keyAt(i); 4859 if (name != null) { 4860 if (userId == UserHandle.USER_ALL) { 4861 if (UserHandle.getAppId(entUid) == appId) { 4862 remove = true; 4863 } 4864 } else { 4865 if (entUid == UserHandle.getUid(userId, appId)) { 4866 remove = true; 4867 } 4868 } 4869 } else if (UserHandle.getUserId(entUid) == userId) { 4870 remove = true; 4871 } 4872 if (remove) { 4873 ba.removeAt(i); 4874 } 4875 } 4876 if (ba.size() == 0) { 4877 pmap.removeAt(ip); 4878 } 4879 } 4880 } 4881 4882 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4883 -100, callerWillRestart, true, doit, evenPersistent, 4884 name == null ? ("stop user " + userId) : ("stop " + name)); 4885 4886 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4887 if (!doit) { 4888 return true; 4889 } 4890 didSomething = true; 4891 } 4892 4893 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4894 if (!doit) { 4895 return true; 4896 } 4897 didSomething = true; 4898 } 4899 4900 if (name == null) { 4901 // Remove all sticky broadcasts from this user. 4902 mStickyBroadcasts.remove(userId); 4903 } 4904 4905 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4906 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4907 userId, providers)) { 4908 if (!doit) { 4909 return true; 4910 } 4911 didSomething = true; 4912 } 4913 N = providers.size(); 4914 for (i=0; i<N; i++) { 4915 removeDyingProviderLocked(null, providers.get(i), true); 4916 } 4917 4918 // Remove transient permissions granted from/to this package/user 4919 removeUriPermissionsForPackageLocked(name, userId, false); 4920 4921 if (name == null || uninstalling) { 4922 // Remove pending intents. For now we only do this when force 4923 // stopping users, because we have some problems when doing this 4924 // for packages -- app widgets are not currently cleaned up for 4925 // such packages, so they can be left with bad pending intents. 4926 if (mIntentSenderRecords.size() > 0) { 4927 Iterator<WeakReference<PendingIntentRecord>> it 4928 = mIntentSenderRecords.values().iterator(); 4929 while (it.hasNext()) { 4930 WeakReference<PendingIntentRecord> wpir = it.next(); 4931 if (wpir == null) { 4932 it.remove(); 4933 continue; 4934 } 4935 PendingIntentRecord pir = wpir.get(); 4936 if (pir == null) { 4937 it.remove(); 4938 continue; 4939 } 4940 if (name == null) { 4941 // Stopping user, remove all objects for the user. 4942 if (pir.key.userId != userId) { 4943 // Not the same user, skip it. 4944 continue; 4945 } 4946 } else { 4947 if (UserHandle.getAppId(pir.uid) != appId) { 4948 // Different app id, skip it. 4949 continue; 4950 } 4951 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4952 // Different user, skip it. 4953 continue; 4954 } 4955 if (!pir.key.packageName.equals(name)) { 4956 // Different package, skip it. 4957 continue; 4958 } 4959 } 4960 if (!doit) { 4961 return true; 4962 } 4963 didSomething = true; 4964 it.remove(); 4965 pir.canceled = true; 4966 if (pir.key.activity != null) { 4967 pir.key.activity.pendingResults.remove(pir.ref); 4968 } 4969 } 4970 } 4971 } 4972 4973 if (doit) { 4974 if (purgeCache && name != null) { 4975 AttributeCache ac = AttributeCache.instance(); 4976 if (ac != null) { 4977 ac.removePackage(name); 4978 } 4979 } 4980 if (mBooted) { 4981 mStackSupervisor.resumeTopActivitiesLocked(); 4982 mStackSupervisor.scheduleIdleLocked(); 4983 } 4984 } 4985 4986 return didSomething; 4987 } 4988 4989 private final boolean removeProcessLocked(ProcessRecord app, 4990 boolean callerWillRestart, boolean allowRestart, String reason) { 4991 final String name = app.processName; 4992 final int uid = app.uid; 4993 if (DEBUG_PROCESSES) Slog.d( 4994 TAG, "Force removing proc " + app.toShortString() + " (" + name 4995 + "/" + uid + ")"); 4996 4997 mProcessNames.remove(name, uid); 4998 mIsolatedProcesses.remove(app.uid); 4999 if (mHeavyWeightProcess == app) { 5000 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5001 mHeavyWeightProcess.userId, 0)); 5002 mHeavyWeightProcess = null; 5003 } 5004 boolean needRestart = false; 5005 if (app.pid > 0 && app.pid != MY_PID) { 5006 int pid = app.pid; 5007 synchronized (mPidsSelfLocked) { 5008 mPidsSelfLocked.remove(pid); 5009 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5010 } 5011 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5012 app.processName, app.info.uid); 5013 if (app.isolated) { 5014 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5015 } 5016 killUnneededProcessLocked(app, reason); 5017 handleAppDiedLocked(app, true, allowRestart); 5018 removeLruProcessLocked(app); 5019 5020 if (app.persistent && !app.isolated) { 5021 if (!callerWillRestart) { 5022 addAppLocked(app.info, false); 5023 } else { 5024 needRestart = true; 5025 } 5026 } 5027 } else { 5028 mRemovedProcesses.add(app); 5029 } 5030 5031 return needRestart; 5032 } 5033 5034 private final void processStartTimedOutLocked(ProcessRecord app) { 5035 final int pid = app.pid; 5036 boolean gone = false; 5037 synchronized (mPidsSelfLocked) { 5038 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5039 if (knownApp != null && knownApp.thread == null) { 5040 mPidsSelfLocked.remove(pid); 5041 gone = true; 5042 } 5043 } 5044 5045 if (gone) { 5046 Slog.w(TAG, "Process " + app + " failed to attach"); 5047 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5048 pid, app.uid, app.processName); 5049 mProcessNames.remove(app.processName, app.uid); 5050 mIsolatedProcesses.remove(app.uid); 5051 if (mHeavyWeightProcess == app) { 5052 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5053 mHeavyWeightProcess.userId, 0)); 5054 mHeavyWeightProcess = null; 5055 } 5056 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5057 app.processName, app.info.uid); 5058 if (app.isolated) { 5059 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5060 } 5061 // Take care of any launching providers waiting for this process. 5062 checkAppInLaunchingProvidersLocked(app, true); 5063 // Take care of any services that are waiting for the process. 5064 mServices.processStartTimedOutLocked(app); 5065 killUnneededProcessLocked(app, "start timeout"); 5066 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5067 Slog.w(TAG, "Unattached app died before backup, skipping"); 5068 try { 5069 IBackupManager bm = IBackupManager.Stub.asInterface( 5070 ServiceManager.getService(Context.BACKUP_SERVICE)); 5071 bm.agentDisconnected(app.info.packageName); 5072 } catch (RemoteException e) { 5073 // Can't happen; the backup manager is local 5074 } 5075 } 5076 if (isPendingBroadcastProcessLocked(pid)) { 5077 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5078 skipPendingBroadcastLocked(pid); 5079 } 5080 } else { 5081 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5082 } 5083 } 5084 5085 private final boolean attachApplicationLocked(IApplicationThread thread, 5086 int pid) { 5087 5088 // Find the application record that is being attached... either via 5089 // the pid if we are running in multiple processes, or just pull the 5090 // next app record if we are emulating process with anonymous threads. 5091 ProcessRecord app; 5092 if (pid != MY_PID && pid >= 0) { 5093 synchronized (mPidsSelfLocked) { 5094 app = mPidsSelfLocked.get(pid); 5095 } 5096 } else { 5097 app = null; 5098 } 5099 5100 if (app == null) { 5101 Slog.w(TAG, "No pending application record for pid " + pid 5102 + " (IApplicationThread " + thread + "); dropping process"); 5103 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5104 if (pid > 0 && pid != MY_PID) { 5105 Process.killProcessQuiet(pid); 5106 } else { 5107 try { 5108 thread.scheduleExit(); 5109 } catch (Exception e) { 5110 // Ignore exceptions. 5111 } 5112 } 5113 return false; 5114 } 5115 5116 // If this application record is still attached to a previous 5117 // process, clean it up now. 5118 if (app.thread != null) { 5119 handleAppDiedLocked(app, true, true); 5120 } 5121 5122 // Tell the process all about itself. 5123 5124 if (localLOGV) Slog.v( 5125 TAG, "Binding process pid " + pid + " to record " + app); 5126 5127 final String processName = app.processName; 5128 try { 5129 AppDeathRecipient adr = new AppDeathRecipient( 5130 app, pid, thread); 5131 thread.asBinder().linkToDeath(adr, 0); 5132 app.deathRecipient = adr; 5133 } catch (RemoteException e) { 5134 app.resetPackageList(mProcessStats); 5135 startProcessLocked(app, "link fail", processName); 5136 return false; 5137 } 5138 5139 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5140 5141 app.makeActive(thread, mProcessStats); 5142 app.curAdj = app.setAdj = -100; 5143 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5144 app.forcingToForeground = null; 5145 updateProcessForegroundLocked(app, false, false); 5146 app.hasShownUi = false; 5147 app.debugging = false; 5148 app.cached = false; 5149 5150 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5151 5152 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5153 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5154 5155 if (!normalMode) { 5156 Slog.i(TAG, "Launching preboot mode app: " + app); 5157 } 5158 5159 if (localLOGV) Slog.v( 5160 TAG, "New app record " + app 5161 + " thread=" + thread.asBinder() + " pid=" + pid); 5162 try { 5163 int testMode = IApplicationThread.DEBUG_OFF; 5164 if (mDebugApp != null && mDebugApp.equals(processName)) { 5165 testMode = mWaitForDebugger 5166 ? IApplicationThread.DEBUG_WAIT 5167 : IApplicationThread.DEBUG_ON; 5168 app.debugging = true; 5169 if (mDebugTransient) { 5170 mDebugApp = mOrigDebugApp; 5171 mWaitForDebugger = mOrigWaitForDebugger; 5172 } 5173 } 5174 String profileFile = app.instrumentationProfileFile; 5175 ParcelFileDescriptor profileFd = null; 5176 boolean profileAutoStop = false; 5177 if (mProfileApp != null && mProfileApp.equals(processName)) { 5178 mProfileProc = app; 5179 profileFile = mProfileFile; 5180 profileFd = mProfileFd; 5181 profileAutoStop = mAutoStopProfiler; 5182 } 5183 boolean enableOpenGlTrace = false; 5184 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5185 enableOpenGlTrace = true; 5186 mOpenGlTraceApp = null; 5187 } 5188 5189 // If the app is being launched for restore or full backup, set it up specially 5190 boolean isRestrictedBackupMode = false; 5191 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5192 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5193 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5194 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5195 } 5196 5197 ensurePackageDexOpt(app.instrumentationInfo != null 5198 ? app.instrumentationInfo.packageName 5199 : app.info.packageName); 5200 if (app.instrumentationClass != null) { 5201 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5202 } 5203 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5204 + processName + " with config " + mConfiguration); 5205 ApplicationInfo appInfo = app.instrumentationInfo != null 5206 ? app.instrumentationInfo : app.info; 5207 app.compat = compatibilityInfoForPackageLocked(appInfo); 5208 if (profileFd != null) { 5209 profileFd = profileFd.dup(); 5210 } 5211 thread.bindApplication(processName, appInfo, providers, 5212 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5213 app.instrumentationArguments, app.instrumentationWatcher, 5214 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5215 isRestrictedBackupMode || !normalMode, app.persistent, 5216 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5217 mCoreSettingsObserver.getCoreSettingsLocked()); 5218 updateLruProcessLocked(app, false, null); 5219 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5220 } catch (Exception e) { 5221 // todo: Yikes! What should we do? For now we will try to 5222 // start another process, but that could easily get us in 5223 // an infinite loop of restarting processes... 5224 Slog.w(TAG, "Exception thrown during bind!", e); 5225 5226 app.resetPackageList(mProcessStats); 5227 app.unlinkDeathRecipient(); 5228 startProcessLocked(app, "bind fail", processName); 5229 return false; 5230 } 5231 5232 // Remove this record from the list of starting applications. 5233 mPersistentStartingProcesses.remove(app); 5234 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5235 "Attach application locked removing on hold: " + app); 5236 mProcessesOnHold.remove(app); 5237 5238 boolean badApp = false; 5239 boolean didSomething = false; 5240 5241 // See if the top visible activity is waiting to run in this process... 5242 if (normalMode) { 5243 try { 5244 if (mStackSupervisor.attachApplicationLocked(app)) { 5245 didSomething = true; 5246 } 5247 } catch (Exception e) { 5248 badApp = true; 5249 } 5250 } 5251 5252 // Find any services that should be running in this process... 5253 if (!badApp) { 5254 try { 5255 didSomething |= mServices.attachApplicationLocked(app, processName); 5256 } catch (Exception e) { 5257 badApp = true; 5258 } 5259 } 5260 5261 // Check if a next-broadcast receiver is in this process... 5262 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5263 try { 5264 didSomething |= sendPendingBroadcastsLocked(app); 5265 } catch (Exception e) { 5266 // If the app died trying to launch the receiver we declare it 'bad' 5267 badApp = true; 5268 } 5269 } 5270 5271 // Check whether the next backup agent is in this process... 5272 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5273 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5274 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5275 try { 5276 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5277 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5278 mBackupTarget.backupMode); 5279 } catch (Exception e) { 5280 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5281 e.printStackTrace(); 5282 } 5283 } 5284 5285 if (badApp) { 5286 // todo: Also need to kill application to deal with all 5287 // kinds of exceptions. 5288 handleAppDiedLocked(app, false, true); 5289 return false; 5290 } 5291 5292 if (!didSomething) { 5293 updateOomAdjLocked(); 5294 } 5295 5296 return true; 5297 } 5298 5299 @Override 5300 public final void attachApplication(IApplicationThread thread) { 5301 synchronized (this) { 5302 int callingPid = Binder.getCallingPid(); 5303 final long origId = Binder.clearCallingIdentity(); 5304 attachApplicationLocked(thread, callingPid); 5305 Binder.restoreCallingIdentity(origId); 5306 } 5307 } 5308 5309 @Override 5310 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5311 final long origId = Binder.clearCallingIdentity(); 5312 synchronized (this) { 5313 ActivityStack stack = ActivityRecord.getStackLocked(token); 5314 if (stack != null) { 5315 ActivityRecord r = 5316 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5317 if (stopProfiling) { 5318 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5319 try { 5320 mProfileFd.close(); 5321 } catch (IOException e) { 5322 } 5323 clearProfilerLocked(); 5324 } 5325 } 5326 } 5327 } 5328 Binder.restoreCallingIdentity(origId); 5329 } 5330 5331 void enableScreenAfterBoot() { 5332 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5333 SystemClock.uptimeMillis()); 5334 mWindowManager.enableScreenAfterBoot(); 5335 5336 synchronized (this) { 5337 updateEventDispatchingLocked(); 5338 } 5339 } 5340 5341 @Override 5342 public void showBootMessage(final CharSequence msg, final boolean always) { 5343 enforceNotIsolatedCaller("showBootMessage"); 5344 mWindowManager.showBootMessage(msg, always); 5345 } 5346 5347 @Override 5348 public void dismissKeyguardOnNextActivity() { 5349 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5350 final long token = Binder.clearCallingIdentity(); 5351 try { 5352 synchronized (this) { 5353 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5354 if (mLockScreenShown) { 5355 mLockScreenShown = false; 5356 comeOutOfSleepIfNeededLocked(); 5357 } 5358 mStackSupervisor.setDismissKeyguard(true); 5359 } 5360 } finally { 5361 Binder.restoreCallingIdentity(token); 5362 } 5363 } 5364 5365 final void finishBooting() { 5366 // Register receivers to handle package update events 5367 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5368 5369 synchronized (this) { 5370 // Ensure that any processes we had put on hold are now started 5371 // up. 5372 final int NP = mProcessesOnHold.size(); 5373 if (NP > 0) { 5374 ArrayList<ProcessRecord> procs = 5375 new ArrayList<ProcessRecord>(mProcessesOnHold); 5376 for (int ip=0; ip<NP; ip++) { 5377 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5378 + procs.get(ip)); 5379 startProcessLocked(procs.get(ip), "on-hold", null); 5380 } 5381 } 5382 5383 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5384 // Start looking for apps that are abusing wake locks. 5385 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5386 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5387 // Tell anyone interested that we are done booting! 5388 SystemProperties.set("sys.boot_completed", "1"); 5389 SystemProperties.set("dev.bootcomplete", "1"); 5390 for (int i=0; i<mStartedUsers.size(); i++) { 5391 UserStartedState uss = mStartedUsers.valueAt(i); 5392 if (uss.mState == UserStartedState.STATE_BOOTING) { 5393 uss.mState = UserStartedState.STATE_RUNNING; 5394 final int userId = mStartedUsers.keyAt(i); 5395 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5396 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5397 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5398 broadcastIntentLocked(null, null, intent, null, 5399 new IIntentReceiver.Stub() { 5400 @Override 5401 public void performReceive(Intent intent, int resultCode, 5402 String data, Bundle extras, boolean ordered, 5403 boolean sticky, int sendingUser) { 5404 synchronized (ActivityManagerService.this) { 5405 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5406 true, false); 5407 } 5408 } 5409 }, 5410 0, null, null, 5411 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5412 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5413 userId); 5414 } 5415 } 5416 scheduleStartProfilesLocked(); 5417 } 5418 } 5419 } 5420 5421 final void ensureBootCompleted() { 5422 boolean booting; 5423 boolean enableScreen; 5424 synchronized (this) { 5425 booting = mBooting; 5426 mBooting = false; 5427 enableScreen = !mBooted; 5428 mBooted = true; 5429 } 5430 5431 if (booting) { 5432 finishBooting(); 5433 } 5434 5435 if (enableScreen) { 5436 enableScreenAfterBoot(); 5437 } 5438 } 5439 5440 @Override 5441 public final void activityResumed(IBinder token) { 5442 final long origId = Binder.clearCallingIdentity(); 5443 synchronized(this) { 5444 ActivityStack stack = ActivityRecord.getStackLocked(token); 5445 if (stack != null) { 5446 ActivityRecord.activityResumedLocked(token); 5447 } 5448 } 5449 Binder.restoreCallingIdentity(origId); 5450 } 5451 5452 @Override 5453 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5454 final long origId = Binder.clearCallingIdentity(); 5455 synchronized(this) { 5456 ActivityStack stack = ActivityRecord.getStackLocked(token); 5457 if (stack != null) { 5458 stack.activityPausedLocked(token, false, persistentState); 5459 } 5460 } 5461 Binder.restoreCallingIdentity(origId); 5462 } 5463 5464 @Override 5465 public final void activityStopped(IBinder token, Bundle icicle, 5466 PersistableBundle persistentState, CharSequence description) { 5467 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5468 5469 // Refuse possible leaked file descriptors 5470 if (icicle != null && icicle.hasFileDescriptors()) { 5471 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5472 } 5473 5474 final long origId = Binder.clearCallingIdentity(); 5475 5476 synchronized (this) { 5477 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5478 if (r != null) { 5479 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5480 } 5481 } 5482 5483 trimApplications(); 5484 5485 Binder.restoreCallingIdentity(origId); 5486 } 5487 5488 @Override 5489 public final void activityDestroyed(IBinder token) { 5490 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5491 synchronized (this) { 5492 ActivityStack stack = ActivityRecord.getStackLocked(token); 5493 if (stack != null) { 5494 stack.activityDestroyedLocked(token); 5495 } 5496 } 5497 } 5498 5499 @Override 5500 public String getCallingPackage(IBinder token) { 5501 synchronized (this) { 5502 ActivityRecord r = getCallingRecordLocked(token); 5503 return r != null ? r.info.packageName : null; 5504 } 5505 } 5506 5507 @Override 5508 public ComponentName getCallingActivity(IBinder token) { 5509 synchronized (this) { 5510 ActivityRecord r = getCallingRecordLocked(token); 5511 return r != null ? r.intent.getComponent() : null; 5512 } 5513 } 5514 5515 private ActivityRecord getCallingRecordLocked(IBinder token) { 5516 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5517 if (r == null) { 5518 return null; 5519 } 5520 return r.resultTo; 5521 } 5522 5523 @Override 5524 public ComponentName getActivityClassForToken(IBinder token) { 5525 synchronized(this) { 5526 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5527 if (r == null) { 5528 return null; 5529 } 5530 return r.intent.getComponent(); 5531 } 5532 } 5533 5534 @Override 5535 public String getPackageForToken(IBinder token) { 5536 synchronized(this) { 5537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5538 if (r == null) { 5539 return null; 5540 } 5541 return r.packageName; 5542 } 5543 } 5544 5545 @Override 5546 public IIntentSender getIntentSender(int type, 5547 String packageName, IBinder token, String resultWho, 5548 int requestCode, Intent[] intents, String[] resolvedTypes, 5549 int flags, Bundle options, int userId) { 5550 enforceNotIsolatedCaller("getIntentSender"); 5551 // Refuse possible leaked file descriptors 5552 if (intents != null) { 5553 if (intents.length < 1) { 5554 throw new IllegalArgumentException("Intents array length must be >= 1"); 5555 } 5556 for (int i=0; i<intents.length; i++) { 5557 Intent intent = intents[i]; 5558 if (intent != null) { 5559 if (intent.hasFileDescriptors()) { 5560 throw new IllegalArgumentException("File descriptors passed in Intent"); 5561 } 5562 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5563 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5564 throw new IllegalArgumentException( 5565 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5566 } 5567 intents[i] = new Intent(intent); 5568 } 5569 } 5570 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5571 throw new IllegalArgumentException( 5572 "Intent array length does not match resolvedTypes length"); 5573 } 5574 } 5575 if (options != null) { 5576 if (options.hasFileDescriptors()) { 5577 throw new IllegalArgumentException("File descriptors passed in options"); 5578 } 5579 } 5580 5581 synchronized(this) { 5582 int callingUid = Binder.getCallingUid(); 5583 int origUserId = userId; 5584 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5585 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5586 "getIntentSender", null); 5587 if (origUserId == UserHandle.USER_CURRENT) { 5588 // We don't want to evaluate this until the pending intent is 5589 // actually executed. However, we do want to always do the 5590 // security checking for it above. 5591 userId = UserHandle.USER_CURRENT; 5592 } 5593 try { 5594 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5595 int uid = AppGlobals.getPackageManager() 5596 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5597 if (!UserHandle.isSameApp(callingUid, uid)) { 5598 String msg = "Permission Denial: getIntentSender() from pid=" 5599 + Binder.getCallingPid() 5600 + ", uid=" + Binder.getCallingUid() 5601 + ", (need uid=" + uid + ")" 5602 + " is not allowed to send as package " + packageName; 5603 Slog.w(TAG, msg); 5604 throw new SecurityException(msg); 5605 } 5606 } 5607 5608 return getIntentSenderLocked(type, packageName, callingUid, userId, 5609 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5610 5611 } catch (RemoteException e) { 5612 throw new SecurityException(e); 5613 } 5614 } 5615 } 5616 5617 IIntentSender getIntentSenderLocked(int type, String packageName, 5618 int callingUid, int userId, IBinder token, String resultWho, 5619 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5620 Bundle options) { 5621 if (DEBUG_MU) 5622 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5623 ActivityRecord activity = null; 5624 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5625 activity = ActivityRecord.isInStackLocked(token); 5626 if (activity == null) { 5627 return null; 5628 } 5629 if (activity.finishing) { 5630 return null; 5631 } 5632 } 5633 5634 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5635 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5636 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5637 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5638 |PendingIntent.FLAG_UPDATE_CURRENT); 5639 5640 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5641 type, packageName, activity, resultWho, 5642 requestCode, intents, resolvedTypes, flags, options, userId); 5643 WeakReference<PendingIntentRecord> ref; 5644 ref = mIntentSenderRecords.get(key); 5645 PendingIntentRecord rec = ref != null ? ref.get() : null; 5646 if (rec != null) { 5647 if (!cancelCurrent) { 5648 if (updateCurrent) { 5649 if (rec.key.requestIntent != null) { 5650 rec.key.requestIntent.replaceExtras(intents != null ? 5651 intents[intents.length - 1] : null); 5652 } 5653 if (intents != null) { 5654 intents[intents.length-1] = rec.key.requestIntent; 5655 rec.key.allIntents = intents; 5656 rec.key.allResolvedTypes = resolvedTypes; 5657 } else { 5658 rec.key.allIntents = null; 5659 rec.key.allResolvedTypes = null; 5660 } 5661 } 5662 return rec; 5663 } 5664 rec.canceled = true; 5665 mIntentSenderRecords.remove(key); 5666 } 5667 if (noCreate) { 5668 return rec; 5669 } 5670 rec = new PendingIntentRecord(this, key, callingUid); 5671 mIntentSenderRecords.put(key, rec.ref); 5672 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5673 if (activity.pendingResults == null) { 5674 activity.pendingResults 5675 = new HashSet<WeakReference<PendingIntentRecord>>(); 5676 } 5677 activity.pendingResults.add(rec.ref); 5678 } 5679 return rec; 5680 } 5681 5682 @Override 5683 public void cancelIntentSender(IIntentSender sender) { 5684 if (!(sender instanceof PendingIntentRecord)) { 5685 return; 5686 } 5687 synchronized(this) { 5688 PendingIntentRecord rec = (PendingIntentRecord)sender; 5689 try { 5690 int uid = AppGlobals.getPackageManager() 5691 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5692 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5693 String msg = "Permission Denial: cancelIntentSender() from pid=" 5694 + Binder.getCallingPid() 5695 + ", uid=" + Binder.getCallingUid() 5696 + " is not allowed to cancel packges " 5697 + rec.key.packageName; 5698 Slog.w(TAG, msg); 5699 throw new SecurityException(msg); 5700 } 5701 } catch (RemoteException e) { 5702 throw new SecurityException(e); 5703 } 5704 cancelIntentSenderLocked(rec, true); 5705 } 5706 } 5707 5708 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5709 rec.canceled = true; 5710 mIntentSenderRecords.remove(rec.key); 5711 if (cleanActivity && rec.key.activity != null) { 5712 rec.key.activity.pendingResults.remove(rec.ref); 5713 } 5714 } 5715 5716 @Override 5717 public String getPackageForIntentSender(IIntentSender pendingResult) { 5718 if (!(pendingResult instanceof PendingIntentRecord)) { 5719 return null; 5720 } 5721 try { 5722 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5723 return res.key.packageName; 5724 } catch (ClassCastException e) { 5725 } 5726 return null; 5727 } 5728 5729 @Override 5730 public int getUidForIntentSender(IIntentSender sender) { 5731 if (sender instanceof PendingIntentRecord) { 5732 try { 5733 PendingIntentRecord res = (PendingIntentRecord)sender; 5734 return res.uid; 5735 } catch (ClassCastException e) { 5736 } 5737 } 5738 return -1; 5739 } 5740 5741 @Override 5742 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return false; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 if (res.key.allIntents == null) { 5749 return false; 5750 } 5751 for (int i=0; i<res.key.allIntents.length; i++) { 5752 Intent intent = res.key.allIntents[i]; 5753 if (intent.getPackage() != null && intent.getComponent() != null) { 5754 return false; 5755 } 5756 } 5757 return true; 5758 } catch (ClassCastException e) { 5759 } 5760 return false; 5761 } 5762 5763 @Override 5764 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5765 if (!(pendingResult instanceof PendingIntentRecord)) { 5766 return false; 5767 } 5768 try { 5769 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5770 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5771 return true; 5772 } 5773 return false; 5774 } catch (ClassCastException e) { 5775 } 5776 return false; 5777 } 5778 5779 @Override 5780 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5781 if (!(pendingResult instanceof PendingIntentRecord)) { 5782 return null; 5783 } 5784 try { 5785 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5786 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5787 } catch (ClassCastException e) { 5788 } 5789 return null; 5790 } 5791 5792 @Override 5793 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5794 if (!(pendingResult instanceof PendingIntentRecord)) { 5795 return null; 5796 } 5797 try { 5798 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5799 Intent intent = res.key.requestIntent; 5800 if (intent != null) { 5801 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5802 || res.lastTagPrefix.equals(prefix))) { 5803 return res.lastTag; 5804 } 5805 res.lastTagPrefix = prefix; 5806 StringBuilder sb = new StringBuilder(128); 5807 if (prefix != null) { 5808 sb.append(prefix); 5809 } 5810 if (intent.getAction() != null) { 5811 sb.append(intent.getAction()); 5812 } else if (intent.getComponent() != null) { 5813 intent.getComponent().appendShortString(sb); 5814 } else { 5815 sb.append("?"); 5816 } 5817 return res.lastTag = sb.toString(); 5818 } 5819 } catch (ClassCastException e) { 5820 } 5821 return null; 5822 } 5823 5824 @Override 5825 public void setProcessLimit(int max) { 5826 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5827 "setProcessLimit()"); 5828 synchronized (this) { 5829 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5830 mProcessLimitOverride = max; 5831 } 5832 trimApplications(); 5833 } 5834 5835 @Override 5836 public int getProcessLimit() { 5837 synchronized (this) { 5838 return mProcessLimitOverride; 5839 } 5840 } 5841 5842 void foregroundTokenDied(ForegroundToken token) { 5843 synchronized (ActivityManagerService.this) { 5844 synchronized (mPidsSelfLocked) { 5845 ForegroundToken cur 5846 = mForegroundProcesses.get(token.pid); 5847 if (cur != token) { 5848 return; 5849 } 5850 mForegroundProcesses.remove(token.pid); 5851 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5852 if (pr == null) { 5853 return; 5854 } 5855 pr.forcingToForeground = null; 5856 updateProcessForegroundLocked(pr, false, false); 5857 } 5858 updateOomAdjLocked(); 5859 } 5860 } 5861 5862 @Override 5863 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5864 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5865 "setProcessForeground()"); 5866 synchronized(this) { 5867 boolean changed = false; 5868 5869 synchronized (mPidsSelfLocked) { 5870 ProcessRecord pr = mPidsSelfLocked.get(pid); 5871 if (pr == null && isForeground) { 5872 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5873 return; 5874 } 5875 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5876 if (oldToken != null) { 5877 oldToken.token.unlinkToDeath(oldToken, 0); 5878 mForegroundProcesses.remove(pid); 5879 if (pr != null) { 5880 pr.forcingToForeground = null; 5881 } 5882 changed = true; 5883 } 5884 if (isForeground && token != null) { 5885 ForegroundToken newToken = new ForegroundToken() { 5886 @Override 5887 public void binderDied() { 5888 foregroundTokenDied(this); 5889 } 5890 }; 5891 newToken.pid = pid; 5892 newToken.token = token; 5893 try { 5894 token.linkToDeath(newToken, 0); 5895 mForegroundProcesses.put(pid, newToken); 5896 pr.forcingToForeground = token; 5897 changed = true; 5898 } catch (RemoteException e) { 5899 // If the process died while doing this, we will later 5900 // do the cleanup with the process death link. 5901 } 5902 } 5903 } 5904 5905 if (changed) { 5906 updateOomAdjLocked(); 5907 } 5908 } 5909 } 5910 5911 // ========================================================= 5912 // PERMISSIONS 5913 // ========================================================= 5914 5915 static class PermissionController extends IPermissionController.Stub { 5916 ActivityManagerService mActivityManagerService; 5917 PermissionController(ActivityManagerService activityManagerService) { 5918 mActivityManagerService = activityManagerService; 5919 } 5920 5921 @Override 5922 public boolean checkPermission(String permission, int pid, int uid) { 5923 return mActivityManagerService.checkPermission(permission, pid, 5924 uid) == PackageManager.PERMISSION_GRANTED; 5925 } 5926 } 5927 5928 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5929 @Override 5930 public int checkComponentPermission(String permission, int pid, int uid, 5931 int owningUid, boolean exported) { 5932 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5933 owningUid, exported); 5934 } 5935 5936 @Override 5937 public Object getAMSLock() { 5938 return ActivityManagerService.this; 5939 } 5940 } 5941 5942 /** 5943 * This can be called with or without the global lock held. 5944 */ 5945 int checkComponentPermission(String permission, int pid, int uid, 5946 int owningUid, boolean exported) { 5947 // We might be performing an operation on behalf of an indirect binder 5948 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5949 // client identity accordingly before proceeding. 5950 Identity tlsIdentity = sCallerIdentity.get(); 5951 if (tlsIdentity != null) { 5952 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5953 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5954 uid = tlsIdentity.uid; 5955 pid = tlsIdentity.pid; 5956 } 5957 5958 if (pid == MY_PID) { 5959 return PackageManager.PERMISSION_GRANTED; 5960 } 5961 5962 return ActivityManager.checkComponentPermission(permission, uid, 5963 owningUid, exported); 5964 } 5965 5966 /** 5967 * As the only public entry point for permissions checking, this method 5968 * can enforce the semantic that requesting a check on a null global 5969 * permission is automatically denied. (Internally a null permission 5970 * string is used when calling {@link #checkComponentPermission} in cases 5971 * when only uid-based security is needed.) 5972 * 5973 * This can be called with or without the global lock held. 5974 */ 5975 @Override 5976 public int checkPermission(String permission, int pid, int uid) { 5977 if (permission == null) { 5978 return PackageManager.PERMISSION_DENIED; 5979 } 5980 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5981 } 5982 5983 /** 5984 * Binder IPC calls go through the public entry point. 5985 * This can be called with or without the global lock held. 5986 */ 5987 int checkCallingPermission(String permission) { 5988 return checkPermission(permission, 5989 Binder.getCallingPid(), 5990 UserHandle.getAppId(Binder.getCallingUid())); 5991 } 5992 5993 /** 5994 * This can be called with or without the global lock held. 5995 */ 5996 void enforceCallingPermission(String permission, String func) { 5997 if (checkCallingPermission(permission) 5998 == PackageManager.PERMISSION_GRANTED) { 5999 return; 6000 } 6001 6002 String msg = "Permission Denial: " + func + " from pid=" 6003 + Binder.getCallingPid() 6004 + ", uid=" + Binder.getCallingUid() 6005 + " requires " + permission; 6006 Slog.w(TAG, msg); 6007 throw new SecurityException(msg); 6008 } 6009 6010 /** 6011 * Determine if UID is holding permissions required to access {@link Uri} in 6012 * the given {@link ProviderInfo}. Final permission checking is always done 6013 * in {@link ContentProvider}. 6014 */ 6015 private final boolean checkHoldingPermissionsLocked( 6016 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6017 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6018 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6019 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6020 return false; 6021 } 6022 6023 if (pi.applicationInfo.uid == uid) { 6024 return true; 6025 } else if (!pi.exported) { 6026 return false; 6027 } 6028 6029 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6030 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6031 try { 6032 // check if target holds top-level <provider> permissions 6033 if (!readMet && pi.readPermission != null 6034 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6035 readMet = true; 6036 } 6037 if (!writeMet && pi.writePermission != null 6038 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6039 writeMet = true; 6040 } 6041 6042 // track if unprotected read/write is allowed; any denied 6043 // <path-permission> below removes this ability 6044 boolean allowDefaultRead = pi.readPermission == null; 6045 boolean allowDefaultWrite = pi.writePermission == null; 6046 6047 // check if target holds any <path-permission> that match uri 6048 final PathPermission[] pps = pi.pathPermissions; 6049 if (pps != null) { 6050 final String path = grantUri.uri.getPath(); 6051 int i = pps.length; 6052 while (i > 0 && (!readMet || !writeMet)) { 6053 i--; 6054 PathPermission pp = pps[i]; 6055 if (pp.match(path)) { 6056 if (!readMet) { 6057 final String pprperm = pp.getReadPermission(); 6058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6059 + pprperm + " for " + pp.getPath() 6060 + ": match=" + pp.match(path) 6061 + " check=" + pm.checkUidPermission(pprperm, uid)); 6062 if (pprperm != null) { 6063 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6064 readMet = true; 6065 } else { 6066 allowDefaultRead = false; 6067 } 6068 } 6069 } 6070 if (!writeMet) { 6071 final String ppwperm = pp.getWritePermission(); 6072 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6073 + ppwperm + " for " + pp.getPath() 6074 + ": match=" + pp.match(path) 6075 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6076 if (ppwperm != null) { 6077 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6078 writeMet = true; 6079 } else { 6080 allowDefaultWrite = false; 6081 } 6082 } 6083 } 6084 } 6085 } 6086 } 6087 6088 // grant unprotected <provider> read/write, if not blocked by 6089 // <path-permission> above 6090 if (allowDefaultRead) readMet = true; 6091 if (allowDefaultWrite) writeMet = true; 6092 6093 } catch (RemoteException e) { 6094 return false; 6095 } 6096 6097 return readMet && writeMet; 6098 } 6099 6100 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6101 ProviderInfo pi = null; 6102 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6103 if (cpr != null) { 6104 pi = cpr.info; 6105 } else { 6106 try { 6107 pi = AppGlobals.getPackageManager().resolveContentProvider( 6108 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6109 } catch (RemoteException ex) { 6110 } 6111 } 6112 return pi; 6113 } 6114 6115 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6116 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6117 if (targetUris != null) { 6118 return targetUris.get(grantUri); 6119 } 6120 return null; 6121 } 6122 6123 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6124 String targetPkg, int targetUid, GrantUri grantUri) { 6125 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6126 if (targetUris == null) { 6127 targetUris = Maps.newArrayMap(); 6128 mGrantedUriPermissions.put(targetUid, targetUris); 6129 } 6130 6131 UriPermission perm = targetUris.get(grantUri); 6132 if (perm == null) { 6133 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6134 targetUris.put(grantUri, perm); 6135 } 6136 6137 return perm; 6138 } 6139 6140 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6141 final int modeFlags) { 6142 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6143 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6144 : UriPermission.STRENGTH_OWNED; 6145 6146 // Root gets to do everything. 6147 if (uid == 0) { 6148 return true; 6149 } 6150 6151 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6152 if (perms == null) return false; 6153 6154 // First look for exact match 6155 final UriPermission exactPerm = perms.get(grantUri); 6156 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6157 return true; 6158 } 6159 6160 // No exact match, look for prefixes 6161 final int N = perms.size(); 6162 for (int i = 0; i < N; i++) { 6163 final UriPermission perm = perms.valueAt(i); 6164 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6165 && perm.getStrength(modeFlags) >= minStrength) { 6166 return true; 6167 } 6168 } 6169 6170 return false; 6171 } 6172 6173 @Override 6174 public int checkUriPermission(Uri uri, int pid, int uid, 6175 final int modeFlags, int userId) { 6176 enforceNotIsolatedCaller("checkUriPermission"); 6177 6178 // Another redirected-binder-call permissions check as in 6179 // {@link checkComponentPermission}. 6180 Identity tlsIdentity = sCallerIdentity.get(); 6181 if (tlsIdentity != null) { 6182 uid = tlsIdentity.uid; 6183 pid = tlsIdentity.pid; 6184 } 6185 6186 // Our own process gets to do everything. 6187 if (pid == MY_PID) { 6188 return PackageManager.PERMISSION_GRANTED; 6189 } 6190 synchronized (this) { 6191 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6192 ? PackageManager.PERMISSION_GRANTED 6193 : PackageManager.PERMISSION_DENIED; 6194 } 6195 } 6196 6197 /** 6198 * Check if the targetPkg can be granted permission to access uri by 6199 * the callingUid using the given modeFlags. Throws a security exception 6200 * if callingUid is not allowed to do this. Returns the uid of the target 6201 * if the URI permission grant should be performed; returns -1 if it is not 6202 * needed (for example targetPkg already has permission to access the URI). 6203 * If you already know the uid of the target, you can supply it in 6204 * lastTargetUid else set that to -1. 6205 */ 6206 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6207 final int modeFlags, int lastTargetUid) { 6208 if (!Intent.isAccessUriMode(modeFlags)) { 6209 return -1; 6210 } 6211 6212 if (targetPkg != null) { 6213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6214 "Checking grant " + targetPkg + " permission to " + grantUri); 6215 } 6216 6217 final IPackageManager pm = AppGlobals.getPackageManager(); 6218 6219 // If this is not a content: uri, we can't do anything with it. 6220 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6221 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6222 "Can't grant URI permission for non-content URI: " + grantUri); 6223 return -1; 6224 } 6225 6226 final String authority = grantUri.uri.getAuthority(); 6227 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6228 if (pi == null) { 6229 Slog.w(TAG, "No content provider found for permission check: " + 6230 grantUri.uri.toSafeString()); 6231 return -1; 6232 } 6233 6234 int targetUid = lastTargetUid; 6235 if (targetUid < 0 && targetPkg != null) { 6236 try { 6237 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6238 if (targetUid < 0) { 6239 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6240 "Can't grant URI permission no uid for: " + targetPkg); 6241 return -1; 6242 } 6243 } catch (RemoteException ex) { 6244 return -1; 6245 } 6246 } 6247 6248 if (targetUid >= 0) { 6249 // First... does the target actually need this permission? 6250 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6251 // No need to grant the target this permission. 6252 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6253 "Target " + targetPkg + " already has full permission to " + grantUri); 6254 return -1; 6255 } 6256 } else { 6257 // First... there is no target package, so can anyone access it? 6258 boolean allowed = pi.exported; 6259 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6260 if (pi.readPermission != null) { 6261 allowed = false; 6262 } 6263 } 6264 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6265 if (pi.writePermission != null) { 6266 allowed = false; 6267 } 6268 } 6269 if (allowed) { 6270 return -1; 6271 } 6272 } 6273 6274 // Second... is the provider allowing granting of URI permissions? 6275 if (!pi.grantUriPermissions) { 6276 throw new SecurityException("Provider " + pi.packageName 6277 + "/" + pi.name 6278 + " does not allow granting of Uri permissions (uri " 6279 + grantUri + ")"); 6280 } 6281 if (pi.uriPermissionPatterns != null) { 6282 final int N = pi.uriPermissionPatterns.length; 6283 boolean allowed = false; 6284 for (int i=0; i<N; i++) { 6285 if (pi.uriPermissionPatterns[i] != null 6286 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6287 allowed = true; 6288 break; 6289 } 6290 } 6291 if (!allowed) { 6292 throw new SecurityException("Provider " + pi.packageName 6293 + "/" + pi.name 6294 + " does not allow granting of permission to path of Uri " 6295 + grantUri); 6296 } 6297 } 6298 6299 // Third... does the caller itself have permission to access 6300 // this uri? 6301 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6302 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6303 // Require they hold a strong enough Uri permission 6304 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6305 throw new SecurityException("Uid " + callingUid 6306 + " does not have permission to uri " + grantUri); 6307 } 6308 } 6309 } 6310 return targetUid; 6311 } 6312 6313 @Override 6314 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6315 final int modeFlags, int userId) { 6316 enforceNotIsolatedCaller("checkGrantUriPermission"); 6317 synchronized(this) { 6318 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6319 new GrantUri(userId, uri, false), modeFlags, -1); 6320 } 6321 } 6322 6323 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6324 final int modeFlags, UriPermissionOwner owner) { 6325 if (!Intent.isAccessUriMode(modeFlags)) { 6326 return; 6327 } 6328 6329 // So here we are: the caller has the assumed permission 6330 // to the uri, and the target doesn't. Let's now give this to 6331 // the target. 6332 6333 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6334 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6335 6336 final String authority = grantUri.uri.getAuthority(); 6337 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6338 if (pi == null) { 6339 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6340 return; 6341 } 6342 6343 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6344 grantUri.prefix = true; 6345 } 6346 final UriPermission perm = findOrCreateUriPermissionLocked( 6347 pi.packageName, targetPkg, targetUid, grantUri); 6348 perm.grantModes(modeFlags, owner); 6349 } 6350 6351 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6352 final int modeFlags, UriPermissionOwner owner) { 6353 if (targetPkg == null) { 6354 throw new NullPointerException("targetPkg"); 6355 } 6356 6357 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6358 -1); 6359 if (targetUid < 0) { 6360 return; 6361 } 6362 6363 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6364 owner); 6365 } 6366 6367 static class NeededUriGrants extends ArrayList<GrantUri> { 6368 final String targetPkg; 6369 final int targetUid; 6370 final int flags; 6371 6372 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6373 this.targetPkg = targetPkg; 6374 this.targetUid = targetUid; 6375 this.flags = flags; 6376 } 6377 } 6378 6379 /** 6380 * Like checkGrantUriPermissionLocked, but takes an Intent. 6381 */ 6382 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6383 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6384 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6385 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6386 + " clip=" + (intent != null ? intent.getClipData() : null) 6387 + " from " + intent + "; flags=0x" 6388 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6389 6390 if (targetPkg == null) { 6391 throw new NullPointerException("targetPkg"); 6392 } 6393 6394 if (intent == null) { 6395 return null; 6396 } 6397 Uri data = intent.getData(); 6398 ClipData clip = intent.getClipData(); 6399 if (data == null && clip == null) { 6400 return null; 6401 } 6402 final IPackageManager pm = AppGlobals.getPackageManager(); 6403 int targetUid; 6404 if (needed != null) { 6405 targetUid = needed.targetUid; 6406 } else { 6407 try { 6408 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6409 } catch (RemoteException ex) { 6410 return null; 6411 } 6412 if (targetUid < 0) { 6413 if (DEBUG_URI_PERMISSION) { 6414 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6415 + " on user " + targetUserId); 6416 } 6417 return null; 6418 } 6419 } 6420 if (data != null) { 6421 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6422 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6423 targetUid); 6424 if (targetUid > 0) { 6425 if (needed == null) { 6426 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6427 } 6428 needed.add(grantUri); 6429 } 6430 } 6431 if (clip != null) { 6432 for (int i=0; i<clip.getItemCount(); i++) { 6433 Uri uri = clip.getItemAt(i).getUri(); 6434 if (uri != null) { 6435 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6436 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6437 targetUid); 6438 if (targetUid > 0) { 6439 if (needed == null) { 6440 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6441 } 6442 needed.add(grantUri); 6443 } 6444 } else { 6445 Intent clipIntent = clip.getItemAt(i).getIntent(); 6446 if (clipIntent != null) { 6447 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6448 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6449 if (newNeeded != null) { 6450 needed = newNeeded; 6451 } 6452 } 6453 } 6454 } 6455 } 6456 6457 return needed; 6458 } 6459 6460 /** 6461 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6462 */ 6463 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6464 UriPermissionOwner owner) { 6465 if (needed != null) { 6466 for (int i=0; i<needed.size(); i++) { 6467 GrantUri grantUri = needed.get(i); 6468 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6469 grantUri, needed.flags, owner); 6470 } 6471 } 6472 } 6473 6474 void grantUriPermissionFromIntentLocked(int callingUid, 6475 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6476 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6477 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6478 if (needed == null) { 6479 return; 6480 } 6481 6482 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6483 } 6484 6485 @Override 6486 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6487 final int modeFlags, int userId) { 6488 enforceNotIsolatedCaller("grantUriPermission"); 6489 GrantUri grantUri = new GrantUri(userId, uri, false); 6490 synchronized(this) { 6491 final ProcessRecord r = getRecordForAppLocked(caller); 6492 if (r == null) { 6493 throw new SecurityException("Unable to find app for caller " 6494 + caller 6495 + " when granting permission to uri " + grantUri); 6496 } 6497 if (targetPkg == null) { 6498 throw new IllegalArgumentException("null target"); 6499 } 6500 if (grantUri == null) { 6501 throw new IllegalArgumentException("null uri"); 6502 } 6503 6504 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6505 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6506 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6507 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6508 6509 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6510 } 6511 } 6512 6513 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6514 if (perm.modeFlags == 0) { 6515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6516 perm.targetUid); 6517 if (perms != null) { 6518 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6519 "Removing " + perm.targetUid + " permission to " + perm.uri); 6520 6521 perms.remove(perm.uri); 6522 if (perms.isEmpty()) { 6523 mGrantedUriPermissions.remove(perm.targetUid); 6524 } 6525 } 6526 } 6527 } 6528 6529 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6530 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6531 6532 final IPackageManager pm = AppGlobals.getPackageManager(); 6533 final String authority = grantUri.uri.getAuthority(); 6534 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6535 if (pi == null) { 6536 Slog.w(TAG, "No content provider found for permission revoke: " 6537 + grantUri.toSafeString()); 6538 return; 6539 } 6540 6541 // Does the caller have this permission on the URI? 6542 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6543 // Right now, if you are not the original owner of the permission, 6544 // you are not allowed to revoke it. 6545 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6546 throw new SecurityException("Uid " + callingUid 6547 + " does not have permission to uri " + grantUri); 6548 //} 6549 } 6550 6551 boolean persistChanged = false; 6552 6553 // Go through all of the permissions and remove any that match. 6554 int N = mGrantedUriPermissions.size(); 6555 for (int i = 0; i < N; i++) { 6556 final int targetUid = mGrantedUriPermissions.keyAt(i); 6557 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6558 6559 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6560 final UriPermission perm = it.next(); 6561 if (perm.uri.sourceUserId == grantUri.sourceUserId 6562 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6563 if (DEBUG_URI_PERMISSION) 6564 Slog.v(TAG, 6565 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6566 persistChanged |= perm.revokeModes( 6567 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6568 if (perm.modeFlags == 0) { 6569 it.remove(); 6570 } 6571 } 6572 } 6573 6574 if (perms.isEmpty()) { 6575 mGrantedUriPermissions.remove(targetUid); 6576 N--; 6577 i--; 6578 } 6579 } 6580 6581 if (persistChanged) { 6582 schedulePersistUriGrants(); 6583 } 6584 } 6585 6586 @Override 6587 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6588 int userId) { 6589 enforceNotIsolatedCaller("revokeUriPermission"); 6590 synchronized(this) { 6591 final ProcessRecord r = getRecordForAppLocked(caller); 6592 if (r == null) { 6593 throw new SecurityException("Unable to find app for caller " 6594 + caller 6595 + " when revoking permission to uri " + uri); 6596 } 6597 if (uri == null) { 6598 Slog.w(TAG, "revokeUriPermission: null uri"); 6599 return; 6600 } 6601 6602 if (!Intent.isAccessUriMode(modeFlags)) { 6603 return; 6604 } 6605 6606 final IPackageManager pm = AppGlobals.getPackageManager(); 6607 final String authority = uri.getAuthority(); 6608 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6609 if (pi == null) { 6610 Slog.w(TAG, "No content provider found for permission revoke: " 6611 + uri.toSafeString()); 6612 return; 6613 } 6614 6615 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6616 } 6617 } 6618 6619 /** 6620 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6621 * given package. 6622 * 6623 * @param packageName Package name to match, or {@code null} to apply to all 6624 * packages. 6625 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6626 * to all users. 6627 * @param persistable If persistable grants should be removed. 6628 */ 6629 private void removeUriPermissionsForPackageLocked( 6630 String packageName, int userHandle, boolean persistable) { 6631 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6632 throw new IllegalArgumentException("Must narrow by either package or user"); 6633 } 6634 6635 boolean persistChanged = false; 6636 6637 int N = mGrantedUriPermissions.size(); 6638 for (int i = 0; i < N; i++) { 6639 final int targetUid = mGrantedUriPermissions.keyAt(i); 6640 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6641 6642 // Only inspect grants matching user 6643 if (userHandle == UserHandle.USER_ALL 6644 || userHandle == UserHandle.getUserId(targetUid)) { 6645 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6646 final UriPermission perm = it.next(); 6647 6648 // Only inspect grants matching package 6649 if (packageName == null || perm.sourcePkg.equals(packageName) 6650 || perm.targetPkg.equals(packageName)) { 6651 persistChanged |= perm.revokeModes( 6652 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6653 6654 // Only remove when no modes remain; any persisted grants 6655 // will keep this alive. 6656 if (perm.modeFlags == 0) { 6657 it.remove(); 6658 } 6659 } 6660 } 6661 6662 if (perms.isEmpty()) { 6663 mGrantedUriPermissions.remove(targetUid); 6664 N--; 6665 i--; 6666 } 6667 } 6668 } 6669 6670 if (persistChanged) { 6671 schedulePersistUriGrants(); 6672 } 6673 } 6674 6675 @Override 6676 public IBinder newUriPermissionOwner(String name) { 6677 enforceNotIsolatedCaller("newUriPermissionOwner"); 6678 synchronized(this) { 6679 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6680 return owner.getExternalTokenLocked(); 6681 } 6682 } 6683 6684 @Override 6685 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6686 final int modeFlags, int userId) { 6687 synchronized(this) { 6688 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6689 if (owner == null) { 6690 throw new IllegalArgumentException("Unknown owner: " + token); 6691 } 6692 if (fromUid != Binder.getCallingUid()) { 6693 if (Binder.getCallingUid() != Process.myUid()) { 6694 // Only system code can grant URI permissions on behalf 6695 // of other users. 6696 throw new SecurityException("nice try"); 6697 } 6698 } 6699 if (targetPkg == null) { 6700 throw new IllegalArgumentException("null target"); 6701 } 6702 if (uri == null) { 6703 throw new IllegalArgumentException("null uri"); 6704 } 6705 6706 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6707 modeFlags, owner); 6708 } 6709 } 6710 6711 @Override 6712 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6713 synchronized(this) { 6714 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6715 if (owner == null) { 6716 throw new IllegalArgumentException("Unknown owner: " + token); 6717 } 6718 6719 if (uri == null) { 6720 owner.removeUriPermissionsLocked(mode); 6721 } else { 6722 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6723 } 6724 } 6725 } 6726 6727 private void schedulePersistUriGrants() { 6728 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6729 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6730 10 * DateUtils.SECOND_IN_MILLIS); 6731 } 6732 } 6733 6734 private void writeGrantedUriPermissions() { 6735 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6736 6737 // Snapshot permissions so we can persist without lock 6738 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6739 synchronized (this) { 6740 final int size = mGrantedUriPermissions.size(); 6741 for (int i = 0; i < size; i++) { 6742 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6743 for (UriPermission perm : perms.values()) { 6744 if (perm.persistedModeFlags != 0) { 6745 persist.add(perm.snapshot()); 6746 } 6747 } 6748 } 6749 } 6750 6751 FileOutputStream fos = null; 6752 try { 6753 fos = mGrantFile.startWrite(); 6754 6755 XmlSerializer out = new FastXmlSerializer(); 6756 out.setOutput(fos, "utf-8"); 6757 out.startDocument(null, true); 6758 out.startTag(null, TAG_URI_GRANTS); 6759 for (UriPermission.Snapshot perm : persist) { 6760 out.startTag(null, TAG_URI_GRANT); 6761 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6762 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6763 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6764 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6765 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6766 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6767 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6768 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6769 out.endTag(null, TAG_URI_GRANT); 6770 } 6771 out.endTag(null, TAG_URI_GRANTS); 6772 out.endDocument(); 6773 6774 mGrantFile.finishWrite(fos); 6775 } catch (IOException e) { 6776 if (fos != null) { 6777 mGrantFile.failWrite(fos); 6778 } 6779 } 6780 } 6781 6782 private void readGrantedUriPermissionsLocked() { 6783 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6784 6785 final long now = System.currentTimeMillis(); 6786 6787 FileInputStream fis = null; 6788 try { 6789 fis = mGrantFile.openRead(); 6790 final XmlPullParser in = Xml.newPullParser(); 6791 in.setInput(fis, null); 6792 6793 int type; 6794 while ((type = in.next()) != END_DOCUMENT) { 6795 final String tag = in.getName(); 6796 if (type == START_TAG) { 6797 if (TAG_URI_GRANT.equals(tag)) { 6798 final int sourceUserId; 6799 final int targetUserId; 6800 final int userHandle = readIntAttribute(in, 6801 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6802 if (userHandle != UserHandle.USER_NULL) { 6803 // For backwards compatibility. 6804 sourceUserId = userHandle; 6805 targetUserId = userHandle; 6806 } else { 6807 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6808 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6809 } 6810 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6811 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6812 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6813 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6814 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6815 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6816 6817 // Sanity check that provider still belongs to source package 6818 final ProviderInfo pi = getProviderInfoLocked( 6819 uri.getAuthority(), sourceUserId); 6820 if (pi != null && sourcePkg.equals(pi.packageName)) { 6821 int targetUid = -1; 6822 try { 6823 targetUid = AppGlobals.getPackageManager() 6824 .getPackageUid(targetPkg, targetUserId); 6825 } catch (RemoteException e) { 6826 } 6827 if (targetUid != -1) { 6828 final UriPermission perm = findOrCreateUriPermissionLocked( 6829 sourcePkg, targetPkg, targetUid, 6830 new GrantUri(sourceUserId, uri, prefix)); 6831 perm.initPersistedModes(modeFlags, createdTime); 6832 } 6833 } else { 6834 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6835 + " but instead found " + pi); 6836 } 6837 } 6838 } 6839 } 6840 } catch (FileNotFoundException e) { 6841 // Missing grants is okay 6842 } catch (IOException e) { 6843 Log.wtf(TAG, "Failed reading Uri grants", e); 6844 } catch (XmlPullParserException e) { 6845 Log.wtf(TAG, "Failed reading Uri grants", e); 6846 } finally { 6847 IoUtils.closeQuietly(fis); 6848 } 6849 } 6850 6851 @Override 6852 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6853 enforceNotIsolatedCaller("takePersistableUriPermission"); 6854 6855 Preconditions.checkFlagsArgument(modeFlags, 6856 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6857 6858 synchronized (this) { 6859 final int callingUid = Binder.getCallingUid(); 6860 boolean persistChanged = false; 6861 GrantUri grantUri = new GrantUri(userId, uri, false); 6862 6863 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6864 new GrantUri(userId, uri, false)); 6865 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6866 new GrantUri(userId, uri, true)); 6867 6868 final boolean exactValid = (exactPerm != null) 6869 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6870 final boolean prefixValid = (prefixPerm != null) 6871 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6872 6873 if (!(exactValid || prefixValid)) { 6874 throw new SecurityException("No persistable permission grants found for UID " 6875 + callingUid + " and Uri " + grantUri.toSafeString()); 6876 } 6877 6878 if (exactValid) { 6879 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6880 } 6881 if (prefixValid) { 6882 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6883 } 6884 6885 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6886 6887 if (persistChanged) { 6888 schedulePersistUriGrants(); 6889 } 6890 } 6891 } 6892 6893 @Override 6894 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6895 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6896 6897 Preconditions.checkFlagsArgument(modeFlags, 6898 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6899 6900 synchronized (this) { 6901 final int callingUid = Binder.getCallingUid(); 6902 boolean persistChanged = false; 6903 6904 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6905 new GrantUri(userId, uri, false)); 6906 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6907 new GrantUri(userId, uri, true)); 6908 if (exactPerm == null && prefixPerm == null) { 6909 throw new SecurityException("No permission grants found for UID " + callingUid 6910 + " and Uri " + uri.toSafeString()); 6911 } 6912 6913 if (exactPerm != null) { 6914 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6915 removeUriPermissionIfNeededLocked(exactPerm); 6916 } 6917 if (prefixPerm != null) { 6918 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6919 removeUriPermissionIfNeededLocked(prefixPerm); 6920 } 6921 6922 if (persistChanged) { 6923 schedulePersistUriGrants(); 6924 } 6925 } 6926 } 6927 6928 /** 6929 * Prune any older {@link UriPermission} for the given UID until outstanding 6930 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6931 * 6932 * @return if any mutations occured that require persisting. 6933 */ 6934 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6935 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6936 if (perms == null) return false; 6937 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6938 6939 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6940 for (UriPermission perm : perms.values()) { 6941 if (perm.persistedModeFlags != 0) { 6942 persisted.add(perm); 6943 } 6944 } 6945 6946 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6947 if (trimCount <= 0) return false; 6948 6949 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6950 for (int i = 0; i < trimCount; i++) { 6951 final UriPermission perm = persisted.get(i); 6952 6953 if (DEBUG_URI_PERMISSION) { 6954 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6955 } 6956 6957 perm.releasePersistableModes(~0); 6958 removeUriPermissionIfNeededLocked(perm); 6959 } 6960 6961 return true; 6962 } 6963 6964 @Override 6965 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6966 String packageName, boolean incoming) { 6967 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6968 Preconditions.checkNotNull(packageName, "packageName"); 6969 6970 final int callingUid = Binder.getCallingUid(); 6971 final IPackageManager pm = AppGlobals.getPackageManager(); 6972 try { 6973 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6974 if (packageUid != callingUid) { 6975 throw new SecurityException( 6976 "Package " + packageName + " does not belong to calling UID " + callingUid); 6977 } 6978 } catch (RemoteException e) { 6979 throw new SecurityException("Failed to verify package name ownership"); 6980 } 6981 6982 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6983 synchronized (this) { 6984 if (incoming) { 6985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6986 callingUid); 6987 if (perms == null) { 6988 Slog.w(TAG, "No permission grants found for " + packageName); 6989 } else { 6990 for (UriPermission perm : perms.values()) { 6991 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6992 result.add(perm.buildPersistedPublicApiObject()); 6993 } 6994 } 6995 } 6996 } else { 6997 final int size = mGrantedUriPermissions.size(); 6998 for (int i = 0; i < size; i++) { 6999 final ArrayMap<GrantUri, UriPermission> perms = 7000 mGrantedUriPermissions.valueAt(i); 7001 for (UriPermission perm : perms.values()) { 7002 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7003 result.add(perm.buildPersistedPublicApiObject()); 7004 } 7005 } 7006 } 7007 } 7008 } 7009 return new ParceledListSlice<android.content.UriPermission>(result); 7010 } 7011 7012 @Override 7013 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7014 synchronized (this) { 7015 ProcessRecord app = 7016 who != null ? getRecordForAppLocked(who) : null; 7017 if (app == null) return; 7018 7019 Message msg = Message.obtain(); 7020 msg.what = WAIT_FOR_DEBUGGER_MSG; 7021 msg.obj = app; 7022 msg.arg1 = waiting ? 1 : 0; 7023 mHandler.sendMessage(msg); 7024 } 7025 } 7026 7027 @Override 7028 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7029 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7030 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7031 outInfo.availMem = Process.getFreeMemory(); 7032 outInfo.totalMem = Process.getTotalMemory(); 7033 outInfo.threshold = homeAppMem; 7034 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7035 outInfo.hiddenAppThreshold = cachedAppMem; 7036 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7037 ProcessList.SERVICE_ADJ); 7038 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7039 ProcessList.VISIBLE_APP_ADJ); 7040 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7041 ProcessList.FOREGROUND_APP_ADJ); 7042 } 7043 7044 // ========================================================= 7045 // TASK MANAGEMENT 7046 // ========================================================= 7047 7048 @Override 7049 public List<IAppTask> getAppTasks() { 7050 int callingUid = Binder.getCallingUid(); 7051 long ident = Binder.clearCallingIdentity(); 7052 synchronized(this) { 7053 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7054 try { 7055 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7056 7057 final int N = mRecentTasks.size(); 7058 for (int i = 0; i < N; i++) { 7059 TaskRecord tr = mRecentTasks.get(i); 7060 // Skip tasks that are not created by the caller 7061 if (tr.creatorUid == callingUid) { 7062 ActivityManager.RecentTaskInfo taskInfo = 7063 createRecentTaskInfoFromTaskRecord(tr); 7064 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7065 list.add(taskImpl); 7066 } 7067 } 7068 } finally { 7069 Binder.restoreCallingIdentity(ident); 7070 } 7071 return list; 7072 } 7073 } 7074 7075 @Override 7076 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7077 final int callingUid = Binder.getCallingUid(); 7078 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7079 7080 synchronized(this) { 7081 if (localLOGV) Slog.v( 7082 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7083 7084 final boolean allowed = checkCallingPermission( 7085 android.Manifest.permission.GET_TASKS) 7086 == PackageManager.PERMISSION_GRANTED; 7087 if (!allowed) { 7088 Slog.w(TAG, "getTasks: caller " + callingUid 7089 + " does not hold GET_TASKS; limiting output"); 7090 } 7091 7092 // TODO: Improve with MRU list from all ActivityStacks. 7093 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7094 } 7095 7096 return list; 7097 } 7098 7099 TaskRecord getMostRecentTask() { 7100 return mRecentTasks.get(0); 7101 } 7102 7103 /** 7104 * Creates a new RecentTaskInfo from a TaskRecord. 7105 */ 7106 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7107 // Update the task description to reflect any changes in the task stack 7108 tr.updateTaskDescription(); 7109 7110 // Compose the recent task info 7111 ActivityManager.RecentTaskInfo rti 7112 = new ActivityManager.RecentTaskInfo(); 7113 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7114 rti.persistentId = tr.taskId; 7115 rti.baseIntent = new Intent(tr.getBaseIntent()); 7116 rti.origActivity = tr.origActivity; 7117 rti.description = tr.lastDescription; 7118 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7119 rti.userId = tr.userId; 7120 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7121 return rti; 7122 } 7123 7124 @Override 7125 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7126 int flags, int userId) { 7127 final int callingUid = Binder.getCallingUid(); 7128 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7129 false, true, "getRecentTasks", null); 7130 7131 synchronized (this) { 7132 final boolean allowed = checkCallingPermission( 7133 android.Manifest.permission.GET_TASKS) 7134 == PackageManager.PERMISSION_GRANTED; 7135 if (!allowed) { 7136 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7137 + " does not hold GET_TASKS; limiting output"); 7138 } 7139 final boolean detailed = checkCallingPermission( 7140 android.Manifest.permission.GET_DETAILED_TASKS) 7141 == PackageManager.PERMISSION_GRANTED; 7142 7143 IPackageManager pm = AppGlobals.getPackageManager(); 7144 7145 final int N = mRecentTasks.size(); 7146 ArrayList<ActivityManager.RecentTaskInfo> res 7147 = new ArrayList<ActivityManager.RecentTaskInfo>( 7148 maxNum < N ? maxNum : N); 7149 7150 final Set<Integer> includedUsers; 7151 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7152 includedUsers = getProfileIdsLocked(userId); 7153 } else { 7154 includedUsers = new HashSet<Integer>(); 7155 } 7156 includedUsers.add(Integer.valueOf(userId)); 7157 for (int i=0; i<N && maxNum > 0; i++) { 7158 TaskRecord tr = mRecentTasks.get(i); 7159 // Only add calling user or related users recent tasks 7160 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7161 7162 // Return the entry if desired by the caller. We always return 7163 // the first entry, because callers always expect this to be the 7164 // foreground app. We may filter others if the caller has 7165 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7166 // we should exclude the entry. 7167 7168 if (i == 0 7169 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7170 || (tr.intent == null) 7171 || ((tr.intent.getFlags() 7172 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7173 if (!allowed) { 7174 // If the caller doesn't have the GET_TASKS permission, then only 7175 // allow them to see a small subset of tasks -- their own and home. 7176 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7177 continue; 7178 } 7179 } 7180 7181 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7182 if (!detailed) { 7183 rti.baseIntent.replaceExtras((Bundle)null); 7184 } 7185 7186 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7187 // Check whether this activity is currently available. 7188 try { 7189 if (rti.origActivity != null) { 7190 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7191 == null) { 7192 continue; 7193 } 7194 } else if (rti.baseIntent != null) { 7195 if (pm.queryIntentActivities(rti.baseIntent, 7196 null, 0, userId) == null) { 7197 continue; 7198 } 7199 } 7200 } catch (RemoteException e) { 7201 // Will never happen. 7202 } 7203 } 7204 7205 res.add(rti); 7206 maxNum--; 7207 } 7208 } 7209 return res; 7210 } 7211 } 7212 7213 private TaskRecord recentTaskForIdLocked(int id) { 7214 final int N = mRecentTasks.size(); 7215 for (int i=0; i<N; i++) { 7216 TaskRecord tr = mRecentTasks.get(i); 7217 if (tr.taskId == id) { 7218 return tr; 7219 } 7220 } 7221 return null; 7222 } 7223 7224 @Override 7225 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7226 synchronized (this) { 7227 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7228 "getTaskThumbnails()"); 7229 TaskRecord tr = recentTaskForIdLocked(id); 7230 if (tr != null) { 7231 return tr.getTaskThumbnailsLocked(); 7232 } 7233 } 7234 return null; 7235 } 7236 7237 @Override 7238 public Bitmap getTaskTopThumbnail(int id) { 7239 synchronized (this) { 7240 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7241 "getTaskTopThumbnail()"); 7242 TaskRecord tr = recentTaskForIdLocked(id); 7243 if (tr != null) { 7244 return tr.getTaskTopThumbnailLocked(); 7245 } 7246 } 7247 return null; 7248 } 7249 7250 @Override 7251 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7252 synchronized (this) { 7253 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7254 if (r != null) { 7255 r.taskDescription = td; 7256 r.task.updateTaskDescription(); 7257 } 7258 } 7259 } 7260 7261 @Override 7262 public boolean removeSubTask(int taskId, int subTaskIndex) { 7263 synchronized (this) { 7264 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7265 "removeSubTask()"); 7266 long ident = Binder.clearCallingIdentity(); 7267 try { 7268 TaskRecord tr = recentTaskForIdLocked(taskId); 7269 if (tr != null) { 7270 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7271 } 7272 return false; 7273 } finally { 7274 Binder.restoreCallingIdentity(ident); 7275 } 7276 } 7277 } 7278 7279 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7280 if (!pr.killedByAm) { 7281 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7282 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7283 pr.processName, pr.setAdj, reason); 7284 pr.killedByAm = true; 7285 Process.killProcessQuiet(pr.pid); 7286 } 7287 } 7288 7289 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7290 tr.disposeThumbnail(); 7291 mRecentTasks.remove(tr); 7292 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7293 Intent baseIntent = new Intent( 7294 tr.intent != null ? tr.intent : tr.affinityIntent); 7295 ComponentName component = baseIntent.getComponent(); 7296 if (component == null) { 7297 Slog.w(TAG, "Now component for base intent of task: " + tr); 7298 return; 7299 } 7300 7301 // Find any running services associated with this app. 7302 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7303 7304 if (killProcesses) { 7305 // Find any running processes associated with this app. 7306 final String pkg = component.getPackageName(); 7307 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7308 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7309 for (int i=0; i<pmap.size(); i++) { 7310 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7311 for (int j=0; j<uids.size(); j++) { 7312 ProcessRecord proc = uids.valueAt(j); 7313 if (proc.userId != tr.userId) { 7314 continue; 7315 } 7316 if (!proc.pkgList.containsKey(pkg)) { 7317 continue; 7318 } 7319 procs.add(proc); 7320 } 7321 } 7322 7323 // Kill the running processes. 7324 for (int i=0; i<procs.size(); i++) { 7325 ProcessRecord pr = procs.get(i); 7326 if (pr == mHomeProcess) { 7327 // Don't kill the home process along with tasks from the same package. 7328 continue; 7329 } 7330 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7331 killUnneededProcessLocked(pr, "remove task"); 7332 } else { 7333 pr.waitingToKill = "remove task"; 7334 } 7335 } 7336 } 7337 } 7338 7339 /** 7340 * Removes the task with the specified task id. 7341 * 7342 * @param taskId Identifier of the task to be removed. 7343 * @param flags Additional operational flags. May be 0 or 7344 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7345 * @return Returns true if the given task was found and removed. 7346 */ 7347 private boolean removeTaskByIdLocked(int taskId, int flags) { 7348 TaskRecord tr = recentTaskForIdLocked(taskId); 7349 if (tr != null) { 7350 tr.removeTaskActivitiesLocked(-1, false); 7351 cleanUpRemovedTaskLocked(tr, flags); 7352 if (tr.isPersistable) { 7353 notifyTaskPersisterLocked(tr, true); 7354 } 7355 return true; 7356 } 7357 return false; 7358 } 7359 7360 @Override 7361 public boolean removeTask(int taskId, int flags) { 7362 synchronized (this) { 7363 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7364 "removeTask()"); 7365 long ident = Binder.clearCallingIdentity(); 7366 try { 7367 return removeTaskByIdLocked(taskId, flags); 7368 } finally { 7369 Binder.restoreCallingIdentity(ident); 7370 } 7371 } 7372 } 7373 7374 /** 7375 * TODO: Add mController hook 7376 */ 7377 @Override 7378 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7379 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7380 "moveTaskToFront()"); 7381 7382 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7383 synchronized(this) { 7384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7385 Binder.getCallingUid(), "Task to front")) { 7386 ActivityOptions.abort(options); 7387 return; 7388 } 7389 final long origId = Binder.clearCallingIdentity(); 7390 try { 7391 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7392 if (task == null) { 7393 return; 7394 } 7395 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7396 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7397 return; 7398 } 7399 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7400 } finally { 7401 Binder.restoreCallingIdentity(origId); 7402 } 7403 ActivityOptions.abort(options); 7404 } 7405 } 7406 7407 @Override 7408 public void moveTaskToBack(int taskId) { 7409 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7410 "moveTaskToBack()"); 7411 7412 synchronized(this) { 7413 TaskRecord tr = recentTaskForIdLocked(taskId); 7414 if (tr != null) { 7415 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7416 ActivityStack stack = tr.stack; 7417 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7418 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7419 Binder.getCallingUid(), "Task to back")) { 7420 return; 7421 } 7422 } 7423 final long origId = Binder.clearCallingIdentity(); 7424 try { 7425 stack.moveTaskToBackLocked(taskId, null); 7426 } finally { 7427 Binder.restoreCallingIdentity(origId); 7428 } 7429 } 7430 } 7431 } 7432 7433 /** 7434 * Moves an activity, and all of the other activities within the same task, to the bottom 7435 * of the history stack. The activity's order within the task is unchanged. 7436 * 7437 * @param token A reference to the activity we wish to move 7438 * @param nonRoot If false then this only works if the activity is the root 7439 * of a task; if true it will work for any activity in a task. 7440 * @return Returns true if the move completed, false if not. 7441 */ 7442 @Override 7443 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7444 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7445 synchronized(this) { 7446 final long origId = Binder.clearCallingIdentity(); 7447 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7448 if (taskId >= 0) { 7449 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7450 } 7451 Binder.restoreCallingIdentity(origId); 7452 } 7453 return false; 7454 } 7455 7456 @Override 7457 public void moveTaskBackwards(int task) { 7458 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7459 "moveTaskBackwards()"); 7460 7461 synchronized(this) { 7462 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7463 Binder.getCallingUid(), "Task backwards")) { 7464 return; 7465 } 7466 final long origId = Binder.clearCallingIdentity(); 7467 moveTaskBackwardsLocked(task); 7468 Binder.restoreCallingIdentity(origId); 7469 } 7470 } 7471 7472 private final void moveTaskBackwardsLocked(int task) { 7473 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7474 } 7475 7476 @Override 7477 public IBinder getHomeActivityToken() throws RemoteException { 7478 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7479 "getHomeActivityToken()"); 7480 synchronized (this) { 7481 return mStackSupervisor.getHomeActivityToken(); 7482 } 7483 } 7484 7485 @Override 7486 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7487 IActivityContainerCallback callback) throws RemoteException { 7488 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7489 "createActivityContainer()"); 7490 synchronized (this) { 7491 if (parentActivityToken == null) { 7492 throw new IllegalArgumentException("parent token must not be null"); 7493 } 7494 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7495 if (r == null) { 7496 return null; 7497 } 7498 if (callback == null) { 7499 throw new IllegalArgumentException("callback must not be null"); 7500 } 7501 return mStackSupervisor.createActivityContainer(r, callback); 7502 } 7503 } 7504 7505 @Override 7506 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7507 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7508 "deleteActivityContainer()"); 7509 synchronized (this) { 7510 mStackSupervisor.deleteActivityContainer(container); 7511 } 7512 } 7513 7514 @Override 7515 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7516 throws RemoteException { 7517 synchronized (this) { 7518 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7519 if (stack != null) { 7520 return stack.mActivityContainer; 7521 } 7522 return null; 7523 } 7524 } 7525 7526 @Override 7527 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7528 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7529 "moveTaskToStack()"); 7530 if (stackId == HOME_STACK_ID) { 7531 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7532 new RuntimeException("here").fillInStackTrace()); 7533 } 7534 synchronized (this) { 7535 long ident = Binder.clearCallingIdentity(); 7536 try { 7537 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7538 + stackId + " toTop=" + toTop); 7539 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7540 } finally { 7541 Binder.restoreCallingIdentity(ident); 7542 } 7543 } 7544 } 7545 7546 @Override 7547 public void resizeStack(int stackBoxId, Rect bounds) { 7548 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7549 "resizeStackBox()"); 7550 long ident = Binder.clearCallingIdentity(); 7551 try { 7552 mWindowManager.resizeStack(stackBoxId, bounds); 7553 } finally { 7554 Binder.restoreCallingIdentity(ident); 7555 } 7556 } 7557 7558 @Override 7559 public List<StackInfo> getAllStackInfos() { 7560 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7561 "getAllStackInfos()"); 7562 long ident = Binder.clearCallingIdentity(); 7563 try { 7564 synchronized (this) { 7565 return mStackSupervisor.getAllStackInfosLocked(); 7566 } 7567 } finally { 7568 Binder.restoreCallingIdentity(ident); 7569 } 7570 } 7571 7572 @Override 7573 public StackInfo getStackInfo(int stackId) { 7574 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7575 "getStackInfo()"); 7576 long ident = Binder.clearCallingIdentity(); 7577 try { 7578 synchronized (this) { 7579 return mStackSupervisor.getStackInfoLocked(stackId); 7580 } 7581 } finally { 7582 Binder.restoreCallingIdentity(ident); 7583 } 7584 } 7585 7586 @Override 7587 public boolean isInHomeStack(int taskId) { 7588 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7589 "getStackInfo()"); 7590 long ident = Binder.clearCallingIdentity(); 7591 try { 7592 synchronized (this) { 7593 TaskRecord tr = recentTaskForIdLocked(taskId); 7594 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7595 } 7596 } finally { 7597 Binder.restoreCallingIdentity(ident); 7598 } 7599 } 7600 7601 @Override 7602 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7603 synchronized(this) { 7604 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7605 } 7606 } 7607 7608 private boolean isLockTaskAuthorized(ComponentName name) { 7609 final DevicePolicyManager dpm = (DevicePolicyManager) 7610 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7611 return dpm != null && dpm.isLockTaskPermitted(name); 7612 } 7613 7614 private void startLockTaskMode(TaskRecord task) { 7615 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7616 return; 7617 } 7618 long ident = Binder.clearCallingIdentity(); 7619 try { 7620 synchronized (this) { 7621 // Since we lost lock on task, make sure it is still there. 7622 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7623 if (task != null) { 7624 mStackSupervisor.setLockTaskModeLocked(task); 7625 } 7626 } 7627 } finally { 7628 Binder.restoreCallingIdentity(ident); 7629 } 7630 } 7631 7632 @Override 7633 public void startLockTaskMode(int taskId) { 7634 long ident = Binder.clearCallingIdentity(); 7635 try { 7636 final TaskRecord task; 7637 synchronized (this) { 7638 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7639 } 7640 if (task != null) { 7641 startLockTaskMode(task); 7642 } 7643 } finally { 7644 Binder.restoreCallingIdentity(ident); 7645 } 7646 } 7647 7648 @Override 7649 public void startLockTaskMode(IBinder token) { 7650 long ident = Binder.clearCallingIdentity(); 7651 try { 7652 final TaskRecord task; 7653 synchronized (this) { 7654 final ActivityRecord r = ActivityRecord.forToken(token); 7655 if (r == null) { 7656 return; 7657 } 7658 task = r.task; 7659 } 7660 if (task != null) { 7661 startLockTaskMode(task); 7662 } 7663 } finally { 7664 Binder.restoreCallingIdentity(ident); 7665 } 7666 } 7667 7668 @Override 7669 public void stopLockTaskMode() { 7670 // Check if the calling task is eligible to use lock task 7671 final int uid = Binder.getCallingUid(); 7672 try { 7673 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7674 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7675 return; 7676 } 7677 } catch (RemoteException e) { 7678 Log.d(TAG, "stopLockTaskMode " + e); 7679 return; 7680 } 7681 // Stop lock task 7682 synchronized (this) { 7683 mStackSupervisor.setLockTaskModeLocked(null); 7684 } 7685 } 7686 7687 @Override 7688 public boolean isInLockTaskMode() { 7689 synchronized (this) { 7690 return mStackSupervisor.isInLockTaskMode(); 7691 } 7692 } 7693 7694 // ========================================================= 7695 // CONTENT PROVIDERS 7696 // ========================================================= 7697 7698 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7699 List<ProviderInfo> providers = null; 7700 try { 7701 providers = AppGlobals.getPackageManager(). 7702 queryContentProviders(app.processName, app.uid, 7703 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7704 } catch (RemoteException ex) { 7705 } 7706 if (DEBUG_MU) 7707 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7708 int userId = app.userId; 7709 if (providers != null) { 7710 int N = providers.size(); 7711 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7712 for (int i=0; i<N; i++) { 7713 ProviderInfo cpi = 7714 (ProviderInfo)providers.get(i); 7715 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7716 cpi.name, cpi.flags); 7717 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7718 // This is a singleton provider, but a user besides the 7719 // default user is asking to initialize a process it runs 7720 // in... well, no, it doesn't actually run in this process, 7721 // it runs in the process of the default user. Get rid of it. 7722 providers.remove(i); 7723 N--; 7724 i--; 7725 continue; 7726 } 7727 7728 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7729 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7730 if (cpr == null) { 7731 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7732 mProviderMap.putProviderByClass(comp, cpr); 7733 } 7734 if (DEBUG_MU) 7735 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7736 app.pubProviders.put(cpi.name, cpr); 7737 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7738 // Don't add this if it is a platform component that is marked 7739 // to run in multiple processes, because this is actually 7740 // part of the framework so doesn't make sense to track as a 7741 // separate apk in the process. 7742 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7743 } 7744 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7745 } 7746 } 7747 return providers; 7748 } 7749 7750 /** 7751 * Check if {@link ProcessRecord} has a possible chance at accessing the 7752 * given {@link ProviderInfo}. Final permission checking is always done 7753 * in {@link ContentProvider}. 7754 */ 7755 private final String checkContentProviderPermissionLocked( 7756 ProviderInfo cpi, ProcessRecord r, int userId) { 7757 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7758 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7759 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7760 // Looking for cross-user grants before to enforce the typical cross-users permissions 7761 if (userId != UserHandle.getUserId(callingUid)) { 7762 if (perms != null) { 7763 for (GrantUri grantUri : perms.keySet()) { 7764 if (grantUri.sourceUserId == userId) { 7765 String authority = grantUri.uri.getAuthority(); 7766 if (authority.equals(cpi.authority)) { 7767 return null; 7768 } 7769 } 7770 } 7771 } 7772 } 7773 userId = handleIncomingUser(callingPid, callingUid, userId, 7774 false, true, "checkContentProviderPermissionLocked", null); 7775 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7776 cpi.applicationInfo.uid, cpi.exported) 7777 == PackageManager.PERMISSION_GRANTED) { 7778 return null; 7779 } 7780 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7781 cpi.applicationInfo.uid, cpi.exported) 7782 == PackageManager.PERMISSION_GRANTED) { 7783 return null; 7784 } 7785 7786 PathPermission[] pps = cpi.pathPermissions; 7787 if (pps != null) { 7788 int i = pps.length; 7789 while (i > 0) { 7790 i--; 7791 PathPermission pp = pps[i]; 7792 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7793 cpi.applicationInfo.uid, cpi.exported) 7794 == PackageManager.PERMISSION_GRANTED) { 7795 return null; 7796 } 7797 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7798 cpi.applicationInfo.uid, cpi.exported) 7799 == PackageManager.PERMISSION_GRANTED) { 7800 return null; 7801 } 7802 } 7803 } 7804 7805 if (perms != null) { 7806 for (GrantUri grantUri : perms.keySet()) { 7807 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7808 return null; 7809 } 7810 } 7811 } 7812 7813 String msg; 7814 if (!cpi.exported) { 7815 msg = "Permission Denial: opening provider " + cpi.name 7816 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7817 + ", uid=" + callingUid + ") that is not exported from uid " 7818 + cpi.applicationInfo.uid; 7819 } else { 7820 msg = "Permission Denial: opening provider " + cpi.name 7821 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7822 + ", uid=" + callingUid + ") requires " 7823 + cpi.readPermission + " or " + cpi.writePermission; 7824 } 7825 Slog.w(TAG, msg); 7826 return msg; 7827 } 7828 7829 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7830 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7831 if (r != null) { 7832 for (int i=0; i<r.conProviders.size(); i++) { 7833 ContentProviderConnection conn = r.conProviders.get(i); 7834 if (conn.provider == cpr) { 7835 if (DEBUG_PROVIDER) Slog.v(TAG, 7836 "Adding provider requested by " 7837 + r.processName + " from process " 7838 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7839 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7840 if (stable) { 7841 conn.stableCount++; 7842 conn.numStableIncs++; 7843 } else { 7844 conn.unstableCount++; 7845 conn.numUnstableIncs++; 7846 } 7847 return conn; 7848 } 7849 } 7850 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7851 if (stable) { 7852 conn.stableCount = 1; 7853 conn.numStableIncs = 1; 7854 } else { 7855 conn.unstableCount = 1; 7856 conn.numUnstableIncs = 1; 7857 } 7858 cpr.connections.add(conn); 7859 r.conProviders.add(conn); 7860 return conn; 7861 } 7862 cpr.addExternalProcessHandleLocked(externalProcessToken); 7863 return null; 7864 } 7865 7866 boolean decProviderCountLocked(ContentProviderConnection conn, 7867 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7868 if (conn != null) { 7869 cpr = conn.provider; 7870 if (DEBUG_PROVIDER) Slog.v(TAG, 7871 "Removing provider requested by " 7872 + conn.client.processName + " from process " 7873 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7874 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7875 if (stable) { 7876 conn.stableCount--; 7877 } else { 7878 conn.unstableCount--; 7879 } 7880 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7881 cpr.connections.remove(conn); 7882 conn.client.conProviders.remove(conn); 7883 return true; 7884 } 7885 return false; 7886 } 7887 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7888 return false; 7889 } 7890 7891 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7892 String name, IBinder token, boolean stable, int userId) { 7893 ContentProviderRecord cpr; 7894 ContentProviderConnection conn = null; 7895 ProviderInfo cpi = null; 7896 7897 synchronized(this) { 7898 ProcessRecord r = null; 7899 if (caller != null) { 7900 r = getRecordForAppLocked(caller); 7901 if (r == null) { 7902 throw new SecurityException( 7903 "Unable to find app for caller " + caller 7904 + " (pid=" + Binder.getCallingPid() 7905 + ") when getting content provider " + name); 7906 } 7907 } 7908 7909 // First check if this content provider has been published... 7910 cpr = mProviderMap.getProviderByName(name, userId); 7911 boolean providerRunning = cpr != null; 7912 if (providerRunning) { 7913 cpi = cpr.info; 7914 String msg; 7915 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7916 throw new SecurityException(msg); 7917 } 7918 7919 if (r != null && cpr.canRunHere(r)) { 7920 // This provider has been published or is in the process 7921 // of being published... but it is also allowed to run 7922 // in the caller's process, so don't make a connection 7923 // and just let the caller instantiate its own instance. 7924 ContentProviderHolder holder = cpr.newHolder(null); 7925 // don't give caller the provider object, it needs 7926 // to make its own. 7927 holder.provider = null; 7928 return holder; 7929 } 7930 7931 final long origId = Binder.clearCallingIdentity(); 7932 7933 // In this case the provider instance already exists, so we can 7934 // return it right away. 7935 conn = incProviderCountLocked(r, cpr, token, stable); 7936 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7937 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7938 // If this is a perceptible app accessing the provider, 7939 // make sure to count it as being accessed and thus 7940 // back up on the LRU list. This is good because 7941 // content providers are often expensive to start. 7942 updateLruProcessLocked(cpr.proc, false, null); 7943 } 7944 } 7945 7946 if (cpr.proc != null) { 7947 if (false) { 7948 if (cpr.name.flattenToShortString().equals( 7949 "com.android.providers.calendar/.CalendarProvider2")) { 7950 Slog.v(TAG, "****************** KILLING " 7951 + cpr.name.flattenToShortString()); 7952 Process.killProcess(cpr.proc.pid); 7953 } 7954 } 7955 boolean success = updateOomAdjLocked(cpr.proc); 7956 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7957 // NOTE: there is still a race here where a signal could be 7958 // pending on the process even though we managed to update its 7959 // adj level. Not sure what to do about this, but at least 7960 // the race is now smaller. 7961 if (!success) { 7962 // Uh oh... it looks like the provider's process 7963 // has been killed on us. We need to wait for a new 7964 // process to be started, and make sure its death 7965 // doesn't kill our process. 7966 Slog.i(TAG, 7967 "Existing provider " + cpr.name.flattenToShortString() 7968 + " is crashing; detaching " + r); 7969 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7970 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7971 if (!lastRef) { 7972 // This wasn't the last ref our process had on 7973 // the provider... we have now been killed, bail. 7974 return null; 7975 } 7976 providerRunning = false; 7977 conn = null; 7978 } 7979 } 7980 7981 Binder.restoreCallingIdentity(origId); 7982 } 7983 7984 boolean singleton; 7985 if (!providerRunning) { 7986 try { 7987 cpi = AppGlobals.getPackageManager(). 7988 resolveContentProvider(name, 7989 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7990 } catch (RemoteException ex) { 7991 } 7992 if (cpi == null) { 7993 return null; 7994 } 7995 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7996 cpi.name, cpi.flags); 7997 if (singleton) { 7998 userId = 0; 7999 } 8000 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8001 8002 String msg; 8003 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 8004 throw new SecurityException(msg); 8005 } 8006 8007 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8008 && !cpi.processName.equals("system")) { 8009 // If this content provider does not run in the system 8010 // process, and the system is not yet ready to run other 8011 // processes, then fail fast instead of hanging. 8012 throw new IllegalArgumentException( 8013 "Attempt to launch content provider before system ready"); 8014 } 8015 8016 // Make sure that the user who owns this provider is started. If not, 8017 // we don't want to allow it to run. 8018 if (mStartedUsers.get(userId) == null) { 8019 Slog.w(TAG, "Unable to launch app " 8020 + cpi.applicationInfo.packageName + "/" 8021 + cpi.applicationInfo.uid + " for provider " 8022 + name + ": user " + userId + " is stopped"); 8023 return null; 8024 } 8025 8026 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8027 cpr = mProviderMap.getProviderByClass(comp, userId); 8028 final boolean firstClass = cpr == null; 8029 if (firstClass) { 8030 try { 8031 ApplicationInfo ai = 8032 AppGlobals.getPackageManager(). 8033 getApplicationInfo( 8034 cpi.applicationInfo.packageName, 8035 STOCK_PM_FLAGS, userId); 8036 if (ai == null) { 8037 Slog.w(TAG, "No package info for content provider " 8038 + cpi.name); 8039 return null; 8040 } 8041 ai = getAppInfoForUser(ai, userId); 8042 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8043 } catch (RemoteException ex) { 8044 // pm is in same process, this will never happen. 8045 } 8046 } 8047 8048 if (r != null && cpr.canRunHere(r)) { 8049 // If this is a multiprocess provider, then just return its 8050 // info and allow the caller to instantiate it. Only do 8051 // this if the provider is the same user as the caller's 8052 // process, or can run as root (so can be in any process). 8053 return cpr.newHolder(null); 8054 } 8055 8056 if (DEBUG_PROVIDER) { 8057 RuntimeException e = new RuntimeException("here"); 8058 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8059 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8060 } 8061 8062 // This is single process, and our app is now connecting to it. 8063 // See if we are already in the process of launching this 8064 // provider. 8065 final int N = mLaunchingProviders.size(); 8066 int i; 8067 for (i=0; i<N; i++) { 8068 if (mLaunchingProviders.get(i) == cpr) { 8069 break; 8070 } 8071 } 8072 8073 // If the provider is not already being launched, then get it 8074 // started. 8075 if (i >= N) { 8076 final long origId = Binder.clearCallingIdentity(); 8077 8078 try { 8079 // Content provider is now in use, its package can't be stopped. 8080 try { 8081 AppGlobals.getPackageManager().setPackageStoppedState( 8082 cpr.appInfo.packageName, false, userId); 8083 } catch (RemoteException e) { 8084 } catch (IllegalArgumentException e) { 8085 Slog.w(TAG, "Failed trying to unstop package " 8086 + cpr.appInfo.packageName + ": " + e); 8087 } 8088 8089 // Use existing process if already started 8090 ProcessRecord proc = getProcessRecordLocked( 8091 cpi.processName, cpr.appInfo.uid, false); 8092 if (proc != null && proc.thread != null) { 8093 if (DEBUG_PROVIDER) { 8094 Slog.d(TAG, "Installing in existing process " + proc); 8095 } 8096 proc.pubProviders.put(cpi.name, cpr); 8097 try { 8098 proc.thread.scheduleInstallProvider(cpi); 8099 } catch (RemoteException e) { 8100 } 8101 } else { 8102 proc = startProcessLocked(cpi.processName, 8103 cpr.appInfo, false, 0, "content provider", 8104 new ComponentName(cpi.applicationInfo.packageName, 8105 cpi.name), false, false, false); 8106 if (proc == null) { 8107 Slog.w(TAG, "Unable to launch app " 8108 + cpi.applicationInfo.packageName + "/" 8109 + cpi.applicationInfo.uid + " for provider " 8110 + name + ": process is bad"); 8111 return null; 8112 } 8113 } 8114 cpr.launchingApp = proc; 8115 mLaunchingProviders.add(cpr); 8116 } finally { 8117 Binder.restoreCallingIdentity(origId); 8118 } 8119 } 8120 8121 // Make sure the provider is published (the same provider class 8122 // may be published under multiple names). 8123 if (firstClass) { 8124 mProviderMap.putProviderByClass(comp, cpr); 8125 } 8126 8127 mProviderMap.putProviderByName(name, cpr); 8128 conn = incProviderCountLocked(r, cpr, token, stable); 8129 if (conn != null) { 8130 conn.waiting = true; 8131 } 8132 } 8133 } 8134 8135 // Wait for the provider to be published... 8136 synchronized (cpr) { 8137 while (cpr.provider == null) { 8138 if (cpr.launchingApp == null) { 8139 Slog.w(TAG, "Unable to launch app " 8140 + cpi.applicationInfo.packageName + "/" 8141 + cpi.applicationInfo.uid + " for provider " 8142 + name + ": launching app became null"); 8143 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8144 UserHandle.getUserId(cpi.applicationInfo.uid), 8145 cpi.applicationInfo.packageName, 8146 cpi.applicationInfo.uid, name); 8147 return null; 8148 } 8149 try { 8150 if (DEBUG_MU) { 8151 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8152 + cpr.launchingApp); 8153 } 8154 if (conn != null) { 8155 conn.waiting = true; 8156 } 8157 cpr.wait(); 8158 } catch (InterruptedException ex) { 8159 } finally { 8160 if (conn != null) { 8161 conn.waiting = false; 8162 } 8163 } 8164 } 8165 } 8166 return cpr != null ? cpr.newHolder(conn) : null; 8167 } 8168 8169 @Override 8170 public final ContentProviderHolder getContentProvider( 8171 IApplicationThread caller, String name, int userId, boolean stable) { 8172 enforceNotIsolatedCaller("getContentProvider"); 8173 if (caller == null) { 8174 String msg = "null IApplicationThread when getting content provider " 8175 + name; 8176 Slog.w(TAG, msg); 8177 throw new SecurityException(msg); 8178 } 8179 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8180 // with cross-user grant. 8181 return getContentProviderImpl(caller, name, null, stable, userId); 8182 } 8183 8184 public ContentProviderHolder getContentProviderExternal( 8185 String name, int userId, IBinder token) { 8186 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8187 "Do not have permission in call getContentProviderExternal()"); 8188 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8189 false, true, "getContentProvider", null); 8190 return getContentProviderExternalUnchecked(name, token, userId); 8191 } 8192 8193 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8194 IBinder token, int userId) { 8195 return getContentProviderImpl(null, name, token, true, userId); 8196 } 8197 8198 /** 8199 * Drop a content provider from a ProcessRecord's bookkeeping 8200 */ 8201 public void removeContentProvider(IBinder connection, boolean stable) { 8202 enforceNotIsolatedCaller("removeContentProvider"); 8203 long ident = Binder.clearCallingIdentity(); 8204 try { 8205 synchronized (this) { 8206 ContentProviderConnection conn; 8207 try { 8208 conn = (ContentProviderConnection)connection; 8209 } catch (ClassCastException e) { 8210 String msg ="removeContentProvider: " + connection 8211 + " not a ContentProviderConnection"; 8212 Slog.w(TAG, msg); 8213 throw new IllegalArgumentException(msg); 8214 } 8215 if (conn == null) { 8216 throw new NullPointerException("connection is null"); 8217 } 8218 if (decProviderCountLocked(conn, null, null, stable)) { 8219 updateOomAdjLocked(); 8220 } 8221 } 8222 } finally { 8223 Binder.restoreCallingIdentity(ident); 8224 } 8225 } 8226 8227 public void removeContentProviderExternal(String name, IBinder token) { 8228 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8229 "Do not have permission in call removeContentProviderExternal()"); 8230 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8231 } 8232 8233 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8234 synchronized (this) { 8235 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8236 if(cpr == null) { 8237 //remove from mProvidersByClass 8238 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8239 return; 8240 } 8241 8242 //update content provider record entry info 8243 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8244 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8245 if (localCpr.hasExternalProcessHandles()) { 8246 if (localCpr.removeExternalProcessHandleLocked(token)) { 8247 updateOomAdjLocked(); 8248 } else { 8249 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8250 + " with no external reference for token: " 8251 + token + "."); 8252 } 8253 } else { 8254 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8255 + " with no external references."); 8256 } 8257 } 8258 } 8259 8260 public final void publishContentProviders(IApplicationThread caller, 8261 List<ContentProviderHolder> providers) { 8262 if (providers == null) { 8263 return; 8264 } 8265 8266 enforceNotIsolatedCaller("publishContentProviders"); 8267 synchronized (this) { 8268 final ProcessRecord r = getRecordForAppLocked(caller); 8269 if (DEBUG_MU) 8270 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8271 if (r == null) { 8272 throw new SecurityException( 8273 "Unable to find app for caller " + caller 8274 + " (pid=" + Binder.getCallingPid() 8275 + ") when publishing content providers"); 8276 } 8277 8278 final long origId = Binder.clearCallingIdentity(); 8279 8280 final int N = providers.size(); 8281 for (int i=0; i<N; i++) { 8282 ContentProviderHolder src = providers.get(i); 8283 if (src == null || src.info == null || src.provider == null) { 8284 continue; 8285 } 8286 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8287 if (DEBUG_MU) 8288 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8289 if (dst != null) { 8290 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8291 mProviderMap.putProviderByClass(comp, dst); 8292 String names[] = dst.info.authority.split(";"); 8293 for (int j = 0; j < names.length; j++) { 8294 mProviderMap.putProviderByName(names[j], dst); 8295 } 8296 8297 int NL = mLaunchingProviders.size(); 8298 int j; 8299 for (j=0; j<NL; j++) { 8300 if (mLaunchingProviders.get(j) == dst) { 8301 mLaunchingProviders.remove(j); 8302 j--; 8303 NL--; 8304 } 8305 } 8306 synchronized (dst) { 8307 dst.provider = src.provider; 8308 dst.proc = r; 8309 dst.notifyAll(); 8310 } 8311 updateOomAdjLocked(r); 8312 } 8313 } 8314 8315 Binder.restoreCallingIdentity(origId); 8316 } 8317 } 8318 8319 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8320 ContentProviderConnection conn; 8321 try { 8322 conn = (ContentProviderConnection)connection; 8323 } catch (ClassCastException e) { 8324 String msg ="refContentProvider: " + connection 8325 + " not a ContentProviderConnection"; 8326 Slog.w(TAG, msg); 8327 throw new IllegalArgumentException(msg); 8328 } 8329 if (conn == null) { 8330 throw new NullPointerException("connection is null"); 8331 } 8332 8333 synchronized (this) { 8334 if (stable > 0) { 8335 conn.numStableIncs += stable; 8336 } 8337 stable = conn.stableCount + stable; 8338 if (stable < 0) { 8339 throw new IllegalStateException("stableCount < 0: " + stable); 8340 } 8341 8342 if (unstable > 0) { 8343 conn.numUnstableIncs += unstable; 8344 } 8345 unstable = conn.unstableCount + unstable; 8346 if (unstable < 0) { 8347 throw new IllegalStateException("unstableCount < 0: " + unstable); 8348 } 8349 8350 if ((stable+unstable) <= 0) { 8351 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8352 + stable + " unstable=" + unstable); 8353 } 8354 conn.stableCount = stable; 8355 conn.unstableCount = unstable; 8356 return !conn.dead; 8357 } 8358 } 8359 8360 public void unstableProviderDied(IBinder connection) { 8361 ContentProviderConnection conn; 8362 try { 8363 conn = (ContentProviderConnection)connection; 8364 } catch (ClassCastException e) { 8365 String msg ="refContentProvider: " + connection 8366 + " not a ContentProviderConnection"; 8367 Slog.w(TAG, msg); 8368 throw new IllegalArgumentException(msg); 8369 } 8370 if (conn == null) { 8371 throw new NullPointerException("connection is null"); 8372 } 8373 8374 // Safely retrieve the content provider associated with the connection. 8375 IContentProvider provider; 8376 synchronized (this) { 8377 provider = conn.provider.provider; 8378 } 8379 8380 if (provider == null) { 8381 // Um, yeah, we're way ahead of you. 8382 return; 8383 } 8384 8385 // Make sure the caller is being honest with us. 8386 if (provider.asBinder().pingBinder()) { 8387 // Er, no, still looks good to us. 8388 synchronized (this) { 8389 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8390 + " says " + conn + " died, but we don't agree"); 8391 return; 8392 } 8393 } 8394 8395 // Well look at that! It's dead! 8396 synchronized (this) { 8397 if (conn.provider.provider != provider) { 8398 // But something changed... good enough. 8399 return; 8400 } 8401 8402 ProcessRecord proc = conn.provider.proc; 8403 if (proc == null || proc.thread == null) { 8404 // Seems like the process is already cleaned up. 8405 return; 8406 } 8407 8408 // As far as we're concerned, this is just like receiving a 8409 // death notification... just a bit prematurely. 8410 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8411 + ") early provider death"); 8412 final long ident = Binder.clearCallingIdentity(); 8413 try { 8414 appDiedLocked(proc, proc.pid, proc.thread); 8415 } finally { 8416 Binder.restoreCallingIdentity(ident); 8417 } 8418 } 8419 } 8420 8421 @Override 8422 public void appNotRespondingViaProvider(IBinder connection) { 8423 enforceCallingPermission( 8424 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8425 8426 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8427 if (conn == null) { 8428 Slog.w(TAG, "ContentProviderConnection is null"); 8429 return; 8430 } 8431 8432 final ProcessRecord host = conn.provider.proc; 8433 if (host == null) { 8434 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8435 return; 8436 } 8437 8438 final long token = Binder.clearCallingIdentity(); 8439 try { 8440 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8441 } finally { 8442 Binder.restoreCallingIdentity(token); 8443 } 8444 } 8445 8446 public final void installSystemProviders() { 8447 List<ProviderInfo> providers; 8448 synchronized (this) { 8449 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8450 providers = generateApplicationProvidersLocked(app); 8451 if (providers != null) { 8452 for (int i=providers.size()-1; i>=0; i--) { 8453 ProviderInfo pi = (ProviderInfo)providers.get(i); 8454 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8455 Slog.w(TAG, "Not installing system proc provider " + pi.name 8456 + ": not system .apk"); 8457 providers.remove(i); 8458 } 8459 } 8460 } 8461 } 8462 if (providers != null) { 8463 mSystemThread.installSystemProviders(providers); 8464 } 8465 8466 mCoreSettingsObserver = new CoreSettingsObserver(this); 8467 8468 mUsageStatsService.monitorPackages(); 8469 } 8470 8471 /** 8472 * Allows app to retrieve the MIME type of a URI without having permission 8473 * to access its content provider. 8474 * 8475 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8476 * 8477 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8478 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8479 */ 8480 public String getProviderMimeType(Uri uri, int userId) { 8481 enforceNotIsolatedCaller("getProviderMimeType"); 8482 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8483 userId, false, true, "getProviderMimeType", null); 8484 final String name = uri.getAuthority(); 8485 final long ident = Binder.clearCallingIdentity(); 8486 ContentProviderHolder holder = null; 8487 8488 try { 8489 holder = getContentProviderExternalUnchecked(name, null, userId); 8490 if (holder != null) { 8491 return holder.provider.getType(uri); 8492 } 8493 } catch (RemoteException e) { 8494 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8495 return null; 8496 } finally { 8497 if (holder != null) { 8498 removeContentProviderExternalUnchecked(name, null, userId); 8499 } 8500 Binder.restoreCallingIdentity(ident); 8501 } 8502 8503 return null; 8504 } 8505 8506 // ========================================================= 8507 // GLOBAL MANAGEMENT 8508 // ========================================================= 8509 8510 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8511 boolean isolated) { 8512 String proc = customProcess != null ? customProcess : info.processName; 8513 BatteryStatsImpl.Uid.Proc ps = null; 8514 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8515 int uid = info.uid; 8516 if (isolated) { 8517 int userId = UserHandle.getUserId(uid); 8518 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8519 while (true) { 8520 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8521 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8522 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8523 } 8524 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8525 mNextIsolatedProcessUid++; 8526 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8527 // No process for this uid, use it. 8528 break; 8529 } 8530 stepsLeft--; 8531 if (stepsLeft <= 0) { 8532 return null; 8533 } 8534 } 8535 } 8536 return new ProcessRecord(stats, info, proc, uid); 8537 } 8538 8539 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8540 ProcessRecord app; 8541 if (!isolated) { 8542 app = getProcessRecordLocked(info.processName, info.uid, true); 8543 } else { 8544 app = null; 8545 } 8546 8547 if (app == null) { 8548 app = newProcessRecordLocked(info, null, isolated); 8549 mProcessNames.put(info.processName, app.uid, app); 8550 if (isolated) { 8551 mIsolatedProcesses.put(app.uid, app); 8552 } 8553 updateLruProcessLocked(app, false, null); 8554 updateOomAdjLocked(); 8555 } 8556 8557 // This package really, really can not be stopped. 8558 try { 8559 AppGlobals.getPackageManager().setPackageStoppedState( 8560 info.packageName, false, UserHandle.getUserId(app.uid)); 8561 } catch (RemoteException e) { 8562 } catch (IllegalArgumentException e) { 8563 Slog.w(TAG, "Failed trying to unstop package " 8564 + info.packageName + ": " + e); 8565 } 8566 8567 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8568 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8569 app.persistent = true; 8570 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8571 } 8572 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8573 mPersistentStartingProcesses.add(app); 8574 startProcessLocked(app, "added application", app.processName); 8575 } 8576 8577 return app; 8578 } 8579 8580 public void unhandledBack() { 8581 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8582 "unhandledBack()"); 8583 8584 synchronized(this) { 8585 final long origId = Binder.clearCallingIdentity(); 8586 try { 8587 getFocusedStack().unhandledBackLocked(); 8588 } finally { 8589 Binder.restoreCallingIdentity(origId); 8590 } 8591 } 8592 } 8593 8594 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8595 enforceNotIsolatedCaller("openContentUri"); 8596 final int userId = UserHandle.getCallingUserId(); 8597 String name = uri.getAuthority(); 8598 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8599 ParcelFileDescriptor pfd = null; 8600 if (cph != null) { 8601 // We record the binder invoker's uid in thread-local storage before 8602 // going to the content provider to open the file. Later, in the code 8603 // that handles all permissions checks, we look for this uid and use 8604 // that rather than the Activity Manager's own uid. The effect is that 8605 // we do the check against the caller's permissions even though it looks 8606 // to the content provider like the Activity Manager itself is making 8607 // the request. 8608 sCallerIdentity.set(new Identity( 8609 Binder.getCallingPid(), Binder.getCallingUid())); 8610 try { 8611 pfd = cph.provider.openFile(null, uri, "r", null); 8612 } catch (FileNotFoundException e) { 8613 // do nothing; pfd will be returned null 8614 } finally { 8615 // Ensure that whatever happens, we clean up the identity state 8616 sCallerIdentity.remove(); 8617 } 8618 8619 // We've got the fd now, so we're done with the provider. 8620 removeContentProviderExternalUnchecked(name, null, userId); 8621 } else { 8622 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8623 } 8624 return pfd; 8625 } 8626 8627 // Actually is sleeping or shutting down or whatever else in the future 8628 // is an inactive state. 8629 public boolean isSleepingOrShuttingDown() { 8630 return mSleeping || mShuttingDown; 8631 } 8632 8633 public boolean isSleeping() { 8634 return mSleeping; 8635 } 8636 8637 void goingToSleep() { 8638 synchronized(this) { 8639 mWentToSleep = true; 8640 updateEventDispatchingLocked(); 8641 goToSleepIfNeededLocked(); 8642 } 8643 } 8644 8645 void finishRunningVoiceLocked() { 8646 if (mRunningVoice) { 8647 mRunningVoice = false; 8648 goToSleepIfNeededLocked(); 8649 } 8650 } 8651 8652 void goToSleepIfNeededLocked() { 8653 if (mWentToSleep && !mRunningVoice) { 8654 if (!mSleeping) { 8655 mSleeping = true; 8656 mStackSupervisor.goingToSleepLocked(); 8657 8658 // Initialize the wake times of all processes. 8659 checkExcessivePowerUsageLocked(false); 8660 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8661 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8662 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8663 } 8664 } 8665 } 8666 8667 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8668 mTaskPersister.notify(task, flush); 8669 } 8670 8671 @Override 8672 public boolean shutdown(int timeout) { 8673 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8674 != PackageManager.PERMISSION_GRANTED) { 8675 throw new SecurityException("Requires permission " 8676 + android.Manifest.permission.SHUTDOWN); 8677 } 8678 8679 boolean timedout = false; 8680 8681 synchronized(this) { 8682 mShuttingDown = true; 8683 updateEventDispatchingLocked(); 8684 timedout = mStackSupervisor.shutdownLocked(timeout); 8685 } 8686 8687 mAppOpsService.shutdown(); 8688 mUsageStatsService.shutdown(); 8689 mBatteryStatsService.shutdown(); 8690 synchronized (this) { 8691 mProcessStats.shutdownLocked(); 8692 } 8693 notifyTaskPersisterLocked(null, true); 8694 8695 return timedout; 8696 } 8697 8698 public final void activitySlept(IBinder token) { 8699 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8700 8701 final long origId = Binder.clearCallingIdentity(); 8702 8703 synchronized (this) { 8704 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8705 if (r != null) { 8706 mStackSupervisor.activitySleptLocked(r); 8707 } 8708 } 8709 8710 Binder.restoreCallingIdentity(origId); 8711 } 8712 8713 void logLockScreen(String msg) { 8714 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8715 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8716 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8717 mStackSupervisor.mDismissKeyguardOnNextActivity); 8718 } 8719 8720 private void comeOutOfSleepIfNeededLocked() { 8721 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8722 if (mSleeping) { 8723 mSleeping = false; 8724 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8725 } 8726 } 8727 } 8728 8729 void wakingUp() { 8730 synchronized(this) { 8731 mWentToSleep = false; 8732 updateEventDispatchingLocked(); 8733 comeOutOfSleepIfNeededLocked(); 8734 } 8735 } 8736 8737 void startRunningVoiceLocked() { 8738 if (!mRunningVoice) { 8739 mRunningVoice = true; 8740 comeOutOfSleepIfNeededLocked(); 8741 } 8742 } 8743 8744 private void updateEventDispatchingLocked() { 8745 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8746 } 8747 8748 public void setLockScreenShown(boolean shown) { 8749 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8750 != PackageManager.PERMISSION_GRANTED) { 8751 throw new SecurityException("Requires permission " 8752 + android.Manifest.permission.DEVICE_POWER); 8753 } 8754 8755 synchronized(this) { 8756 long ident = Binder.clearCallingIdentity(); 8757 try { 8758 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8759 mLockScreenShown = shown; 8760 comeOutOfSleepIfNeededLocked(); 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 } 8766 8767 public void stopAppSwitches() { 8768 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8769 != PackageManager.PERMISSION_GRANTED) { 8770 throw new SecurityException("Requires permission " 8771 + android.Manifest.permission.STOP_APP_SWITCHES); 8772 } 8773 8774 synchronized(this) { 8775 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8776 + APP_SWITCH_DELAY_TIME; 8777 mDidAppSwitch = false; 8778 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8779 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8780 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8781 } 8782 } 8783 8784 public void resumeAppSwitches() { 8785 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8786 != PackageManager.PERMISSION_GRANTED) { 8787 throw new SecurityException("Requires permission " 8788 + android.Manifest.permission.STOP_APP_SWITCHES); 8789 } 8790 8791 synchronized(this) { 8792 // Note that we don't execute any pending app switches... we will 8793 // let those wait until either the timeout, or the next start 8794 // activity request. 8795 mAppSwitchesAllowedTime = 0; 8796 } 8797 } 8798 8799 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8800 String name) { 8801 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8802 return true; 8803 } 8804 8805 final int perm = checkComponentPermission( 8806 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8807 callingUid, -1, true); 8808 if (perm == PackageManager.PERMISSION_GRANTED) { 8809 return true; 8810 } 8811 8812 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8813 return false; 8814 } 8815 8816 public void setDebugApp(String packageName, boolean waitForDebugger, 8817 boolean persistent) { 8818 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8819 "setDebugApp()"); 8820 8821 long ident = Binder.clearCallingIdentity(); 8822 try { 8823 // Note that this is not really thread safe if there are multiple 8824 // callers into it at the same time, but that's not a situation we 8825 // care about. 8826 if (persistent) { 8827 final ContentResolver resolver = mContext.getContentResolver(); 8828 Settings.Global.putString( 8829 resolver, Settings.Global.DEBUG_APP, 8830 packageName); 8831 Settings.Global.putInt( 8832 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8833 waitForDebugger ? 1 : 0); 8834 } 8835 8836 synchronized (this) { 8837 if (!persistent) { 8838 mOrigDebugApp = mDebugApp; 8839 mOrigWaitForDebugger = mWaitForDebugger; 8840 } 8841 mDebugApp = packageName; 8842 mWaitForDebugger = waitForDebugger; 8843 mDebugTransient = !persistent; 8844 if (packageName != null) { 8845 forceStopPackageLocked(packageName, -1, false, false, true, true, 8846 false, UserHandle.USER_ALL, "set debug app"); 8847 } 8848 } 8849 } finally { 8850 Binder.restoreCallingIdentity(ident); 8851 } 8852 } 8853 8854 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8855 synchronized (this) { 8856 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8857 if (!isDebuggable) { 8858 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8859 throw new SecurityException("Process not debuggable: " + app.packageName); 8860 } 8861 } 8862 8863 mOpenGlTraceApp = processName; 8864 } 8865 } 8866 8867 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8868 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8869 synchronized (this) { 8870 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8871 if (!isDebuggable) { 8872 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8873 throw new SecurityException("Process not debuggable: " + app.packageName); 8874 } 8875 } 8876 mProfileApp = processName; 8877 mProfileFile = profileFile; 8878 if (mProfileFd != null) { 8879 try { 8880 mProfileFd.close(); 8881 } catch (IOException e) { 8882 } 8883 mProfileFd = null; 8884 } 8885 mProfileFd = profileFd; 8886 mProfileType = 0; 8887 mAutoStopProfiler = autoStopProfiler; 8888 } 8889 } 8890 8891 @Override 8892 public void setAlwaysFinish(boolean enabled) { 8893 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8894 "setAlwaysFinish()"); 8895 8896 Settings.Global.putInt( 8897 mContext.getContentResolver(), 8898 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8899 8900 synchronized (this) { 8901 mAlwaysFinishActivities = enabled; 8902 } 8903 } 8904 8905 @Override 8906 public void setActivityController(IActivityController controller) { 8907 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8908 "setActivityController()"); 8909 synchronized (this) { 8910 mController = controller; 8911 Watchdog.getInstance().setActivityController(controller); 8912 } 8913 } 8914 8915 @Override 8916 public void setUserIsMonkey(boolean userIsMonkey) { 8917 synchronized (this) { 8918 synchronized (mPidsSelfLocked) { 8919 final int callingPid = Binder.getCallingPid(); 8920 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8921 if (precessRecord == null) { 8922 throw new SecurityException("Unknown process: " + callingPid); 8923 } 8924 if (precessRecord.instrumentationUiAutomationConnection == null) { 8925 throw new SecurityException("Only an instrumentation process " 8926 + "with a UiAutomation can call setUserIsMonkey"); 8927 } 8928 } 8929 mUserIsMonkey = userIsMonkey; 8930 } 8931 } 8932 8933 @Override 8934 public boolean isUserAMonkey() { 8935 synchronized (this) { 8936 // If there is a controller also implies the user is a monkey. 8937 return (mUserIsMonkey || mController != null); 8938 } 8939 } 8940 8941 public void requestBugReport() { 8942 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8943 SystemProperties.set("ctl.start", "bugreport"); 8944 } 8945 8946 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8947 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8948 } 8949 8950 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8951 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8952 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8953 } 8954 return KEY_DISPATCHING_TIMEOUT; 8955 } 8956 8957 @Override 8958 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8959 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8960 != PackageManager.PERMISSION_GRANTED) { 8961 throw new SecurityException("Requires permission " 8962 + android.Manifest.permission.FILTER_EVENTS); 8963 } 8964 ProcessRecord proc; 8965 long timeout; 8966 synchronized (this) { 8967 synchronized (mPidsSelfLocked) { 8968 proc = mPidsSelfLocked.get(pid); 8969 } 8970 timeout = getInputDispatchingTimeoutLocked(proc); 8971 } 8972 8973 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8974 return -1; 8975 } 8976 8977 return timeout; 8978 } 8979 8980 /** 8981 * Handle input dispatching timeouts. 8982 * Returns whether input dispatching should be aborted or not. 8983 */ 8984 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8985 final ActivityRecord activity, final ActivityRecord parent, 8986 final boolean aboveSystem, String reason) { 8987 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8988 != PackageManager.PERMISSION_GRANTED) { 8989 throw new SecurityException("Requires permission " 8990 + android.Manifest.permission.FILTER_EVENTS); 8991 } 8992 8993 final String annotation; 8994 if (reason == null) { 8995 annotation = "Input dispatching timed out"; 8996 } else { 8997 annotation = "Input dispatching timed out (" + reason + ")"; 8998 } 8999 9000 if (proc != null) { 9001 synchronized (this) { 9002 if (proc.debugging) { 9003 return false; 9004 } 9005 9006 if (mDidDexOpt) { 9007 // Give more time since we were dexopting. 9008 mDidDexOpt = false; 9009 return false; 9010 } 9011 9012 if (proc.instrumentationClass != null) { 9013 Bundle info = new Bundle(); 9014 info.putString("shortMsg", "keyDispatchingTimedOut"); 9015 info.putString("longMsg", annotation); 9016 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9017 return true; 9018 } 9019 } 9020 mHandler.post(new Runnable() { 9021 @Override 9022 public void run() { 9023 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9024 } 9025 }); 9026 } 9027 9028 return true; 9029 } 9030 9031 public Bundle getAssistContextExtras(int requestType) { 9032 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9033 "getAssistContextExtras()"); 9034 PendingAssistExtras pae; 9035 Bundle extras = new Bundle(); 9036 synchronized (this) { 9037 ActivityRecord activity = getFocusedStack().mResumedActivity; 9038 if (activity == null) { 9039 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9040 return null; 9041 } 9042 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9043 if (activity.app == null || activity.app.thread == null) { 9044 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9045 return extras; 9046 } 9047 if (activity.app.pid == Binder.getCallingPid()) { 9048 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9049 return extras; 9050 } 9051 pae = new PendingAssistExtras(activity); 9052 try { 9053 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9054 requestType); 9055 mPendingAssistExtras.add(pae); 9056 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9057 } catch (RemoteException e) { 9058 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9059 return extras; 9060 } 9061 } 9062 synchronized (pae) { 9063 while (!pae.haveResult) { 9064 try { 9065 pae.wait(); 9066 } catch (InterruptedException e) { 9067 } 9068 } 9069 if (pae.result != null) { 9070 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9071 } 9072 } 9073 synchronized (this) { 9074 mPendingAssistExtras.remove(pae); 9075 mHandler.removeCallbacks(pae); 9076 } 9077 return extras; 9078 } 9079 9080 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9081 PendingAssistExtras pae = (PendingAssistExtras)token; 9082 synchronized (pae) { 9083 pae.result = extras; 9084 pae.haveResult = true; 9085 pae.notifyAll(); 9086 } 9087 } 9088 9089 public void registerProcessObserver(IProcessObserver observer) { 9090 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9091 "registerProcessObserver()"); 9092 synchronized (this) { 9093 mProcessObservers.register(observer); 9094 } 9095 } 9096 9097 @Override 9098 public void unregisterProcessObserver(IProcessObserver observer) { 9099 synchronized (this) { 9100 mProcessObservers.unregister(observer); 9101 } 9102 } 9103 9104 @Override 9105 public boolean convertFromTranslucent(IBinder token) { 9106 final long origId = Binder.clearCallingIdentity(); 9107 try { 9108 synchronized (this) { 9109 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9110 if (r == null) { 9111 return false; 9112 } 9113 if (r.changeWindowTranslucency(true)) { 9114 mWindowManager.setAppFullscreen(token, true); 9115 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9116 return true; 9117 } 9118 return false; 9119 } 9120 } finally { 9121 Binder.restoreCallingIdentity(origId); 9122 } 9123 } 9124 9125 @Override 9126 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9127 final long origId = Binder.clearCallingIdentity(); 9128 try { 9129 synchronized (this) { 9130 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9131 if (r == null) { 9132 return false; 9133 } 9134 if (r.changeWindowTranslucency(false)) { 9135 r.task.stack.convertToTranslucent(r, options); 9136 mWindowManager.setAppFullscreen(token, false); 9137 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9138 return true; 9139 } 9140 return false; 9141 } 9142 } finally { 9143 Binder.restoreCallingIdentity(origId); 9144 } 9145 } 9146 9147 @Override 9148 public ActivityOptions getActivityOptions(IBinder token) { 9149 final long origId = Binder.clearCallingIdentity(); 9150 try { 9151 synchronized (this) { 9152 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9153 if (r != null) { 9154 final ActivityOptions activityOptions = r.pendingOptions; 9155 r.pendingOptions = null; 9156 return activityOptions; 9157 } 9158 return null; 9159 } 9160 } finally { 9161 Binder.restoreCallingIdentity(origId); 9162 } 9163 } 9164 9165 @Override 9166 public void setImmersive(IBinder token, boolean immersive) { 9167 synchronized(this) { 9168 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9169 if (r == null) { 9170 throw new IllegalArgumentException(); 9171 } 9172 r.immersive = immersive; 9173 9174 // update associated state if we're frontmost 9175 if (r == mFocusedActivity) { 9176 if (DEBUG_IMMERSIVE) { 9177 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9178 } 9179 applyUpdateLockStateLocked(r); 9180 } 9181 } 9182 } 9183 9184 @Override 9185 public boolean isImmersive(IBinder token) { 9186 synchronized (this) { 9187 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9188 if (r == null) { 9189 throw new IllegalArgumentException(); 9190 } 9191 return r.immersive; 9192 } 9193 } 9194 9195 public boolean isTopActivityImmersive() { 9196 enforceNotIsolatedCaller("startActivity"); 9197 synchronized (this) { 9198 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9199 return (r != null) ? r.immersive : false; 9200 } 9201 } 9202 9203 public final void enterSafeMode() { 9204 synchronized(this) { 9205 // It only makes sense to do this before the system is ready 9206 // and started launching other packages. 9207 if (!mSystemReady) { 9208 try { 9209 AppGlobals.getPackageManager().enterSafeMode(); 9210 } catch (RemoteException e) { 9211 } 9212 } 9213 9214 mSafeMode = true; 9215 } 9216 } 9217 9218 public final void showSafeModeOverlay() { 9219 View v = LayoutInflater.from(mContext).inflate( 9220 com.android.internal.R.layout.safe_mode, null); 9221 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9222 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9223 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9224 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9225 lp.gravity = Gravity.BOTTOM | Gravity.START; 9226 lp.format = v.getBackground().getOpacity(); 9227 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9228 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9229 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9230 ((WindowManager)mContext.getSystemService( 9231 Context.WINDOW_SERVICE)).addView(v, lp); 9232 } 9233 9234 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9235 if (!(sender instanceof PendingIntentRecord)) { 9236 return; 9237 } 9238 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9239 synchronized (stats) { 9240 if (mBatteryStatsService.isOnBattery()) { 9241 mBatteryStatsService.enforceCallingPermission(); 9242 PendingIntentRecord rec = (PendingIntentRecord)sender; 9243 int MY_UID = Binder.getCallingUid(); 9244 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9245 BatteryStatsImpl.Uid.Pkg pkg = 9246 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9247 sourcePkg != null ? sourcePkg : rec.key.packageName); 9248 pkg.incWakeupsLocked(); 9249 } 9250 } 9251 } 9252 9253 public boolean killPids(int[] pids, String pReason, boolean secure) { 9254 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9255 throw new SecurityException("killPids only available to the system"); 9256 } 9257 String reason = (pReason == null) ? "Unknown" : pReason; 9258 // XXX Note: don't acquire main activity lock here, because the window 9259 // manager calls in with its locks held. 9260 9261 boolean killed = false; 9262 synchronized (mPidsSelfLocked) { 9263 int[] types = new int[pids.length]; 9264 int worstType = 0; 9265 for (int i=0; i<pids.length; i++) { 9266 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9267 if (proc != null) { 9268 int type = proc.setAdj; 9269 types[i] = type; 9270 if (type > worstType) { 9271 worstType = type; 9272 } 9273 } 9274 } 9275 9276 // If the worst oom_adj is somewhere in the cached proc LRU range, 9277 // then constrain it so we will kill all cached procs. 9278 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9279 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9280 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9281 } 9282 9283 // If this is not a secure call, don't let it kill processes that 9284 // are important. 9285 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9286 worstType = ProcessList.SERVICE_ADJ; 9287 } 9288 9289 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9290 for (int i=0; i<pids.length; i++) { 9291 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9292 if (proc == null) { 9293 continue; 9294 } 9295 int adj = proc.setAdj; 9296 if (adj >= worstType && !proc.killedByAm) { 9297 killUnneededProcessLocked(proc, reason); 9298 killed = true; 9299 } 9300 } 9301 } 9302 return killed; 9303 } 9304 9305 @Override 9306 public void killUid(int uid, String reason) { 9307 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9308 throw new SecurityException("killUid only available to the system"); 9309 } 9310 synchronized (this) { 9311 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9312 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9313 reason != null ? reason : "kill uid"); 9314 } 9315 } 9316 9317 @Override 9318 public boolean killProcessesBelowForeground(String reason) { 9319 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9320 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9321 } 9322 9323 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9324 } 9325 9326 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9327 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9328 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9329 } 9330 9331 boolean killed = false; 9332 synchronized (mPidsSelfLocked) { 9333 final int size = mPidsSelfLocked.size(); 9334 for (int i = 0; i < size; i++) { 9335 final int pid = mPidsSelfLocked.keyAt(i); 9336 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9337 if (proc == null) continue; 9338 9339 final int adj = proc.setAdj; 9340 if (adj > belowAdj && !proc.killedByAm) { 9341 killUnneededProcessLocked(proc, reason); 9342 killed = true; 9343 } 9344 } 9345 } 9346 return killed; 9347 } 9348 9349 @Override 9350 public void hang(final IBinder who, boolean allowRestart) { 9351 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9352 != PackageManager.PERMISSION_GRANTED) { 9353 throw new SecurityException("Requires permission " 9354 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9355 } 9356 9357 final IBinder.DeathRecipient death = new DeathRecipient() { 9358 @Override 9359 public void binderDied() { 9360 synchronized (this) { 9361 notifyAll(); 9362 } 9363 } 9364 }; 9365 9366 try { 9367 who.linkToDeath(death, 0); 9368 } catch (RemoteException e) { 9369 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9370 return; 9371 } 9372 9373 synchronized (this) { 9374 Watchdog.getInstance().setAllowRestart(allowRestart); 9375 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9376 synchronized (death) { 9377 while (who.isBinderAlive()) { 9378 try { 9379 death.wait(); 9380 } catch (InterruptedException e) { 9381 } 9382 } 9383 } 9384 Watchdog.getInstance().setAllowRestart(true); 9385 } 9386 } 9387 9388 @Override 9389 public void restart() { 9390 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9391 != PackageManager.PERMISSION_GRANTED) { 9392 throw new SecurityException("Requires permission " 9393 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9394 } 9395 9396 Log.i(TAG, "Sending shutdown broadcast..."); 9397 9398 BroadcastReceiver br = new BroadcastReceiver() { 9399 @Override public void onReceive(Context context, Intent intent) { 9400 // Now the broadcast is done, finish up the low-level shutdown. 9401 Log.i(TAG, "Shutting down activity manager..."); 9402 shutdown(10000); 9403 Log.i(TAG, "Shutdown complete, restarting!"); 9404 Process.killProcess(Process.myPid()); 9405 System.exit(10); 9406 } 9407 }; 9408 9409 // First send the high-level shut down broadcast. 9410 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9411 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9412 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9413 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9414 mContext.sendOrderedBroadcastAsUser(intent, 9415 UserHandle.ALL, null, br, mHandler, 0, null, null); 9416 */ 9417 br.onReceive(mContext, intent); 9418 } 9419 9420 private long getLowRamTimeSinceIdle(long now) { 9421 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9422 } 9423 9424 @Override 9425 public void performIdleMaintenance() { 9426 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9427 != PackageManager.PERMISSION_GRANTED) { 9428 throw new SecurityException("Requires permission " 9429 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9430 } 9431 9432 synchronized (this) { 9433 final long now = SystemClock.uptimeMillis(); 9434 final long timeSinceLastIdle = now - mLastIdleTime; 9435 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9436 mLastIdleTime = now; 9437 mLowRamTimeSinceLastIdle = 0; 9438 if (mLowRamStartTime != 0) { 9439 mLowRamStartTime = now; 9440 } 9441 9442 StringBuilder sb = new StringBuilder(128); 9443 sb.append("Idle maintenance over "); 9444 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9445 sb.append(" low RAM for "); 9446 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9447 Slog.i(TAG, sb.toString()); 9448 9449 // If at least 1/3 of our time since the last idle period has been spent 9450 // with RAM low, then we want to kill processes. 9451 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9452 9453 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9454 ProcessRecord proc = mLruProcesses.get(i); 9455 if (proc.notCachedSinceIdle) { 9456 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9457 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9458 if (doKilling && proc.initialIdlePss != 0 9459 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9460 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9461 + " from " + proc.initialIdlePss + ")"); 9462 } 9463 } 9464 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9465 proc.notCachedSinceIdle = true; 9466 proc.initialIdlePss = 0; 9467 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9468 isSleeping(), now); 9469 } 9470 } 9471 9472 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9473 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9474 } 9475 } 9476 9477 private void retrieveSettings() { 9478 final ContentResolver resolver = mContext.getContentResolver(); 9479 String debugApp = Settings.Global.getString( 9480 resolver, Settings.Global.DEBUG_APP); 9481 boolean waitForDebugger = Settings.Global.getInt( 9482 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9483 boolean alwaysFinishActivities = Settings.Global.getInt( 9484 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9485 boolean forceRtl = Settings.Global.getInt( 9486 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9487 // Transfer any global setting for forcing RTL layout, into a System Property 9488 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9489 9490 Configuration configuration = new Configuration(); 9491 Settings.System.getConfiguration(resolver, configuration); 9492 if (forceRtl) { 9493 // This will take care of setting the correct layout direction flags 9494 configuration.setLayoutDirection(configuration.locale); 9495 } 9496 9497 synchronized (this) { 9498 mDebugApp = mOrigDebugApp = debugApp; 9499 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9500 mAlwaysFinishActivities = alwaysFinishActivities; 9501 // This happens before any activities are started, so we can 9502 // change mConfiguration in-place. 9503 updateConfigurationLocked(configuration, null, false, true); 9504 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9505 } 9506 } 9507 9508 public boolean testIsSystemReady() { 9509 // no need to synchronize(this) just to read & return the value 9510 return mSystemReady; 9511 } 9512 9513 private static File getCalledPreBootReceiversFile() { 9514 File dataDir = Environment.getDataDirectory(); 9515 File systemDir = new File(dataDir, "system"); 9516 File fname = new File(systemDir, "called_pre_boots.dat"); 9517 return fname; 9518 } 9519 9520 static final int LAST_DONE_VERSION = 10000; 9521 9522 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9523 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9524 File file = getCalledPreBootReceiversFile(); 9525 FileInputStream fis = null; 9526 try { 9527 fis = new FileInputStream(file); 9528 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9529 int fvers = dis.readInt(); 9530 if (fvers == LAST_DONE_VERSION) { 9531 String vers = dis.readUTF(); 9532 String codename = dis.readUTF(); 9533 String build = dis.readUTF(); 9534 if (android.os.Build.VERSION.RELEASE.equals(vers) 9535 && android.os.Build.VERSION.CODENAME.equals(codename) 9536 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9537 int num = dis.readInt(); 9538 while (num > 0) { 9539 num--; 9540 String pkg = dis.readUTF(); 9541 String cls = dis.readUTF(); 9542 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9543 } 9544 } 9545 } 9546 } catch (FileNotFoundException e) { 9547 } catch (IOException e) { 9548 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9549 } finally { 9550 if (fis != null) { 9551 try { 9552 fis.close(); 9553 } catch (IOException e) { 9554 } 9555 } 9556 } 9557 return lastDoneReceivers; 9558 } 9559 9560 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9561 File file = getCalledPreBootReceiversFile(); 9562 FileOutputStream fos = null; 9563 DataOutputStream dos = null; 9564 try { 9565 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9566 fos = new FileOutputStream(file); 9567 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9568 dos.writeInt(LAST_DONE_VERSION); 9569 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9570 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9571 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9572 dos.writeInt(list.size()); 9573 for (int i=0; i<list.size(); i++) { 9574 dos.writeUTF(list.get(i).getPackageName()); 9575 dos.writeUTF(list.get(i).getClassName()); 9576 } 9577 } catch (IOException e) { 9578 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9579 file.delete(); 9580 } finally { 9581 FileUtils.sync(fos); 9582 if (dos != null) { 9583 try { 9584 dos.close(); 9585 } catch (IOException e) { 9586 // TODO Auto-generated catch block 9587 e.printStackTrace(); 9588 } 9589 } 9590 } 9591 } 9592 9593 public void systemReady(final Runnable goingCallback) { 9594 synchronized(this) { 9595 if (mSystemReady) { 9596 if (goingCallback != null) goingCallback.run(); 9597 return; 9598 } 9599 9600 if (mRecentTasks == null) { 9601 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9602 if (!mRecentTasks.isEmpty()) { 9603 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9604 } 9605 mTaskPersister.startPersisting(); 9606 } 9607 9608 // Check to see if there are any update receivers to run. 9609 if (!mDidUpdate) { 9610 if (mWaitingUpdate) { 9611 return; 9612 } 9613 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9614 List<ResolveInfo> ris = null; 9615 try { 9616 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9617 intent, null, 0, 0); 9618 } catch (RemoteException e) { 9619 } 9620 if (ris != null) { 9621 for (int i=ris.size()-1; i>=0; i--) { 9622 if ((ris.get(i).activityInfo.applicationInfo.flags 9623 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9624 ris.remove(i); 9625 } 9626 } 9627 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9628 9629 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9630 9631 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9632 for (int i=0; i<ris.size(); i++) { 9633 ActivityInfo ai = ris.get(i).activityInfo; 9634 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9635 if (lastDoneReceivers.contains(comp)) { 9636 // We already did the pre boot receiver for this app with the current 9637 // platform version, so don't do it again... 9638 ris.remove(i); 9639 i--; 9640 // ...however, do keep it as one that has been done, so we don't 9641 // forget about it when rewriting the file of last done receivers. 9642 doneReceivers.add(comp); 9643 } 9644 } 9645 9646 final int[] users = getUsersLocked(); 9647 for (int i=0; i<ris.size(); i++) { 9648 ActivityInfo ai = ris.get(i).activityInfo; 9649 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9650 doneReceivers.add(comp); 9651 intent.setComponent(comp); 9652 for (int j=0; j<users.length; j++) { 9653 IIntentReceiver finisher = null; 9654 if (i == ris.size()-1 && j == users.length-1) { 9655 finisher = new IIntentReceiver.Stub() { 9656 public void performReceive(Intent intent, int resultCode, 9657 String data, Bundle extras, boolean ordered, 9658 boolean sticky, int sendingUser) { 9659 // The raw IIntentReceiver interface is called 9660 // with the AM lock held, so redispatch to 9661 // execute our code without the lock. 9662 mHandler.post(new Runnable() { 9663 public void run() { 9664 synchronized (ActivityManagerService.this) { 9665 mDidUpdate = true; 9666 } 9667 writeLastDonePreBootReceivers(doneReceivers); 9668 showBootMessage(mContext.getText( 9669 R.string.android_upgrading_complete), 9670 false); 9671 systemReady(goingCallback); 9672 } 9673 }); 9674 } 9675 }; 9676 } 9677 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9678 + " for user " + users[j]); 9679 broadcastIntentLocked(null, null, intent, null, finisher, 9680 0, null, null, null, AppOpsManager.OP_NONE, 9681 true, false, MY_PID, Process.SYSTEM_UID, 9682 users[j]); 9683 if (finisher != null) { 9684 mWaitingUpdate = true; 9685 } 9686 } 9687 } 9688 } 9689 if (mWaitingUpdate) { 9690 return; 9691 } 9692 mDidUpdate = true; 9693 } 9694 9695 mAppOpsService.systemReady(); 9696 mUsageStatsService.systemReady(); 9697 mSystemReady = true; 9698 } 9699 9700 ArrayList<ProcessRecord> procsToKill = null; 9701 synchronized(mPidsSelfLocked) { 9702 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9703 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9704 if (!isAllowedWhileBooting(proc.info)){ 9705 if (procsToKill == null) { 9706 procsToKill = new ArrayList<ProcessRecord>(); 9707 } 9708 procsToKill.add(proc); 9709 } 9710 } 9711 } 9712 9713 synchronized(this) { 9714 if (procsToKill != null) { 9715 for (int i=procsToKill.size()-1; i>=0; i--) { 9716 ProcessRecord proc = procsToKill.get(i); 9717 Slog.i(TAG, "Removing system update proc: " + proc); 9718 removeProcessLocked(proc, true, false, "system update done"); 9719 } 9720 } 9721 9722 // Now that we have cleaned up any update processes, we 9723 // are ready to start launching real processes and know that 9724 // we won't trample on them any more. 9725 mProcessesReady = true; 9726 } 9727 9728 Slog.i(TAG, "System now ready"); 9729 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9730 SystemClock.uptimeMillis()); 9731 9732 synchronized(this) { 9733 // Make sure we have no pre-ready processes sitting around. 9734 9735 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9736 ResolveInfo ri = mContext.getPackageManager() 9737 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9738 STOCK_PM_FLAGS); 9739 CharSequence errorMsg = null; 9740 if (ri != null) { 9741 ActivityInfo ai = ri.activityInfo; 9742 ApplicationInfo app = ai.applicationInfo; 9743 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9744 mTopAction = Intent.ACTION_FACTORY_TEST; 9745 mTopData = null; 9746 mTopComponent = new ComponentName(app.packageName, 9747 ai.name); 9748 } else { 9749 errorMsg = mContext.getResources().getText( 9750 com.android.internal.R.string.factorytest_not_system); 9751 } 9752 } else { 9753 errorMsg = mContext.getResources().getText( 9754 com.android.internal.R.string.factorytest_no_action); 9755 } 9756 if (errorMsg != null) { 9757 mTopAction = null; 9758 mTopData = null; 9759 mTopComponent = null; 9760 Message msg = Message.obtain(); 9761 msg.what = SHOW_FACTORY_ERROR_MSG; 9762 msg.getData().putCharSequence("msg", errorMsg); 9763 mHandler.sendMessage(msg); 9764 } 9765 } 9766 } 9767 9768 retrieveSettings(); 9769 9770 synchronized (this) { 9771 readGrantedUriPermissionsLocked(); 9772 } 9773 9774 if (goingCallback != null) goingCallback.run(); 9775 9776 mSystemServiceManager.startUser(mCurrentUserId); 9777 9778 synchronized (this) { 9779 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9780 try { 9781 List apps = AppGlobals.getPackageManager(). 9782 getPersistentApplications(STOCK_PM_FLAGS); 9783 if (apps != null) { 9784 int N = apps.size(); 9785 int i; 9786 for (i=0; i<N; i++) { 9787 ApplicationInfo info 9788 = (ApplicationInfo)apps.get(i); 9789 if (info != null && 9790 !info.packageName.equals("android")) { 9791 addAppLocked(info, false); 9792 } 9793 } 9794 } 9795 } catch (RemoteException ex) { 9796 // pm is in same process, this will never happen. 9797 } 9798 } 9799 9800 // Start up initial activity. 9801 mBooting = true; 9802 9803 try { 9804 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9805 Message msg = Message.obtain(); 9806 msg.what = SHOW_UID_ERROR_MSG; 9807 mHandler.sendMessage(msg); 9808 } 9809 } catch (RemoteException e) { 9810 } 9811 9812 long ident = Binder.clearCallingIdentity(); 9813 try { 9814 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9815 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9816 | Intent.FLAG_RECEIVER_FOREGROUND); 9817 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9818 broadcastIntentLocked(null, null, intent, 9819 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9820 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9821 intent = new Intent(Intent.ACTION_USER_STARTING); 9822 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9823 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9824 broadcastIntentLocked(null, null, intent, 9825 null, new IIntentReceiver.Stub() { 9826 @Override 9827 public void performReceive(Intent intent, int resultCode, String data, 9828 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9829 throws RemoteException { 9830 } 9831 }, 0, null, null, 9832 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9833 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9834 } catch (Throwable t) { 9835 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9836 } finally { 9837 Binder.restoreCallingIdentity(ident); 9838 } 9839 mStackSupervisor.resumeTopActivitiesLocked(); 9840 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9841 } 9842 } 9843 9844 private boolean makeAppCrashingLocked(ProcessRecord app, 9845 String shortMsg, String longMsg, String stackTrace) { 9846 app.crashing = true; 9847 app.crashingReport = generateProcessError(app, 9848 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9849 startAppProblemLocked(app); 9850 app.stopFreezingAllLocked(); 9851 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9852 } 9853 9854 private void makeAppNotRespondingLocked(ProcessRecord app, 9855 String activity, String shortMsg, String longMsg) { 9856 app.notResponding = true; 9857 app.notRespondingReport = generateProcessError(app, 9858 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9859 activity, shortMsg, longMsg, null); 9860 startAppProblemLocked(app); 9861 app.stopFreezingAllLocked(); 9862 } 9863 9864 /** 9865 * Generate a process error record, suitable for attachment to a ProcessRecord. 9866 * 9867 * @param app The ProcessRecord in which the error occurred. 9868 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9869 * ActivityManager.AppErrorStateInfo 9870 * @param activity The activity associated with the crash, if known. 9871 * @param shortMsg Short message describing the crash. 9872 * @param longMsg Long message describing the crash. 9873 * @param stackTrace Full crash stack trace, may be null. 9874 * 9875 * @return Returns a fully-formed AppErrorStateInfo record. 9876 */ 9877 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9878 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9879 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9880 9881 report.condition = condition; 9882 report.processName = app.processName; 9883 report.pid = app.pid; 9884 report.uid = app.info.uid; 9885 report.tag = activity; 9886 report.shortMsg = shortMsg; 9887 report.longMsg = longMsg; 9888 report.stackTrace = stackTrace; 9889 9890 return report; 9891 } 9892 9893 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9894 synchronized (this) { 9895 app.crashing = false; 9896 app.crashingReport = null; 9897 app.notResponding = false; 9898 app.notRespondingReport = null; 9899 if (app.anrDialog == fromDialog) { 9900 app.anrDialog = null; 9901 } 9902 if (app.waitDialog == fromDialog) { 9903 app.waitDialog = null; 9904 } 9905 if (app.pid > 0 && app.pid != MY_PID) { 9906 handleAppCrashLocked(app, null, null, null); 9907 killUnneededProcessLocked(app, "user request after error"); 9908 } 9909 } 9910 } 9911 9912 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9913 String stackTrace) { 9914 long now = SystemClock.uptimeMillis(); 9915 9916 Long crashTime; 9917 if (!app.isolated) { 9918 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9919 } else { 9920 crashTime = null; 9921 } 9922 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9923 // This process loses! 9924 Slog.w(TAG, "Process " + app.info.processName 9925 + " has crashed too many times: killing!"); 9926 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9927 app.userId, app.info.processName, app.uid); 9928 mStackSupervisor.handleAppCrashLocked(app); 9929 if (!app.persistent) { 9930 // We don't want to start this process again until the user 9931 // explicitly does so... but for persistent process, we really 9932 // need to keep it running. If a persistent process is actually 9933 // repeatedly crashing, then badness for everyone. 9934 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9935 app.info.processName); 9936 if (!app.isolated) { 9937 // XXX We don't have a way to mark isolated processes 9938 // as bad, since they don't have a peristent identity. 9939 mBadProcesses.put(app.info.processName, app.uid, 9940 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9941 mProcessCrashTimes.remove(app.info.processName, app.uid); 9942 } 9943 app.bad = true; 9944 app.removed = true; 9945 // Don't let services in this process be restarted and potentially 9946 // annoy the user repeatedly. Unless it is persistent, since those 9947 // processes run critical code. 9948 removeProcessLocked(app, false, false, "crash"); 9949 mStackSupervisor.resumeTopActivitiesLocked(); 9950 return false; 9951 } 9952 mStackSupervisor.resumeTopActivitiesLocked(); 9953 } else { 9954 mStackSupervisor.finishTopRunningActivityLocked(app); 9955 } 9956 9957 // Bump up the crash count of any services currently running in the proc. 9958 for (int i=app.services.size()-1; i>=0; i--) { 9959 // Any services running in the application need to be placed 9960 // back in the pending list. 9961 ServiceRecord sr = app.services.valueAt(i); 9962 sr.crashCount++; 9963 } 9964 9965 // If the crashing process is what we consider to be the "home process" and it has been 9966 // replaced by a third-party app, clear the package preferred activities from packages 9967 // with a home activity running in the process to prevent a repeatedly crashing app 9968 // from blocking the user to manually clear the list. 9969 final ArrayList<ActivityRecord> activities = app.activities; 9970 if (app == mHomeProcess && activities.size() > 0 9971 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9972 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9973 final ActivityRecord r = activities.get(activityNdx); 9974 if (r.isHomeActivity()) { 9975 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9976 try { 9977 ActivityThread.getPackageManager() 9978 .clearPackagePreferredActivities(r.packageName); 9979 } catch (RemoteException c) { 9980 // pm is in same process, this will never happen. 9981 } 9982 } 9983 } 9984 } 9985 9986 if (!app.isolated) { 9987 // XXX Can't keep track of crash times for isolated processes, 9988 // because they don't have a perisistent identity. 9989 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9990 } 9991 9992 return true; 9993 } 9994 9995 void startAppProblemLocked(ProcessRecord app) { 9996 if (app.userId == mCurrentUserId) { 9997 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9998 mContext, app.info.packageName, app.info.flags); 9999 } else { 10000 // If this app is not running under the current user, then we 10001 // can't give it a report button because that would require 10002 // launching the report UI under a different user. 10003 app.errorReportReceiver = null; 10004 } 10005 skipCurrentReceiverLocked(app); 10006 } 10007 10008 void skipCurrentReceiverLocked(ProcessRecord app) { 10009 for (BroadcastQueue queue : mBroadcastQueues) { 10010 queue.skipCurrentReceiverLocked(app); 10011 } 10012 } 10013 10014 /** 10015 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10016 * The application process will exit immediately after this call returns. 10017 * @param app object of the crashing app, null for the system server 10018 * @param crashInfo describing the exception 10019 */ 10020 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10021 ProcessRecord r = findAppProcess(app, "Crash"); 10022 final String processName = app == null ? "system_server" 10023 : (r == null ? "unknown" : r.processName); 10024 10025 handleApplicationCrashInner("crash", r, processName, crashInfo); 10026 } 10027 10028 /* Native crash reporting uses this inner version because it needs to be somewhat 10029 * decoupled from the AM-managed cleanup lifecycle 10030 */ 10031 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10032 ApplicationErrorReport.CrashInfo crashInfo) { 10033 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10034 UserHandle.getUserId(Binder.getCallingUid()), processName, 10035 r == null ? -1 : r.info.flags, 10036 crashInfo.exceptionClassName, 10037 crashInfo.exceptionMessage, 10038 crashInfo.throwFileName, 10039 crashInfo.throwLineNumber); 10040 10041 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10042 10043 crashApplication(r, crashInfo); 10044 } 10045 10046 public void handleApplicationStrictModeViolation( 10047 IBinder app, 10048 int violationMask, 10049 StrictMode.ViolationInfo info) { 10050 ProcessRecord r = findAppProcess(app, "StrictMode"); 10051 if (r == null) { 10052 return; 10053 } 10054 10055 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10056 Integer stackFingerprint = info.hashCode(); 10057 boolean logIt = true; 10058 synchronized (mAlreadyLoggedViolatedStacks) { 10059 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10060 logIt = false; 10061 // TODO: sub-sample into EventLog for these, with 10062 // the info.durationMillis? Then we'd get 10063 // the relative pain numbers, without logging all 10064 // the stack traces repeatedly. We'd want to do 10065 // likewise in the client code, which also does 10066 // dup suppression, before the Binder call. 10067 } else { 10068 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10069 mAlreadyLoggedViolatedStacks.clear(); 10070 } 10071 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10072 } 10073 } 10074 if (logIt) { 10075 logStrictModeViolationToDropBox(r, info); 10076 } 10077 } 10078 10079 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10080 AppErrorResult result = new AppErrorResult(); 10081 synchronized (this) { 10082 final long origId = Binder.clearCallingIdentity(); 10083 10084 Message msg = Message.obtain(); 10085 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10086 HashMap<String, Object> data = new HashMap<String, Object>(); 10087 data.put("result", result); 10088 data.put("app", r); 10089 data.put("violationMask", violationMask); 10090 data.put("info", info); 10091 msg.obj = data; 10092 mHandler.sendMessage(msg); 10093 10094 Binder.restoreCallingIdentity(origId); 10095 } 10096 int res = result.get(); 10097 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10098 } 10099 } 10100 10101 // Depending on the policy in effect, there could be a bunch of 10102 // these in quick succession so we try to batch these together to 10103 // minimize disk writes, number of dropbox entries, and maximize 10104 // compression, by having more fewer, larger records. 10105 private void logStrictModeViolationToDropBox( 10106 ProcessRecord process, 10107 StrictMode.ViolationInfo info) { 10108 if (info == null) { 10109 return; 10110 } 10111 final boolean isSystemApp = process == null || 10112 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10113 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10114 final String processName = process == null ? "unknown" : process.processName; 10115 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10116 final DropBoxManager dbox = (DropBoxManager) 10117 mContext.getSystemService(Context.DROPBOX_SERVICE); 10118 10119 // Exit early if the dropbox isn't configured to accept this report type. 10120 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10121 10122 boolean bufferWasEmpty; 10123 boolean needsFlush; 10124 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10125 synchronized (sb) { 10126 bufferWasEmpty = sb.length() == 0; 10127 appendDropBoxProcessHeaders(process, processName, sb); 10128 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10129 sb.append("System-App: ").append(isSystemApp).append("\n"); 10130 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10131 if (info.violationNumThisLoop != 0) { 10132 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10133 } 10134 if (info.numAnimationsRunning != 0) { 10135 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10136 } 10137 if (info.broadcastIntentAction != null) { 10138 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10139 } 10140 if (info.durationMillis != -1) { 10141 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10142 } 10143 if (info.numInstances != -1) { 10144 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10145 } 10146 if (info.tags != null) { 10147 for (String tag : info.tags) { 10148 sb.append("Span-Tag: ").append(tag).append("\n"); 10149 } 10150 } 10151 sb.append("\n"); 10152 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10153 sb.append(info.crashInfo.stackTrace); 10154 } 10155 sb.append("\n"); 10156 10157 // Only buffer up to ~64k. Various logging bits truncate 10158 // things at 128k. 10159 needsFlush = (sb.length() > 64 * 1024); 10160 } 10161 10162 // Flush immediately if the buffer's grown too large, or this 10163 // is a non-system app. Non-system apps are isolated with a 10164 // different tag & policy and not batched. 10165 // 10166 // Batching is useful during internal testing with 10167 // StrictMode settings turned up high. Without batching, 10168 // thousands of separate files could be created on boot. 10169 if (!isSystemApp || needsFlush) { 10170 new Thread("Error dump: " + dropboxTag) { 10171 @Override 10172 public void run() { 10173 String report; 10174 synchronized (sb) { 10175 report = sb.toString(); 10176 sb.delete(0, sb.length()); 10177 sb.trimToSize(); 10178 } 10179 if (report.length() != 0) { 10180 dbox.addText(dropboxTag, report); 10181 } 10182 } 10183 }.start(); 10184 return; 10185 } 10186 10187 // System app batching: 10188 if (!bufferWasEmpty) { 10189 // An existing dropbox-writing thread is outstanding, so 10190 // we don't need to start it up. The existing thread will 10191 // catch the buffer appends we just did. 10192 return; 10193 } 10194 10195 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10196 // (After this point, we shouldn't access AMS internal data structures.) 10197 new Thread("Error dump: " + dropboxTag) { 10198 @Override 10199 public void run() { 10200 // 5 second sleep to let stacks arrive and be batched together 10201 try { 10202 Thread.sleep(5000); // 5 seconds 10203 } catch (InterruptedException e) {} 10204 10205 String errorReport; 10206 synchronized (mStrictModeBuffer) { 10207 errorReport = mStrictModeBuffer.toString(); 10208 if (errorReport.length() == 0) { 10209 return; 10210 } 10211 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10212 mStrictModeBuffer.trimToSize(); 10213 } 10214 dbox.addText(dropboxTag, errorReport); 10215 } 10216 }.start(); 10217 } 10218 10219 /** 10220 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10221 * @param app object of the crashing app, null for the system server 10222 * @param tag reported by the caller 10223 * @param crashInfo describing the context of the error 10224 * @return true if the process should exit immediately (WTF is fatal) 10225 */ 10226 public boolean handleApplicationWtf(IBinder app, String tag, 10227 ApplicationErrorReport.CrashInfo crashInfo) { 10228 ProcessRecord r = findAppProcess(app, "WTF"); 10229 final String processName = app == null ? "system_server" 10230 : (r == null ? "unknown" : r.processName); 10231 10232 EventLog.writeEvent(EventLogTags.AM_WTF, 10233 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10234 processName, 10235 r == null ? -1 : r.info.flags, 10236 tag, crashInfo.exceptionMessage); 10237 10238 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10239 10240 if (r != null && r.pid != Process.myPid() && 10241 Settings.Global.getInt(mContext.getContentResolver(), 10242 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10243 crashApplication(r, crashInfo); 10244 return true; 10245 } else { 10246 return false; 10247 } 10248 } 10249 10250 /** 10251 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10252 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10253 */ 10254 private ProcessRecord findAppProcess(IBinder app, String reason) { 10255 if (app == null) { 10256 return null; 10257 } 10258 10259 synchronized (this) { 10260 final int NP = mProcessNames.getMap().size(); 10261 for (int ip=0; ip<NP; ip++) { 10262 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10263 final int NA = apps.size(); 10264 for (int ia=0; ia<NA; ia++) { 10265 ProcessRecord p = apps.valueAt(ia); 10266 if (p.thread != null && p.thread.asBinder() == app) { 10267 return p; 10268 } 10269 } 10270 } 10271 10272 Slog.w(TAG, "Can't find mystery application for " + reason 10273 + " from pid=" + Binder.getCallingPid() 10274 + " uid=" + Binder.getCallingUid() + ": " + app); 10275 return null; 10276 } 10277 } 10278 10279 /** 10280 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10281 * to append various headers to the dropbox log text. 10282 */ 10283 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10284 StringBuilder sb) { 10285 // Watchdog thread ends up invoking this function (with 10286 // a null ProcessRecord) to add the stack file to dropbox. 10287 // Do not acquire a lock on this (am) in such cases, as it 10288 // could cause a potential deadlock, if and when watchdog 10289 // is invoked due to unavailability of lock on am and it 10290 // would prevent watchdog from killing system_server. 10291 if (process == null) { 10292 sb.append("Process: ").append(processName).append("\n"); 10293 return; 10294 } 10295 // Note: ProcessRecord 'process' is guarded by the service 10296 // instance. (notably process.pkgList, which could otherwise change 10297 // concurrently during execution of this method) 10298 synchronized (this) { 10299 sb.append("Process: ").append(processName).append("\n"); 10300 int flags = process.info.flags; 10301 IPackageManager pm = AppGlobals.getPackageManager(); 10302 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10303 for (int ip=0; ip<process.pkgList.size(); ip++) { 10304 String pkg = process.pkgList.keyAt(ip); 10305 sb.append("Package: ").append(pkg); 10306 try { 10307 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10308 if (pi != null) { 10309 sb.append(" v").append(pi.versionCode); 10310 if (pi.versionName != null) { 10311 sb.append(" (").append(pi.versionName).append(")"); 10312 } 10313 } 10314 } catch (RemoteException e) { 10315 Slog.e(TAG, "Error getting package info: " + pkg, e); 10316 } 10317 sb.append("\n"); 10318 } 10319 } 10320 } 10321 10322 private static String processClass(ProcessRecord process) { 10323 if (process == null || process.pid == MY_PID) { 10324 return "system_server"; 10325 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10326 return "system_app"; 10327 } else { 10328 return "data_app"; 10329 } 10330 } 10331 10332 /** 10333 * Write a description of an error (crash, WTF, ANR) to the drop box. 10334 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10335 * @param process which caused the error, null means the system server 10336 * @param activity which triggered the error, null if unknown 10337 * @param parent activity related to the error, null if unknown 10338 * @param subject line related to the error, null if absent 10339 * @param report in long form describing the error, null if absent 10340 * @param logFile to include in the report, null if none 10341 * @param crashInfo giving an application stack trace, null if absent 10342 */ 10343 public void addErrorToDropBox(String eventType, 10344 ProcessRecord process, String processName, ActivityRecord activity, 10345 ActivityRecord parent, String subject, 10346 final String report, final File logFile, 10347 final ApplicationErrorReport.CrashInfo crashInfo) { 10348 // NOTE -- this must never acquire the ActivityManagerService lock, 10349 // otherwise the watchdog may be prevented from resetting the system. 10350 10351 final String dropboxTag = processClass(process) + "_" + eventType; 10352 final DropBoxManager dbox = (DropBoxManager) 10353 mContext.getSystemService(Context.DROPBOX_SERVICE); 10354 10355 // Exit early if the dropbox isn't configured to accept this report type. 10356 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10357 10358 final StringBuilder sb = new StringBuilder(1024); 10359 appendDropBoxProcessHeaders(process, processName, sb); 10360 if (activity != null) { 10361 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10362 } 10363 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10364 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10365 } 10366 if (parent != null && parent != activity) { 10367 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10368 } 10369 if (subject != null) { 10370 sb.append("Subject: ").append(subject).append("\n"); 10371 } 10372 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10373 if (Debug.isDebuggerConnected()) { 10374 sb.append("Debugger: Connected\n"); 10375 } 10376 sb.append("\n"); 10377 10378 // Do the rest in a worker thread to avoid blocking the caller on I/O 10379 // (After this point, we shouldn't access AMS internal data structures.) 10380 Thread worker = new Thread("Error dump: " + dropboxTag) { 10381 @Override 10382 public void run() { 10383 if (report != null) { 10384 sb.append(report); 10385 } 10386 if (logFile != null) { 10387 try { 10388 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10389 "\n\n[[TRUNCATED]]")); 10390 } catch (IOException e) { 10391 Slog.e(TAG, "Error reading " + logFile, e); 10392 } 10393 } 10394 if (crashInfo != null && crashInfo.stackTrace != null) { 10395 sb.append(crashInfo.stackTrace); 10396 } 10397 10398 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10399 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10400 if (lines > 0) { 10401 sb.append("\n"); 10402 10403 // Merge several logcat streams, and take the last N lines 10404 InputStreamReader input = null; 10405 try { 10406 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10407 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10408 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10409 10410 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10411 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10412 input = new InputStreamReader(logcat.getInputStream()); 10413 10414 int num; 10415 char[] buf = new char[8192]; 10416 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10417 } catch (IOException e) { 10418 Slog.e(TAG, "Error running logcat", e); 10419 } finally { 10420 if (input != null) try { input.close(); } catch (IOException e) {} 10421 } 10422 } 10423 10424 dbox.addText(dropboxTag, sb.toString()); 10425 } 10426 }; 10427 10428 if (process == null) { 10429 // If process is null, we are being called from some internal code 10430 // and may be about to die -- run this synchronously. 10431 worker.run(); 10432 } else { 10433 worker.start(); 10434 } 10435 } 10436 10437 /** 10438 * Bring up the "unexpected error" dialog box for a crashing app. 10439 * Deal with edge cases (intercepts from instrumented applications, 10440 * ActivityController, error intent receivers, that sort of thing). 10441 * @param r the application crashing 10442 * @param crashInfo describing the failure 10443 */ 10444 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10445 long timeMillis = System.currentTimeMillis(); 10446 String shortMsg = crashInfo.exceptionClassName; 10447 String longMsg = crashInfo.exceptionMessage; 10448 String stackTrace = crashInfo.stackTrace; 10449 if (shortMsg != null && longMsg != null) { 10450 longMsg = shortMsg + ": " + longMsg; 10451 } else if (shortMsg != null) { 10452 longMsg = shortMsg; 10453 } 10454 10455 AppErrorResult result = new AppErrorResult(); 10456 synchronized (this) { 10457 if (mController != null) { 10458 try { 10459 String name = r != null ? r.processName : null; 10460 int pid = r != null ? r.pid : Binder.getCallingPid(); 10461 if (!mController.appCrashed(name, pid, 10462 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10463 Slog.w(TAG, "Force-killing crashed app " + name 10464 + " at watcher's request"); 10465 Process.killProcess(pid); 10466 return; 10467 } 10468 } catch (RemoteException e) { 10469 mController = null; 10470 Watchdog.getInstance().setActivityController(null); 10471 } 10472 } 10473 10474 final long origId = Binder.clearCallingIdentity(); 10475 10476 // If this process is running instrumentation, finish it. 10477 if (r != null && r.instrumentationClass != null) { 10478 Slog.w(TAG, "Error in app " + r.processName 10479 + " running instrumentation " + r.instrumentationClass + ":"); 10480 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10481 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10482 Bundle info = new Bundle(); 10483 info.putString("shortMsg", shortMsg); 10484 info.putString("longMsg", longMsg); 10485 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10486 Binder.restoreCallingIdentity(origId); 10487 return; 10488 } 10489 10490 // If we can't identify the process or it's already exceeded its crash quota, 10491 // quit right away without showing a crash dialog. 10492 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10493 Binder.restoreCallingIdentity(origId); 10494 return; 10495 } 10496 10497 Message msg = Message.obtain(); 10498 msg.what = SHOW_ERROR_MSG; 10499 HashMap data = new HashMap(); 10500 data.put("result", result); 10501 data.put("app", r); 10502 msg.obj = data; 10503 mHandler.sendMessage(msg); 10504 10505 Binder.restoreCallingIdentity(origId); 10506 } 10507 10508 int res = result.get(); 10509 10510 Intent appErrorIntent = null; 10511 synchronized (this) { 10512 if (r != null && !r.isolated) { 10513 // XXX Can't keep track of crash time for isolated processes, 10514 // since they don't have a persistent identity. 10515 mProcessCrashTimes.put(r.info.processName, r.uid, 10516 SystemClock.uptimeMillis()); 10517 } 10518 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10519 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10520 } 10521 } 10522 10523 if (appErrorIntent != null) { 10524 try { 10525 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10526 } catch (ActivityNotFoundException e) { 10527 Slog.w(TAG, "bug report receiver dissappeared", e); 10528 } 10529 } 10530 } 10531 10532 Intent createAppErrorIntentLocked(ProcessRecord r, 10533 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10534 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10535 if (report == null) { 10536 return null; 10537 } 10538 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10539 result.setComponent(r.errorReportReceiver); 10540 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10541 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10542 return result; 10543 } 10544 10545 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10546 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10547 if (r.errorReportReceiver == null) { 10548 return null; 10549 } 10550 10551 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10552 return null; 10553 } 10554 10555 ApplicationErrorReport report = new ApplicationErrorReport(); 10556 report.packageName = r.info.packageName; 10557 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10558 report.processName = r.processName; 10559 report.time = timeMillis; 10560 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10561 10562 if (r.crashing || r.forceCrashReport) { 10563 report.type = ApplicationErrorReport.TYPE_CRASH; 10564 report.crashInfo = crashInfo; 10565 } else if (r.notResponding) { 10566 report.type = ApplicationErrorReport.TYPE_ANR; 10567 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10568 10569 report.anrInfo.activity = r.notRespondingReport.tag; 10570 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10571 report.anrInfo.info = r.notRespondingReport.longMsg; 10572 } 10573 10574 return report; 10575 } 10576 10577 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10578 enforceNotIsolatedCaller("getProcessesInErrorState"); 10579 // assume our apps are happy - lazy create the list 10580 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10581 10582 final boolean allUsers = ActivityManager.checkUidPermission( 10583 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10584 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10585 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10586 10587 synchronized (this) { 10588 10589 // iterate across all processes 10590 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10591 ProcessRecord app = mLruProcesses.get(i); 10592 if (!allUsers && app.userId != userId) { 10593 continue; 10594 } 10595 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10596 // This one's in trouble, so we'll generate a report for it 10597 // crashes are higher priority (in case there's a crash *and* an anr) 10598 ActivityManager.ProcessErrorStateInfo report = null; 10599 if (app.crashing) { 10600 report = app.crashingReport; 10601 } else if (app.notResponding) { 10602 report = app.notRespondingReport; 10603 } 10604 10605 if (report != null) { 10606 if (errList == null) { 10607 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10608 } 10609 errList.add(report); 10610 } else { 10611 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10612 " crashing = " + app.crashing + 10613 " notResponding = " + app.notResponding); 10614 } 10615 } 10616 } 10617 } 10618 10619 return errList; 10620 } 10621 10622 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10623 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10624 if (currApp != null) { 10625 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10626 } 10627 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10628 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10629 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10630 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10631 if (currApp != null) { 10632 currApp.lru = 0; 10633 } 10634 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10635 } else if (adj >= ProcessList.SERVICE_ADJ) { 10636 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10637 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10638 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10639 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10640 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10641 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10642 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10643 } else { 10644 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10645 } 10646 } 10647 10648 private void fillInProcMemInfo(ProcessRecord app, 10649 ActivityManager.RunningAppProcessInfo outInfo) { 10650 outInfo.pid = app.pid; 10651 outInfo.uid = app.info.uid; 10652 if (mHeavyWeightProcess == app) { 10653 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10654 } 10655 if (app.persistent) { 10656 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10657 } 10658 if (app.activities.size() > 0) { 10659 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10660 } 10661 outInfo.lastTrimLevel = app.trimMemoryLevel; 10662 int adj = app.curAdj; 10663 outInfo.importance = oomAdjToImportance(adj, outInfo); 10664 outInfo.importanceReasonCode = app.adjTypeCode; 10665 outInfo.processState = app.curProcState; 10666 } 10667 10668 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10669 enforceNotIsolatedCaller("getRunningAppProcesses"); 10670 // Lazy instantiation of list 10671 List<ActivityManager.RunningAppProcessInfo> runList = null; 10672 final boolean allUsers = ActivityManager.checkUidPermission( 10673 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10674 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10675 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10676 synchronized (this) { 10677 // Iterate across all processes 10678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10679 ProcessRecord app = mLruProcesses.get(i); 10680 if (!allUsers && app.userId != userId) { 10681 continue; 10682 } 10683 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10684 // Generate process state info for running application 10685 ActivityManager.RunningAppProcessInfo currApp = 10686 new ActivityManager.RunningAppProcessInfo(app.processName, 10687 app.pid, app.getPackageList()); 10688 fillInProcMemInfo(app, currApp); 10689 if (app.adjSource instanceof ProcessRecord) { 10690 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10691 currApp.importanceReasonImportance = oomAdjToImportance( 10692 app.adjSourceOom, null); 10693 } else if (app.adjSource instanceof ActivityRecord) { 10694 ActivityRecord r = (ActivityRecord)app.adjSource; 10695 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10696 } 10697 if (app.adjTarget instanceof ComponentName) { 10698 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10699 } 10700 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10701 // + " lru=" + currApp.lru); 10702 if (runList == null) { 10703 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10704 } 10705 runList.add(currApp); 10706 } 10707 } 10708 } 10709 return runList; 10710 } 10711 10712 public List<ApplicationInfo> getRunningExternalApplications() { 10713 enforceNotIsolatedCaller("getRunningExternalApplications"); 10714 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10715 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10716 if (runningApps != null && runningApps.size() > 0) { 10717 Set<String> extList = new HashSet<String>(); 10718 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10719 if (app.pkgList != null) { 10720 for (String pkg : app.pkgList) { 10721 extList.add(pkg); 10722 } 10723 } 10724 } 10725 IPackageManager pm = AppGlobals.getPackageManager(); 10726 for (String pkg : extList) { 10727 try { 10728 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10729 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10730 retList.add(info); 10731 } 10732 } catch (RemoteException e) { 10733 } 10734 } 10735 } 10736 return retList; 10737 } 10738 10739 @Override 10740 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10741 enforceNotIsolatedCaller("getMyMemoryState"); 10742 synchronized (this) { 10743 ProcessRecord proc; 10744 synchronized (mPidsSelfLocked) { 10745 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10746 } 10747 fillInProcMemInfo(proc, outInfo); 10748 } 10749 } 10750 10751 @Override 10752 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10753 if (checkCallingPermission(android.Manifest.permission.DUMP) 10754 != PackageManager.PERMISSION_GRANTED) { 10755 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10756 + Binder.getCallingPid() 10757 + ", uid=" + Binder.getCallingUid() 10758 + " without permission " 10759 + android.Manifest.permission.DUMP); 10760 return; 10761 } 10762 10763 boolean dumpAll = false; 10764 boolean dumpClient = false; 10765 String dumpPackage = null; 10766 10767 int opti = 0; 10768 while (opti < args.length) { 10769 String opt = args[opti]; 10770 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10771 break; 10772 } 10773 opti++; 10774 if ("-a".equals(opt)) { 10775 dumpAll = true; 10776 } else if ("-c".equals(opt)) { 10777 dumpClient = true; 10778 } else if ("-h".equals(opt)) { 10779 pw.println("Activity manager dump options:"); 10780 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10781 pw.println(" cmd may be one of:"); 10782 pw.println(" a[ctivities]: activity stack state"); 10783 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10784 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10785 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10786 pw.println(" o[om]: out of memory management"); 10787 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10788 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10789 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10790 pw.println(" service [COMP_SPEC]: service client-side state"); 10791 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10792 pw.println(" all: dump all activities"); 10793 pw.println(" top: dump the top activity"); 10794 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10795 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10796 pw.println(" a partial substring in a component name, a"); 10797 pw.println(" hex object identifier."); 10798 pw.println(" -a: include all available server state."); 10799 pw.println(" -c: include client state."); 10800 return; 10801 } else { 10802 pw.println("Unknown argument: " + opt + "; use -h for help"); 10803 } 10804 } 10805 10806 long origId = Binder.clearCallingIdentity(); 10807 boolean more = false; 10808 // Is the caller requesting to dump a particular piece of data? 10809 if (opti < args.length) { 10810 String cmd = args[opti]; 10811 opti++; 10812 if ("activities".equals(cmd) || "a".equals(cmd)) { 10813 synchronized (this) { 10814 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10815 } 10816 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10817 String[] newArgs; 10818 String name; 10819 if (opti >= args.length) { 10820 name = null; 10821 newArgs = EMPTY_STRING_ARRAY; 10822 } else { 10823 name = args[opti]; 10824 opti++; 10825 newArgs = new String[args.length - opti]; 10826 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10827 args.length - opti); 10828 } 10829 synchronized (this) { 10830 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10831 } 10832 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10833 String[] newArgs; 10834 String name; 10835 if (opti >= args.length) { 10836 name = null; 10837 newArgs = EMPTY_STRING_ARRAY; 10838 } else { 10839 name = args[opti]; 10840 opti++; 10841 newArgs = new String[args.length - opti]; 10842 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10843 args.length - opti); 10844 } 10845 synchronized (this) { 10846 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10847 } 10848 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10849 String[] newArgs; 10850 String name; 10851 if (opti >= args.length) { 10852 name = null; 10853 newArgs = EMPTY_STRING_ARRAY; 10854 } else { 10855 name = args[opti]; 10856 opti++; 10857 newArgs = new String[args.length - opti]; 10858 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10859 args.length - opti); 10860 } 10861 synchronized (this) { 10862 dumpProcessesLocked(fd, pw, args, opti, true, name); 10863 } 10864 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10865 synchronized (this) { 10866 dumpOomLocked(fd, pw, args, opti, true); 10867 } 10868 } else if ("provider".equals(cmd)) { 10869 String[] newArgs; 10870 String name; 10871 if (opti >= args.length) { 10872 name = null; 10873 newArgs = EMPTY_STRING_ARRAY; 10874 } else { 10875 name = args[opti]; 10876 opti++; 10877 newArgs = new String[args.length - opti]; 10878 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10879 } 10880 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10881 pw.println("No providers match: " + name); 10882 pw.println("Use -h for help."); 10883 } 10884 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10885 synchronized (this) { 10886 dumpProvidersLocked(fd, pw, args, opti, true, null); 10887 } 10888 } else if ("service".equals(cmd)) { 10889 String[] newArgs; 10890 String name; 10891 if (opti >= args.length) { 10892 name = null; 10893 newArgs = EMPTY_STRING_ARRAY; 10894 } else { 10895 name = args[opti]; 10896 opti++; 10897 newArgs = new String[args.length - opti]; 10898 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10899 args.length - opti); 10900 } 10901 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10902 pw.println("No services match: " + name); 10903 pw.println("Use -h for help."); 10904 } 10905 } else if ("package".equals(cmd)) { 10906 String[] newArgs; 10907 if (opti >= args.length) { 10908 pw.println("package: no package name specified"); 10909 pw.println("Use -h for help."); 10910 } else { 10911 dumpPackage = args[opti]; 10912 opti++; 10913 newArgs = new String[args.length - opti]; 10914 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10915 args.length - opti); 10916 args = newArgs; 10917 opti = 0; 10918 more = true; 10919 } 10920 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10921 synchronized (this) { 10922 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10923 } 10924 } else { 10925 // Dumping a single activity? 10926 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10927 pw.println("Bad activity command, or no activities match: " + cmd); 10928 pw.println("Use -h for help."); 10929 } 10930 } 10931 if (!more) { 10932 Binder.restoreCallingIdentity(origId); 10933 return; 10934 } 10935 } 10936 10937 // No piece of data specified, dump everything. 10938 synchronized (this) { 10939 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10940 pw.println(); 10941 if (dumpAll) { 10942 pw.println("-------------------------------------------------------------------------------"); 10943 } 10944 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10945 pw.println(); 10946 if (dumpAll) { 10947 pw.println("-------------------------------------------------------------------------------"); 10948 } 10949 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10950 pw.println(); 10951 if (dumpAll) { 10952 pw.println("-------------------------------------------------------------------------------"); 10953 } 10954 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10955 pw.println(); 10956 if (dumpAll) { 10957 pw.println("-------------------------------------------------------------------------------"); 10958 } 10959 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10960 pw.println(); 10961 if (dumpAll) { 10962 pw.println("-------------------------------------------------------------------------------"); 10963 } 10964 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10965 } 10966 Binder.restoreCallingIdentity(origId); 10967 } 10968 10969 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10970 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10971 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10972 10973 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10974 dumpPackage); 10975 boolean needSep = printedAnything; 10976 10977 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10978 dumpPackage, needSep, " mFocusedActivity: "); 10979 if (printed) { 10980 printedAnything = true; 10981 needSep = false; 10982 } 10983 10984 if (dumpPackage == null) { 10985 if (needSep) { 10986 pw.println(); 10987 } 10988 needSep = true; 10989 printedAnything = true; 10990 mStackSupervisor.dump(pw, " "); 10991 } 10992 10993 if (mRecentTasks.size() > 0) { 10994 boolean printedHeader = false; 10995 10996 final int N = mRecentTasks.size(); 10997 for (int i=0; i<N; i++) { 10998 TaskRecord tr = mRecentTasks.get(i); 10999 if (dumpPackage != null) { 11000 if (tr.realActivity == null || 11001 !dumpPackage.equals(tr.realActivity)) { 11002 continue; 11003 } 11004 } 11005 if (!printedHeader) { 11006 if (needSep) { 11007 pw.println(); 11008 } 11009 pw.println(" Recent tasks:"); 11010 printedHeader = true; 11011 printedAnything = true; 11012 } 11013 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11014 pw.println(tr); 11015 if (dumpAll) { 11016 mRecentTasks.get(i).dump(pw, " "); 11017 } 11018 } 11019 } 11020 11021 if (!printedAnything) { 11022 pw.println(" (nothing)"); 11023 } 11024 } 11025 11026 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11027 int opti, boolean dumpAll, String dumpPackage) { 11028 boolean needSep = false; 11029 boolean printedAnything = false; 11030 int numPers = 0; 11031 11032 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11033 11034 if (dumpAll) { 11035 final int NP = mProcessNames.getMap().size(); 11036 for (int ip=0; ip<NP; ip++) { 11037 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11038 final int NA = procs.size(); 11039 for (int ia=0; ia<NA; ia++) { 11040 ProcessRecord r = procs.valueAt(ia); 11041 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11042 continue; 11043 } 11044 if (!needSep) { 11045 pw.println(" All known processes:"); 11046 needSep = true; 11047 printedAnything = true; 11048 } 11049 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11050 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11051 pw.print(" "); pw.println(r); 11052 r.dump(pw, " "); 11053 if (r.persistent) { 11054 numPers++; 11055 } 11056 } 11057 } 11058 } 11059 11060 if (mIsolatedProcesses.size() > 0) { 11061 boolean printed = false; 11062 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11063 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11064 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11065 continue; 11066 } 11067 if (!printed) { 11068 if (needSep) { 11069 pw.println(); 11070 } 11071 pw.println(" Isolated process list (sorted by uid):"); 11072 printedAnything = true; 11073 printed = true; 11074 needSep = true; 11075 } 11076 pw.println(String.format("%sIsolated #%2d: %s", 11077 " ", i, r.toString())); 11078 } 11079 } 11080 11081 if (mLruProcesses.size() > 0) { 11082 if (needSep) { 11083 pw.println(); 11084 } 11085 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11086 pw.print(" total, non-act at "); 11087 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11088 pw.print(", non-svc at "); 11089 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11090 pw.println("):"); 11091 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11092 needSep = true; 11093 printedAnything = true; 11094 } 11095 11096 if (dumpAll || dumpPackage != null) { 11097 synchronized (mPidsSelfLocked) { 11098 boolean printed = false; 11099 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11100 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11101 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11102 continue; 11103 } 11104 if (!printed) { 11105 if (needSep) pw.println(); 11106 needSep = true; 11107 pw.println(" PID mappings:"); 11108 printed = true; 11109 printedAnything = true; 11110 } 11111 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11112 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11113 } 11114 } 11115 } 11116 11117 if (mForegroundProcesses.size() > 0) { 11118 synchronized (mPidsSelfLocked) { 11119 boolean printed = false; 11120 for (int i=0; i<mForegroundProcesses.size(); i++) { 11121 ProcessRecord r = mPidsSelfLocked.get( 11122 mForegroundProcesses.valueAt(i).pid); 11123 if (dumpPackage != null && (r == null 11124 || !r.pkgList.containsKey(dumpPackage))) { 11125 continue; 11126 } 11127 if (!printed) { 11128 if (needSep) pw.println(); 11129 needSep = true; 11130 pw.println(" Foreground Processes:"); 11131 printed = true; 11132 printedAnything = true; 11133 } 11134 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11135 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11136 } 11137 } 11138 } 11139 11140 if (mPersistentStartingProcesses.size() > 0) { 11141 if (needSep) pw.println(); 11142 needSep = true; 11143 printedAnything = true; 11144 pw.println(" Persisent processes that are starting:"); 11145 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11146 "Starting Norm", "Restarting PERS", dumpPackage); 11147 } 11148 11149 if (mRemovedProcesses.size() > 0) { 11150 if (needSep) pw.println(); 11151 needSep = true; 11152 printedAnything = true; 11153 pw.println(" Processes that are being removed:"); 11154 dumpProcessList(pw, this, mRemovedProcesses, " ", 11155 "Removed Norm", "Removed PERS", dumpPackage); 11156 } 11157 11158 if (mProcessesOnHold.size() > 0) { 11159 if (needSep) pw.println(); 11160 needSep = true; 11161 printedAnything = true; 11162 pw.println(" Processes that are on old until the system is ready:"); 11163 dumpProcessList(pw, this, mProcessesOnHold, " ", 11164 "OnHold Norm", "OnHold PERS", dumpPackage); 11165 } 11166 11167 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11168 11169 if (mProcessCrashTimes.getMap().size() > 0) { 11170 boolean printed = false; 11171 long now = SystemClock.uptimeMillis(); 11172 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11173 final int NP = pmap.size(); 11174 for (int ip=0; ip<NP; ip++) { 11175 String pname = pmap.keyAt(ip); 11176 SparseArray<Long> uids = pmap.valueAt(ip); 11177 final int N = uids.size(); 11178 for (int i=0; i<N; i++) { 11179 int puid = uids.keyAt(i); 11180 ProcessRecord r = mProcessNames.get(pname, puid); 11181 if (dumpPackage != null && (r == null 11182 || !r.pkgList.containsKey(dumpPackage))) { 11183 continue; 11184 } 11185 if (!printed) { 11186 if (needSep) pw.println(); 11187 needSep = true; 11188 pw.println(" Time since processes crashed:"); 11189 printed = true; 11190 printedAnything = true; 11191 } 11192 pw.print(" Process "); pw.print(pname); 11193 pw.print(" uid "); pw.print(puid); 11194 pw.print(": last crashed "); 11195 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11196 pw.println(" ago"); 11197 } 11198 } 11199 } 11200 11201 if (mBadProcesses.getMap().size() > 0) { 11202 boolean printed = false; 11203 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11204 final int NP = pmap.size(); 11205 for (int ip=0; ip<NP; ip++) { 11206 String pname = pmap.keyAt(ip); 11207 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11208 final int N = uids.size(); 11209 for (int i=0; i<N; i++) { 11210 int puid = uids.keyAt(i); 11211 ProcessRecord r = mProcessNames.get(pname, puid); 11212 if (dumpPackage != null && (r == null 11213 || !r.pkgList.containsKey(dumpPackage))) { 11214 continue; 11215 } 11216 if (!printed) { 11217 if (needSep) pw.println(); 11218 needSep = true; 11219 pw.println(" Bad processes:"); 11220 printedAnything = true; 11221 } 11222 BadProcessInfo info = uids.valueAt(i); 11223 pw.print(" Bad process "); pw.print(pname); 11224 pw.print(" uid "); pw.print(puid); 11225 pw.print(": crashed at time "); pw.println(info.time); 11226 if (info.shortMsg != null) { 11227 pw.print(" Short msg: "); pw.println(info.shortMsg); 11228 } 11229 if (info.longMsg != null) { 11230 pw.print(" Long msg: "); pw.println(info.longMsg); 11231 } 11232 if (info.stack != null) { 11233 pw.println(" Stack:"); 11234 int lastPos = 0; 11235 for (int pos=0; pos<info.stack.length(); pos++) { 11236 if (info.stack.charAt(pos) == '\n') { 11237 pw.print(" "); 11238 pw.write(info.stack, lastPos, pos-lastPos); 11239 pw.println(); 11240 lastPos = pos+1; 11241 } 11242 } 11243 if (lastPos < info.stack.length()) { 11244 pw.print(" "); 11245 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11246 pw.println(); 11247 } 11248 } 11249 } 11250 } 11251 } 11252 11253 if (dumpPackage == null) { 11254 pw.println(); 11255 needSep = false; 11256 pw.println(" mStartedUsers:"); 11257 for (int i=0; i<mStartedUsers.size(); i++) { 11258 UserStartedState uss = mStartedUsers.valueAt(i); 11259 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11260 pw.print(": "); uss.dump("", pw); 11261 } 11262 pw.print(" mStartedUserArray: ["); 11263 for (int i=0; i<mStartedUserArray.length; i++) { 11264 if (i > 0) pw.print(", "); 11265 pw.print(mStartedUserArray[i]); 11266 } 11267 pw.println("]"); 11268 pw.print(" mUserLru: ["); 11269 for (int i=0; i<mUserLru.size(); i++) { 11270 if (i > 0) pw.print(", "); 11271 pw.print(mUserLru.get(i)); 11272 } 11273 pw.println("]"); 11274 if (dumpAll) { 11275 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11276 } 11277 } 11278 if (mHomeProcess != null && (dumpPackage == null 11279 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11280 if (needSep) { 11281 pw.println(); 11282 needSep = false; 11283 } 11284 pw.println(" mHomeProcess: " + mHomeProcess); 11285 } 11286 if (mPreviousProcess != null && (dumpPackage == null 11287 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11288 if (needSep) { 11289 pw.println(); 11290 needSep = false; 11291 } 11292 pw.println(" mPreviousProcess: " + mPreviousProcess); 11293 } 11294 if (dumpAll) { 11295 StringBuilder sb = new StringBuilder(128); 11296 sb.append(" mPreviousProcessVisibleTime: "); 11297 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11298 pw.println(sb); 11299 } 11300 if (mHeavyWeightProcess != null && (dumpPackage == null 11301 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11302 if (needSep) { 11303 pw.println(); 11304 needSep = false; 11305 } 11306 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11307 } 11308 if (dumpPackage == null) { 11309 pw.println(" mConfiguration: " + mConfiguration); 11310 } 11311 if (dumpAll) { 11312 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11313 if (mCompatModePackages.getPackages().size() > 0) { 11314 boolean printed = false; 11315 for (Map.Entry<String, Integer> entry 11316 : mCompatModePackages.getPackages().entrySet()) { 11317 String pkg = entry.getKey(); 11318 int mode = entry.getValue(); 11319 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11320 continue; 11321 } 11322 if (!printed) { 11323 pw.println(" mScreenCompatPackages:"); 11324 printed = true; 11325 } 11326 pw.print(" "); pw.print(pkg); pw.print(": "); 11327 pw.print(mode); pw.println(); 11328 } 11329 } 11330 } 11331 if (dumpPackage == null) { 11332 if (mSleeping || mWentToSleep || mLockScreenShown) { 11333 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11334 + " mLockScreenShown " + mLockScreenShown); 11335 } 11336 if (mShuttingDown || mRunningVoice) { 11337 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11338 } 11339 } 11340 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11341 || mOrigWaitForDebugger) { 11342 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11343 || dumpPackage.equals(mOrigDebugApp)) { 11344 if (needSep) { 11345 pw.println(); 11346 needSep = false; 11347 } 11348 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11349 + " mDebugTransient=" + mDebugTransient 11350 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11351 } 11352 } 11353 if (mOpenGlTraceApp != null) { 11354 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11355 if (needSep) { 11356 pw.println(); 11357 needSep = false; 11358 } 11359 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11360 } 11361 } 11362 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11363 || mProfileFd != null) { 11364 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11365 if (needSep) { 11366 pw.println(); 11367 needSep = false; 11368 } 11369 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11370 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11371 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11372 + mAutoStopProfiler); 11373 } 11374 } 11375 if (dumpPackage == null) { 11376 if (mAlwaysFinishActivities || mController != null) { 11377 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11378 + " mController=" + mController); 11379 } 11380 if (dumpAll) { 11381 pw.println(" Total persistent processes: " + numPers); 11382 pw.println(" mProcessesReady=" + mProcessesReady 11383 + " mSystemReady=" + mSystemReady); 11384 pw.println(" mBooting=" + mBooting 11385 + " mBooted=" + mBooted 11386 + " mFactoryTest=" + mFactoryTest); 11387 pw.print(" mLastPowerCheckRealtime="); 11388 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11389 pw.println(""); 11390 pw.print(" mLastPowerCheckUptime="); 11391 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11392 pw.println(""); 11393 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11394 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11395 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11396 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11397 + " (" + mLruProcesses.size() + " total)" 11398 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11399 + " mNumServiceProcs=" + mNumServiceProcs 11400 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11401 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11402 + " mLastMemoryLevel" + mLastMemoryLevel 11403 + " mLastNumProcesses" + mLastNumProcesses); 11404 long now = SystemClock.uptimeMillis(); 11405 pw.print(" mLastIdleTime="); 11406 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11407 pw.print(" mLowRamSinceLastIdle="); 11408 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11409 pw.println(); 11410 } 11411 } 11412 11413 if (!printedAnything) { 11414 pw.println(" (nothing)"); 11415 } 11416 } 11417 11418 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11419 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11420 if (mProcessesToGc.size() > 0) { 11421 boolean printed = false; 11422 long now = SystemClock.uptimeMillis(); 11423 for (int i=0; i<mProcessesToGc.size(); i++) { 11424 ProcessRecord proc = mProcessesToGc.get(i); 11425 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11426 continue; 11427 } 11428 if (!printed) { 11429 if (needSep) pw.println(); 11430 needSep = true; 11431 pw.println(" Processes that are waiting to GC:"); 11432 printed = true; 11433 } 11434 pw.print(" Process "); pw.println(proc); 11435 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11436 pw.print(", last gced="); 11437 pw.print(now-proc.lastRequestedGc); 11438 pw.print(" ms ago, last lowMem="); 11439 pw.print(now-proc.lastLowMemory); 11440 pw.println(" ms ago"); 11441 11442 } 11443 } 11444 return needSep; 11445 } 11446 11447 void printOomLevel(PrintWriter pw, String name, int adj) { 11448 pw.print(" "); 11449 if (adj >= 0) { 11450 pw.print(' '); 11451 if (adj < 10) pw.print(' '); 11452 } else { 11453 if (adj > -10) pw.print(' '); 11454 } 11455 pw.print(adj); 11456 pw.print(": "); 11457 pw.print(name); 11458 pw.print(" ("); 11459 pw.print(mProcessList.getMemLevel(adj)/1024); 11460 pw.println(" kB)"); 11461 } 11462 11463 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11464 int opti, boolean dumpAll) { 11465 boolean needSep = false; 11466 11467 if (mLruProcesses.size() > 0) { 11468 if (needSep) pw.println(); 11469 needSep = true; 11470 pw.println(" OOM levels:"); 11471 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11472 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11473 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11474 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11475 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11476 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11477 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11478 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11479 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11480 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11481 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11482 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11483 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11484 11485 if (needSep) pw.println(); 11486 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11487 pw.print(" total, non-act at "); 11488 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11489 pw.print(", non-svc at "); 11490 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11491 pw.println("):"); 11492 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11493 needSep = true; 11494 } 11495 11496 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11497 11498 pw.println(); 11499 pw.println(" mHomeProcess: " + mHomeProcess); 11500 pw.println(" mPreviousProcess: " + mPreviousProcess); 11501 if (mHeavyWeightProcess != null) { 11502 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11503 } 11504 11505 return true; 11506 } 11507 11508 /** 11509 * There are three ways to call this: 11510 * - no provider specified: dump all the providers 11511 * - a flattened component name that matched an existing provider was specified as the 11512 * first arg: dump that one provider 11513 * - the first arg isn't the flattened component name of an existing provider: 11514 * dump all providers whose component contains the first arg as a substring 11515 */ 11516 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11517 int opti, boolean dumpAll) { 11518 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11519 } 11520 11521 static class ItemMatcher { 11522 ArrayList<ComponentName> components; 11523 ArrayList<String> strings; 11524 ArrayList<Integer> objects; 11525 boolean all; 11526 11527 ItemMatcher() { 11528 all = true; 11529 } 11530 11531 void build(String name) { 11532 ComponentName componentName = ComponentName.unflattenFromString(name); 11533 if (componentName != null) { 11534 if (components == null) { 11535 components = new ArrayList<ComponentName>(); 11536 } 11537 components.add(componentName); 11538 all = false; 11539 } else { 11540 int objectId = 0; 11541 // Not a '/' separated full component name; maybe an object ID? 11542 try { 11543 objectId = Integer.parseInt(name, 16); 11544 if (objects == null) { 11545 objects = new ArrayList<Integer>(); 11546 } 11547 objects.add(objectId); 11548 all = false; 11549 } catch (RuntimeException e) { 11550 // Not an integer; just do string match. 11551 if (strings == null) { 11552 strings = new ArrayList<String>(); 11553 } 11554 strings.add(name); 11555 all = false; 11556 } 11557 } 11558 } 11559 11560 int build(String[] args, int opti) { 11561 for (; opti<args.length; opti++) { 11562 String name = args[opti]; 11563 if ("--".equals(name)) { 11564 return opti+1; 11565 } 11566 build(name); 11567 } 11568 return opti; 11569 } 11570 11571 boolean match(Object object, ComponentName comp) { 11572 if (all) { 11573 return true; 11574 } 11575 if (components != null) { 11576 for (int i=0; i<components.size(); i++) { 11577 if (components.get(i).equals(comp)) { 11578 return true; 11579 } 11580 } 11581 } 11582 if (objects != null) { 11583 for (int i=0; i<objects.size(); i++) { 11584 if (System.identityHashCode(object) == objects.get(i)) { 11585 return true; 11586 } 11587 } 11588 } 11589 if (strings != null) { 11590 String flat = comp.flattenToString(); 11591 for (int i=0; i<strings.size(); i++) { 11592 if (flat.contains(strings.get(i))) { 11593 return true; 11594 } 11595 } 11596 } 11597 return false; 11598 } 11599 } 11600 11601 /** 11602 * There are three things that cmd can be: 11603 * - a flattened component name that matches an existing activity 11604 * - the cmd arg isn't the flattened component name of an existing activity: 11605 * dump all activity whose component contains the cmd as a substring 11606 * - A hex number of the ActivityRecord object instance. 11607 */ 11608 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11609 int opti, boolean dumpAll) { 11610 ArrayList<ActivityRecord> activities; 11611 11612 synchronized (this) { 11613 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11614 } 11615 11616 if (activities.size() <= 0) { 11617 return false; 11618 } 11619 11620 String[] newArgs = new String[args.length - opti]; 11621 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11622 11623 TaskRecord lastTask = null; 11624 boolean needSep = false; 11625 for (int i=activities.size()-1; i>=0; i--) { 11626 ActivityRecord r = activities.get(i); 11627 if (needSep) { 11628 pw.println(); 11629 } 11630 needSep = true; 11631 synchronized (this) { 11632 if (lastTask != r.task) { 11633 lastTask = r.task; 11634 pw.print("TASK "); pw.print(lastTask.affinity); 11635 pw.print(" id="); pw.println(lastTask.taskId); 11636 if (dumpAll) { 11637 lastTask.dump(pw, " "); 11638 } 11639 } 11640 } 11641 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11642 } 11643 return true; 11644 } 11645 11646 /** 11647 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11648 * there is a thread associated with the activity. 11649 */ 11650 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11651 final ActivityRecord r, String[] args, boolean dumpAll) { 11652 String innerPrefix = prefix + " "; 11653 synchronized (this) { 11654 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11655 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11656 pw.print(" pid="); 11657 if (r.app != null) pw.println(r.app.pid); 11658 else pw.println("(not running)"); 11659 if (dumpAll) { 11660 r.dump(pw, innerPrefix); 11661 } 11662 } 11663 if (r.app != null && r.app.thread != null) { 11664 // flush anything that is already in the PrintWriter since the thread is going 11665 // to write to the file descriptor directly 11666 pw.flush(); 11667 try { 11668 TransferPipe tp = new TransferPipe(); 11669 try { 11670 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11671 r.appToken, innerPrefix, args); 11672 tp.go(fd); 11673 } finally { 11674 tp.kill(); 11675 } 11676 } catch (IOException e) { 11677 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11678 } catch (RemoteException e) { 11679 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11680 } 11681 } 11682 } 11683 11684 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11685 int opti, boolean dumpAll, String dumpPackage) { 11686 boolean needSep = false; 11687 boolean onlyHistory = false; 11688 boolean printedAnything = false; 11689 11690 if ("history".equals(dumpPackage)) { 11691 if (opti < args.length && "-s".equals(args[opti])) { 11692 dumpAll = false; 11693 } 11694 onlyHistory = true; 11695 dumpPackage = null; 11696 } 11697 11698 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11699 if (!onlyHistory && dumpAll) { 11700 if (mRegisteredReceivers.size() > 0) { 11701 boolean printed = false; 11702 Iterator it = mRegisteredReceivers.values().iterator(); 11703 while (it.hasNext()) { 11704 ReceiverList r = (ReceiverList)it.next(); 11705 if (dumpPackage != null && (r.app == null || 11706 !dumpPackage.equals(r.app.info.packageName))) { 11707 continue; 11708 } 11709 if (!printed) { 11710 pw.println(" Registered Receivers:"); 11711 needSep = true; 11712 printed = true; 11713 printedAnything = true; 11714 } 11715 pw.print(" * "); pw.println(r); 11716 r.dump(pw, " "); 11717 } 11718 } 11719 11720 if (mReceiverResolver.dump(pw, needSep ? 11721 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11722 " ", dumpPackage, false)) { 11723 needSep = true; 11724 printedAnything = true; 11725 } 11726 } 11727 11728 for (BroadcastQueue q : mBroadcastQueues) { 11729 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11730 printedAnything |= needSep; 11731 } 11732 11733 needSep = true; 11734 11735 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11736 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11737 if (needSep) { 11738 pw.println(); 11739 } 11740 needSep = true; 11741 printedAnything = true; 11742 pw.print(" Sticky broadcasts for user "); 11743 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11744 StringBuilder sb = new StringBuilder(128); 11745 for (Map.Entry<String, ArrayList<Intent>> ent 11746 : mStickyBroadcasts.valueAt(user).entrySet()) { 11747 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11748 if (dumpAll) { 11749 pw.println(":"); 11750 ArrayList<Intent> intents = ent.getValue(); 11751 final int N = intents.size(); 11752 for (int i=0; i<N; i++) { 11753 sb.setLength(0); 11754 sb.append(" Intent: "); 11755 intents.get(i).toShortString(sb, false, true, false, false); 11756 pw.println(sb.toString()); 11757 Bundle bundle = intents.get(i).getExtras(); 11758 if (bundle != null) { 11759 pw.print(" "); 11760 pw.println(bundle.toString()); 11761 } 11762 } 11763 } else { 11764 pw.println(""); 11765 } 11766 } 11767 } 11768 } 11769 11770 if (!onlyHistory && dumpAll) { 11771 pw.println(); 11772 for (BroadcastQueue queue : mBroadcastQueues) { 11773 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11774 + queue.mBroadcastsScheduled); 11775 } 11776 pw.println(" mHandler:"); 11777 mHandler.dump(new PrintWriterPrinter(pw), " "); 11778 needSep = true; 11779 printedAnything = true; 11780 } 11781 11782 if (!printedAnything) { 11783 pw.println(" (nothing)"); 11784 } 11785 } 11786 11787 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11788 int opti, boolean dumpAll, String dumpPackage) { 11789 boolean needSep; 11790 boolean printedAnything = false; 11791 11792 ItemMatcher matcher = new ItemMatcher(); 11793 matcher.build(args, opti); 11794 11795 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11796 11797 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11798 printedAnything |= needSep; 11799 11800 if (mLaunchingProviders.size() > 0) { 11801 boolean printed = false; 11802 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11803 ContentProviderRecord r = mLaunchingProviders.get(i); 11804 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11805 continue; 11806 } 11807 if (!printed) { 11808 if (needSep) pw.println(); 11809 needSep = true; 11810 pw.println(" Launching content providers:"); 11811 printed = true; 11812 printedAnything = true; 11813 } 11814 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11815 pw.println(r); 11816 } 11817 } 11818 11819 if (mGrantedUriPermissions.size() > 0) { 11820 boolean printed = false; 11821 int dumpUid = -2; 11822 if (dumpPackage != null) { 11823 try { 11824 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11825 } catch (NameNotFoundException e) { 11826 dumpUid = -1; 11827 } 11828 } 11829 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11830 int uid = mGrantedUriPermissions.keyAt(i); 11831 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11832 continue; 11833 } 11834 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11835 if (!printed) { 11836 if (needSep) pw.println(); 11837 needSep = true; 11838 pw.println(" Granted Uri Permissions:"); 11839 printed = true; 11840 printedAnything = true; 11841 } 11842 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11843 for (UriPermission perm : perms.values()) { 11844 pw.print(" "); pw.println(perm); 11845 if (dumpAll) { 11846 perm.dump(pw, " "); 11847 } 11848 } 11849 } 11850 } 11851 11852 if (!printedAnything) { 11853 pw.println(" (nothing)"); 11854 } 11855 } 11856 11857 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11858 int opti, boolean dumpAll, String dumpPackage) { 11859 boolean printed = false; 11860 11861 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11862 11863 if (mIntentSenderRecords.size() > 0) { 11864 Iterator<WeakReference<PendingIntentRecord>> it 11865 = mIntentSenderRecords.values().iterator(); 11866 while (it.hasNext()) { 11867 WeakReference<PendingIntentRecord> ref = it.next(); 11868 PendingIntentRecord rec = ref != null ? ref.get(): null; 11869 if (dumpPackage != null && (rec == null 11870 || !dumpPackage.equals(rec.key.packageName))) { 11871 continue; 11872 } 11873 printed = true; 11874 if (rec != null) { 11875 pw.print(" * "); pw.println(rec); 11876 if (dumpAll) { 11877 rec.dump(pw, " "); 11878 } 11879 } else { 11880 pw.print(" * "); pw.println(ref); 11881 } 11882 } 11883 } 11884 11885 if (!printed) { 11886 pw.println(" (nothing)"); 11887 } 11888 } 11889 11890 private static final int dumpProcessList(PrintWriter pw, 11891 ActivityManagerService service, List list, 11892 String prefix, String normalLabel, String persistentLabel, 11893 String dumpPackage) { 11894 int numPers = 0; 11895 final int N = list.size()-1; 11896 for (int i=N; i>=0; i--) { 11897 ProcessRecord r = (ProcessRecord)list.get(i); 11898 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11899 continue; 11900 } 11901 pw.println(String.format("%s%s #%2d: %s", 11902 prefix, (r.persistent ? persistentLabel : normalLabel), 11903 i, r.toString())); 11904 if (r.persistent) { 11905 numPers++; 11906 } 11907 } 11908 return numPers; 11909 } 11910 11911 private static final boolean dumpProcessOomList(PrintWriter pw, 11912 ActivityManagerService service, List<ProcessRecord> origList, 11913 String prefix, String normalLabel, String persistentLabel, 11914 boolean inclDetails, String dumpPackage) { 11915 11916 ArrayList<Pair<ProcessRecord, Integer>> list 11917 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11918 for (int i=0; i<origList.size(); i++) { 11919 ProcessRecord r = origList.get(i); 11920 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11921 continue; 11922 } 11923 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11924 } 11925 11926 if (list.size() <= 0) { 11927 return false; 11928 } 11929 11930 Comparator<Pair<ProcessRecord, Integer>> comparator 11931 = new Comparator<Pair<ProcessRecord, Integer>>() { 11932 @Override 11933 public int compare(Pair<ProcessRecord, Integer> object1, 11934 Pair<ProcessRecord, Integer> object2) { 11935 if (object1.first.setAdj != object2.first.setAdj) { 11936 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11937 } 11938 if (object1.second.intValue() != object2.second.intValue()) { 11939 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11940 } 11941 return 0; 11942 } 11943 }; 11944 11945 Collections.sort(list, comparator); 11946 11947 final long curRealtime = SystemClock.elapsedRealtime(); 11948 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11949 final long curUptime = SystemClock.uptimeMillis(); 11950 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11951 11952 for (int i=list.size()-1; i>=0; i--) { 11953 ProcessRecord r = list.get(i).first; 11954 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11955 char schedGroup; 11956 switch (r.setSchedGroup) { 11957 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11958 schedGroup = 'B'; 11959 break; 11960 case Process.THREAD_GROUP_DEFAULT: 11961 schedGroup = 'F'; 11962 break; 11963 default: 11964 schedGroup = '?'; 11965 break; 11966 } 11967 char foreground; 11968 if (r.foregroundActivities) { 11969 foreground = 'A'; 11970 } else if (r.foregroundServices) { 11971 foreground = 'S'; 11972 } else { 11973 foreground = ' '; 11974 } 11975 String procState = ProcessList.makeProcStateString(r.curProcState); 11976 pw.print(prefix); 11977 pw.print(r.persistent ? persistentLabel : normalLabel); 11978 pw.print(" #"); 11979 int num = (origList.size()-1)-list.get(i).second; 11980 if (num < 10) pw.print(' '); 11981 pw.print(num); 11982 pw.print(": "); 11983 pw.print(oomAdj); 11984 pw.print(' '); 11985 pw.print(schedGroup); 11986 pw.print('/'); 11987 pw.print(foreground); 11988 pw.print('/'); 11989 pw.print(procState); 11990 pw.print(" trm:"); 11991 if (r.trimMemoryLevel < 10) pw.print(' '); 11992 pw.print(r.trimMemoryLevel); 11993 pw.print(' '); 11994 pw.print(r.toShortString()); 11995 pw.print(" ("); 11996 pw.print(r.adjType); 11997 pw.println(')'); 11998 if (r.adjSource != null || r.adjTarget != null) { 11999 pw.print(prefix); 12000 pw.print(" "); 12001 if (r.adjTarget instanceof ComponentName) { 12002 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12003 } else if (r.adjTarget != null) { 12004 pw.print(r.adjTarget.toString()); 12005 } else { 12006 pw.print("{null}"); 12007 } 12008 pw.print("<="); 12009 if (r.adjSource instanceof ProcessRecord) { 12010 pw.print("Proc{"); 12011 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12012 pw.println("}"); 12013 } else if (r.adjSource != null) { 12014 pw.println(r.adjSource.toString()); 12015 } else { 12016 pw.println("{null}"); 12017 } 12018 } 12019 if (inclDetails) { 12020 pw.print(prefix); 12021 pw.print(" "); 12022 pw.print("oom: max="); pw.print(r.maxAdj); 12023 pw.print(" curRaw="); pw.print(r.curRawAdj); 12024 pw.print(" setRaw="); pw.print(r.setRawAdj); 12025 pw.print(" cur="); pw.print(r.curAdj); 12026 pw.print(" set="); pw.println(r.setAdj); 12027 pw.print(prefix); 12028 pw.print(" "); 12029 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12030 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12031 pw.print(" lastPss="); pw.print(r.lastPss); 12032 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12033 pw.print(prefix); 12034 pw.print(" "); 12035 pw.print("keeping="); pw.print(r.keeping); 12036 pw.print(" cached="); pw.print(r.cached); 12037 pw.print(" empty="); pw.print(r.empty); 12038 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12039 12040 if (!r.keeping) { 12041 if (r.lastWakeTime != 0) { 12042 long wtime; 12043 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12044 synchronized (stats) { 12045 wtime = stats.getProcessWakeTime(r.info.uid, 12046 r.pid, curRealtime); 12047 } 12048 long timeUsed = wtime - r.lastWakeTime; 12049 pw.print(prefix); 12050 pw.print(" "); 12051 pw.print("keep awake over "); 12052 TimeUtils.formatDuration(realtimeSince, pw); 12053 pw.print(" used "); 12054 TimeUtils.formatDuration(timeUsed, pw); 12055 pw.print(" ("); 12056 pw.print((timeUsed*100)/realtimeSince); 12057 pw.println("%)"); 12058 } 12059 if (r.lastCpuTime != 0) { 12060 long timeUsed = r.curCpuTime - r.lastCpuTime; 12061 pw.print(prefix); 12062 pw.print(" "); 12063 pw.print("run cpu over "); 12064 TimeUtils.formatDuration(uptimeSince, pw); 12065 pw.print(" used "); 12066 TimeUtils.formatDuration(timeUsed, pw); 12067 pw.print(" ("); 12068 pw.print((timeUsed*100)/uptimeSince); 12069 pw.println("%)"); 12070 } 12071 } 12072 } 12073 } 12074 return true; 12075 } 12076 12077 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12078 ArrayList<ProcessRecord> procs; 12079 synchronized (this) { 12080 if (args != null && args.length > start 12081 && args[start].charAt(0) != '-') { 12082 procs = new ArrayList<ProcessRecord>(); 12083 int pid = -1; 12084 try { 12085 pid = Integer.parseInt(args[start]); 12086 } catch (NumberFormatException e) { 12087 } 12088 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12089 ProcessRecord proc = mLruProcesses.get(i); 12090 if (proc.pid == pid) { 12091 procs.add(proc); 12092 } else if (proc.processName.equals(args[start])) { 12093 procs.add(proc); 12094 } 12095 } 12096 if (procs.size() <= 0) { 12097 return null; 12098 } 12099 } else { 12100 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12101 } 12102 } 12103 return procs; 12104 } 12105 12106 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12107 PrintWriter pw, String[] args) { 12108 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12109 if (procs == null) { 12110 pw.println("No process found for: " + args[0]); 12111 return; 12112 } 12113 12114 long uptime = SystemClock.uptimeMillis(); 12115 long realtime = SystemClock.elapsedRealtime(); 12116 pw.println("Applications Graphics Acceleration Info:"); 12117 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12118 12119 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12120 ProcessRecord r = procs.get(i); 12121 if (r.thread != null) { 12122 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12123 pw.flush(); 12124 try { 12125 TransferPipe tp = new TransferPipe(); 12126 try { 12127 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12128 tp.go(fd); 12129 } finally { 12130 tp.kill(); 12131 } 12132 } catch (IOException e) { 12133 pw.println("Failure while dumping the app: " + r); 12134 pw.flush(); 12135 } catch (RemoteException e) { 12136 pw.println("Got a RemoteException while dumping the app " + r); 12137 pw.flush(); 12138 } 12139 } 12140 } 12141 } 12142 12143 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12144 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12145 if (procs == null) { 12146 pw.println("No process found for: " + args[0]); 12147 return; 12148 } 12149 12150 pw.println("Applications Database Info:"); 12151 12152 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12153 ProcessRecord r = procs.get(i); 12154 if (r.thread != null) { 12155 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12156 pw.flush(); 12157 try { 12158 TransferPipe tp = new TransferPipe(); 12159 try { 12160 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12161 tp.go(fd); 12162 } finally { 12163 tp.kill(); 12164 } 12165 } catch (IOException e) { 12166 pw.println("Failure while dumping the app: " + r); 12167 pw.flush(); 12168 } catch (RemoteException e) { 12169 pw.println("Got a RemoteException while dumping the app " + r); 12170 pw.flush(); 12171 } 12172 } 12173 } 12174 } 12175 12176 final static class MemItem { 12177 final boolean isProc; 12178 final String label; 12179 final String shortLabel; 12180 final long pss; 12181 final int id; 12182 final boolean hasActivities; 12183 ArrayList<MemItem> subitems; 12184 12185 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12186 boolean _hasActivities) { 12187 isProc = true; 12188 label = _label; 12189 shortLabel = _shortLabel; 12190 pss = _pss; 12191 id = _id; 12192 hasActivities = _hasActivities; 12193 } 12194 12195 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12196 isProc = false; 12197 label = _label; 12198 shortLabel = _shortLabel; 12199 pss = _pss; 12200 id = _id; 12201 hasActivities = false; 12202 } 12203 } 12204 12205 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12206 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12207 if (sort && !isCompact) { 12208 Collections.sort(items, new Comparator<MemItem>() { 12209 @Override 12210 public int compare(MemItem lhs, MemItem rhs) { 12211 if (lhs.pss < rhs.pss) { 12212 return 1; 12213 } else if (lhs.pss > rhs.pss) { 12214 return -1; 12215 } 12216 return 0; 12217 } 12218 }); 12219 } 12220 12221 for (int i=0; i<items.size(); i++) { 12222 MemItem mi = items.get(i); 12223 if (!isCompact) { 12224 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12225 } else if (mi.isProc) { 12226 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12227 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12228 pw.println(mi.hasActivities ? ",a" : ",e"); 12229 } else { 12230 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12231 pw.println(mi.pss); 12232 } 12233 if (mi.subitems != null) { 12234 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12235 true, isCompact); 12236 } 12237 } 12238 } 12239 12240 // These are in KB. 12241 static final long[] DUMP_MEM_BUCKETS = new long[] { 12242 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12243 120*1024, 160*1024, 200*1024, 12244 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12245 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12246 }; 12247 12248 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12249 boolean stackLike) { 12250 int start = label.lastIndexOf('.'); 12251 if (start >= 0) start++; 12252 else start = 0; 12253 int end = label.length(); 12254 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12255 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12256 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12257 out.append(bucket); 12258 out.append(stackLike ? "MB." : "MB "); 12259 out.append(label, start, end); 12260 return; 12261 } 12262 } 12263 out.append(memKB/1024); 12264 out.append(stackLike ? "MB." : "MB "); 12265 out.append(label, start, end); 12266 } 12267 12268 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12269 ProcessList.NATIVE_ADJ, 12270 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12271 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12272 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12273 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12274 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12275 }; 12276 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12277 "Native", 12278 "System", "Persistent", "Foreground", 12279 "Visible", "Perceptible", 12280 "Heavy Weight", "Backup", 12281 "A Services", "Home", 12282 "Previous", "B Services", "Cached" 12283 }; 12284 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12285 "native", 12286 "sys", "pers", "fore", 12287 "vis", "percept", 12288 "heavy", "backup", 12289 "servicea", "home", 12290 "prev", "serviceb", "cached" 12291 }; 12292 12293 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12294 long realtime, boolean isCheckinRequest, boolean isCompact) { 12295 if (isCheckinRequest || isCompact) { 12296 // short checkin version 12297 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12298 } else { 12299 pw.println("Applications Memory Usage (kB):"); 12300 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12301 } 12302 } 12303 12304 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12305 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12306 boolean dumpDetails = false; 12307 boolean dumpFullDetails = false; 12308 boolean dumpDalvik = false; 12309 boolean oomOnly = false; 12310 boolean isCompact = false; 12311 boolean localOnly = false; 12312 12313 int opti = 0; 12314 while (opti < args.length) { 12315 String opt = args[opti]; 12316 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12317 break; 12318 } 12319 opti++; 12320 if ("-a".equals(opt)) { 12321 dumpDetails = true; 12322 dumpFullDetails = true; 12323 dumpDalvik = true; 12324 } else if ("-d".equals(opt)) { 12325 dumpDalvik = true; 12326 } else if ("-c".equals(opt)) { 12327 isCompact = true; 12328 } else if ("--oom".equals(opt)) { 12329 oomOnly = true; 12330 } else if ("--local".equals(opt)) { 12331 localOnly = true; 12332 } else if ("-h".equals(opt)) { 12333 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12334 pw.println(" -a: include all available information for each process."); 12335 pw.println(" -d: include dalvik details when dumping process details."); 12336 pw.println(" -c: dump in a compact machine-parseable representation."); 12337 pw.println(" --oom: only show processes organized by oom adj."); 12338 pw.println(" --local: only collect details locally, don't call process."); 12339 pw.println("If [process] is specified it can be the name or "); 12340 pw.println("pid of a specific process to dump."); 12341 return; 12342 } else { 12343 pw.println("Unknown argument: " + opt + "; use -h for help"); 12344 } 12345 } 12346 12347 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12348 long uptime = SystemClock.uptimeMillis(); 12349 long realtime = SystemClock.elapsedRealtime(); 12350 final long[] tmpLong = new long[1]; 12351 12352 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12353 if (procs == null) { 12354 // No Java processes. Maybe they want to print a native process. 12355 if (args != null && args.length > opti 12356 && args[opti].charAt(0) != '-') { 12357 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12358 = new ArrayList<ProcessCpuTracker.Stats>(); 12359 updateCpuStatsNow(); 12360 int findPid = -1; 12361 try { 12362 findPid = Integer.parseInt(args[opti]); 12363 } catch (NumberFormatException e) { 12364 } 12365 synchronized (mProcessCpuThread) { 12366 final int N = mProcessCpuTracker.countStats(); 12367 for (int i=0; i<N; i++) { 12368 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12369 if (st.pid == findPid || (st.baseName != null 12370 && st.baseName.equals(args[opti]))) { 12371 nativeProcs.add(st); 12372 } 12373 } 12374 } 12375 if (nativeProcs.size() > 0) { 12376 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12377 isCompact); 12378 Debug.MemoryInfo mi = null; 12379 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12380 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12381 final int pid = r.pid; 12382 if (!isCheckinRequest && dumpDetails) { 12383 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12384 } 12385 if (mi == null) { 12386 mi = new Debug.MemoryInfo(); 12387 } 12388 if (dumpDetails || (!brief && !oomOnly)) { 12389 Debug.getMemoryInfo(pid, mi); 12390 } else { 12391 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12392 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12393 } 12394 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12395 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12396 if (isCheckinRequest) { 12397 pw.println(); 12398 } 12399 } 12400 return; 12401 } 12402 } 12403 pw.println("No process found for: " + args[opti]); 12404 return; 12405 } 12406 12407 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12408 dumpDetails = true; 12409 } 12410 12411 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12412 12413 String[] innerArgs = new String[args.length-opti]; 12414 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12415 12416 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12417 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12418 long nativePss=0, dalvikPss=0, otherPss=0; 12419 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12420 12421 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12422 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12423 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12424 12425 long totalPss = 0; 12426 long cachedPss = 0; 12427 12428 Debug.MemoryInfo mi = null; 12429 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12430 final ProcessRecord r = procs.get(i); 12431 final IApplicationThread thread; 12432 final int pid; 12433 final int oomAdj; 12434 final boolean hasActivities; 12435 synchronized (this) { 12436 thread = r.thread; 12437 pid = r.pid; 12438 oomAdj = r.getSetAdjWithServices(); 12439 hasActivities = r.activities.size() > 0; 12440 } 12441 if (thread != null) { 12442 if (!isCheckinRequest && dumpDetails) { 12443 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12444 } 12445 if (mi == null) { 12446 mi = new Debug.MemoryInfo(); 12447 } 12448 if (dumpDetails || (!brief && !oomOnly)) { 12449 Debug.getMemoryInfo(pid, mi); 12450 } else { 12451 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12452 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12453 } 12454 if (dumpDetails) { 12455 if (localOnly) { 12456 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12457 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12458 if (isCheckinRequest) { 12459 pw.println(); 12460 } 12461 } else { 12462 try { 12463 pw.flush(); 12464 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12465 dumpDalvik, innerArgs); 12466 } catch (RemoteException e) { 12467 if (!isCheckinRequest) { 12468 pw.println("Got RemoteException!"); 12469 pw.flush(); 12470 } 12471 } 12472 } 12473 } 12474 12475 final long myTotalPss = mi.getTotalPss(); 12476 final long myTotalUss = mi.getTotalUss(); 12477 12478 synchronized (this) { 12479 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12480 // Record this for posterity if the process has been stable. 12481 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12482 } 12483 } 12484 12485 if (!isCheckinRequest && mi != null) { 12486 totalPss += myTotalPss; 12487 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12488 (hasActivities ? " / activities)" : ")"), 12489 r.processName, myTotalPss, pid, hasActivities); 12490 procMems.add(pssItem); 12491 procMemsMap.put(pid, pssItem); 12492 12493 nativePss += mi.nativePss; 12494 dalvikPss += mi.dalvikPss; 12495 otherPss += mi.otherPss; 12496 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12497 long mem = mi.getOtherPss(j); 12498 miscPss[j] += mem; 12499 otherPss -= mem; 12500 } 12501 12502 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12503 cachedPss += myTotalPss; 12504 } 12505 12506 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12507 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12508 || oomIndex == (oomPss.length-1)) { 12509 oomPss[oomIndex] += myTotalPss; 12510 if (oomProcs[oomIndex] == null) { 12511 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12512 } 12513 oomProcs[oomIndex].add(pssItem); 12514 break; 12515 } 12516 } 12517 } 12518 } 12519 } 12520 12521 if (!isCheckinRequest && procs.size() > 1) { 12522 // If we are showing aggregations, also look for native processes to 12523 // include so that our aggregations are more accurate. 12524 updateCpuStatsNow(); 12525 synchronized (mProcessCpuThread) { 12526 final int N = mProcessCpuTracker.countStats(); 12527 for (int i=0; i<N; i++) { 12528 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12529 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12530 if (mi == null) { 12531 mi = new Debug.MemoryInfo(); 12532 } 12533 if (!brief && !oomOnly) { 12534 Debug.getMemoryInfo(st.pid, mi); 12535 } else { 12536 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12537 mi.nativePrivateDirty = (int)tmpLong[0]; 12538 } 12539 12540 final long myTotalPss = mi.getTotalPss(); 12541 totalPss += myTotalPss; 12542 12543 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12544 st.name, myTotalPss, st.pid, false); 12545 procMems.add(pssItem); 12546 12547 nativePss += mi.nativePss; 12548 dalvikPss += mi.dalvikPss; 12549 otherPss += mi.otherPss; 12550 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12551 long mem = mi.getOtherPss(j); 12552 miscPss[j] += mem; 12553 otherPss -= mem; 12554 } 12555 oomPss[0] += myTotalPss; 12556 if (oomProcs[0] == null) { 12557 oomProcs[0] = new ArrayList<MemItem>(); 12558 } 12559 oomProcs[0].add(pssItem); 12560 } 12561 } 12562 } 12563 12564 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12565 12566 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12567 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12568 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12569 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12570 String label = Debug.MemoryInfo.getOtherLabel(j); 12571 catMems.add(new MemItem(label, label, miscPss[j], j)); 12572 } 12573 12574 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12575 for (int j=0; j<oomPss.length; j++) { 12576 if (oomPss[j] != 0) { 12577 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12578 : DUMP_MEM_OOM_LABEL[j]; 12579 MemItem item = new MemItem(label, label, oomPss[j], 12580 DUMP_MEM_OOM_ADJ[j]); 12581 item.subitems = oomProcs[j]; 12582 oomMems.add(item); 12583 } 12584 } 12585 12586 if (!brief && !oomOnly && !isCompact) { 12587 pw.println(); 12588 pw.println("Total PSS by process:"); 12589 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12590 pw.println(); 12591 } 12592 if (!isCompact) { 12593 pw.println("Total PSS by OOM adjustment:"); 12594 } 12595 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12596 if (!brief && !oomOnly) { 12597 PrintWriter out = categoryPw != null ? categoryPw : pw; 12598 if (!isCompact) { 12599 out.println(); 12600 out.println("Total PSS by category:"); 12601 } 12602 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12603 } 12604 if (!isCompact) { 12605 pw.println(); 12606 } 12607 MemInfoReader memInfo = new MemInfoReader(); 12608 memInfo.readMemInfo(); 12609 if (!brief) { 12610 if (!isCompact) { 12611 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12612 pw.print(" kB (status "); 12613 switch (mLastMemoryLevel) { 12614 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12615 pw.println("normal)"); 12616 break; 12617 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12618 pw.println("moderate)"); 12619 break; 12620 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12621 pw.println("low)"); 12622 break; 12623 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12624 pw.println("critical)"); 12625 break; 12626 default: 12627 pw.print(mLastMemoryLevel); 12628 pw.println(")"); 12629 break; 12630 } 12631 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12632 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12633 pw.print(cachedPss); pw.print(" cached pss + "); 12634 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12635 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12636 } else { 12637 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12638 pw.print(cachedPss + memInfo.getCachedSizeKb() 12639 + memInfo.getFreeSizeKb()); pw.print(","); 12640 pw.println(totalPss - cachedPss); 12641 } 12642 } 12643 if (!isCompact) { 12644 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12645 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12646 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12647 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12648 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12649 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12650 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12651 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12652 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12653 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12654 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12655 } 12656 if (!brief) { 12657 if (memInfo.getZramTotalSizeKb() != 0) { 12658 if (!isCompact) { 12659 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12660 pw.print(" kB physical used for "); 12661 pw.print(memInfo.getSwapTotalSizeKb() 12662 - memInfo.getSwapFreeSizeKb()); 12663 pw.print(" kB in swap ("); 12664 pw.print(memInfo.getSwapTotalSizeKb()); 12665 pw.println(" kB total swap)"); 12666 } else { 12667 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12668 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12669 pw.println(memInfo.getSwapFreeSizeKb()); 12670 } 12671 } 12672 final int[] SINGLE_LONG_FORMAT = new int[] { 12673 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12674 }; 12675 long[] longOut = new long[1]; 12676 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12677 SINGLE_LONG_FORMAT, null, longOut, null); 12678 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12679 longOut[0] = 0; 12680 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12681 SINGLE_LONG_FORMAT, null, longOut, null); 12682 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12683 longOut[0] = 0; 12684 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12685 SINGLE_LONG_FORMAT, null, longOut, null); 12686 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12687 longOut[0] = 0; 12688 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12689 SINGLE_LONG_FORMAT, null, longOut, null); 12690 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12691 if (!isCompact) { 12692 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12693 pw.print(" KSM: "); pw.print(sharing); 12694 pw.print(" kB saved from shared "); 12695 pw.print(shared); pw.println(" kB"); 12696 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12697 pw.print(voltile); pw.println(" kB volatile"); 12698 } 12699 pw.print(" Tuning: "); 12700 pw.print(ActivityManager.staticGetMemoryClass()); 12701 pw.print(" (large "); 12702 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12703 pw.print("), oom "); 12704 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12705 pw.print(" kB"); 12706 pw.print(", restore limit "); 12707 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12708 pw.print(" kB"); 12709 if (ActivityManager.isLowRamDeviceStatic()) { 12710 pw.print(" (low-ram)"); 12711 } 12712 if (ActivityManager.isHighEndGfx()) { 12713 pw.print(" (high-end-gfx)"); 12714 } 12715 pw.println(); 12716 } else { 12717 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12718 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12719 pw.println(voltile); 12720 pw.print("tuning,"); 12721 pw.print(ActivityManager.staticGetMemoryClass()); 12722 pw.print(','); 12723 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12724 pw.print(','); 12725 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12726 if (ActivityManager.isLowRamDeviceStatic()) { 12727 pw.print(",low-ram"); 12728 } 12729 if (ActivityManager.isHighEndGfx()) { 12730 pw.print(",high-end-gfx"); 12731 } 12732 pw.println(); 12733 } 12734 } 12735 } 12736 } 12737 12738 /** 12739 * Searches array of arguments for the specified string 12740 * @param args array of argument strings 12741 * @param value value to search for 12742 * @return true if the value is contained in the array 12743 */ 12744 private static boolean scanArgs(String[] args, String value) { 12745 if (args != null) { 12746 for (String arg : args) { 12747 if (value.equals(arg)) { 12748 return true; 12749 } 12750 } 12751 } 12752 return false; 12753 } 12754 12755 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12756 ContentProviderRecord cpr, boolean always) { 12757 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12758 12759 if (!inLaunching || always) { 12760 synchronized (cpr) { 12761 cpr.launchingApp = null; 12762 cpr.notifyAll(); 12763 } 12764 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12765 String names[] = cpr.info.authority.split(";"); 12766 for (int j = 0; j < names.length; j++) { 12767 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12768 } 12769 } 12770 12771 for (int i=0; i<cpr.connections.size(); i++) { 12772 ContentProviderConnection conn = cpr.connections.get(i); 12773 if (conn.waiting) { 12774 // If this connection is waiting for the provider, then we don't 12775 // need to mess with its process unless we are always removing 12776 // or for some reason the provider is not currently launching. 12777 if (inLaunching && !always) { 12778 continue; 12779 } 12780 } 12781 ProcessRecord capp = conn.client; 12782 conn.dead = true; 12783 if (conn.stableCount > 0) { 12784 if (!capp.persistent && capp.thread != null 12785 && capp.pid != 0 12786 && capp.pid != MY_PID) { 12787 killUnneededProcessLocked(capp, "depends on provider " 12788 + cpr.name.flattenToShortString() 12789 + " in dying proc " + (proc != null ? proc.processName : "??")); 12790 } 12791 } else if (capp.thread != null && conn.provider.provider != null) { 12792 try { 12793 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12794 } catch (RemoteException e) { 12795 } 12796 // In the protocol here, we don't expect the client to correctly 12797 // clean up this connection, we'll just remove it. 12798 cpr.connections.remove(i); 12799 conn.client.conProviders.remove(conn); 12800 } 12801 } 12802 12803 if (inLaunching && always) { 12804 mLaunchingProviders.remove(cpr); 12805 } 12806 return inLaunching; 12807 } 12808 12809 /** 12810 * Main code for cleaning up a process when it has gone away. This is 12811 * called both as a result of the process dying, or directly when stopping 12812 * a process when running in single process mode. 12813 */ 12814 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12815 boolean restarting, boolean allowRestart, int index) { 12816 if (index >= 0) { 12817 removeLruProcessLocked(app); 12818 ProcessList.remove(app.pid); 12819 } 12820 12821 mProcessesToGc.remove(app); 12822 mPendingPssProcesses.remove(app); 12823 12824 // Dismiss any open dialogs. 12825 if (app.crashDialog != null && !app.forceCrashReport) { 12826 app.crashDialog.dismiss(); 12827 app.crashDialog = null; 12828 } 12829 if (app.anrDialog != null) { 12830 app.anrDialog.dismiss(); 12831 app.anrDialog = null; 12832 } 12833 if (app.waitDialog != null) { 12834 app.waitDialog.dismiss(); 12835 app.waitDialog = null; 12836 } 12837 12838 app.crashing = false; 12839 app.notResponding = false; 12840 12841 app.resetPackageList(mProcessStats); 12842 app.unlinkDeathRecipient(); 12843 app.makeInactive(mProcessStats); 12844 app.forcingToForeground = null; 12845 updateProcessForegroundLocked(app, false, false); 12846 app.foregroundActivities = false; 12847 app.hasShownUi = false; 12848 app.treatLikeActivity = false; 12849 app.hasAboveClient = false; 12850 app.hasClientActivities = false; 12851 12852 mServices.killServicesLocked(app, allowRestart); 12853 12854 boolean restart = false; 12855 12856 // Remove published content providers. 12857 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12858 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12859 final boolean always = app.bad || !allowRestart; 12860 if (removeDyingProviderLocked(app, cpr, always) || always) { 12861 // We left the provider in the launching list, need to 12862 // restart it. 12863 restart = true; 12864 } 12865 12866 cpr.provider = null; 12867 cpr.proc = null; 12868 } 12869 app.pubProviders.clear(); 12870 12871 // Take care of any launching providers waiting for this process. 12872 if (checkAppInLaunchingProvidersLocked(app, false)) { 12873 restart = true; 12874 } 12875 12876 // Unregister from connected content providers. 12877 if (!app.conProviders.isEmpty()) { 12878 for (int i=0; i<app.conProviders.size(); i++) { 12879 ContentProviderConnection conn = app.conProviders.get(i); 12880 conn.provider.connections.remove(conn); 12881 } 12882 app.conProviders.clear(); 12883 } 12884 12885 // At this point there may be remaining entries in mLaunchingProviders 12886 // where we were the only one waiting, so they are no longer of use. 12887 // Look for these and clean up if found. 12888 // XXX Commented out for now. Trying to figure out a way to reproduce 12889 // the actual situation to identify what is actually going on. 12890 if (false) { 12891 for (int i=0; i<mLaunchingProviders.size(); i++) { 12892 ContentProviderRecord cpr = (ContentProviderRecord) 12893 mLaunchingProviders.get(i); 12894 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12895 synchronized (cpr) { 12896 cpr.launchingApp = null; 12897 cpr.notifyAll(); 12898 } 12899 } 12900 } 12901 } 12902 12903 skipCurrentReceiverLocked(app); 12904 12905 // Unregister any receivers. 12906 for (int i=app.receivers.size()-1; i>=0; i--) { 12907 removeReceiverLocked(app.receivers.valueAt(i)); 12908 } 12909 app.receivers.clear(); 12910 12911 // If the app is undergoing backup, tell the backup manager about it 12912 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12913 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12914 + mBackupTarget.appInfo + " died during backup"); 12915 try { 12916 IBackupManager bm = IBackupManager.Stub.asInterface( 12917 ServiceManager.getService(Context.BACKUP_SERVICE)); 12918 bm.agentDisconnected(app.info.packageName); 12919 } catch (RemoteException e) { 12920 // can't happen; backup manager is local 12921 } 12922 } 12923 12924 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12925 ProcessChangeItem item = mPendingProcessChanges.get(i); 12926 if (item.pid == app.pid) { 12927 mPendingProcessChanges.remove(i); 12928 mAvailProcessChanges.add(item); 12929 } 12930 } 12931 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12932 12933 // If the caller is restarting this app, then leave it in its 12934 // current lists and let the caller take care of it. 12935 if (restarting) { 12936 return; 12937 } 12938 12939 if (!app.persistent || app.isolated) { 12940 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12941 "Removing non-persistent process during cleanup: " + app); 12942 mProcessNames.remove(app.processName, app.uid); 12943 mIsolatedProcesses.remove(app.uid); 12944 if (mHeavyWeightProcess == app) { 12945 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12946 mHeavyWeightProcess.userId, 0)); 12947 mHeavyWeightProcess = null; 12948 } 12949 } else if (!app.removed) { 12950 // This app is persistent, so we need to keep its record around. 12951 // If it is not already on the pending app list, add it there 12952 // and start a new process for it. 12953 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12954 mPersistentStartingProcesses.add(app); 12955 restart = true; 12956 } 12957 } 12958 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12959 "Clean-up removing on hold: " + app); 12960 mProcessesOnHold.remove(app); 12961 12962 if (app == mHomeProcess) { 12963 mHomeProcess = null; 12964 } 12965 if (app == mPreviousProcess) { 12966 mPreviousProcess = null; 12967 } 12968 12969 if (restart && !app.isolated) { 12970 // We have components that still need to be running in the 12971 // process, so re-launch it. 12972 mProcessNames.put(app.processName, app.uid, app); 12973 startProcessLocked(app, "restart", app.processName); 12974 } else if (app.pid > 0 && app.pid != MY_PID) { 12975 // Goodbye! 12976 boolean removed; 12977 synchronized (mPidsSelfLocked) { 12978 mPidsSelfLocked.remove(app.pid); 12979 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12980 } 12981 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12982 app.processName, app.info.uid); 12983 if (app.isolated) { 12984 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12985 } 12986 app.setPid(0); 12987 } 12988 } 12989 12990 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12991 // Look through the content providers we are waiting to have launched, 12992 // and if any run in this process then either schedule a restart of 12993 // the process or kill the client waiting for it if this process has 12994 // gone bad. 12995 int NL = mLaunchingProviders.size(); 12996 boolean restart = false; 12997 for (int i=0; i<NL; i++) { 12998 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12999 if (cpr.launchingApp == app) { 13000 if (!alwaysBad && !app.bad) { 13001 restart = true; 13002 } else { 13003 removeDyingProviderLocked(app, cpr, true); 13004 // cpr should have been removed from mLaunchingProviders 13005 NL = mLaunchingProviders.size(); 13006 i--; 13007 } 13008 } 13009 } 13010 return restart; 13011 } 13012 13013 // ========================================================= 13014 // SERVICES 13015 // ========================================================= 13016 13017 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13018 int flags) { 13019 enforceNotIsolatedCaller("getServices"); 13020 synchronized (this) { 13021 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13022 } 13023 } 13024 13025 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13026 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13027 synchronized (this) { 13028 return mServices.getRunningServiceControlPanelLocked(name); 13029 } 13030 } 13031 13032 public ComponentName startService(IApplicationThread caller, Intent service, 13033 String resolvedType, int userId) { 13034 enforceNotIsolatedCaller("startService"); 13035 // Refuse possible leaked file descriptors 13036 if (service != null && service.hasFileDescriptors() == true) { 13037 throw new IllegalArgumentException("File descriptors passed in Intent"); 13038 } 13039 13040 if (DEBUG_SERVICE) 13041 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13042 synchronized(this) { 13043 final int callingPid = Binder.getCallingPid(); 13044 final int callingUid = Binder.getCallingUid(); 13045 final long origId = Binder.clearCallingIdentity(); 13046 ComponentName res = mServices.startServiceLocked(caller, service, 13047 resolvedType, callingPid, callingUid, userId); 13048 Binder.restoreCallingIdentity(origId); 13049 return res; 13050 } 13051 } 13052 13053 ComponentName startServiceInPackage(int uid, 13054 Intent service, String resolvedType, int userId) { 13055 synchronized(this) { 13056 if (DEBUG_SERVICE) 13057 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13058 final long origId = Binder.clearCallingIdentity(); 13059 ComponentName res = mServices.startServiceLocked(null, service, 13060 resolvedType, -1, uid, userId); 13061 Binder.restoreCallingIdentity(origId); 13062 return res; 13063 } 13064 } 13065 13066 public int stopService(IApplicationThread caller, Intent service, 13067 String resolvedType, int userId) { 13068 enforceNotIsolatedCaller("stopService"); 13069 // Refuse possible leaked file descriptors 13070 if (service != null && service.hasFileDescriptors() == true) { 13071 throw new IllegalArgumentException("File descriptors passed in Intent"); 13072 } 13073 13074 synchronized(this) { 13075 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13076 } 13077 } 13078 13079 public IBinder peekService(Intent service, String resolvedType) { 13080 enforceNotIsolatedCaller("peekService"); 13081 // Refuse possible leaked file descriptors 13082 if (service != null && service.hasFileDescriptors() == true) { 13083 throw new IllegalArgumentException("File descriptors passed in Intent"); 13084 } 13085 synchronized(this) { 13086 return mServices.peekServiceLocked(service, resolvedType); 13087 } 13088 } 13089 13090 public boolean stopServiceToken(ComponentName className, IBinder token, 13091 int startId) { 13092 synchronized(this) { 13093 return mServices.stopServiceTokenLocked(className, token, startId); 13094 } 13095 } 13096 13097 public void setServiceForeground(ComponentName className, IBinder token, 13098 int id, Notification notification, boolean removeNotification) { 13099 synchronized(this) { 13100 mServices.setServiceForegroundLocked(className, token, id, notification, 13101 removeNotification); 13102 } 13103 } 13104 13105 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13106 boolean requireFull, String name, String callerPackage) { 13107 final int callingUserId = UserHandle.getUserId(callingUid); 13108 if (callingUserId != userId) { 13109 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13110 if ((requireFull || checkComponentPermission( 13111 android.Manifest.permission.INTERACT_ACROSS_USERS, 13112 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13113 && checkComponentPermission( 13114 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13115 callingPid, callingUid, -1, true) 13116 != PackageManager.PERMISSION_GRANTED) { 13117 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13118 // In this case, they would like to just execute as their 13119 // owner user instead of failing. 13120 userId = callingUserId; 13121 } else { 13122 StringBuilder builder = new StringBuilder(128); 13123 builder.append("Permission Denial: "); 13124 builder.append(name); 13125 if (callerPackage != null) { 13126 builder.append(" from "); 13127 builder.append(callerPackage); 13128 } 13129 builder.append(" asks to run as user "); 13130 builder.append(userId); 13131 builder.append(" but is calling from user "); 13132 builder.append(UserHandle.getUserId(callingUid)); 13133 builder.append("; this requires "); 13134 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13135 if (!requireFull) { 13136 builder.append(" or "); 13137 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13138 } 13139 String msg = builder.toString(); 13140 Slog.w(TAG, msg); 13141 throw new SecurityException(msg); 13142 } 13143 } 13144 } 13145 if (userId == UserHandle.USER_CURRENT 13146 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13147 // Note that we may be accessing this outside of a lock... 13148 // shouldn't be a big deal, if this is being called outside 13149 // of a locked context there is intrinsically a race with 13150 // the value the caller will receive and someone else changing it. 13151 userId = mCurrentUserId; 13152 } 13153 if (!allowAll && userId < 0) { 13154 throw new IllegalArgumentException( 13155 "Call does not support special user #" + userId); 13156 } 13157 } 13158 return userId; 13159 } 13160 13161 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13162 String className, int flags) { 13163 boolean result = false; 13164 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13165 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13166 if (ActivityManager.checkUidPermission( 13167 android.Manifest.permission.INTERACT_ACROSS_USERS, 13168 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13169 ComponentName comp = new ComponentName(aInfo.packageName, className); 13170 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13171 + " requests FLAG_SINGLE_USER, but app does not hold " 13172 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13173 Slog.w(TAG, msg); 13174 throw new SecurityException(msg); 13175 } 13176 result = true; 13177 } 13178 } else if (componentProcessName == aInfo.packageName) { 13179 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13180 } else if ("system".equals(componentProcessName)) { 13181 result = true; 13182 } 13183 if (DEBUG_MU) { 13184 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13185 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13186 } 13187 return result; 13188 } 13189 13190 public int bindService(IApplicationThread caller, IBinder token, 13191 Intent service, String resolvedType, 13192 IServiceConnection connection, int flags, int userId) { 13193 enforceNotIsolatedCaller("bindService"); 13194 // Refuse possible leaked file descriptors 13195 if (service != null && service.hasFileDescriptors() == true) { 13196 throw new IllegalArgumentException("File descriptors passed in Intent"); 13197 } 13198 13199 synchronized(this) { 13200 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13201 connection, flags, userId); 13202 } 13203 } 13204 13205 public boolean unbindService(IServiceConnection connection) { 13206 synchronized (this) { 13207 return mServices.unbindServiceLocked(connection); 13208 } 13209 } 13210 13211 public void publishService(IBinder token, Intent intent, IBinder service) { 13212 // Refuse possible leaked file descriptors 13213 if (intent != null && intent.hasFileDescriptors() == true) { 13214 throw new IllegalArgumentException("File descriptors passed in Intent"); 13215 } 13216 13217 synchronized(this) { 13218 if (!(token instanceof ServiceRecord)) { 13219 throw new IllegalArgumentException("Invalid service token"); 13220 } 13221 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13222 } 13223 } 13224 13225 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13226 // Refuse possible leaked file descriptors 13227 if (intent != null && intent.hasFileDescriptors() == true) { 13228 throw new IllegalArgumentException("File descriptors passed in Intent"); 13229 } 13230 13231 synchronized(this) { 13232 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13233 } 13234 } 13235 13236 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13237 synchronized(this) { 13238 if (!(token instanceof ServiceRecord)) { 13239 throw new IllegalArgumentException("Invalid service token"); 13240 } 13241 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13242 } 13243 } 13244 13245 // ========================================================= 13246 // BACKUP AND RESTORE 13247 // ========================================================= 13248 13249 // Cause the target app to be launched if necessary and its backup agent 13250 // instantiated. The backup agent will invoke backupAgentCreated() on the 13251 // activity manager to announce its creation. 13252 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13253 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13254 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13255 13256 synchronized(this) { 13257 // !!! TODO: currently no check here that we're already bound 13258 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13259 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13260 synchronized (stats) { 13261 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13262 } 13263 13264 // Backup agent is now in use, its package can't be stopped. 13265 try { 13266 AppGlobals.getPackageManager().setPackageStoppedState( 13267 app.packageName, false, UserHandle.getUserId(app.uid)); 13268 } catch (RemoteException e) { 13269 } catch (IllegalArgumentException e) { 13270 Slog.w(TAG, "Failed trying to unstop package " 13271 + app.packageName + ": " + e); 13272 } 13273 13274 BackupRecord r = new BackupRecord(ss, app, backupMode); 13275 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13276 ? new ComponentName(app.packageName, app.backupAgentName) 13277 : new ComponentName("android", "FullBackupAgent"); 13278 // startProcessLocked() returns existing proc's record if it's already running 13279 ProcessRecord proc = startProcessLocked(app.processName, app, 13280 false, 0, "backup", hostingName, false, false, false); 13281 if (proc == null) { 13282 Slog.e(TAG, "Unable to start backup agent process " + r); 13283 return false; 13284 } 13285 13286 r.app = proc; 13287 mBackupTarget = r; 13288 mBackupAppName = app.packageName; 13289 13290 // Try not to kill the process during backup 13291 updateOomAdjLocked(proc); 13292 13293 // If the process is already attached, schedule the creation of the backup agent now. 13294 // If it is not yet live, this will be done when it attaches to the framework. 13295 if (proc.thread != null) { 13296 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13297 try { 13298 proc.thread.scheduleCreateBackupAgent(app, 13299 compatibilityInfoForPackageLocked(app), backupMode); 13300 } catch (RemoteException e) { 13301 // Will time out on the backup manager side 13302 } 13303 } else { 13304 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13305 } 13306 // Invariants: at this point, the target app process exists and the application 13307 // is either already running or in the process of coming up. mBackupTarget and 13308 // mBackupAppName describe the app, so that when it binds back to the AM we 13309 // know that it's scheduled for a backup-agent operation. 13310 } 13311 13312 return true; 13313 } 13314 13315 @Override 13316 public void clearPendingBackup() { 13317 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13318 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13319 13320 synchronized (this) { 13321 mBackupTarget = null; 13322 mBackupAppName = null; 13323 } 13324 } 13325 13326 // A backup agent has just come up 13327 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13328 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13329 + " = " + agent); 13330 13331 synchronized(this) { 13332 if (!agentPackageName.equals(mBackupAppName)) { 13333 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13334 return; 13335 } 13336 } 13337 13338 long oldIdent = Binder.clearCallingIdentity(); 13339 try { 13340 IBackupManager bm = IBackupManager.Stub.asInterface( 13341 ServiceManager.getService(Context.BACKUP_SERVICE)); 13342 bm.agentConnected(agentPackageName, agent); 13343 } catch (RemoteException e) { 13344 // can't happen; the backup manager service is local 13345 } catch (Exception e) { 13346 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13347 e.printStackTrace(); 13348 } finally { 13349 Binder.restoreCallingIdentity(oldIdent); 13350 } 13351 } 13352 13353 // done with this agent 13354 public void unbindBackupAgent(ApplicationInfo appInfo) { 13355 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13356 if (appInfo == null) { 13357 Slog.w(TAG, "unbind backup agent for null app"); 13358 return; 13359 } 13360 13361 synchronized(this) { 13362 try { 13363 if (mBackupAppName == null) { 13364 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13365 return; 13366 } 13367 13368 if (!mBackupAppName.equals(appInfo.packageName)) { 13369 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13370 return; 13371 } 13372 13373 // Not backing this app up any more; reset its OOM adjustment 13374 final ProcessRecord proc = mBackupTarget.app; 13375 updateOomAdjLocked(proc); 13376 13377 // If the app crashed during backup, 'thread' will be null here 13378 if (proc.thread != null) { 13379 try { 13380 proc.thread.scheduleDestroyBackupAgent(appInfo, 13381 compatibilityInfoForPackageLocked(appInfo)); 13382 } catch (Exception e) { 13383 Slog.e(TAG, "Exception when unbinding backup agent:"); 13384 e.printStackTrace(); 13385 } 13386 } 13387 } finally { 13388 mBackupTarget = null; 13389 mBackupAppName = null; 13390 } 13391 } 13392 } 13393 // ========================================================= 13394 // BROADCASTS 13395 // ========================================================= 13396 13397 private final List getStickiesLocked(String action, IntentFilter filter, 13398 List cur, int userId) { 13399 final ContentResolver resolver = mContext.getContentResolver(); 13400 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13401 if (stickies == null) { 13402 return cur; 13403 } 13404 final ArrayList<Intent> list = stickies.get(action); 13405 if (list == null) { 13406 return cur; 13407 } 13408 int N = list.size(); 13409 for (int i=0; i<N; i++) { 13410 Intent intent = list.get(i); 13411 if (filter.match(resolver, intent, true, TAG) >= 0) { 13412 if (cur == null) { 13413 cur = new ArrayList<Intent>(); 13414 } 13415 cur.add(intent); 13416 } 13417 } 13418 return cur; 13419 } 13420 13421 boolean isPendingBroadcastProcessLocked(int pid) { 13422 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13423 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13424 } 13425 13426 void skipPendingBroadcastLocked(int pid) { 13427 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13428 for (BroadcastQueue queue : mBroadcastQueues) { 13429 queue.skipPendingBroadcastLocked(pid); 13430 } 13431 } 13432 13433 // The app just attached; send any pending broadcasts that it should receive 13434 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13435 boolean didSomething = false; 13436 for (BroadcastQueue queue : mBroadcastQueues) { 13437 didSomething |= queue.sendPendingBroadcastsLocked(app); 13438 } 13439 return didSomething; 13440 } 13441 13442 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13443 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13444 enforceNotIsolatedCaller("registerReceiver"); 13445 int callingUid; 13446 int callingPid; 13447 synchronized(this) { 13448 ProcessRecord callerApp = null; 13449 if (caller != null) { 13450 callerApp = getRecordForAppLocked(caller); 13451 if (callerApp == null) { 13452 throw new SecurityException( 13453 "Unable to find app for caller " + caller 13454 + " (pid=" + Binder.getCallingPid() 13455 + ") when registering receiver " + receiver); 13456 } 13457 if (callerApp.info.uid != Process.SYSTEM_UID && 13458 !callerApp.pkgList.containsKey(callerPackage) && 13459 !"android".equals(callerPackage)) { 13460 throw new SecurityException("Given caller package " + callerPackage 13461 + " is not running in process " + callerApp); 13462 } 13463 callingUid = callerApp.info.uid; 13464 callingPid = callerApp.pid; 13465 } else { 13466 callerPackage = null; 13467 callingUid = Binder.getCallingUid(); 13468 callingPid = Binder.getCallingPid(); 13469 } 13470 13471 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13472 true, true, "registerReceiver", callerPackage); 13473 13474 List allSticky = null; 13475 13476 // Look for any matching sticky broadcasts... 13477 Iterator actions = filter.actionsIterator(); 13478 if (actions != null) { 13479 while (actions.hasNext()) { 13480 String action = (String)actions.next(); 13481 allSticky = getStickiesLocked(action, filter, allSticky, 13482 UserHandle.USER_ALL); 13483 allSticky = getStickiesLocked(action, filter, allSticky, 13484 UserHandle.getUserId(callingUid)); 13485 } 13486 } else { 13487 allSticky = getStickiesLocked(null, filter, allSticky, 13488 UserHandle.USER_ALL); 13489 allSticky = getStickiesLocked(null, filter, allSticky, 13490 UserHandle.getUserId(callingUid)); 13491 } 13492 13493 // The first sticky in the list is returned directly back to 13494 // the client. 13495 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13496 13497 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13498 + ": " + sticky); 13499 13500 if (receiver == null) { 13501 return sticky; 13502 } 13503 13504 ReceiverList rl 13505 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13506 if (rl == null) { 13507 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13508 userId, receiver); 13509 if (rl.app != null) { 13510 rl.app.receivers.add(rl); 13511 } else { 13512 try { 13513 receiver.asBinder().linkToDeath(rl, 0); 13514 } catch (RemoteException e) { 13515 return sticky; 13516 } 13517 rl.linkedToDeath = true; 13518 } 13519 mRegisteredReceivers.put(receiver.asBinder(), rl); 13520 } else if (rl.uid != callingUid) { 13521 throw new IllegalArgumentException( 13522 "Receiver requested to register for uid " + callingUid 13523 + " was previously registered for uid " + rl.uid); 13524 } else if (rl.pid != callingPid) { 13525 throw new IllegalArgumentException( 13526 "Receiver requested to register for pid " + callingPid 13527 + " was previously registered for pid " + rl.pid); 13528 } else if (rl.userId != userId) { 13529 throw new IllegalArgumentException( 13530 "Receiver requested to register for user " + userId 13531 + " was previously registered for user " + rl.userId); 13532 } 13533 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13534 permission, callingUid, userId); 13535 rl.add(bf); 13536 if (!bf.debugCheck()) { 13537 Slog.w(TAG, "==> For Dynamic broadast"); 13538 } 13539 mReceiverResolver.addFilter(bf); 13540 13541 // Enqueue broadcasts for all existing stickies that match 13542 // this filter. 13543 if (allSticky != null) { 13544 ArrayList receivers = new ArrayList(); 13545 receivers.add(bf); 13546 13547 int N = allSticky.size(); 13548 for (int i=0; i<N; i++) { 13549 Intent intent = (Intent)allSticky.get(i); 13550 BroadcastQueue queue = broadcastQueueForIntent(intent); 13551 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13552 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13553 null, null, false, true, true, -1); 13554 queue.enqueueParallelBroadcastLocked(r); 13555 queue.scheduleBroadcastsLocked(); 13556 } 13557 } 13558 13559 return sticky; 13560 } 13561 } 13562 13563 public void unregisterReceiver(IIntentReceiver receiver) { 13564 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13565 13566 final long origId = Binder.clearCallingIdentity(); 13567 try { 13568 boolean doTrim = false; 13569 13570 synchronized(this) { 13571 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13572 if (rl != null) { 13573 if (rl.curBroadcast != null) { 13574 BroadcastRecord r = rl.curBroadcast; 13575 final boolean doNext = finishReceiverLocked( 13576 receiver.asBinder(), r.resultCode, r.resultData, 13577 r.resultExtras, r.resultAbort); 13578 if (doNext) { 13579 doTrim = true; 13580 r.queue.processNextBroadcast(false); 13581 } 13582 } 13583 13584 if (rl.app != null) { 13585 rl.app.receivers.remove(rl); 13586 } 13587 removeReceiverLocked(rl); 13588 if (rl.linkedToDeath) { 13589 rl.linkedToDeath = false; 13590 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13591 } 13592 } 13593 } 13594 13595 // If we actually concluded any broadcasts, we might now be able 13596 // to trim the recipients' apps from our working set 13597 if (doTrim) { 13598 trimApplications(); 13599 return; 13600 } 13601 13602 } finally { 13603 Binder.restoreCallingIdentity(origId); 13604 } 13605 } 13606 13607 void removeReceiverLocked(ReceiverList rl) { 13608 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13609 int N = rl.size(); 13610 for (int i=0; i<N; i++) { 13611 mReceiverResolver.removeFilter(rl.get(i)); 13612 } 13613 } 13614 13615 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13616 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13617 ProcessRecord r = mLruProcesses.get(i); 13618 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13619 try { 13620 r.thread.dispatchPackageBroadcast(cmd, packages); 13621 } catch (RemoteException ex) { 13622 } 13623 } 13624 } 13625 } 13626 13627 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13628 int[] users) { 13629 List<ResolveInfo> receivers = null; 13630 try { 13631 HashSet<ComponentName> singleUserReceivers = null; 13632 boolean scannedFirstReceivers = false; 13633 for (int user : users) { 13634 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13635 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13636 if (user != 0 && newReceivers != null) { 13637 // If this is not the primary user, we need to check for 13638 // any receivers that should be filtered out. 13639 for (int i=0; i<newReceivers.size(); i++) { 13640 ResolveInfo ri = newReceivers.get(i); 13641 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13642 newReceivers.remove(i); 13643 i--; 13644 } 13645 } 13646 } 13647 if (newReceivers != null && newReceivers.size() == 0) { 13648 newReceivers = null; 13649 } 13650 if (receivers == null) { 13651 receivers = newReceivers; 13652 } else if (newReceivers != null) { 13653 // We need to concatenate the additional receivers 13654 // found with what we have do far. This would be easy, 13655 // but we also need to de-dup any receivers that are 13656 // singleUser. 13657 if (!scannedFirstReceivers) { 13658 // Collect any single user receivers we had already retrieved. 13659 scannedFirstReceivers = true; 13660 for (int i=0; i<receivers.size(); i++) { 13661 ResolveInfo ri = receivers.get(i); 13662 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13663 ComponentName cn = new ComponentName( 13664 ri.activityInfo.packageName, ri.activityInfo.name); 13665 if (singleUserReceivers == null) { 13666 singleUserReceivers = new HashSet<ComponentName>(); 13667 } 13668 singleUserReceivers.add(cn); 13669 } 13670 } 13671 } 13672 // Add the new results to the existing results, tracking 13673 // and de-dupping single user receivers. 13674 for (int i=0; i<newReceivers.size(); i++) { 13675 ResolveInfo ri = newReceivers.get(i); 13676 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13677 ComponentName cn = new ComponentName( 13678 ri.activityInfo.packageName, ri.activityInfo.name); 13679 if (singleUserReceivers == null) { 13680 singleUserReceivers = new HashSet<ComponentName>(); 13681 } 13682 if (!singleUserReceivers.contains(cn)) { 13683 singleUserReceivers.add(cn); 13684 receivers.add(ri); 13685 } 13686 } else { 13687 receivers.add(ri); 13688 } 13689 } 13690 } 13691 } 13692 } catch (RemoteException ex) { 13693 // pm is in same process, this will never happen. 13694 } 13695 return receivers; 13696 } 13697 13698 private final int broadcastIntentLocked(ProcessRecord callerApp, 13699 String callerPackage, Intent intent, String resolvedType, 13700 IIntentReceiver resultTo, int resultCode, String resultData, 13701 Bundle map, String requiredPermission, int appOp, 13702 boolean ordered, boolean sticky, int callingPid, int callingUid, 13703 int userId) { 13704 intent = new Intent(intent); 13705 13706 // By default broadcasts do not go to stopped apps. 13707 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13708 13709 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13710 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13711 + " ordered=" + ordered + " userid=" + userId); 13712 if ((resultTo != null) && !ordered) { 13713 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13714 } 13715 13716 userId = handleIncomingUser(callingPid, callingUid, userId, 13717 true, false, "broadcast", callerPackage); 13718 13719 // Make sure that the user who is receiving this broadcast is started. 13720 // If not, we will just skip it. 13721 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13722 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13723 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13724 Slog.w(TAG, "Skipping broadcast of " + intent 13725 + ": user " + userId + " is stopped"); 13726 return ActivityManager.BROADCAST_SUCCESS; 13727 } 13728 } 13729 13730 /* 13731 * Prevent non-system code (defined here to be non-persistent 13732 * processes) from sending protected broadcasts. 13733 */ 13734 int callingAppId = UserHandle.getAppId(callingUid); 13735 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13736 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13737 callingUid == 0) { 13738 // Always okay. 13739 } else if (callerApp == null || !callerApp.persistent) { 13740 try { 13741 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13742 intent.getAction())) { 13743 String msg = "Permission Denial: not allowed to send broadcast " 13744 + intent.getAction() + " from pid=" 13745 + callingPid + ", uid=" + callingUid; 13746 Slog.w(TAG, msg); 13747 throw new SecurityException(msg); 13748 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13749 // Special case for compatibility: we don't want apps to send this, 13750 // but historically it has not been protected and apps may be using it 13751 // to poke their own app widget. So, instead of making it protected, 13752 // just limit it to the caller. 13753 if (callerApp == null) { 13754 String msg = "Permission Denial: not allowed to send broadcast " 13755 + intent.getAction() + " from unknown caller."; 13756 Slog.w(TAG, msg); 13757 throw new SecurityException(msg); 13758 } else if (intent.getComponent() != null) { 13759 // They are good enough to send to an explicit component... verify 13760 // it is being sent to the calling app. 13761 if (!intent.getComponent().getPackageName().equals( 13762 callerApp.info.packageName)) { 13763 String msg = "Permission Denial: not allowed to send broadcast " 13764 + intent.getAction() + " to " 13765 + intent.getComponent().getPackageName() + " from " 13766 + callerApp.info.packageName; 13767 Slog.w(TAG, msg); 13768 throw new SecurityException(msg); 13769 } 13770 } else { 13771 // Limit broadcast to their own package. 13772 intent.setPackage(callerApp.info.packageName); 13773 } 13774 } 13775 } catch (RemoteException e) { 13776 Slog.w(TAG, "Remote exception", e); 13777 return ActivityManager.BROADCAST_SUCCESS; 13778 } 13779 } 13780 13781 // Handle special intents: if this broadcast is from the package 13782 // manager about a package being removed, we need to remove all of 13783 // its activities from the history stack. 13784 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13785 intent.getAction()); 13786 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13787 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13788 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13789 || uidRemoved) { 13790 if (checkComponentPermission( 13791 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13792 callingPid, callingUid, -1, true) 13793 == PackageManager.PERMISSION_GRANTED) { 13794 if (uidRemoved) { 13795 final Bundle intentExtras = intent.getExtras(); 13796 final int uid = intentExtras != null 13797 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13798 if (uid >= 0) { 13799 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13800 synchronized (bs) { 13801 bs.removeUidStatsLocked(uid); 13802 } 13803 mAppOpsService.uidRemoved(uid); 13804 } 13805 } else { 13806 // If resources are unavailable just force stop all 13807 // those packages and flush the attribute cache as well. 13808 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13809 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13810 if (list != null && (list.length > 0)) { 13811 for (String pkg : list) { 13812 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13813 "storage unmount"); 13814 } 13815 sendPackageBroadcastLocked( 13816 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13817 } 13818 } else { 13819 Uri data = intent.getData(); 13820 String ssp; 13821 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13822 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13823 intent.getAction()); 13824 boolean fullUninstall = removed && 13825 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13826 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13827 forceStopPackageLocked(ssp, UserHandle.getAppId( 13828 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13829 false, fullUninstall, userId, 13830 removed ? "pkg removed" : "pkg changed"); 13831 } 13832 if (removed) { 13833 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13834 new String[] {ssp}, userId); 13835 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13836 mAppOpsService.packageRemoved( 13837 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13838 13839 // Remove all permissions granted from/to this package 13840 removeUriPermissionsForPackageLocked(ssp, userId, true); 13841 } 13842 } 13843 } 13844 } 13845 } 13846 } else { 13847 String msg = "Permission Denial: " + intent.getAction() 13848 + " broadcast from " + callerPackage + " (pid=" + callingPid 13849 + ", uid=" + callingUid + ")" 13850 + " requires " 13851 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13852 Slog.w(TAG, msg); 13853 throw new SecurityException(msg); 13854 } 13855 13856 // Special case for adding a package: by default turn on compatibility 13857 // mode. 13858 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13859 Uri data = intent.getData(); 13860 String ssp; 13861 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13862 mCompatModePackages.handlePackageAddedLocked(ssp, 13863 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13864 } 13865 } 13866 13867 /* 13868 * If this is the time zone changed action, queue up a message that will reset the timezone 13869 * of all currently running processes. This message will get queued up before the broadcast 13870 * happens. 13871 */ 13872 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13873 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13874 } 13875 13876 /* 13877 * If the user set the time, let all running processes know. 13878 */ 13879 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13880 final int is24Hour = intent.getBooleanExtra( 13881 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13882 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13883 } 13884 13885 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13886 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13887 } 13888 13889 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13890 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13891 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13892 } 13893 13894 // Add to the sticky list if requested. 13895 if (sticky) { 13896 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13897 callingPid, callingUid) 13898 != PackageManager.PERMISSION_GRANTED) { 13899 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13900 + callingPid + ", uid=" + callingUid 13901 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13902 Slog.w(TAG, msg); 13903 throw new SecurityException(msg); 13904 } 13905 if (requiredPermission != null) { 13906 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13907 + " and enforce permission " + requiredPermission); 13908 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13909 } 13910 if (intent.getComponent() != null) { 13911 throw new SecurityException( 13912 "Sticky broadcasts can't target a specific component"); 13913 } 13914 // We use userId directly here, since the "all" target is maintained 13915 // as a separate set of sticky broadcasts. 13916 if (userId != UserHandle.USER_ALL) { 13917 // But first, if this is not a broadcast to all users, then 13918 // make sure it doesn't conflict with an existing broadcast to 13919 // all users. 13920 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13921 UserHandle.USER_ALL); 13922 if (stickies != null) { 13923 ArrayList<Intent> list = stickies.get(intent.getAction()); 13924 if (list != null) { 13925 int N = list.size(); 13926 int i; 13927 for (i=0; i<N; i++) { 13928 if (intent.filterEquals(list.get(i))) { 13929 throw new IllegalArgumentException( 13930 "Sticky broadcast " + intent + " for user " 13931 + userId + " conflicts with existing global broadcast"); 13932 } 13933 } 13934 } 13935 } 13936 } 13937 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13938 if (stickies == null) { 13939 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13940 mStickyBroadcasts.put(userId, stickies); 13941 } 13942 ArrayList<Intent> list = stickies.get(intent.getAction()); 13943 if (list == null) { 13944 list = new ArrayList<Intent>(); 13945 stickies.put(intent.getAction(), list); 13946 } 13947 int N = list.size(); 13948 int i; 13949 for (i=0; i<N; i++) { 13950 if (intent.filterEquals(list.get(i))) { 13951 // This sticky already exists, replace it. 13952 list.set(i, new Intent(intent)); 13953 break; 13954 } 13955 } 13956 if (i >= N) { 13957 list.add(new Intent(intent)); 13958 } 13959 } 13960 13961 int[] users; 13962 if (userId == UserHandle.USER_ALL) { 13963 // Caller wants broadcast to go to all started users. 13964 users = mStartedUserArray; 13965 } else { 13966 // Caller wants broadcast to go to one specific user. 13967 users = new int[] {userId}; 13968 } 13969 13970 // Figure out who all will receive this broadcast. 13971 List receivers = null; 13972 List<BroadcastFilter> registeredReceivers = null; 13973 // Need to resolve the intent to interested receivers... 13974 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13975 == 0) { 13976 receivers = collectReceiverComponents(intent, resolvedType, users); 13977 } 13978 if (intent.getComponent() == null) { 13979 registeredReceivers = mReceiverResolver.queryIntent(intent, 13980 resolvedType, false, userId); 13981 } 13982 13983 final boolean replacePending = 13984 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13985 13986 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13987 + " replacePending=" + replacePending); 13988 13989 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13990 if (!ordered && NR > 0) { 13991 // If we are not serializing this broadcast, then send the 13992 // registered receivers separately so they don't wait for the 13993 // components to be launched. 13994 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13995 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13996 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13997 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13998 ordered, sticky, false, userId); 13999 if (DEBUG_BROADCAST) Slog.v( 14000 TAG, "Enqueueing parallel broadcast " + r); 14001 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14002 if (!replaced) { 14003 queue.enqueueParallelBroadcastLocked(r); 14004 queue.scheduleBroadcastsLocked(); 14005 } 14006 registeredReceivers = null; 14007 NR = 0; 14008 } 14009 14010 // Merge into one list. 14011 int ir = 0; 14012 if (receivers != null) { 14013 // A special case for PACKAGE_ADDED: do not allow the package 14014 // being added to see this broadcast. This prevents them from 14015 // using this as a back door to get run as soon as they are 14016 // installed. Maybe in the future we want to have a special install 14017 // broadcast or such for apps, but we'd like to deliberately make 14018 // this decision. 14019 String skipPackages[] = null; 14020 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14021 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14022 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14023 Uri data = intent.getData(); 14024 if (data != null) { 14025 String pkgName = data.getSchemeSpecificPart(); 14026 if (pkgName != null) { 14027 skipPackages = new String[] { pkgName }; 14028 } 14029 } 14030 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14031 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14032 } 14033 if (skipPackages != null && (skipPackages.length > 0)) { 14034 for (String skipPackage : skipPackages) { 14035 if (skipPackage != null) { 14036 int NT = receivers.size(); 14037 for (int it=0; it<NT; it++) { 14038 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14039 if (curt.activityInfo.packageName.equals(skipPackage)) { 14040 receivers.remove(it); 14041 it--; 14042 NT--; 14043 } 14044 } 14045 } 14046 } 14047 } 14048 14049 int NT = receivers != null ? receivers.size() : 0; 14050 int it = 0; 14051 ResolveInfo curt = null; 14052 BroadcastFilter curr = null; 14053 while (it < NT && ir < NR) { 14054 if (curt == null) { 14055 curt = (ResolveInfo)receivers.get(it); 14056 } 14057 if (curr == null) { 14058 curr = registeredReceivers.get(ir); 14059 } 14060 if (curr.getPriority() >= curt.priority) { 14061 // Insert this broadcast record into the final list. 14062 receivers.add(it, curr); 14063 ir++; 14064 curr = null; 14065 it++; 14066 NT++; 14067 } else { 14068 // Skip to the next ResolveInfo in the final list. 14069 it++; 14070 curt = null; 14071 } 14072 } 14073 } 14074 while (ir < NR) { 14075 if (receivers == null) { 14076 receivers = new ArrayList(); 14077 } 14078 receivers.add(registeredReceivers.get(ir)); 14079 ir++; 14080 } 14081 14082 if ((receivers != null && receivers.size() > 0) 14083 || resultTo != null) { 14084 BroadcastQueue queue = broadcastQueueForIntent(intent); 14085 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14086 callerPackage, callingPid, callingUid, resolvedType, 14087 requiredPermission, appOp, receivers, resultTo, resultCode, 14088 resultData, map, ordered, sticky, false, userId); 14089 if (DEBUG_BROADCAST) Slog.v( 14090 TAG, "Enqueueing ordered broadcast " + r 14091 + ": prev had " + queue.mOrderedBroadcasts.size()); 14092 if (DEBUG_BROADCAST) { 14093 int seq = r.intent.getIntExtra("seq", -1); 14094 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14095 } 14096 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14097 if (!replaced) { 14098 queue.enqueueOrderedBroadcastLocked(r); 14099 queue.scheduleBroadcastsLocked(); 14100 } 14101 } 14102 14103 return ActivityManager.BROADCAST_SUCCESS; 14104 } 14105 14106 final Intent verifyBroadcastLocked(Intent intent) { 14107 // Refuse possible leaked file descriptors 14108 if (intent != null && intent.hasFileDescriptors() == true) { 14109 throw new IllegalArgumentException("File descriptors passed in Intent"); 14110 } 14111 14112 int flags = intent.getFlags(); 14113 14114 if (!mProcessesReady) { 14115 // if the caller really truly claims to know what they're doing, go 14116 // ahead and allow the broadcast without launching any receivers 14117 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14118 intent = new Intent(intent); 14119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14120 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14121 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14122 + " before boot completion"); 14123 throw new IllegalStateException("Cannot broadcast before boot completed"); 14124 } 14125 } 14126 14127 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14128 throw new IllegalArgumentException( 14129 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14130 } 14131 14132 return intent; 14133 } 14134 14135 public final int broadcastIntent(IApplicationThread caller, 14136 Intent intent, String resolvedType, IIntentReceiver resultTo, 14137 int resultCode, String resultData, Bundle map, 14138 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14139 enforceNotIsolatedCaller("broadcastIntent"); 14140 synchronized(this) { 14141 intent = verifyBroadcastLocked(intent); 14142 14143 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14144 final int callingPid = Binder.getCallingPid(); 14145 final int callingUid = Binder.getCallingUid(); 14146 final long origId = Binder.clearCallingIdentity(); 14147 int res = broadcastIntentLocked(callerApp, 14148 callerApp != null ? callerApp.info.packageName : null, 14149 intent, resolvedType, resultTo, 14150 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14151 callingPid, callingUid, userId); 14152 Binder.restoreCallingIdentity(origId); 14153 return res; 14154 } 14155 } 14156 14157 int broadcastIntentInPackage(String packageName, int uid, 14158 Intent intent, String resolvedType, IIntentReceiver resultTo, 14159 int resultCode, String resultData, Bundle map, 14160 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14161 synchronized(this) { 14162 intent = verifyBroadcastLocked(intent); 14163 14164 final long origId = Binder.clearCallingIdentity(); 14165 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14166 resultTo, resultCode, resultData, map, requiredPermission, 14167 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14168 Binder.restoreCallingIdentity(origId); 14169 return res; 14170 } 14171 } 14172 14173 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14174 // Refuse possible leaked file descriptors 14175 if (intent != null && intent.hasFileDescriptors() == true) { 14176 throw new IllegalArgumentException("File descriptors passed in Intent"); 14177 } 14178 14179 userId = handleIncomingUser(Binder.getCallingPid(), 14180 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14181 14182 synchronized(this) { 14183 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14184 != PackageManager.PERMISSION_GRANTED) { 14185 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14186 + Binder.getCallingPid() 14187 + ", uid=" + Binder.getCallingUid() 14188 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14189 Slog.w(TAG, msg); 14190 throw new SecurityException(msg); 14191 } 14192 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14193 if (stickies != null) { 14194 ArrayList<Intent> list = stickies.get(intent.getAction()); 14195 if (list != null) { 14196 int N = list.size(); 14197 int i; 14198 for (i=0; i<N; i++) { 14199 if (intent.filterEquals(list.get(i))) { 14200 list.remove(i); 14201 break; 14202 } 14203 } 14204 if (list.size() <= 0) { 14205 stickies.remove(intent.getAction()); 14206 } 14207 } 14208 if (stickies.size() <= 0) { 14209 mStickyBroadcasts.remove(userId); 14210 } 14211 } 14212 } 14213 } 14214 14215 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14216 String resultData, Bundle resultExtras, boolean resultAbort) { 14217 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14218 if (r == null) { 14219 Slog.w(TAG, "finishReceiver called but not found on queue"); 14220 return false; 14221 } 14222 14223 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14224 } 14225 14226 void backgroundServicesFinishedLocked(int userId) { 14227 for (BroadcastQueue queue : mBroadcastQueues) { 14228 queue.backgroundServicesFinishedLocked(userId); 14229 } 14230 } 14231 14232 public void finishReceiver(IBinder who, int resultCode, String resultData, 14233 Bundle resultExtras, boolean resultAbort) { 14234 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14235 14236 // Refuse possible leaked file descriptors 14237 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14238 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14239 } 14240 14241 final long origId = Binder.clearCallingIdentity(); 14242 try { 14243 boolean doNext = false; 14244 BroadcastRecord r; 14245 14246 synchronized(this) { 14247 r = broadcastRecordForReceiverLocked(who); 14248 if (r != null) { 14249 doNext = r.queue.finishReceiverLocked(r, resultCode, 14250 resultData, resultExtras, resultAbort, true); 14251 } 14252 } 14253 14254 if (doNext) { 14255 r.queue.processNextBroadcast(false); 14256 } 14257 trimApplications(); 14258 } finally { 14259 Binder.restoreCallingIdentity(origId); 14260 } 14261 } 14262 14263 // ========================================================= 14264 // INSTRUMENTATION 14265 // ========================================================= 14266 14267 public boolean startInstrumentation(ComponentName className, 14268 String profileFile, int flags, Bundle arguments, 14269 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14270 int userId) { 14271 enforceNotIsolatedCaller("startInstrumentation"); 14272 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14273 userId, false, true, "startInstrumentation", null); 14274 // Refuse possible leaked file descriptors 14275 if (arguments != null && arguments.hasFileDescriptors()) { 14276 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14277 } 14278 14279 synchronized(this) { 14280 InstrumentationInfo ii = null; 14281 ApplicationInfo ai = null; 14282 try { 14283 ii = mContext.getPackageManager().getInstrumentationInfo( 14284 className, STOCK_PM_FLAGS); 14285 ai = AppGlobals.getPackageManager().getApplicationInfo( 14286 ii.targetPackage, STOCK_PM_FLAGS, userId); 14287 } catch (PackageManager.NameNotFoundException e) { 14288 } catch (RemoteException e) { 14289 } 14290 if (ii == null) { 14291 reportStartInstrumentationFailure(watcher, className, 14292 "Unable to find instrumentation info for: " + className); 14293 return false; 14294 } 14295 if (ai == null) { 14296 reportStartInstrumentationFailure(watcher, className, 14297 "Unable to find instrumentation target package: " + ii.targetPackage); 14298 return false; 14299 } 14300 14301 int match = mContext.getPackageManager().checkSignatures( 14302 ii.targetPackage, ii.packageName); 14303 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14304 String msg = "Permission Denial: starting instrumentation " 14305 + className + " from pid=" 14306 + Binder.getCallingPid() 14307 + ", uid=" + Binder.getCallingPid() 14308 + " not allowed because package " + ii.packageName 14309 + " does not have a signature matching the target " 14310 + ii.targetPackage; 14311 reportStartInstrumentationFailure(watcher, className, msg); 14312 throw new SecurityException(msg); 14313 } 14314 14315 final long origId = Binder.clearCallingIdentity(); 14316 // Instrumentation can kill and relaunch even persistent processes 14317 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14318 "start instr"); 14319 ProcessRecord app = addAppLocked(ai, false); 14320 app.instrumentationClass = className; 14321 app.instrumentationInfo = ai; 14322 app.instrumentationProfileFile = profileFile; 14323 app.instrumentationArguments = arguments; 14324 app.instrumentationWatcher = watcher; 14325 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14326 app.instrumentationResultClass = className; 14327 Binder.restoreCallingIdentity(origId); 14328 } 14329 14330 return true; 14331 } 14332 14333 /** 14334 * Report errors that occur while attempting to start Instrumentation. Always writes the 14335 * error to the logs, but if somebody is watching, send the report there too. This enables 14336 * the "am" command to report errors with more information. 14337 * 14338 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14339 * @param cn The component name of the instrumentation. 14340 * @param report The error report. 14341 */ 14342 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14343 ComponentName cn, String report) { 14344 Slog.w(TAG, report); 14345 try { 14346 if (watcher != null) { 14347 Bundle results = new Bundle(); 14348 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14349 results.putString("Error", report); 14350 watcher.instrumentationStatus(cn, -1, results); 14351 } 14352 } catch (RemoteException e) { 14353 Slog.w(TAG, e); 14354 } 14355 } 14356 14357 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14358 if (app.instrumentationWatcher != null) { 14359 try { 14360 // NOTE: IInstrumentationWatcher *must* be oneway here 14361 app.instrumentationWatcher.instrumentationFinished( 14362 app.instrumentationClass, 14363 resultCode, 14364 results); 14365 } catch (RemoteException e) { 14366 } 14367 } 14368 if (app.instrumentationUiAutomationConnection != null) { 14369 try { 14370 app.instrumentationUiAutomationConnection.shutdown(); 14371 } catch (RemoteException re) { 14372 /* ignore */ 14373 } 14374 // Only a UiAutomation can set this flag and now that 14375 // it is finished we make sure it is reset to its default. 14376 mUserIsMonkey = false; 14377 } 14378 app.instrumentationWatcher = null; 14379 app.instrumentationUiAutomationConnection = null; 14380 app.instrumentationClass = null; 14381 app.instrumentationInfo = null; 14382 app.instrumentationProfileFile = null; 14383 app.instrumentationArguments = null; 14384 14385 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14386 "finished inst"); 14387 } 14388 14389 public void finishInstrumentation(IApplicationThread target, 14390 int resultCode, Bundle results) { 14391 int userId = UserHandle.getCallingUserId(); 14392 // Refuse possible leaked file descriptors 14393 if (results != null && results.hasFileDescriptors()) { 14394 throw new IllegalArgumentException("File descriptors passed in Intent"); 14395 } 14396 14397 synchronized(this) { 14398 ProcessRecord app = getRecordForAppLocked(target); 14399 if (app == null) { 14400 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14401 return; 14402 } 14403 final long origId = Binder.clearCallingIdentity(); 14404 finishInstrumentationLocked(app, resultCode, results); 14405 Binder.restoreCallingIdentity(origId); 14406 } 14407 } 14408 14409 // ========================================================= 14410 // CONFIGURATION 14411 // ========================================================= 14412 14413 public ConfigurationInfo getDeviceConfigurationInfo() { 14414 ConfigurationInfo config = new ConfigurationInfo(); 14415 synchronized (this) { 14416 config.reqTouchScreen = mConfiguration.touchscreen; 14417 config.reqKeyboardType = mConfiguration.keyboard; 14418 config.reqNavigation = mConfiguration.navigation; 14419 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14420 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14421 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14422 } 14423 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14424 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14425 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14426 } 14427 config.reqGlEsVersion = GL_ES_VERSION; 14428 } 14429 return config; 14430 } 14431 14432 ActivityStack getFocusedStack() { 14433 return mStackSupervisor.getFocusedStack(); 14434 } 14435 14436 public Configuration getConfiguration() { 14437 Configuration ci; 14438 synchronized(this) { 14439 ci = new Configuration(mConfiguration); 14440 } 14441 return ci; 14442 } 14443 14444 public void updatePersistentConfiguration(Configuration values) { 14445 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14446 "updateConfiguration()"); 14447 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14448 "updateConfiguration()"); 14449 if (values == null) { 14450 throw new NullPointerException("Configuration must not be null"); 14451 } 14452 14453 synchronized(this) { 14454 final long origId = Binder.clearCallingIdentity(); 14455 updateConfigurationLocked(values, null, true, false); 14456 Binder.restoreCallingIdentity(origId); 14457 } 14458 } 14459 14460 public void updateConfiguration(Configuration values) { 14461 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14462 "updateConfiguration()"); 14463 14464 synchronized(this) { 14465 if (values == null && mWindowManager != null) { 14466 // sentinel: fetch the current configuration from the window manager 14467 values = mWindowManager.computeNewConfiguration(); 14468 } 14469 14470 if (mWindowManager != null) { 14471 mProcessList.applyDisplaySize(mWindowManager); 14472 } 14473 14474 final long origId = Binder.clearCallingIdentity(); 14475 if (values != null) { 14476 Settings.System.clearConfiguration(values); 14477 } 14478 updateConfigurationLocked(values, null, false, false); 14479 Binder.restoreCallingIdentity(origId); 14480 } 14481 } 14482 14483 /** 14484 * Do either or both things: (1) change the current configuration, and (2) 14485 * make sure the given activity is running with the (now) current 14486 * configuration. Returns true if the activity has been left running, or 14487 * false if <var>starting</var> is being destroyed to match the new 14488 * configuration. 14489 * @param persistent TODO 14490 */ 14491 boolean updateConfigurationLocked(Configuration values, 14492 ActivityRecord starting, boolean persistent, boolean initLocale) { 14493 int changes = 0; 14494 14495 if (values != null) { 14496 Configuration newConfig = new Configuration(mConfiguration); 14497 changes = newConfig.updateFrom(values); 14498 if (changes != 0) { 14499 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14500 Slog.i(TAG, "Updating configuration to: " + values); 14501 } 14502 14503 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14504 14505 if (values.locale != null && !initLocale) { 14506 saveLocaleLocked(values.locale, 14507 !values.locale.equals(mConfiguration.locale), 14508 values.userSetLocale); 14509 } 14510 14511 mConfigurationSeq++; 14512 if (mConfigurationSeq <= 0) { 14513 mConfigurationSeq = 1; 14514 } 14515 newConfig.seq = mConfigurationSeq; 14516 mConfiguration = newConfig; 14517 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14518 mUsageStatsService.noteStartConfig(newConfig); 14519 14520 final Configuration configCopy = new Configuration(mConfiguration); 14521 14522 // TODO: If our config changes, should we auto dismiss any currently 14523 // showing dialogs? 14524 mShowDialogs = shouldShowDialogs(newConfig); 14525 14526 AttributeCache ac = AttributeCache.instance(); 14527 if (ac != null) { 14528 ac.updateConfiguration(configCopy); 14529 } 14530 14531 // Make sure all resources in our process are updated 14532 // right now, so that anyone who is going to retrieve 14533 // resource values after we return will be sure to get 14534 // the new ones. This is especially important during 14535 // boot, where the first config change needs to guarantee 14536 // all resources have that config before following boot 14537 // code is executed. 14538 mSystemThread.applyConfigurationToResources(configCopy); 14539 14540 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14541 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14542 msg.obj = new Configuration(configCopy); 14543 mHandler.sendMessage(msg); 14544 } 14545 14546 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14547 ProcessRecord app = mLruProcesses.get(i); 14548 try { 14549 if (app.thread != null) { 14550 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14551 + app.processName + " new config " + mConfiguration); 14552 app.thread.scheduleConfigurationChanged(configCopy); 14553 } 14554 } catch (Exception e) { 14555 } 14556 } 14557 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14558 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14559 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14560 | Intent.FLAG_RECEIVER_FOREGROUND); 14561 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14562 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14563 Process.SYSTEM_UID, UserHandle.USER_ALL); 14564 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14565 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14566 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14567 broadcastIntentLocked(null, null, intent, 14568 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14569 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14570 } 14571 } 14572 } 14573 14574 boolean kept = true; 14575 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14576 // mainStack is null during startup. 14577 if (mainStack != null) { 14578 if (changes != 0 && starting == null) { 14579 // If the configuration changed, and the caller is not already 14580 // in the process of starting an activity, then find the top 14581 // activity to check if its configuration needs to change. 14582 starting = mainStack.topRunningActivityLocked(null); 14583 } 14584 14585 if (starting != null) { 14586 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14587 // And we need to make sure at this point that all other activities 14588 // are made visible with the correct configuration. 14589 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14590 } 14591 } 14592 14593 if (values != null && mWindowManager != null) { 14594 mWindowManager.setNewConfiguration(mConfiguration); 14595 } 14596 14597 return kept; 14598 } 14599 14600 /** 14601 * Decide based on the configuration whether we should shouw the ANR, 14602 * crash, etc dialogs. The idea is that if there is no affordnace to 14603 * press the on-screen buttons, we shouldn't show the dialog. 14604 * 14605 * A thought: SystemUI might also want to get told about this, the Power 14606 * dialog / global actions also might want different behaviors. 14607 */ 14608 private static final boolean shouldShowDialogs(Configuration config) { 14609 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14610 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14611 } 14612 14613 /** 14614 * Save the locale. You must be inside a synchronized (this) block. 14615 */ 14616 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14617 if(isDiff) { 14618 SystemProperties.set("user.language", l.getLanguage()); 14619 SystemProperties.set("user.region", l.getCountry()); 14620 } 14621 14622 if(isPersist) { 14623 SystemProperties.set("persist.sys.language", l.getLanguage()); 14624 SystemProperties.set("persist.sys.country", l.getCountry()); 14625 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14626 } 14627 } 14628 14629 @Override 14630 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14631 ActivityRecord srec = ActivityRecord.forToken(token); 14632 return srec != null && srec.task.affinity != null && 14633 srec.task.affinity.equals(destAffinity); 14634 } 14635 14636 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14637 Intent resultData) { 14638 14639 synchronized (this) { 14640 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14641 if (stack != null) { 14642 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14643 } 14644 return false; 14645 } 14646 } 14647 14648 public int getLaunchedFromUid(IBinder activityToken) { 14649 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14650 if (srec == null) { 14651 return -1; 14652 } 14653 return srec.launchedFromUid; 14654 } 14655 14656 public String getLaunchedFromPackage(IBinder activityToken) { 14657 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14658 if (srec == null) { 14659 return null; 14660 } 14661 return srec.launchedFromPackage; 14662 } 14663 14664 // ========================================================= 14665 // LIFETIME MANAGEMENT 14666 // ========================================================= 14667 14668 // Returns which broadcast queue the app is the current [or imminent] receiver 14669 // on, or 'null' if the app is not an active broadcast recipient. 14670 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14671 BroadcastRecord r = app.curReceiver; 14672 if (r != null) { 14673 return r.queue; 14674 } 14675 14676 // It's not the current receiver, but it might be starting up to become one 14677 synchronized (this) { 14678 for (BroadcastQueue queue : mBroadcastQueues) { 14679 r = queue.mPendingBroadcast; 14680 if (r != null && r.curApp == app) { 14681 // found it; report which queue it's in 14682 return queue; 14683 } 14684 } 14685 } 14686 14687 return null; 14688 } 14689 14690 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14691 boolean doingAll, long now) { 14692 if (mAdjSeq == app.adjSeq) { 14693 // This adjustment has already been computed. 14694 return app.curRawAdj; 14695 } 14696 14697 if (app.thread == null) { 14698 app.adjSeq = mAdjSeq; 14699 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14700 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14701 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14702 } 14703 14704 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14705 app.adjSource = null; 14706 app.adjTarget = null; 14707 app.empty = false; 14708 app.cached = false; 14709 14710 final int activitiesSize = app.activities.size(); 14711 14712 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14713 // The max adjustment doesn't allow this app to be anything 14714 // below foreground, so it is not worth doing work for it. 14715 app.adjType = "fixed"; 14716 app.adjSeq = mAdjSeq; 14717 app.curRawAdj = app.maxAdj; 14718 app.foregroundActivities = false; 14719 app.keeping = true; 14720 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14721 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14722 // System processes can do UI, and when they do we want to have 14723 // them trim their memory after the user leaves the UI. To 14724 // facilitate this, here we need to determine whether or not it 14725 // is currently showing UI. 14726 app.systemNoUi = true; 14727 if (app == TOP_APP) { 14728 app.systemNoUi = false; 14729 } else if (activitiesSize > 0) { 14730 for (int j = 0; j < activitiesSize; j++) { 14731 final ActivityRecord r = app.activities.get(j); 14732 if (r.visible) { 14733 app.systemNoUi = false; 14734 } 14735 } 14736 } 14737 if (!app.systemNoUi) { 14738 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14739 } 14740 return (app.curAdj=app.maxAdj); 14741 } 14742 14743 app.keeping = false; 14744 app.systemNoUi = false; 14745 14746 // Determine the importance of the process, starting with most 14747 // important to least, and assign an appropriate OOM adjustment. 14748 int adj; 14749 int schedGroup; 14750 int procState; 14751 boolean foregroundActivities = false; 14752 boolean interesting = false; 14753 BroadcastQueue queue; 14754 if (app == TOP_APP) { 14755 // The last app on the list is the foreground app. 14756 adj = ProcessList.FOREGROUND_APP_ADJ; 14757 schedGroup = Process.THREAD_GROUP_DEFAULT; 14758 app.adjType = "top-activity"; 14759 foregroundActivities = true; 14760 interesting = true; 14761 procState = ActivityManager.PROCESS_STATE_TOP; 14762 } else if (app.instrumentationClass != null) { 14763 // Don't want to kill running instrumentation. 14764 adj = ProcessList.FOREGROUND_APP_ADJ; 14765 schedGroup = Process.THREAD_GROUP_DEFAULT; 14766 app.adjType = "instrumentation"; 14767 interesting = true; 14768 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14769 } else if ((queue = isReceivingBroadcast(app)) != null) { 14770 // An app that is currently receiving a broadcast also 14771 // counts as being in the foreground for OOM killer purposes. 14772 // It's placed in a sched group based on the nature of the 14773 // broadcast as reflected by which queue it's active in. 14774 adj = ProcessList.FOREGROUND_APP_ADJ; 14775 schedGroup = (queue == mFgBroadcastQueue) 14776 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14777 app.adjType = "broadcast"; 14778 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14779 } else if (app.executingServices.size() > 0) { 14780 // An app that is currently executing a service callback also 14781 // counts as being in the foreground. 14782 adj = ProcessList.FOREGROUND_APP_ADJ; 14783 schedGroup = app.execServicesFg ? 14784 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14785 app.adjType = "exec-service"; 14786 procState = ActivityManager.PROCESS_STATE_SERVICE; 14787 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14788 } else { 14789 // As far as we know the process is empty. We may change our mind later. 14790 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14791 // At this point we don't actually know the adjustment. Use the cached adj 14792 // value that the caller wants us to. 14793 adj = cachedAdj; 14794 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14795 app.cached = true; 14796 app.empty = true; 14797 app.adjType = "cch-empty"; 14798 } 14799 14800 // Examine all activities if not already foreground. 14801 if (!foregroundActivities && activitiesSize > 0) { 14802 for (int j = 0; j < activitiesSize; j++) { 14803 final ActivityRecord r = app.activities.get(j); 14804 if (r.app != app) { 14805 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14806 + app + "?!?"); 14807 continue; 14808 } 14809 if (r.visible) { 14810 // App has a visible activity; only upgrade adjustment. 14811 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14812 adj = ProcessList.VISIBLE_APP_ADJ; 14813 app.adjType = "visible"; 14814 } 14815 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14816 procState = ActivityManager.PROCESS_STATE_TOP; 14817 } 14818 schedGroup = Process.THREAD_GROUP_DEFAULT; 14819 app.cached = false; 14820 app.empty = false; 14821 foregroundActivities = true; 14822 break; 14823 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14824 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14825 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14826 app.adjType = "pausing"; 14827 } 14828 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14829 procState = ActivityManager.PROCESS_STATE_TOP; 14830 } 14831 schedGroup = Process.THREAD_GROUP_DEFAULT; 14832 app.cached = false; 14833 app.empty = false; 14834 foregroundActivities = true; 14835 } else if (r.state == ActivityState.STOPPING) { 14836 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14837 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14838 app.adjType = "stopping"; 14839 } 14840 // For the process state, we will at this point consider the 14841 // process to be cached. It will be cached either as an activity 14842 // or empty depending on whether the activity is finishing. We do 14843 // this so that we can treat the process as cached for purposes of 14844 // memory trimming (determing current memory level, trim command to 14845 // send to process) since there can be an arbitrary number of stopping 14846 // processes and they should soon all go into the cached state. 14847 if (!r.finishing) { 14848 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14849 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14850 } 14851 } 14852 app.cached = false; 14853 app.empty = false; 14854 foregroundActivities = true; 14855 } else { 14856 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14857 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14858 app.adjType = "cch-act"; 14859 } 14860 } 14861 } 14862 } 14863 14864 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14865 if (app.foregroundServices) { 14866 // The user is aware of this app, so make it visible. 14867 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14868 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14869 app.cached = false; 14870 app.adjType = "fg-service"; 14871 schedGroup = Process.THREAD_GROUP_DEFAULT; 14872 } else if (app.forcingToForeground != null) { 14873 // The user is aware of this app, so make it visible. 14874 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14875 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14876 app.cached = false; 14877 app.adjType = "force-fg"; 14878 app.adjSource = app.forcingToForeground; 14879 schedGroup = Process.THREAD_GROUP_DEFAULT; 14880 } 14881 } 14882 14883 if (app.foregroundServices) { 14884 interesting = true; 14885 } 14886 14887 if (app == mHeavyWeightProcess) { 14888 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14889 // We don't want to kill the current heavy-weight process. 14890 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14891 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14892 app.cached = false; 14893 app.adjType = "heavy"; 14894 } 14895 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14896 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14897 } 14898 } 14899 14900 if (app == mHomeProcess) { 14901 if (adj > ProcessList.HOME_APP_ADJ) { 14902 // This process is hosting what we currently consider to be the 14903 // home app, so we don't want to let it go into the background. 14904 adj = ProcessList.HOME_APP_ADJ; 14905 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14906 app.cached = false; 14907 app.adjType = "home"; 14908 } 14909 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14910 procState = ActivityManager.PROCESS_STATE_HOME; 14911 } 14912 } 14913 14914 if (app == mPreviousProcess && app.activities.size() > 0) { 14915 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14916 // This was the previous process that showed UI to the user. 14917 // We want to try to keep it around more aggressively, to give 14918 // a good experience around switching between two apps. 14919 adj = ProcessList.PREVIOUS_APP_ADJ; 14920 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14921 app.cached = false; 14922 app.adjType = "previous"; 14923 } 14924 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14925 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14926 } 14927 } 14928 14929 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14930 + " reason=" + app.adjType); 14931 14932 // By default, we use the computed adjustment. It may be changed if 14933 // there are applications dependent on our services or providers, but 14934 // this gives us a baseline and makes sure we don't get into an 14935 // infinite recursion. 14936 app.adjSeq = mAdjSeq; 14937 app.curRawAdj = adj; 14938 app.hasStartedServices = false; 14939 14940 if (mBackupTarget != null && app == mBackupTarget.app) { 14941 // If possible we want to avoid killing apps while they're being backed up 14942 if (adj > ProcessList.BACKUP_APP_ADJ) { 14943 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14944 adj = ProcessList.BACKUP_APP_ADJ; 14945 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14946 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14947 } 14948 app.adjType = "backup"; 14949 app.cached = false; 14950 } 14951 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14952 procState = ActivityManager.PROCESS_STATE_BACKUP; 14953 } 14954 } 14955 14956 boolean mayBeTop = false; 14957 14958 for (int is = app.services.size()-1; 14959 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14960 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14961 || procState > ActivityManager.PROCESS_STATE_TOP); 14962 is--) { 14963 ServiceRecord s = app.services.valueAt(is); 14964 if (s.startRequested) { 14965 app.hasStartedServices = true; 14966 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14967 procState = ActivityManager.PROCESS_STATE_SERVICE; 14968 } 14969 if (app.hasShownUi && app != mHomeProcess) { 14970 // If this process has shown some UI, let it immediately 14971 // go to the LRU list because it may be pretty heavy with 14972 // UI stuff. We'll tag it with a label just to help 14973 // debug and understand what is going on. 14974 if (adj > ProcessList.SERVICE_ADJ) { 14975 app.adjType = "cch-started-ui-services"; 14976 } 14977 } else { 14978 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14979 // This service has seen some activity within 14980 // recent memory, so we will keep its process ahead 14981 // of the background processes. 14982 if (adj > ProcessList.SERVICE_ADJ) { 14983 adj = ProcessList.SERVICE_ADJ; 14984 app.adjType = "started-services"; 14985 app.cached = false; 14986 } 14987 } 14988 // If we have let the service slide into the background 14989 // state, still have some text describing what it is doing 14990 // even though the service no longer has an impact. 14991 if (adj > ProcessList.SERVICE_ADJ) { 14992 app.adjType = "cch-started-services"; 14993 } 14994 } 14995 // Don't kill this process because it is doing work; it 14996 // has said it is doing work. 14997 app.keeping = true; 14998 } 14999 for (int conni = s.connections.size()-1; 15000 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15001 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15002 || procState > ActivityManager.PROCESS_STATE_TOP); 15003 conni--) { 15004 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15005 for (int i = 0; 15006 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15007 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15008 || procState > ActivityManager.PROCESS_STATE_TOP); 15009 i++) { 15010 // XXX should compute this based on the max of 15011 // all connected clients. 15012 ConnectionRecord cr = clist.get(i); 15013 if (cr.binding.client == app) { 15014 // Binding to ourself is not interesting. 15015 continue; 15016 } 15017 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15018 ProcessRecord client = cr.binding.client; 15019 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15020 TOP_APP, doingAll, now); 15021 int clientProcState = client.curProcState; 15022 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15023 // If the other app is cached for any reason, for purposes here 15024 // we are going to consider it empty. The specific cached state 15025 // doesn't propagate except under certain conditions. 15026 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15027 } 15028 String adjType = null; 15029 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15030 // Not doing bind OOM management, so treat 15031 // this guy more like a started service. 15032 if (app.hasShownUi && app != mHomeProcess) { 15033 // If this process has shown some UI, let it immediately 15034 // go to the LRU list because it may be pretty heavy with 15035 // UI stuff. We'll tag it with a label just to help 15036 // debug and understand what is going on. 15037 if (adj > clientAdj) { 15038 adjType = "cch-bound-ui-services"; 15039 } 15040 app.cached = false; 15041 clientAdj = adj; 15042 clientProcState = procState; 15043 } else { 15044 if (now >= (s.lastActivity 15045 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15046 // This service has not seen activity within 15047 // recent memory, so allow it to drop to the 15048 // LRU list if there is no other reason to keep 15049 // it around. We'll also tag it with a label just 15050 // to help debug and undertand what is going on. 15051 if (adj > clientAdj) { 15052 adjType = "cch-bound-services"; 15053 } 15054 clientAdj = adj; 15055 } 15056 } 15057 } 15058 if (adj > clientAdj) { 15059 // If this process has recently shown UI, and 15060 // the process that is binding to it is less 15061 // important than being visible, then we don't 15062 // care about the binding as much as we care 15063 // about letting this process get into the LRU 15064 // list to be killed and restarted if needed for 15065 // memory. 15066 if (app.hasShownUi && app != mHomeProcess 15067 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15068 adjType = "cch-bound-ui-services"; 15069 } else { 15070 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15071 |Context.BIND_IMPORTANT)) != 0) { 15072 adj = clientAdj; 15073 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15074 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15075 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15076 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15077 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15078 adj = clientAdj; 15079 } else { 15080 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15081 adj = ProcessList.VISIBLE_APP_ADJ; 15082 } 15083 } 15084 if (!client.cached) { 15085 app.cached = false; 15086 } 15087 if (client.keeping) { 15088 app.keeping = true; 15089 } 15090 adjType = "service"; 15091 } 15092 } 15093 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15094 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15095 schedGroup = Process.THREAD_GROUP_DEFAULT; 15096 } 15097 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15098 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15099 // Special handling of clients who are in the top state. 15100 // We *may* want to consider this process to be in the 15101 // top state as well, but only if there is not another 15102 // reason for it to be running. Being on the top is a 15103 // special state, meaning you are specifically running 15104 // for the current top app. If the process is already 15105 // running in the background for some other reason, it 15106 // is more important to continue considering it to be 15107 // in the background state. 15108 mayBeTop = true; 15109 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15110 } else { 15111 // Special handling for above-top states (persistent 15112 // processes). These should not bring the current process 15113 // into the top state, since they are not on top. Instead 15114 // give them the best state after that. 15115 clientProcState = 15116 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15117 } 15118 } 15119 } else { 15120 if (clientProcState < 15121 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15122 clientProcState = 15123 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15124 } 15125 } 15126 if (procState > clientProcState) { 15127 procState = clientProcState; 15128 } 15129 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15130 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15131 app.pendingUiClean = true; 15132 } 15133 if (adjType != null) { 15134 app.adjType = adjType; 15135 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15136 .REASON_SERVICE_IN_USE; 15137 app.adjSource = cr.binding.client; 15138 app.adjSourceOom = clientAdj; 15139 app.adjTarget = s.name; 15140 } 15141 } 15142 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15143 app.treatLikeActivity = true; 15144 } 15145 final ActivityRecord a = cr.activity; 15146 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15147 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15148 (a.visible || a.state == ActivityState.RESUMED 15149 || a.state == ActivityState.PAUSING)) { 15150 adj = ProcessList.FOREGROUND_APP_ADJ; 15151 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15152 schedGroup = Process.THREAD_GROUP_DEFAULT; 15153 } 15154 app.cached = false; 15155 app.adjType = "service"; 15156 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15157 .REASON_SERVICE_IN_USE; 15158 app.adjSource = a; 15159 app.adjSourceOom = adj; 15160 app.adjTarget = s.name; 15161 } 15162 } 15163 } 15164 } 15165 } 15166 15167 for (int provi = app.pubProviders.size()-1; 15168 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15169 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15170 || procState > ActivityManager.PROCESS_STATE_TOP); 15171 provi--) { 15172 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15173 for (int i = cpr.connections.size()-1; 15174 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15175 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15176 || procState > ActivityManager.PROCESS_STATE_TOP); 15177 i--) { 15178 ContentProviderConnection conn = cpr.connections.get(i); 15179 ProcessRecord client = conn.client; 15180 if (client == app) { 15181 // Being our own client is not interesting. 15182 continue; 15183 } 15184 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15185 int clientProcState = client.curProcState; 15186 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15187 // If the other app is cached for any reason, for purposes here 15188 // we are going to consider it empty. 15189 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15190 } 15191 if (adj > clientAdj) { 15192 if (app.hasShownUi && app != mHomeProcess 15193 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15194 app.adjType = "cch-ui-provider"; 15195 } else { 15196 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15197 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15198 app.adjType = "provider"; 15199 } 15200 app.cached &= client.cached; 15201 app.keeping |= client.keeping; 15202 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15203 .REASON_PROVIDER_IN_USE; 15204 app.adjSource = client; 15205 app.adjSourceOom = clientAdj; 15206 app.adjTarget = cpr.name; 15207 } 15208 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15209 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15210 // Special handling of clients who are in the top state. 15211 // We *may* want to consider this process to be in the 15212 // top state as well, but only if there is not another 15213 // reason for it to be running. Being on the top is a 15214 // special state, meaning you are specifically running 15215 // for the current top app. If the process is already 15216 // running in the background for some other reason, it 15217 // is more important to continue considering it to be 15218 // in the background state. 15219 mayBeTop = true; 15220 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15221 } else { 15222 // Special handling for above-top states (persistent 15223 // processes). These should not bring the current process 15224 // into the top state, since they are not on top. Instead 15225 // give them the best state after that. 15226 clientProcState = 15227 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15228 } 15229 } 15230 if (procState > clientProcState) { 15231 procState = clientProcState; 15232 } 15233 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15234 schedGroup = Process.THREAD_GROUP_DEFAULT; 15235 } 15236 } 15237 // If the provider has external (non-framework) process 15238 // dependencies, ensure that its adjustment is at least 15239 // FOREGROUND_APP_ADJ. 15240 if (cpr.hasExternalProcessHandles()) { 15241 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15242 adj = ProcessList.FOREGROUND_APP_ADJ; 15243 schedGroup = Process.THREAD_GROUP_DEFAULT; 15244 app.cached = false; 15245 app.keeping = true; 15246 app.adjType = "provider"; 15247 app.adjTarget = cpr.name; 15248 } 15249 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15250 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15251 } 15252 } 15253 } 15254 15255 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15256 // A client of one of our services or providers is in the top state. We 15257 // *may* want to be in the top state, but not if we are already running in 15258 // the background for some other reason. For the decision here, we are going 15259 // to pick out a few specific states that we want to remain in when a client 15260 // is top (states that tend to be longer-term) and otherwise allow it to go 15261 // to the top state. 15262 switch (procState) { 15263 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15264 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15265 case ActivityManager.PROCESS_STATE_SERVICE: 15266 // These all are longer-term states, so pull them up to the top 15267 // of the background states, but not all the way to the top state. 15268 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15269 break; 15270 default: 15271 // Otherwise, top is a better choice, so take it. 15272 procState = ActivityManager.PROCESS_STATE_TOP; 15273 break; 15274 } 15275 } 15276 15277 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15278 if (app.hasClientActivities) { 15279 // This is a cached process, but with client activities. Mark it so. 15280 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15281 app.adjType = "cch-client-act"; 15282 } else if (app.treatLikeActivity) { 15283 // This is a cached process, but somebody wants us to treat it like it has 15284 // an activity, okay! 15285 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15286 app.adjType = "cch-as-act"; 15287 } 15288 } 15289 15290 if (adj == ProcessList.SERVICE_ADJ) { 15291 if (doingAll) { 15292 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15293 mNewNumServiceProcs++; 15294 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15295 if (!app.serviceb) { 15296 // This service isn't far enough down on the LRU list to 15297 // normally be a B service, but if we are low on RAM and it 15298 // is large we want to force it down since we would prefer to 15299 // keep launcher over it. 15300 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15301 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15302 app.serviceHighRam = true; 15303 app.serviceb = true; 15304 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15305 } else { 15306 mNewNumAServiceProcs++; 15307 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15308 } 15309 } else { 15310 app.serviceHighRam = false; 15311 } 15312 } 15313 if (app.serviceb) { 15314 adj = ProcessList.SERVICE_B_ADJ; 15315 } 15316 } 15317 15318 app.curRawAdj = adj; 15319 15320 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15321 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15322 if (adj > app.maxAdj) { 15323 adj = app.maxAdj; 15324 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15325 schedGroup = Process.THREAD_GROUP_DEFAULT; 15326 } 15327 } 15328 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15329 app.keeping = true; 15330 } 15331 15332 // Do final modification to adj. Everything we do between here and applying 15333 // the final setAdj must be done in this function, because we will also use 15334 // it when computing the final cached adj later. Note that we don't need to 15335 // worry about this for max adj above, since max adj will always be used to 15336 // keep it out of the cached vaues. 15337 app.curAdj = app.modifyRawOomAdj(adj); 15338 app.curSchedGroup = schedGroup; 15339 app.curProcState = procState; 15340 app.foregroundActivities = foregroundActivities; 15341 15342 return app.curRawAdj; 15343 } 15344 15345 /** 15346 * Schedule PSS collection of a process. 15347 */ 15348 void requestPssLocked(ProcessRecord proc, int procState) { 15349 if (mPendingPssProcesses.contains(proc)) { 15350 return; 15351 } 15352 if (mPendingPssProcesses.size() == 0) { 15353 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15354 } 15355 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15356 proc.pssProcState = procState; 15357 mPendingPssProcesses.add(proc); 15358 } 15359 15360 /** 15361 * Schedule PSS collection of all processes. 15362 */ 15363 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15364 if (!always) { 15365 if (now < (mLastFullPssTime + 15366 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15367 return; 15368 } 15369 } 15370 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15371 mLastFullPssTime = now; 15372 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15373 mPendingPssProcesses.clear(); 15374 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15375 ProcessRecord app = mLruProcesses.get(i); 15376 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15377 app.pssProcState = app.setProcState; 15378 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15379 isSleeping(), now); 15380 mPendingPssProcesses.add(app); 15381 } 15382 } 15383 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15384 } 15385 15386 /** 15387 * Ask a given process to GC right now. 15388 */ 15389 final void performAppGcLocked(ProcessRecord app) { 15390 try { 15391 app.lastRequestedGc = SystemClock.uptimeMillis(); 15392 if (app.thread != null) { 15393 if (app.reportLowMemory) { 15394 app.reportLowMemory = false; 15395 app.thread.scheduleLowMemory(); 15396 } else { 15397 app.thread.processInBackground(); 15398 } 15399 } 15400 } catch (Exception e) { 15401 // whatever. 15402 } 15403 } 15404 15405 /** 15406 * Returns true if things are idle enough to perform GCs. 15407 */ 15408 private final boolean canGcNowLocked() { 15409 boolean processingBroadcasts = false; 15410 for (BroadcastQueue q : mBroadcastQueues) { 15411 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15412 processingBroadcasts = true; 15413 } 15414 } 15415 return !processingBroadcasts 15416 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15417 } 15418 15419 /** 15420 * Perform GCs on all processes that are waiting for it, but only 15421 * if things are idle. 15422 */ 15423 final void performAppGcsLocked() { 15424 final int N = mProcessesToGc.size(); 15425 if (N <= 0) { 15426 return; 15427 } 15428 if (canGcNowLocked()) { 15429 while (mProcessesToGc.size() > 0) { 15430 ProcessRecord proc = mProcessesToGc.remove(0); 15431 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15432 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15433 <= SystemClock.uptimeMillis()) { 15434 // To avoid spamming the system, we will GC processes one 15435 // at a time, waiting a few seconds between each. 15436 performAppGcLocked(proc); 15437 scheduleAppGcsLocked(); 15438 return; 15439 } else { 15440 // It hasn't been long enough since we last GCed this 15441 // process... put it in the list to wait for its time. 15442 addProcessToGcListLocked(proc); 15443 break; 15444 } 15445 } 15446 } 15447 15448 scheduleAppGcsLocked(); 15449 } 15450 } 15451 15452 /** 15453 * If all looks good, perform GCs on all processes waiting for them. 15454 */ 15455 final void performAppGcsIfAppropriateLocked() { 15456 if (canGcNowLocked()) { 15457 performAppGcsLocked(); 15458 return; 15459 } 15460 // Still not idle, wait some more. 15461 scheduleAppGcsLocked(); 15462 } 15463 15464 /** 15465 * Schedule the execution of all pending app GCs. 15466 */ 15467 final void scheduleAppGcsLocked() { 15468 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15469 15470 if (mProcessesToGc.size() > 0) { 15471 // Schedule a GC for the time to the next process. 15472 ProcessRecord proc = mProcessesToGc.get(0); 15473 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15474 15475 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15476 long now = SystemClock.uptimeMillis(); 15477 if (when < (now+GC_TIMEOUT)) { 15478 when = now + GC_TIMEOUT; 15479 } 15480 mHandler.sendMessageAtTime(msg, when); 15481 } 15482 } 15483 15484 /** 15485 * Add a process to the array of processes waiting to be GCed. Keeps the 15486 * list in sorted order by the last GC time. The process can't already be 15487 * on the list. 15488 */ 15489 final void addProcessToGcListLocked(ProcessRecord proc) { 15490 boolean added = false; 15491 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15492 if (mProcessesToGc.get(i).lastRequestedGc < 15493 proc.lastRequestedGc) { 15494 added = true; 15495 mProcessesToGc.add(i+1, proc); 15496 break; 15497 } 15498 } 15499 if (!added) { 15500 mProcessesToGc.add(0, proc); 15501 } 15502 } 15503 15504 /** 15505 * Set up to ask a process to GC itself. This will either do it 15506 * immediately, or put it on the list of processes to gc the next 15507 * time things are idle. 15508 */ 15509 final void scheduleAppGcLocked(ProcessRecord app) { 15510 long now = SystemClock.uptimeMillis(); 15511 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15512 return; 15513 } 15514 if (!mProcessesToGc.contains(app)) { 15515 addProcessToGcListLocked(app); 15516 scheduleAppGcsLocked(); 15517 } 15518 } 15519 15520 final void checkExcessivePowerUsageLocked(boolean doKills) { 15521 updateCpuStatsNow(); 15522 15523 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15524 boolean doWakeKills = doKills; 15525 boolean doCpuKills = doKills; 15526 if (mLastPowerCheckRealtime == 0) { 15527 doWakeKills = false; 15528 } 15529 if (mLastPowerCheckUptime == 0) { 15530 doCpuKills = false; 15531 } 15532 if (stats.isScreenOn()) { 15533 doWakeKills = false; 15534 } 15535 final long curRealtime = SystemClock.elapsedRealtime(); 15536 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15537 final long curUptime = SystemClock.uptimeMillis(); 15538 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15539 mLastPowerCheckRealtime = curRealtime; 15540 mLastPowerCheckUptime = curUptime; 15541 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15542 doWakeKills = false; 15543 } 15544 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15545 doCpuKills = false; 15546 } 15547 int i = mLruProcesses.size(); 15548 while (i > 0) { 15549 i--; 15550 ProcessRecord app = mLruProcesses.get(i); 15551 if (!app.keeping) { 15552 long wtime; 15553 synchronized (stats) { 15554 wtime = stats.getProcessWakeTime(app.info.uid, 15555 app.pid, curRealtime); 15556 } 15557 long wtimeUsed = wtime - app.lastWakeTime; 15558 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15559 if (DEBUG_POWER) { 15560 StringBuilder sb = new StringBuilder(128); 15561 sb.append("Wake for "); 15562 app.toShortString(sb); 15563 sb.append(": over "); 15564 TimeUtils.formatDuration(realtimeSince, sb); 15565 sb.append(" used "); 15566 TimeUtils.formatDuration(wtimeUsed, sb); 15567 sb.append(" ("); 15568 sb.append((wtimeUsed*100)/realtimeSince); 15569 sb.append("%)"); 15570 Slog.i(TAG, sb.toString()); 15571 sb.setLength(0); 15572 sb.append("CPU for "); 15573 app.toShortString(sb); 15574 sb.append(": over "); 15575 TimeUtils.formatDuration(uptimeSince, sb); 15576 sb.append(" used "); 15577 TimeUtils.formatDuration(cputimeUsed, sb); 15578 sb.append(" ("); 15579 sb.append((cputimeUsed*100)/uptimeSince); 15580 sb.append("%)"); 15581 Slog.i(TAG, sb.toString()); 15582 } 15583 // If a process has held a wake lock for more 15584 // than 50% of the time during this period, 15585 // that sounds bad. Kill! 15586 if (doWakeKills && realtimeSince > 0 15587 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15588 synchronized (stats) { 15589 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15590 realtimeSince, wtimeUsed); 15591 } 15592 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15593 + " during " + realtimeSince); 15594 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15595 } else if (doCpuKills && uptimeSince > 0 15596 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15597 synchronized (stats) { 15598 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15599 uptimeSince, cputimeUsed); 15600 } 15601 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15602 + " during " + uptimeSince); 15603 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15604 } else { 15605 app.lastWakeTime = wtime; 15606 app.lastCpuTime = app.curCpuTime; 15607 } 15608 } 15609 } 15610 } 15611 15612 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15613 ProcessRecord TOP_APP, boolean doingAll, long now) { 15614 boolean success = true; 15615 15616 if (app.curRawAdj != app.setRawAdj) { 15617 if (wasKeeping && !app.keeping) { 15618 // This app is no longer something we want to keep. Note 15619 // its current wake lock time to later know to kill it if 15620 // it is not behaving well. 15621 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15622 synchronized (stats) { 15623 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15624 app.pid, SystemClock.elapsedRealtime()); 15625 } 15626 app.lastCpuTime = app.curCpuTime; 15627 } 15628 15629 app.setRawAdj = app.curRawAdj; 15630 } 15631 15632 int changes = 0; 15633 15634 if (app.curAdj != app.setAdj) { 15635 ProcessList.setOomAdj(app.pid, app.curAdj); 15636 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15637 TAG, "Set " + app.pid + " " + app.processName + 15638 " adj " + app.curAdj + ": " + app.adjType); 15639 app.setAdj = app.curAdj; 15640 } 15641 15642 if (app.setSchedGroup != app.curSchedGroup) { 15643 app.setSchedGroup = app.curSchedGroup; 15644 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15645 "Setting process group of " + app.processName 15646 + " to " + app.curSchedGroup); 15647 if (app.waitingToKill != null && 15648 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15649 killUnneededProcessLocked(app, app.waitingToKill); 15650 success = false; 15651 } else { 15652 if (true) { 15653 long oldId = Binder.clearCallingIdentity(); 15654 try { 15655 Process.setProcessGroup(app.pid, app.curSchedGroup); 15656 } catch (Exception e) { 15657 Slog.w(TAG, "Failed setting process group of " + app.pid 15658 + " to " + app.curSchedGroup); 15659 e.printStackTrace(); 15660 } finally { 15661 Binder.restoreCallingIdentity(oldId); 15662 } 15663 } else { 15664 if (app.thread != null) { 15665 try { 15666 app.thread.setSchedulingGroup(app.curSchedGroup); 15667 } catch (RemoteException e) { 15668 } 15669 } 15670 } 15671 Process.setSwappiness(app.pid, 15672 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15673 } 15674 } 15675 if (app.repForegroundActivities != app.foregroundActivities) { 15676 app.repForegroundActivities = app.foregroundActivities; 15677 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15678 } 15679 if (app.repProcState != app.curProcState) { 15680 app.repProcState = app.curProcState; 15681 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15682 if (app.thread != null) { 15683 try { 15684 if (false) { 15685 //RuntimeException h = new RuntimeException("here"); 15686 Slog.i(TAG, "Sending new process state " + app.repProcState 15687 + " to " + app /*, h*/); 15688 } 15689 app.thread.setProcessState(app.repProcState); 15690 } catch (RemoteException e) { 15691 } 15692 } 15693 } 15694 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15695 app.setProcState)) { 15696 app.lastStateTime = now; 15697 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15698 isSleeping(), now); 15699 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15700 + ProcessList.makeProcStateString(app.setProcState) + " to " 15701 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15702 + (app.nextPssTime-now) + ": " + app); 15703 } else { 15704 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15705 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15706 requestPssLocked(app, app.setProcState); 15707 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15708 isSleeping(), now); 15709 } else if (false && DEBUG_PSS) { 15710 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15711 } 15712 } 15713 if (app.setProcState != app.curProcState) { 15714 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15715 "Proc state change of " + app.processName 15716 + " to " + app.curProcState); 15717 app.setProcState = app.curProcState; 15718 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15719 app.notCachedSinceIdle = false; 15720 } 15721 if (!doingAll) { 15722 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15723 } else { 15724 app.procStateChanged = true; 15725 } 15726 } 15727 15728 if (changes != 0) { 15729 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15730 int i = mPendingProcessChanges.size()-1; 15731 ProcessChangeItem item = null; 15732 while (i >= 0) { 15733 item = mPendingProcessChanges.get(i); 15734 if (item.pid == app.pid) { 15735 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15736 break; 15737 } 15738 i--; 15739 } 15740 if (i < 0) { 15741 // No existing item in pending changes; need a new one. 15742 final int NA = mAvailProcessChanges.size(); 15743 if (NA > 0) { 15744 item = mAvailProcessChanges.remove(NA-1); 15745 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15746 } else { 15747 item = new ProcessChangeItem(); 15748 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15749 } 15750 item.changes = 0; 15751 item.pid = app.pid; 15752 item.uid = app.info.uid; 15753 if (mPendingProcessChanges.size() == 0) { 15754 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15755 "*** Enqueueing dispatch processes changed!"); 15756 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15757 } 15758 mPendingProcessChanges.add(item); 15759 } 15760 item.changes |= changes; 15761 item.processState = app.repProcState; 15762 item.foregroundActivities = app.repForegroundActivities; 15763 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15764 + Integer.toHexString(System.identityHashCode(item)) 15765 + " " + app.toShortString() + ": changes=" + item.changes 15766 + " procState=" + item.processState 15767 + " foreground=" + item.foregroundActivities 15768 + " type=" + app.adjType + " source=" + app.adjSource 15769 + " target=" + app.adjTarget); 15770 } 15771 15772 return success; 15773 } 15774 15775 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15776 if (proc.thread != null && proc.baseProcessTracker != null) { 15777 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15778 } 15779 } 15780 15781 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15782 ProcessRecord TOP_APP, boolean doingAll, long now) { 15783 if (app.thread == null) { 15784 return false; 15785 } 15786 15787 final boolean wasKeeping = app.keeping; 15788 15789 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15790 15791 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15792 } 15793 15794 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15795 boolean oomAdj) { 15796 if (isForeground != proc.foregroundServices) { 15797 proc.foregroundServices = isForeground; 15798 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15799 proc.info.uid); 15800 if (isForeground) { 15801 if (curProcs == null) { 15802 curProcs = new ArrayList<ProcessRecord>(); 15803 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15804 } 15805 if (!curProcs.contains(proc)) { 15806 curProcs.add(proc); 15807 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15808 proc.info.packageName, proc.info.uid); 15809 } 15810 } else { 15811 if (curProcs != null) { 15812 if (curProcs.remove(proc)) { 15813 mBatteryStatsService.noteEvent( 15814 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15815 proc.info.packageName, proc.info.uid); 15816 if (curProcs.size() <= 0) { 15817 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15818 } 15819 } 15820 } 15821 } 15822 if (oomAdj) { 15823 updateOomAdjLocked(); 15824 } 15825 } 15826 } 15827 15828 private final ActivityRecord resumedAppLocked() { 15829 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15830 String pkg; 15831 int uid; 15832 if (act != null && !act.sleeping) { 15833 pkg = act.packageName; 15834 uid = act.info.applicationInfo.uid; 15835 } else { 15836 pkg = null; 15837 uid = -1; 15838 } 15839 // Has the UID or resumed package name changed? 15840 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15841 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15842 if (mCurResumedPackage != null) { 15843 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15844 mCurResumedPackage, mCurResumedUid); 15845 } 15846 mCurResumedPackage = pkg; 15847 mCurResumedUid = uid; 15848 if (mCurResumedPackage != null) { 15849 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15850 mCurResumedPackage, mCurResumedUid); 15851 } 15852 } 15853 return act; 15854 } 15855 15856 final boolean updateOomAdjLocked(ProcessRecord app) { 15857 final ActivityRecord TOP_ACT = resumedAppLocked(); 15858 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15859 final boolean wasCached = app.cached; 15860 15861 mAdjSeq++; 15862 15863 // This is the desired cached adjusment we want to tell it to use. 15864 // If our app is currently cached, we know it, and that is it. Otherwise, 15865 // we don't know it yet, and it needs to now be cached we will then 15866 // need to do a complete oom adj. 15867 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15868 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15869 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15870 SystemClock.uptimeMillis()); 15871 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15872 // Changed to/from cached state, so apps after it in the LRU 15873 // list may also be changed. 15874 updateOomAdjLocked(); 15875 } 15876 return success; 15877 } 15878 15879 final void updateOomAdjLocked() { 15880 final ActivityRecord TOP_ACT = resumedAppLocked(); 15881 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15882 final long now = SystemClock.uptimeMillis(); 15883 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15884 final int N = mLruProcesses.size(); 15885 15886 if (false) { 15887 RuntimeException e = new RuntimeException(); 15888 e.fillInStackTrace(); 15889 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15890 } 15891 15892 mAdjSeq++; 15893 mNewNumServiceProcs = 0; 15894 mNewNumAServiceProcs = 0; 15895 15896 final int emptyProcessLimit; 15897 final int cachedProcessLimit; 15898 if (mProcessLimit <= 0) { 15899 emptyProcessLimit = cachedProcessLimit = 0; 15900 } else if (mProcessLimit == 1) { 15901 emptyProcessLimit = 1; 15902 cachedProcessLimit = 0; 15903 } else { 15904 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15905 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15906 } 15907 15908 // Let's determine how many processes we have running vs. 15909 // how many slots we have for background processes; we may want 15910 // to put multiple processes in a slot of there are enough of 15911 // them. 15912 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15913 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15914 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15915 if (numEmptyProcs > cachedProcessLimit) { 15916 // If there are more empty processes than our limit on cached 15917 // processes, then use the cached process limit for the factor. 15918 // This ensures that the really old empty processes get pushed 15919 // down to the bottom, so if we are running low on memory we will 15920 // have a better chance at keeping around more cached processes 15921 // instead of a gazillion empty processes. 15922 numEmptyProcs = cachedProcessLimit; 15923 } 15924 int emptyFactor = numEmptyProcs/numSlots; 15925 if (emptyFactor < 1) emptyFactor = 1; 15926 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15927 if (cachedFactor < 1) cachedFactor = 1; 15928 int stepCached = 0; 15929 int stepEmpty = 0; 15930 int numCached = 0; 15931 int numEmpty = 0; 15932 int numTrimming = 0; 15933 15934 mNumNonCachedProcs = 0; 15935 mNumCachedHiddenProcs = 0; 15936 15937 // First update the OOM adjustment for each of the 15938 // application processes based on their current state. 15939 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15940 int nextCachedAdj = curCachedAdj+1; 15941 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15942 int nextEmptyAdj = curEmptyAdj+2; 15943 for (int i=N-1; i>=0; i--) { 15944 ProcessRecord app = mLruProcesses.get(i); 15945 if (!app.killedByAm && app.thread != null) { 15946 app.procStateChanged = false; 15947 final boolean wasKeeping = app.keeping; 15948 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15949 15950 // If we haven't yet assigned the final cached adj 15951 // to the process, do that now. 15952 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15953 switch (app.curProcState) { 15954 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15955 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15956 // This process is a cached process holding activities... 15957 // assign it the next cached value for that type, and then 15958 // step that cached level. 15959 app.curRawAdj = curCachedAdj; 15960 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15961 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15962 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15963 + ")"); 15964 if (curCachedAdj != nextCachedAdj) { 15965 stepCached++; 15966 if (stepCached >= cachedFactor) { 15967 stepCached = 0; 15968 curCachedAdj = nextCachedAdj; 15969 nextCachedAdj += 2; 15970 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15971 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15972 } 15973 } 15974 } 15975 break; 15976 default: 15977 // For everything else, assign next empty cached process 15978 // level and bump that up. Note that this means that 15979 // long-running services that have dropped down to the 15980 // cached level will be treated as empty (since their process 15981 // state is still as a service), which is what we want. 15982 app.curRawAdj = curEmptyAdj; 15983 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15984 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15985 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15986 + ")"); 15987 if (curEmptyAdj != nextEmptyAdj) { 15988 stepEmpty++; 15989 if (stepEmpty >= emptyFactor) { 15990 stepEmpty = 0; 15991 curEmptyAdj = nextEmptyAdj; 15992 nextEmptyAdj += 2; 15993 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15994 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15995 } 15996 } 15997 } 15998 break; 15999 } 16000 } 16001 16002 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16003 16004 // Count the number of process types. 16005 switch (app.curProcState) { 16006 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16007 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16008 mNumCachedHiddenProcs++; 16009 numCached++; 16010 if (numCached > cachedProcessLimit) { 16011 killUnneededProcessLocked(app, "cached #" + numCached); 16012 } 16013 break; 16014 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16015 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16016 && app.lastActivityTime < oldTime) { 16017 killUnneededProcessLocked(app, "empty for " 16018 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16019 / 1000) + "s"); 16020 } else { 16021 numEmpty++; 16022 if (numEmpty > emptyProcessLimit) { 16023 killUnneededProcessLocked(app, "empty #" + numEmpty); 16024 } 16025 } 16026 break; 16027 default: 16028 mNumNonCachedProcs++; 16029 break; 16030 } 16031 16032 if (app.isolated && app.services.size() <= 0) { 16033 // If this is an isolated process, and there are no 16034 // services running in it, then the process is no longer 16035 // needed. We agressively kill these because we can by 16036 // definition not re-use the same process again, and it is 16037 // good to avoid having whatever code was running in them 16038 // left sitting around after no longer needed. 16039 killUnneededProcessLocked(app, "isolated not needed"); 16040 } 16041 16042 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16043 && !app.killedByAm) { 16044 numTrimming++; 16045 } 16046 } 16047 } 16048 16049 mNumServiceProcs = mNewNumServiceProcs; 16050 16051 // Now determine the memory trimming level of background processes. 16052 // Unfortunately we need to start at the back of the list to do this 16053 // properly. We only do this if the number of background apps we 16054 // are managing to keep around is less than half the maximum we desire; 16055 // if we are keeping a good number around, we'll let them use whatever 16056 // memory they want. 16057 final int numCachedAndEmpty = numCached + numEmpty; 16058 int memFactor; 16059 if (numCached <= ProcessList.TRIM_CACHED_APPS 16060 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16061 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16062 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16063 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16064 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16065 } else { 16066 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16067 } 16068 } else { 16069 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16070 } 16071 // We always allow the memory level to go up (better). We only allow it to go 16072 // down if we are in a state where that is allowed, *and* the total number of processes 16073 // has gone down since last time. 16074 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16075 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16076 + " last=" + mLastNumProcesses); 16077 if (memFactor > mLastMemoryLevel) { 16078 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16079 memFactor = mLastMemoryLevel; 16080 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16081 } 16082 } 16083 mLastMemoryLevel = memFactor; 16084 mLastNumProcesses = mLruProcesses.size(); 16085 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16086 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16087 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16088 if (mLowRamStartTime == 0) { 16089 mLowRamStartTime = now; 16090 } 16091 int step = 0; 16092 int fgTrimLevel; 16093 switch (memFactor) { 16094 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16095 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16096 break; 16097 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16098 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16099 break; 16100 default: 16101 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16102 break; 16103 } 16104 int factor = numTrimming/3; 16105 int minFactor = 2; 16106 if (mHomeProcess != null) minFactor++; 16107 if (mPreviousProcess != null) minFactor++; 16108 if (factor < minFactor) factor = minFactor; 16109 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16110 for (int i=N-1; i>=0; i--) { 16111 ProcessRecord app = mLruProcesses.get(i); 16112 if (allChanged || app.procStateChanged) { 16113 setProcessTrackerState(app, trackerMemFactor, now); 16114 app.procStateChanged = false; 16115 } 16116 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16117 && !app.killedByAm) { 16118 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16119 try { 16120 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16121 "Trimming memory of " + app.processName 16122 + " to " + curLevel); 16123 app.thread.scheduleTrimMemory(curLevel); 16124 } catch (RemoteException e) { 16125 } 16126 if (false) { 16127 // For now we won't do this; our memory trimming seems 16128 // to be good enough at this point that destroying 16129 // activities causes more harm than good. 16130 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16131 && app != mHomeProcess && app != mPreviousProcess) { 16132 // Need to do this on its own message because the stack may not 16133 // be in a consistent state at this point. 16134 // For these apps we will also finish their activities 16135 // to help them free memory. 16136 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16137 } 16138 } 16139 } 16140 app.trimMemoryLevel = curLevel; 16141 step++; 16142 if (step >= factor) { 16143 step = 0; 16144 switch (curLevel) { 16145 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16146 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16147 break; 16148 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16149 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16150 break; 16151 } 16152 } 16153 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16154 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16155 && app.thread != null) { 16156 try { 16157 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16158 "Trimming memory of heavy-weight " + app.processName 16159 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16160 app.thread.scheduleTrimMemory( 16161 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16162 } catch (RemoteException e) { 16163 } 16164 } 16165 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16166 } else { 16167 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16168 || app.systemNoUi) && app.pendingUiClean) { 16169 // If this application is now in the background and it 16170 // had done UI, then give it the special trim level to 16171 // have it free UI resources. 16172 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16173 if (app.trimMemoryLevel < level && app.thread != null) { 16174 try { 16175 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16176 "Trimming memory of bg-ui " + app.processName 16177 + " to " + level); 16178 app.thread.scheduleTrimMemory(level); 16179 } catch (RemoteException e) { 16180 } 16181 } 16182 app.pendingUiClean = false; 16183 } 16184 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16185 try { 16186 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16187 "Trimming memory of fg " + app.processName 16188 + " to " + fgTrimLevel); 16189 app.thread.scheduleTrimMemory(fgTrimLevel); 16190 } catch (RemoteException e) { 16191 } 16192 } 16193 app.trimMemoryLevel = fgTrimLevel; 16194 } 16195 } 16196 } else { 16197 if (mLowRamStartTime != 0) { 16198 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16199 mLowRamStartTime = 0; 16200 } 16201 for (int i=N-1; i>=0; i--) { 16202 ProcessRecord app = mLruProcesses.get(i); 16203 if (allChanged || app.procStateChanged) { 16204 setProcessTrackerState(app, trackerMemFactor, now); 16205 app.procStateChanged = false; 16206 } 16207 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16208 || app.systemNoUi) && app.pendingUiClean) { 16209 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16210 && app.thread != null) { 16211 try { 16212 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16213 "Trimming memory of ui hidden " + app.processName 16214 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16215 app.thread.scheduleTrimMemory( 16216 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16217 } catch (RemoteException e) { 16218 } 16219 } 16220 app.pendingUiClean = false; 16221 } 16222 app.trimMemoryLevel = 0; 16223 } 16224 } 16225 16226 if (mAlwaysFinishActivities) { 16227 // Need to do this on its own message because the stack may not 16228 // be in a consistent state at this point. 16229 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16230 } 16231 16232 if (allChanged) { 16233 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16234 } 16235 16236 if (mProcessStats.shouldWriteNowLocked(now)) { 16237 mHandler.post(new Runnable() { 16238 @Override public void run() { 16239 synchronized (ActivityManagerService.this) { 16240 mProcessStats.writeStateAsyncLocked(); 16241 } 16242 } 16243 }); 16244 } 16245 16246 if (DEBUG_OOM_ADJ) { 16247 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16248 } 16249 } 16250 16251 final void trimApplications() { 16252 synchronized (this) { 16253 int i; 16254 16255 // First remove any unused application processes whose package 16256 // has been removed. 16257 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16258 final ProcessRecord app = mRemovedProcesses.get(i); 16259 if (app.activities.size() == 0 16260 && app.curReceiver == null && app.services.size() == 0) { 16261 Slog.i( 16262 TAG, "Exiting empty application process " 16263 + app.processName + " (" 16264 + (app.thread != null ? app.thread.asBinder() : null) 16265 + ")\n"); 16266 if (app.pid > 0 && app.pid != MY_PID) { 16267 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16268 app.processName, app.setAdj, "empty"); 16269 app.killedByAm = true; 16270 Process.killProcessQuiet(app.pid); 16271 } else { 16272 try { 16273 app.thread.scheduleExit(); 16274 } catch (Exception e) { 16275 // Ignore exceptions. 16276 } 16277 } 16278 cleanUpApplicationRecordLocked(app, false, true, -1); 16279 mRemovedProcesses.remove(i); 16280 16281 if (app.persistent) { 16282 if (app.persistent) { 16283 addAppLocked(app.info, false); 16284 } 16285 } 16286 } 16287 } 16288 16289 // Now update the oom adj for all processes. 16290 updateOomAdjLocked(); 16291 } 16292 } 16293 16294 /** This method sends the specified signal to each of the persistent apps */ 16295 public void signalPersistentProcesses(int sig) throws RemoteException { 16296 if (sig != Process.SIGNAL_USR1) { 16297 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16298 } 16299 16300 synchronized (this) { 16301 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16302 != PackageManager.PERMISSION_GRANTED) { 16303 throw new SecurityException("Requires permission " 16304 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16305 } 16306 16307 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16308 ProcessRecord r = mLruProcesses.get(i); 16309 if (r.thread != null && r.persistent) { 16310 Process.sendSignal(r.pid, sig); 16311 } 16312 } 16313 } 16314 } 16315 16316 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16317 if (proc == null || proc == mProfileProc) { 16318 proc = mProfileProc; 16319 path = mProfileFile; 16320 profileType = mProfileType; 16321 clearProfilerLocked(); 16322 } 16323 if (proc == null) { 16324 return; 16325 } 16326 try { 16327 proc.thread.profilerControl(false, path, null, profileType); 16328 } catch (RemoteException e) { 16329 throw new IllegalStateException("Process disappeared"); 16330 } 16331 } 16332 16333 private void clearProfilerLocked() { 16334 if (mProfileFd != null) { 16335 try { 16336 mProfileFd.close(); 16337 } catch (IOException e) { 16338 } 16339 } 16340 mProfileApp = null; 16341 mProfileProc = null; 16342 mProfileFile = null; 16343 mProfileType = 0; 16344 mAutoStopProfiler = false; 16345 } 16346 16347 public boolean profileControl(String process, int userId, boolean start, 16348 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16349 16350 try { 16351 synchronized (this) { 16352 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16353 // its own permission. 16354 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16355 != PackageManager.PERMISSION_GRANTED) { 16356 throw new SecurityException("Requires permission " 16357 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16358 } 16359 16360 if (start && fd == null) { 16361 throw new IllegalArgumentException("null fd"); 16362 } 16363 16364 ProcessRecord proc = null; 16365 if (process != null) { 16366 proc = findProcessLocked(process, userId, "profileControl"); 16367 } 16368 16369 if (start && (proc == null || proc.thread == null)) { 16370 throw new IllegalArgumentException("Unknown process: " + process); 16371 } 16372 16373 if (start) { 16374 stopProfilerLocked(null, null, 0); 16375 setProfileApp(proc.info, proc.processName, path, fd, false); 16376 mProfileProc = proc; 16377 mProfileType = profileType; 16378 try { 16379 fd = fd.dup(); 16380 } catch (IOException e) { 16381 fd = null; 16382 } 16383 proc.thread.profilerControl(start, path, fd, profileType); 16384 fd = null; 16385 mProfileFd = null; 16386 } else { 16387 stopProfilerLocked(proc, path, profileType); 16388 if (fd != null) { 16389 try { 16390 fd.close(); 16391 } catch (IOException e) { 16392 } 16393 } 16394 } 16395 16396 return true; 16397 } 16398 } catch (RemoteException e) { 16399 throw new IllegalStateException("Process disappeared"); 16400 } finally { 16401 if (fd != null) { 16402 try { 16403 fd.close(); 16404 } catch (IOException e) { 16405 } 16406 } 16407 } 16408 } 16409 16410 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16411 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16412 userId, true, true, callName, null); 16413 ProcessRecord proc = null; 16414 try { 16415 int pid = Integer.parseInt(process); 16416 synchronized (mPidsSelfLocked) { 16417 proc = mPidsSelfLocked.get(pid); 16418 } 16419 } catch (NumberFormatException e) { 16420 } 16421 16422 if (proc == null) { 16423 ArrayMap<String, SparseArray<ProcessRecord>> all 16424 = mProcessNames.getMap(); 16425 SparseArray<ProcessRecord> procs = all.get(process); 16426 if (procs != null && procs.size() > 0) { 16427 proc = procs.valueAt(0); 16428 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16429 for (int i=1; i<procs.size(); i++) { 16430 ProcessRecord thisProc = procs.valueAt(i); 16431 if (thisProc.userId == userId) { 16432 proc = thisProc; 16433 break; 16434 } 16435 } 16436 } 16437 } 16438 } 16439 16440 return proc; 16441 } 16442 16443 public boolean dumpHeap(String process, int userId, boolean managed, 16444 String path, ParcelFileDescriptor fd) throws RemoteException { 16445 16446 try { 16447 synchronized (this) { 16448 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16449 // its own permission (same as profileControl). 16450 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16451 != PackageManager.PERMISSION_GRANTED) { 16452 throw new SecurityException("Requires permission " 16453 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16454 } 16455 16456 if (fd == null) { 16457 throw new IllegalArgumentException("null fd"); 16458 } 16459 16460 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16461 if (proc == null || proc.thread == null) { 16462 throw new IllegalArgumentException("Unknown process: " + process); 16463 } 16464 16465 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16466 if (!isDebuggable) { 16467 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16468 throw new SecurityException("Process not debuggable: " + proc); 16469 } 16470 } 16471 16472 proc.thread.dumpHeap(managed, path, fd); 16473 fd = null; 16474 return true; 16475 } 16476 } catch (RemoteException e) { 16477 throw new IllegalStateException("Process disappeared"); 16478 } finally { 16479 if (fd != null) { 16480 try { 16481 fd.close(); 16482 } catch (IOException e) { 16483 } 16484 } 16485 } 16486 } 16487 16488 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16489 public void monitor() { 16490 synchronized (this) { } 16491 } 16492 16493 void onCoreSettingsChange(Bundle settings) { 16494 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16495 ProcessRecord processRecord = mLruProcesses.get(i); 16496 try { 16497 if (processRecord.thread != null) { 16498 processRecord.thread.setCoreSettings(settings); 16499 } 16500 } catch (RemoteException re) { 16501 /* ignore */ 16502 } 16503 } 16504 } 16505 16506 // Multi-user methods 16507 16508 /** 16509 * Start user, if its not already running, but don't bring it to foreground. 16510 */ 16511 @Override 16512 public boolean startUserInBackground(final int userId) { 16513 return startUser(userId, /* foreground */ false); 16514 } 16515 16516 /** 16517 * Refreshes the list of users related to the current user when either a 16518 * user switch happens or when a new related user is started in the 16519 * background. 16520 */ 16521 private void updateCurrentProfileIdsLocked() { 16522 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16523 mCurrentUserId, false /* enabledOnly */); 16524 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16525 for (int i = 0; i < currentProfileIds.length; i++) { 16526 currentProfileIds[i] = profiles.get(i).id; 16527 } 16528 mCurrentProfileIds = currentProfileIds; 16529 } 16530 16531 private Set getProfileIdsLocked(int userId) { 16532 Set userIds = new HashSet<Integer>(); 16533 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16534 userId, false /* enabledOnly */); 16535 for (UserInfo user : profiles) { 16536 userIds.add(Integer.valueOf(user.id)); 16537 } 16538 return userIds; 16539 } 16540 16541 @Override 16542 public boolean switchUser(final int userId) { 16543 return startUser(userId, /* foregound */ true); 16544 } 16545 16546 private boolean startUser(final int userId, boolean foreground) { 16547 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16548 != PackageManager.PERMISSION_GRANTED) { 16549 String msg = "Permission Denial: switchUser() from pid=" 16550 + Binder.getCallingPid() 16551 + ", uid=" + Binder.getCallingUid() 16552 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16553 Slog.w(TAG, msg); 16554 throw new SecurityException(msg); 16555 } 16556 16557 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16558 16559 final long ident = Binder.clearCallingIdentity(); 16560 try { 16561 synchronized (this) { 16562 final int oldUserId = mCurrentUserId; 16563 if (oldUserId == userId) { 16564 return true; 16565 } 16566 16567 mStackSupervisor.setLockTaskModeLocked(null); 16568 16569 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16570 if (userInfo == null) { 16571 Slog.w(TAG, "No user info for user #" + userId); 16572 return false; 16573 } 16574 16575 if (foreground) { 16576 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16577 R.anim.screen_user_enter); 16578 } 16579 16580 boolean needStart = false; 16581 16582 // If the user we are switching to is not currently started, then 16583 // we need to start it now. 16584 if (mStartedUsers.get(userId) == null) { 16585 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16586 updateStartedUserArrayLocked(); 16587 needStart = true; 16588 } 16589 16590 final Integer userIdInt = Integer.valueOf(userId); 16591 mUserLru.remove(userIdInt); 16592 mUserLru.add(userIdInt); 16593 16594 if (foreground) { 16595 mCurrentUserId = userId; 16596 updateCurrentProfileIdsLocked(); 16597 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16598 // Once the internal notion of the active user has switched, we lock the device 16599 // with the option to show the user switcher on the keyguard. 16600 mWindowManager.lockNow(null); 16601 } else { 16602 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16603 updateCurrentProfileIdsLocked(); 16604 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16605 mUserLru.remove(currentUserIdInt); 16606 mUserLru.add(currentUserIdInt); 16607 } 16608 16609 final UserStartedState uss = mStartedUsers.get(userId); 16610 16611 // Make sure user is in the started state. If it is currently 16612 // stopping, we need to knock that off. 16613 if (uss.mState == UserStartedState.STATE_STOPPING) { 16614 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16615 // so we can just fairly silently bring the user back from 16616 // the almost-dead. 16617 uss.mState = UserStartedState.STATE_RUNNING; 16618 updateStartedUserArrayLocked(); 16619 needStart = true; 16620 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16621 // This means ACTION_SHUTDOWN has been sent, so we will 16622 // need to treat this as a new boot of the user. 16623 uss.mState = UserStartedState.STATE_BOOTING; 16624 updateStartedUserArrayLocked(); 16625 needStart = true; 16626 } 16627 16628 if (uss.mState == UserStartedState.STATE_BOOTING) { 16629 // Booting up a new user, need to tell system services about it. 16630 // Note that this is on the same handler as scheduling of broadcasts, 16631 // which is important because it needs to go first. 16632 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16633 } 16634 16635 if (foreground) { 16636 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16637 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16638 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16639 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16640 oldUserId, userId, uss)); 16641 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16642 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16643 } 16644 16645 if (needStart) { 16646 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16647 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16648 | Intent.FLAG_RECEIVER_FOREGROUND); 16649 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16650 broadcastIntentLocked(null, null, intent, 16651 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16652 false, false, MY_PID, Process.SYSTEM_UID, userId); 16653 } 16654 16655 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16656 if (userId != UserHandle.USER_OWNER) { 16657 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16658 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16659 broadcastIntentLocked(null, null, intent, null, 16660 new IIntentReceiver.Stub() { 16661 public void performReceive(Intent intent, int resultCode, 16662 String data, Bundle extras, boolean ordered, 16663 boolean sticky, int sendingUser) { 16664 userInitialized(uss, userId); 16665 } 16666 }, 0, null, null, null, AppOpsManager.OP_NONE, 16667 true, false, MY_PID, Process.SYSTEM_UID, 16668 userId); 16669 uss.initializing = true; 16670 } else { 16671 getUserManagerLocked().makeInitialized(userInfo.id); 16672 } 16673 } 16674 16675 if (foreground) { 16676 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16677 if (homeInFront) { 16678 startHomeActivityLocked(userId); 16679 } else { 16680 mStackSupervisor.resumeTopActivitiesLocked(); 16681 } 16682 EventLogTags.writeAmSwitchUser(userId); 16683 getUserManagerLocked().userForeground(userId); 16684 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16685 } else { 16686 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16687 } 16688 16689 if (needStart) { 16690 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16692 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16693 broadcastIntentLocked(null, null, intent, 16694 null, new IIntentReceiver.Stub() { 16695 @Override 16696 public void performReceive(Intent intent, int resultCode, String data, 16697 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16698 throws RemoteException { 16699 } 16700 }, 0, null, null, 16701 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16702 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16703 } 16704 } 16705 } finally { 16706 Binder.restoreCallingIdentity(ident); 16707 } 16708 16709 return true; 16710 } 16711 16712 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16713 long ident = Binder.clearCallingIdentity(); 16714 try { 16715 Intent intent; 16716 if (oldUserId >= 0) { 16717 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16718 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16719 | Intent.FLAG_RECEIVER_FOREGROUND); 16720 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16721 broadcastIntentLocked(null, null, intent, 16722 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16723 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16724 } 16725 if (newUserId >= 0) { 16726 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16728 | Intent.FLAG_RECEIVER_FOREGROUND); 16729 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16730 broadcastIntentLocked(null, null, intent, 16731 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16732 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16733 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16734 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16735 | Intent.FLAG_RECEIVER_FOREGROUND); 16736 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16737 broadcastIntentLocked(null, null, intent, 16738 null, null, 0, null, null, 16739 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16740 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16741 } 16742 } finally { 16743 Binder.restoreCallingIdentity(ident); 16744 } 16745 } 16746 16747 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16748 final int newUserId) { 16749 final int N = mUserSwitchObservers.beginBroadcast(); 16750 if (N > 0) { 16751 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16752 int mCount = 0; 16753 @Override 16754 public void sendResult(Bundle data) throws RemoteException { 16755 synchronized (ActivityManagerService.this) { 16756 if (mCurUserSwitchCallback == this) { 16757 mCount++; 16758 if (mCount == N) { 16759 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16760 } 16761 } 16762 } 16763 } 16764 }; 16765 synchronized (this) { 16766 uss.switching = true; 16767 mCurUserSwitchCallback = callback; 16768 } 16769 for (int i=0; i<N; i++) { 16770 try { 16771 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16772 newUserId, callback); 16773 } catch (RemoteException e) { 16774 } 16775 } 16776 } else { 16777 synchronized (this) { 16778 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16779 } 16780 } 16781 mUserSwitchObservers.finishBroadcast(); 16782 } 16783 16784 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16785 synchronized (this) { 16786 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16787 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16788 } 16789 } 16790 16791 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16792 mCurUserSwitchCallback = null; 16793 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16794 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16795 oldUserId, newUserId, uss)); 16796 } 16797 16798 void userInitialized(UserStartedState uss, int newUserId) { 16799 completeSwitchAndInitalize(uss, newUserId, true, false); 16800 } 16801 16802 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16803 completeSwitchAndInitalize(uss, newUserId, false, true); 16804 } 16805 16806 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16807 boolean clearInitializing, boolean clearSwitching) { 16808 boolean unfrozen = false; 16809 synchronized (this) { 16810 if (clearInitializing) { 16811 uss.initializing = false; 16812 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16813 } 16814 if (clearSwitching) { 16815 uss.switching = false; 16816 } 16817 if (!uss.switching && !uss.initializing) { 16818 mWindowManager.stopFreezingScreen(); 16819 unfrozen = true; 16820 } 16821 } 16822 if (unfrozen) { 16823 final int N = mUserSwitchObservers.beginBroadcast(); 16824 for (int i=0; i<N; i++) { 16825 try { 16826 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16827 } catch (RemoteException e) { 16828 } 16829 } 16830 mUserSwitchObservers.finishBroadcast(); 16831 } 16832 } 16833 16834 void scheduleStartProfilesLocked() { 16835 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16836 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16837 DateUtils.SECOND_IN_MILLIS); 16838 } 16839 } 16840 16841 void startProfilesLocked() { 16842 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16843 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16844 mCurrentUserId, false /* enabledOnly */); 16845 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16846 for (UserInfo user : profiles) { 16847 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16848 && user.id != mCurrentUserId) { 16849 toStart.add(user); 16850 } 16851 } 16852 final int n = toStart.size(); 16853 int i = 0; 16854 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16855 startUserInBackground(toStart.get(i).id); 16856 } 16857 if (i < n) { 16858 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16859 } 16860 } 16861 16862 void finishUserBoot(UserStartedState uss) { 16863 synchronized (this) { 16864 if (uss.mState == UserStartedState.STATE_BOOTING 16865 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16866 uss.mState = UserStartedState.STATE_RUNNING; 16867 final int userId = uss.mHandle.getIdentifier(); 16868 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16869 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16870 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16871 broadcastIntentLocked(null, null, intent, 16872 null, null, 0, null, null, 16873 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16874 true, false, MY_PID, Process.SYSTEM_UID, userId); 16875 } 16876 } 16877 } 16878 16879 void finishUserSwitch(UserStartedState uss) { 16880 synchronized (this) { 16881 finishUserBoot(uss); 16882 16883 startProfilesLocked(); 16884 16885 int num = mUserLru.size(); 16886 int i = 0; 16887 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16888 Integer oldUserId = mUserLru.get(i); 16889 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16890 if (oldUss == null) { 16891 // Shouldn't happen, but be sane if it does. 16892 mUserLru.remove(i); 16893 num--; 16894 continue; 16895 } 16896 if (oldUss.mState == UserStartedState.STATE_STOPPING 16897 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16898 // This user is already stopping, doesn't count. 16899 num--; 16900 i++; 16901 continue; 16902 } 16903 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16904 // Owner and current can't be stopped, but count as running. 16905 i++; 16906 continue; 16907 } 16908 // This is a user to be stopped. 16909 stopUserLocked(oldUserId, null); 16910 num--; 16911 i++; 16912 } 16913 } 16914 } 16915 16916 @Override 16917 public int stopUser(final int userId, final IStopUserCallback callback) { 16918 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16919 != PackageManager.PERMISSION_GRANTED) { 16920 String msg = "Permission Denial: switchUser() from pid=" 16921 + Binder.getCallingPid() 16922 + ", uid=" + Binder.getCallingUid() 16923 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16924 Slog.w(TAG, msg); 16925 throw new SecurityException(msg); 16926 } 16927 if (userId <= 0) { 16928 throw new IllegalArgumentException("Can't stop primary user " + userId); 16929 } 16930 synchronized (this) { 16931 return stopUserLocked(userId, callback); 16932 } 16933 } 16934 16935 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16936 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16937 if (mCurrentUserId == userId) { 16938 return ActivityManager.USER_OP_IS_CURRENT; 16939 } 16940 16941 final UserStartedState uss = mStartedUsers.get(userId); 16942 if (uss == null) { 16943 // User is not started, nothing to do... but we do need to 16944 // callback if requested. 16945 if (callback != null) { 16946 mHandler.post(new Runnable() { 16947 @Override 16948 public void run() { 16949 try { 16950 callback.userStopped(userId); 16951 } catch (RemoteException e) { 16952 } 16953 } 16954 }); 16955 } 16956 return ActivityManager.USER_OP_SUCCESS; 16957 } 16958 16959 if (callback != null) { 16960 uss.mStopCallbacks.add(callback); 16961 } 16962 16963 if (uss.mState != UserStartedState.STATE_STOPPING 16964 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16965 uss.mState = UserStartedState.STATE_STOPPING; 16966 updateStartedUserArrayLocked(); 16967 16968 long ident = Binder.clearCallingIdentity(); 16969 try { 16970 // We are going to broadcast ACTION_USER_STOPPING and then 16971 // once that is done send a final ACTION_SHUTDOWN and then 16972 // stop the user. 16973 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16974 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16975 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16976 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16977 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16978 // This is the result receiver for the final shutdown broadcast. 16979 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16980 @Override 16981 public void performReceive(Intent intent, int resultCode, String data, 16982 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16983 finishUserStop(uss); 16984 } 16985 }; 16986 // This is the result receiver for the initial stopping broadcast. 16987 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16988 @Override 16989 public void performReceive(Intent intent, int resultCode, String data, 16990 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16991 // On to the next. 16992 synchronized (ActivityManagerService.this) { 16993 if (uss.mState != UserStartedState.STATE_STOPPING) { 16994 // Whoops, we are being started back up. Abort, abort! 16995 return; 16996 } 16997 uss.mState = UserStartedState.STATE_SHUTDOWN; 16998 } 16999 mSystemServiceManager.stopUser(userId); 17000 broadcastIntentLocked(null, null, shutdownIntent, 17001 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17002 true, false, MY_PID, Process.SYSTEM_UID, userId); 17003 } 17004 }; 17005 // Kick things off. 17006 broadcastIntentLocked(null, null, stoppingIntent, 17007 null, stoppingReceiver, 0, null, null, 17008 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17009 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17010 } finally { 17011 Binder.restoreCallingIdentity(ident); 17012 } 17013 } 17014 17015 return ActivityManager.USER_OP_SUCCESS; 17016 } 17017 17018 void finishUserStop(UserStartedState uss) { 17019 final int userId = uss.mHandle.getIdentifier(); 17020 boolean stopped; 17021 ArrayList<IStopUserCallback> callbacks; 17022 synchronized (this) { 17023 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17024 if (mStartedUsers.get(userId) != uss) { 17025 stopped = false; 17026 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17027 stopped = false; 17028 } else { 17029 stopped = true; 17030 // User can no longer run. 17031 mStartedUsers.remove(userId); 17032 mUserLru.remove(Integer.valueOf(userId)); 17033 updateStartedUserArrayLocked(); 17034 17035 // Clean up all state and processes associated with the user. 17036 // Kill all the processes for the user. 17037 forceStopUserLocked(userId, "finish user"); 17038 } 17039 } 17040 17041 for (int i=0; i<callbacks.size(); i++) { 17042 try { 17043 if (stopped) callbacks.get(i).userStopped(userId); 17044 else callbacks.get(i).userStopAborted(userId); 17045 } catch (RemoteException e) { 17046 } 17047 } 17048 17049 if (stopped) { 17050 mSystemServiceManager.cleanupUser(userId); 17051 synchronized (this) { 17052 mStackSupervisor.removeUserLocked(userId); 17053 } 17054 } 17055 } 17056 17057 @Override 17058 public UserInfo getCurrentUser() { 17059 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17060 != PackageManager.PERMISSION_GRANTED) && ( 17061 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17062 != PackageManager.PERMISSION_GRANTED)) { 17063 String msg = "Permission Denial: getCurrentUser() from pid=" 17064 + Binder.getCallingPid() 17065 + ", uid=" + Binder.getCallingUid() 17066 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17067 Slog.w(TAG, msg); 17068 throw new SecurityException(msg); 17069 } 17070 synchronized (this) { 17071 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17072 } 17073 } 17074 17075 int getCurrentUserIdLocked() { 17076 return mCurrentUserId; 17077 } 17078 17079 @Override 17080 public boolean isUserRunning(int userId, boolean orStopped) { 17081 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17082 != PackageManager.PERMISSION_GRANTED) { 17083 String msg = "Permission Denial: isUserRunning() from pid=" 17084 + Binder.getCallingPid() 17085 + ", uid=" + Binder.getCallingUid() 17086 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17087 Slog.w(TAG, msg); 17088 throw new SecurityException(msg); 17089 } 17090 synchronized (this) { 17091 return isUserRunningLocked(userId, orStopped); 17092 } 17093 } 17094 17095 boolean isUserRunningLocked(int userId, boolean orStopped) { 17096 UserStartedState state = mStartedUsers.get(userId); 17097 if (state == null) { 17098 return false; 17099 } 17100 if (orStopped) { 17101 return true; 17102 } 17103 return state.mState != UserStartedState.STATE_STOPPING 17104 && state.mState != UserStartedState.STATE_SHUTDOWN; 17105 } 17106 17107 @Override 17108 public int[] getRunningUserIds() { 17109 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17110 != PackageManager.PERMISSION_GRANTED) { 17111 String msg = "Permission Denial: isUserRunning() from pid=" 17112 + Binder.getCallingPid() 17113 + ", uid=" + Binder.getCallingUid() 17114 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17115 Slog.w(TAG, msg); 17116 throw new SecurityException(msg); 17117 } 17118 synchronized (this) { 17119 return mStartedUserArray; 17120 } 17121 } 17122 17123 private void updateStartedUserArrayLocked() { 17124 int num = 0; 17125 for (int i=0; i<mStartedUsers.size(); i++) { 17126 UserStartedState uss = mStartedUsers.valueAt(i); 17127 // This list does not include stopping users. 17128 if (uss.mState != UserStartedState.STATE_STOPPING 17129 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17130 num++; 17131 } 17132 } 17133 mStartedUserArray = new int[num]; 17134 num = 0; 17135 for (int i=0; i<mStartedUsers.size(); i++) { 17136 UserStartedState uss = mStartedUsers.valueAt(i); 17137 if (uss.mState != UserStartedState.STATE_STOPPING 17138 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17139 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17140 num++; 17141 } 17142 } 17143 } 17144 17145 @Override 17146 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17147 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17148 != PackageManager.PERMISSION_GRANTED) { 17149 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17150 + Binder.getCallingPid() 17151 + ", uid=" + Binder.getCallingUid() 17152 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17153 Slog.w(TAG, msg); 17154 throw new SecurityException(msg); 17155 } 17156 17157 mUserSwitchObservers.register(observer); 17158 } 17159 17160 @Override 17161 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17162 mUserSwitchObservers.unregister(observer); 17163 } 17164 17165 private boolean userExists(int userId) { 17166 if (userId == 0) { 17167 return true; 17168 } 17169 UserManagerService ums = getUserManagerLocked(); 17170 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17171 } 17172 17173 int[] getUsersLocked() { 17174 UserManagerService ums = getUserManagerLocked(); 17175 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17176 } 17177 17178 UserManagerService getUserManagerLocked() { 17179 if (mUserManager == null) { 17180 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17181 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17182 } 17183 return mUserManager; 17184 } 17185 17186 private int applyUserId(int uid, int userId) { 17187 return UserHandle.getUid(userId, uid); 17188 } 17189 17190 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17191 if (info == null) return null; 17192 ApplicationInfo newInfo = new ApplicationInfo(info); 17193 newInfo.uid = applyUserId(info.uid, userId); 17194 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17195 + info.packageName; 17196 return newInfo; 17197 } 17198 17199 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17200 if (aInfo == null 17201 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17202 return aInfo; 17203 } 17204 17205 ActivityInfo info = new ActivityInfo(aInfo); 17206 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17207 return info; 17208 } 17209 17210 private final class LocalService extends ActivityManagerInternal { 17211 @Override 17212 public void goingToSleep() { 17213 ActivityManagerService.this.goingToSleep(); 17214 } 17215 17216 @Override 17217 public void wakingUp() { 17218 ActivityManagerService.this.wakingUp(); 17219 } 17220 } 17221 17222 /** 17223 * An implementation of IAppTask, that allows an app to manage its own tasks via 17224 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17225 * only the process that calls getAppTasks() can call the AppTask methods. 17226 */ 17227 class AppTaskImpl extends IAppTask.Stub { 17228 private int mTaskId; 17229 private int mCallingUid; 17230 17231 public AppTaskImpl(int taskId, int callingUid) { 17232 mTaskId = taskId; 17233 mCallingUid = callingUid; 17234 } 17235 17236 @Override 17237 public void finishAndRemoveTask() { 17238 // Ensure that we are called from the same process that created this AppTask 17239 if (mCallingUid != Binder.getCallingUid()) { 17240 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17241 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17242 return; 17243 } 17244 17245 synchronized (ActivityManagerService.this) { 17246 long origId = Binder.clearCallingIdentity(); 17247 try { 17248 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17249 if (tr != null) { 17250 // Only kill the process if we are not a new document 17251 int flags = tr.getBaseIntent().getFlags(); 17252 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17253 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17254 removeTaskByIdLocked(mTaskId, 17255 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17256 } 17257 } finally { 17258 Binder.restoreCallingIdentity(origId); 17259 } 17260 } 17261 } 17262 17263 @Override 17264 public ActivityManager.RecentTaskInfo getTaskInfo() { 17265 // Ensure that we are called from the same process that created this AppTask 17266 if (mCallingUid != Binder.getCallingUid()) { 17267 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17268 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17269 return null; 17270 } 17271 17272 synchronized (ActivityManagerService.this) { 17273 long origId = Binder.clearCallingIdentity(); 17274 try { 17275 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17276 if (tr != null) { 17277 return createRecentTaskInfoFromTaskRecord(tr); 17278 } 17279 } finally { 17280 Binder.restoreCallingIdentity(origId); 17281 } 17282 return null; 17283 } 17284 } 17285 } 17286} 17287